# gizai:agent

an agent is a model, its instructions, typed tools and the conversation so far. `run` streams one answer: the model writes, calls tools (the calls of one turn run at once), reads their results and writes again, until it answers or a limit ends the run. `ask<T>` asks for a record T and gives a T. A tool is a plain function of a record: its JSON Schema comes from the record's declaration and docs (Memory.describe), and its arguments are read as that record (Json.decode), so no schema is written by hand. A model is one function that streams a turn: `endpoint` is any OpenAI-compatible API (gizlang:hub), and a test gives a scripted one.

```gizlang
import * as Agent from "gizai:agent";
```

## Types

### `Call`

```gizlang
type Call = Hub.Call
```

A tool call the model made: its id, the tool, and its arguments (a JSON object's text).

### `Message`

```gizlang
type Message = { role: string; text: string; reasoning: string; calls: Vec<Call>; call: string; details: Vec<string>; images?: Vec<string>; }
```

One message of the conversation: "user", "assistant" (its text, reasoning, the calls it made and the provider's
reasoning details that continue it) or "tool" (the result `text` of the call `call`).

- `role`: `string`
- `text`: `string`
- `reasoning`: `string`
- `calls`: `Vec<gizlang_hub.Call>`
- `call`: `string`
- `details`: `Vec<string>`
- `images`: `_gizlang_sdk_core.Option<Vec<string>>` — The pictures the person showed with a "user" message, as data URLs (data:image/png;base64,...).

### `Piece`

```gizlang
type Piece = { kind: string; text: string; call: Call; }
```

What a run shows as it goes: "text" and "reasoning" as the model writes them, "call" when it calls a tool (`call`:
its name and JSON input), "result" or "failed" with the tool's answer, and at the end "done" with the answer or
"error" with why the run failed, or "stopped" with the text written when `stop` ended it.

- `kind`: `string`
- `text`: `string`
- `call`: `gizlang_hub.Call`

### `Request`

```gizlang
type Request = { instructions: string; messages: Vec<Message>; tools: Vec<JsonValue>; answer: bool; }
```

What the model is asked for one turn: the instructions, the conversation, the tools (OpenAI function objects),
and `answer`: write, do not call a tool.

- `instructions`: `string`
- `messages`: `Vec<M19.Message>`
- `tools`: `Vec<gizlang_json.Json>`
- `answer`: `bool`

### `Turn`

```gizlang
type Turn = { text: string; reasoning: string; calls: Vec<Call>; details: Vec<string>; tokens: i64; input: i64; window: i64; }
```

One turn of the model: its text, reasoning, tool calls and reasoning details, the tokens it wrote and read, and the
model's context window in tokens (0: unknown).

- `text`: `string`
- `reasoning`: `string`
- `calls`: `Vec<gizlang_hub.Call>`
- `details`: `Vec<string>`
- `tokens`: `i64`
- `input`: `i64`
- `window`: `i64`

### `Model`

```gizlang
type Model = { name: string; turn: (sys: System, r: Request, each: (p: Piece) => bool) => Result<Turn, string>; }
```

A model: its name and the function that writes a turn, giving each text or reasoning piece to `each` as it comes
(a false from `each` stops the turn).

- `name`: `string`
- `turn`: `(sys: gizlang_system.System, r: M19.Request, each: (p: M19.Piece) => bool) => _gizlang_sdk_core.Result<M19.Turn, string>`

### `Tool`

```gizlang
type Tool = { name: string; description: string; parameters: JsonValue; readOnly: bool; run: (arguments: string) => Result<string, string>; }
```

A tool: its name, what it does, the JSON Schema of its input, whether it only reads (a call of it runs without
`approve`), and the function that runs it on its arguments' text and answers JSON text.

- `name`: `string`
- `description`: `string`
- `parameters`: `gizlang_json.Json`
- `readOnly`: `bool`
- `run`: `(arguments: string) => _gizlang_sdk_core.Result<string, string>`

### `Agent`

```gizlang
type Agent = { model: Model; instructions: string; tools: Vec<Tool>; history: Vec<Message>; rounds: i64; maxTokens: i64; maxMs: i64; stop: () => bool; approve: (c: Call) => bool; tokens: i64; input: i64; context: i64; window: i64; }
```

An agent: the model, its instructions and tools, the conversation so far (each run adds to it), its limits (tool
rounds of one run; tokens written and milliseconds of one run, 0: none), the tokens its runs wrote and read, how
many tokens the conversation holds after the last turn (`context`) of the model's window (`window`, 0: unknown), and
what a person does to a running agent: `stop`, asked between pieces and between rounds (true ends the run, keeping
what was written, with a "stopped" piece), and `approve`, asked before each tool call runs (it may wait for the
person; false gives the model DECLINED as the result).

- `model`: `M19.Model`
- `instructions`: `string`
- `tools`: `Vec<M19.Tool>`
- `history`: `Vec<M19.Message>`
- `rounds`: `i64`
- `maxTokens`: `i64`
- `maxMs`: `i64`
- `stop`: `() => bool`
- `approve`: `(c: gizlang_hub.Call) => bool`
- `tokens`: `i64`
- `input`: `i64`
- `context`: `i64`
- `window`: `i64`

### `Attachment`

```gizlang
type Attachment = { name: string; type: string; path: string; }
```

A file the person gives with a message: its name, its media type (image/png, application/pdf, text/csv...) and where
it is on this computer. A picture goes to the model as a picture; a document's text (a PDF's words, a text file) joins
the message, and a long one is read in parts with the tool read_file.

