@canonmsg/agent-sdk 13.0.3 → 13.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/chunks/{chunk-ZPBOGOAD.js → chunk-5YKGDUJX.js} +271 -359
- package/dist/chunks/{chunk-XKUG2BQR.js → chunk-6FD6KFQN.js} +528 -167
- package/dist/cli.js +50 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.js +6 -2
- package/dist/internal/core/client.d.ts +1 -215
- package/dist/internal/core/index.d.ts +0 -1
- package/dist/internal/endpoint/completions.d.ts +45 -0
- package/dist/internal/endpoint/engine.d.ts +15 -0
- package/dist/internal/endpoint/index.d.ts +1 -0
- package/dist/internal/endpoint/transient-publisher.d.ts +3 -2
- package/dist/media.js +1 -1
- package/dist/runner/errands.d.ts +2 -2
- package/dist/runner/runner.d.ts +34 -1
- package/dist/runner/wake.d.ts +16 -0
- package/package.json +1 -1
- package/dist/internal/core/completed-output-journal.d.ts +0 -34
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ process.on('SIGTERM', () => runner.stop().then(() => process.exit(0)));
|
|
|
55
55
|
|
|
56
56
|
`createRunner` checks `home` before anything else. `start()` connects and starts taking input. `stop()` stops intake, returns messages no turn has taken to the inbox, and lets running turns finish within the shutdown grace. The runner reads no environment variables.
|
|
57
57
|
|
|
58
|
-
`runner.communicate(input)` sends outside any turn, for example from a cron job. It takes the `communicate` tool's input (the exported `CommunicateInput` type), acts under the agent's identity, and needs `start()` first:
|
|
58
|
+
`runner.communicate(input)` sends outside any turn, for example from a cron job. It takes the `communicate` tool's input (the exported `CommunicateInput` type), acts under the agent's identity, and needs `start()` first. Text to a conversation is encrypted for the members it has then, journaled in `CANON_HOME` and sent once, even across a restart, as a reply is; `start_conversation` has the agent's device found the conversation encrypted and send the opening line. The same `messageId` is the same message or start, and other text under it is refused (`MESSAGE_ID_CONFLICT`). A send Canon cannot take yet fails with `OPERATION_PENDING`: it is saved and goes on its own, and calling again with the same `messageId` says how it went. One Canon refused stays refused (`MESSAGE_REFUSED`). An agent whose outbound policy is closed writes unprompted only to its owner, in a conversation of just the two of them; anywhere else it is refused (`OUTBOUND_NOT_ALLOWED`). Listing, creating, inviting and leaving go to Canon as they are:
|
|
59
59
|
|
|
60
60
|
```js
|
|
61
61
|
await runner.communicate({
|
|
@@ -227,6 +227,8 @@ Every room is encrypted, so the runner needs the agent's MLS device, which it ke
|
|
|
227
227
|
| `agentTurnCap` | 6 | Encrypted rooms: how many agent @mentions in a row wake the agent in a room before a person writes there again |
|
|
228
228
|
| `mentionAliases` | none | Encrypted rooms: other names that @mention the agent, such as its role |
|
|
229
229
|
| `sessionApprovalForDestructive` | off | Encrypted rooms: whether the owner may allow an action the runtime marks destructive for the rest of the session (CLI `--allow-session-for-destructive`) |
|
|
230
|
+
| `wake` | left as registered | The agent's signed wake callback, registered at each start, or `null` to remove it; see [Waking and sleeping](#waking-and-sleeping) |
|
|
231
|
+
| `idleTimeoutMs`, `onIdle` | off | `onIdle(activity)` once the runner has had nothing to do for this long; see [Waking and sleeping](#waking-and-sleeping) |
|
|
230
232
|
|
|
231
233
|
`baseUrl`, `streamUrl`, `endpoint` and `fetch` are test seams; production never sets them. `codeDriver`'s second argument overrides its capabilities, such as `outboundFiles` and `maxConcurrentTurns` (default 8).
|
|
232
234
|
|
|
@@ -328,6 +330,14 @@ canon-agent errands --profile engineer --cancel <errand id>
|
|
|
328
330
|
- **Replies.** Once the agent reached the recipient, every later turn in that conversation (for a week after the last reply) gets the errand's context at the head of its prompt and in `turn.input.errands`, so the agent knows why it is there. Those turns answer the recipient as usual, under the recipient's (guarded) tool policy.
|
|
329
331
|
- **Status.** `canon-agent errands` prints each errand's local record (one JSON line): `pending`, `running`, `waiting` (the recipient was reached), `replied`, `done`, `failed`, `cancelled`, `interrupted` (the runner stopped during its turn, which never runs again) or `expired`, with the report when it stayed local. `--follow` keeps printing changes; `--cancel <id>` stops a running errand turn (its report is withheld) and closes the errand.
|
|
330
332
|
|
|
333
|
+
## Waking and sleeping
|
|
334
|
+
|
|
335
|
+
An agent need not run all the time. Canon can wake it, and the runner says when it has nothing to do, so its host can stop or suspend it in between ([agent-wake.md](https://github.com/HeyBobChan/canon/blob/main/docs/agent-wake.md)).
|
|
336
|
+
|
|
337
|
+
- **Wake.** `wake: { callbackUrl, secret, conversationIds }` (CLI `--wake-config <file>`) registers, at each start, a public HTTPS callback for up to 32 rooms. When a person types in one, or a message arrives there, Canon POSTs it a signed [Standard Webhooks](https://www.standardwebhooks.com/) request whose body is only `{"type":"wake","reason":"typing"|"event"}`: no room, sender or content. The host starts or resumes the agent and answers 2xx once it is ready; the agent then reads its input as usual. The secret is `whsec_` and the padded base64 of 32 random bytes (`echo "whsec_$(openssl rand -base64 32)"`). Canon first sends the URL a signed `{"type":"verification","challenge":"…"}`, which must be answered with `{"challenge":"…"}` and wake nothing, and the start fails if it is not. `wake: null` (`--wake-off`) removes the callback; leaving it out leaves it as it is.
|
|
338
|
+
- **Idle.** `runner.activity()` reports what the runner has in hand, as counts: running `turns`, `inputs` waiting for one, `errands` waiting, and `outbound` operations Canon has not answered yet (a reply waiting out an outage counts). It is `idle` when all are 0. With `idleTimeoutMs` (at least 1 s), `onIdle(activity)` is called once the runner has been idle that long, and again only after new activity. The CLI's `--idle-timeout 10m` stops gracefully and exits 0 then.
|
|
339
|
+
- **What a host must add.** Typing reaches the host's callback, not the runner, so a host keeps the agent awake while a person types (Canon sends at most one typing hint per room every 10 s while they do). A wake that arrives just as the runner goes idle can leave its input in the inbox: a host that has received a wake since the runner last reported idle starts it again. Errands written while the agent is stopped run at its next start.
|
|
340
|
+
|
|
331
341
|
## Registration
|
|
332
342
|
|
|
333
343
|
`ensureAgentProfile` registers an agent and keeps its key in `$CANON_HOME/agents.json` (default `~/.canon`), as a profile the CLI can use with `--profile`. It reuses an environment-bound profile, resumes the exact saved approval request, persists credentials before acknowledging delivery, and retries an interrupted acknowledgement on the next call. `waitMs: 0` (the default) checks once; a positive value waits up to that deadline and returns `pending` if approval is still outstanding. See the [complete runnable quickstart](https://canonmail.com/agents/build#run-a-complete-agent).
|