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
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,33 @@ Chronicle's audit history.
model: 'claude-opus-4-20250514',
systemPrompt: '...',
strategy: new AutobiographicalStrategy({ recentWindowTokens: 30000 }),
allowedTools: ['search', 'read', 'write'], // or 'all'
allowedTools: ['search--query', 'utils', 'files--archive'], // or 'all'
triggerSources: ['discord'], // or 'all'
maxTokens: 8192,
maxStreamTokens: 150_000, // input token budget before stream restart
}
```

`allowedTools` is enforced at dispatch for registered agents. Omission or
`'all'` permits all tools; an explicit list matches exact names, including
`module--utility` names. Utilities aren't tools of their own: an agent's model
and its scripts are offered them only through `utils`, whose `run` checks the
utility's own name. An agent that should use a utility lists both `utils` and
`module--utility`. The name alone passes the dispatch check for any call by
that name, whether the host makes it with `executeToolCall` on the agent's
behalf or the model or a script makes it without being offered it. The slot
is hidden when the agent can use no registered utility. If utilities exist
but none are permitted, `list` returns a failed `ToolResult` with the registered
and permitted counts and migration advice, and a list containing `utils`
logs one warning per Agent instance after registration.
An empty registry still returns a successful empty list.

Trusted module calls are exempt from agent allowlists. Genuinely unidentified
public callers, including unknown legacy caller names, remain unrestricted.
Framework-created ephemeral and conversation identities fail closed while
unregistered. Hosts using `createEphemeralAgent` must register and run the
returned agent through `runEphemeralToCompletion` for tool authority.

**Inference modes:**
- **Streaming** (default in framework): `startStreamWithInjections()` returns a `YieldingStream` that emits tokens, tool calls, and completion events. The framework drives the stream, dispatches tools, and resumes automatically.
- **Request/response**: `runInferenceWithInjections()` for simple complete-and-return usage with optional `AbortSignal` for cancellation.
Expand Down
1 change: 1 addition & 0 deletions changelog.d/agent-allowed-tools.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **Hosts:** explicit `allowedTools` lists must name each permitted utility as `module--utility`, or use `"all"`. Utilities aren't tools of their own: an agent's model and its scripts are offered them only through `utils`, whose `run` checks the utility's own name. An agent that should use a utility lists both `utils` and `module--utility`. The name alone passes the dispatch check for any call by that name, whether the host makes it with `executeToolCall` on the agent's behalf or the model or a script makes it without being offered it. `utils` alone no longer exposes a usable slot. When utilities are registered but none are permitted, `list` returns a failed `ToolResult` with both counts and migration advice instead of listing every registered utility, as earlier releases do. The slot is hidden in that case, and explicit lists containing `utils` log one warning per Agent instance. Hosts that construct depth-limited lists can obtain the existing namespaced utility catalogue through `getAllUtilities()`. Callers using `"all"` retain the permission policy; an empty registry continues to omit the slot and return a successful empty list. Hosts that drive `createEphemeralAgent` results themselves must use `runEphemeralToCompletion` to register and run them; framework-created identities have tool authority only while registered, and calls before a run or after retirement fail with a registration error. Adopt this change with the first connectome-host release after 0.10.2, which contains https://github.com/anima-research/connectome-host/pull/191.
1 change: 1 addition & 0 deletions changelog.d/agent-allowed-tools.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Enforce each registered agent's allowedTools before model, script and public agent-origin dispatch, including utility names inside utils run. Filter utility list/describe to the same executable names. Refused calls retain paired error results without inner lifecycle state. A refusal withholds a call's effect, never the model's choice about its own words: a refused send changes nothing about prose, so its round and what follows go out; a `skip_reply` that a round calls itself (not one a `code_execution` script makes) keeps that round's prose private and silences nothing after it, as a refused wake already did, when the agent's allowedTools doesn't name it, another module's namespaced `skip_reply` included, or when it's the registry's own `skip_reply` asking for a wake this host can't set; and a refused `think` is read as a permitted one is, so the private same-round policy keeps its round private wherever it applies, which is where rounds are routed live. Framework-created identities (ephemerals and conversation forks) have no tool authority while unregistered, including after disposal; genuine unregistered legacy callers and trusted module closures retain their behavior. Prose primers and bounce notices advertise prose_help only when permitted, and `think`'s and `journal`'s descriptions tell an agent to call `skip_reply` only when it may. `think`'s result and `prose_help`'s reference no longer point at the `skip_reply` tool.
4 changes: 2 additions & 2 deletions docs/explicit-prose-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ The grammar is never injected into context. The mode switch appends one short
durable notice (persisted per agent, so reboots never re-notice); the first
undelivered text produces a bounce notice carrying the exact resend syntax —
the model learns by doing, and the knowledge accretes into its own history.
The full reference is available on demand via the **`prose_help` tool**, whose
result is model-requested content. The system prompt is never touched: those
When the agent's `allowedTools` permits `prose_help`, the full reference is
available on demand through that tool. Its result is model-requested content. The system prompt is never touched: those
bytes belong to the recipe, and the deepest KV prefix must not vary with
framework code.

Expand Down
Loading
Loading