- `name`: `string`
- `type`: `string`
- `path`: `string`

## Functions

### `agent`

```gizlang
function agent(model: Model, instructions: string, tools: Vec<Tool>): Agent
```

An agent of `model` with `instructions` and `tools`, an empty conversation and at most 16 tool rounds a run.

### `tool`

```gizlang
function tool<I, O>(name: string, run: (input: I) => Result<O, string>): Tool
```

The tool `name` that runs `run` on its input record I and answers O as JSON. Its description is I's doc comment
and each field's doc describes that field. `run` is a function `(input: I): O throws string`; what it throws goes
back to the model as the tool's error.

### `schema`

```gizlang
function schema<T>(): JsonValue
```

The JSON Schema of the record or union T, from its declaration.

### `run`

```gizlang
function run(sys: System, a: mut Agent, prompt: string, each?: (p: Piece) => void, files: Vec<Attachment> = []): string throws string
```

Asks the agent `prompt` with the attached `files` (Attachment) and gives its answer, after the tool calls it makes;
each piece goes to `each` as it comes.
The prompt and every message of the run join `a.history`.

Effects: fail, read, write, console, io.

### `ask`

```gizlang
function ask<T>(sys: System, a: mut Agent, prompt: string, each?: (p: Piece) => void): T throws string
```

Asks the agent `prompt` for a record T: the model answers by calling the tool `answer` with a T, which is read and
checked as T. An answer that does not read as T goes back to the model as the error of its call.

### `title`

```gizlang
function title(sys: System, model: Model, first: string): string throws string
```

A short title for a conversation that begins with `first`, for a list of conversations: one turn of `model`, no
tools, its first line without quotes, at most 60 characters.

Effects: fail, read, write, console, io.

### `endpoint`

```gizlang
function endpoint(sys: System, model: string = ""): Model throws string
```

The model `model` (by default AI_MODEL) of the OpenAI-compatible API of AI_URL and AI_API_KEY (gizlang:hub's
modelApi: OpenRouter when AI_URL is unset; vLLM, Ollama, llama.cpp or `giz ai serve` by AI_URL).

Effects: fail, write, io.

### `served`

```gizlang
function served(name: string, id: string, window: i64, api: (s: System) => Result<Hub.ModelApi, string>): Model
```

Model `id` of the API that `api` gives at each turn, shown as `name`; `window` is its context window (-1: read
from the API at the first turn). The API is taken per turn because its key may expire (a sign-in's token): a key
that cannot be had fails that turn with why, and the next turn tries again.

Effects: fail, write.

### `windowOf`

```gizlang
function windowOf(api: Hub.ModelApi, name: string): i64
```

The context window of model `name` as the API `api` lists it (GET /models, asked once a model); 0 when it does not
say or does not answer, which only leaves the window unknown.

Effects: fail, read, write, console, io.

### `streamed`

```gizlang
function streamed(api: Hub.ModelApi, name: string, window: i64, r: Request, each: (p: Piece) => bool): Result<Turn, string>
```

One turn of `r` from model `name` of the API `api`, streamed; `window` is the model's context window (0: unknown).

Effects: fail, read, write, console, io.

### `scripted`

```gizlang
function scripted(turns: Vec<Turn>): Model
```

A model that gives `turns` in order, one a request, each text in pieces of at most 4 bytes. For tests and
examples that need no GPU and no network.

Effects: fail, write.

### `says`

```gizlang
function says(text: string): Turn
```

A scripted turn that says `text`.

### `calls`

```gizlang
function calls(named: Vec<Call>): Turn
```

A scripted turn that calls `calls` (each a tool name and its arguments' JSON text), with ids call_0, call_1...

## Constants

### `ANSWER`

```gizlang
const ANSWER = "answer"
```

The name of the tool that `ask` adds: its input is the record asked for.

### `DECLINED`

```gizlang
const DECLINED = "The person declined this call."
```

What a declined call gives the model as its result.

### `READ_FILE`

```gizlang
const READ_FILE = "read_file"
```

The name of the tool that reads a long document in parts.

