Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/contributing/sdk-typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ const session = query({
| `model` | string | — | Model ID |
| `permissionMode` | string | `default` | Approval mode |
| `canUseTool` | function | — | Per-tool approval callback |
| `timeout` | object | — | `{ canUseTool?: number }` ms; forwarded to the CLI so its control-plane timeout matches your callback (capped 10m) |
| `allowedTools` | string[] | — | Auto-approved tools |
| `excludeTools` | string[] | — | Blocked tools (highest priority) |
| `coreTools` | string[] | — | If set, only these tools available |
Expand Down
10 changes: 10 additions & 0 deletions docs/explanation/agent-harness.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ No configuration required.

---

## Reactive compression

Compression normally runs *proactively* — before a turn is sent, once history crosses a token threshold. Estimates can still be wrong (a tool returns far more than expected, or a provider counts tokens differently), so the harness also compresses *reactively*: if a provider rejects a request because the prompt exceeds the context window, the harness force-compresses the live history once and retries the same request automatically.

Context-overflow rejections are classified provider-agnostically (distinguished from superficially-similar timeouts, which are *not* compressed). The reactive retry fires at most once per request — if the prompt is still too large after compression, the original error surfaces rather than looping.

No configuration required.

---

## Repo map

`repo_map` is a tool available to agents that builds a PageRank-ranked map of the most relevant source files in the repository, using the import graph and optionally seed files to personalize results.
Expand Down
12 changes: 9 additions & 3 deletions docs/guides/goal.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Run `/goal` with no arguments to inspect the current state.
/goal
```

If a goal is active, the status shows the condition, how long it has been running, how many turns have been evaluated, the tokens spent on evaluation so far, and the evaluator's most recent reason. If no goal is active but one was achieved earlier in the session, the status shows the achieved condition along with how long it took.
If a goal is active, the status shows the condition, how long it has been running, how many turns have been evaluated, the tokens spent on evaluation so far, and the evaluator's most recent reason. If no goal is active but one ended earlier in the session, the status reports the most recent outcome: a goal that was **achieved** (with how long it took) or one that was **abandoned as impossible** (with the reason it was deemed unachievable — see [How evaluation works](#how-evaluation-works)).

## Clear a goal

Expand All @@ -59,9 +59,15 @@ Run `/goal clear` to remove an active goal before its condition is met. Any of `

## How evaluation works

Each time the main agent finishes a turn, the condition and the conversation so far are sent to your configured content generator for a one-shot evaluator call. The evaluator returns a yes-or-no decision and a short reason. A "no" tells proto to keep working and includes the reason as guidance for the next turn; a "yes" clears the goal and records the achieved entry on `/goal`.
Each time the main agent finishes a turn, the condition and the conversation so far are sent to your configured content generator for a one-shot evaluator call. The evaluator returns one of three verdicts and a short reason:

The evaluator does not call tools, so it can only judge what proto has already surfaced in the conversation. If the evaluator can't tell from the transcript, treat it as "no" and ask for the missing evidence.
- **Met** — clears the goal and records the achieved entry on `/goal`.
- **Not met** — proto keeps working, passing the reason as guidance for the next turn.
- **Impossible** — the condition is genuinely unachievable in this session (it is self-contradictory, depends on a resource or capability that isn't available, or every reasonable approach has been exhausted with no path forward). Proto stops the autonomous loop and records the goal as **abandoned**, rather than looping forever on something it can never satisfy.

The "impossible" verdict is deliberately conservative: the assistant *claiming* a goal is impossible counts as evidence, not proof, and the evaluator independently confirms it. Slow progress or temporarily missing evidence is treated as "not met", not "impossible".

The evaluator does not call tools, so it can only judge what proto has already surfaced in the conversation. If the evaluator can't tell from the transcript, treat it as "not met" and ask for the missing evidence.

## How `/goal` differs from `/loop`

Expand Down
24 changes: 16 additions & 8 deletions docs/reference/sdk-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,22 @@ Returns a `Query` instance (implements `AsyncIterable<SDKMessage>`).

### Permissions

| Option | Type | Default | Description |
| ---------------- | ---------- | --------- | -------------------------------------- |
| `permissionMode` | string | `default` | `default`, `plan`, `auto-edit`, `yolo` |
| `canUseTool` | CanUseTool | — | Custom per-tool permission callback |
| `allowedTools` | string[] | — | Auto-approved tools |
| `excludeTools` | string[] | — | Blocked tools (highest priority) |
| `coreTools` | string[] | — | If set, only these tools are available |
| `authType` | AuthType | `openai` | `openai`, `anthropic`, `gemini` |
| Option | Type | Default | Description |
| ---------------- | -------------------------- | --------- | -------------------------------------------- |
| `permissionMode` | string | `default` | `default`, `plan`, `auto-edit`, `yolo` |
| `canUseTool` | CanUseTool | — | Custom per-tool permission callback |
| `timeout` | `{ canUseTool?: number }` | — | Per-operation timeouts (ms). See note below. |
| `allowedTools` | string[] | — | Auto-approved tools |
| `excludeTools` | string[] | — | Blocked tools (highest priority) |
| `coreTools` | string[] | — | If set, only these tools are available |
| `authType` | AuthType | `openai` | `openai`, `anthropic`, `gemini` |

> **`timeout.canUseTool`** bounds how long a `canUseTool` permission request may
> stay pending before it is rejected. The SDK forwards this value to the CLI at
> session initialization, so the CLI's control-plane timeout matches your
> callback's — a long-running approval handler is no longer cut short by the
> CLI's default (60s) before your own timeout elapses. Capped at 10 minutes.
> When unset, the CLI default applies.

### Session

Expand Down
Loading