@canonmsg/agent-sdk 12.6.1 → 13.0.2

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.
Files changed (30) hide show
  1. package/README.md +23 -21
  2. package/dist/chunks/{chunk-S7BV74DN.js → chunk-5WPAB5MB.js} +293 -8
  3. package/dist/chunks/{chunk-DAJ7L7TN.js → chunk-DNHJGAEL.js} +378 -663
  4. package/dist/chunks/{chunk-HH7KR22P.js → chunk-DTAWEQCM.js} +2 -2
  5. package/dist/chunks/{chunk-5J4YPLNW.js → chunk-TYZT346O.js} +266 -1217
  6. package/dist/chunks/{chunk-QK37HAHC.js → chunk-YHDDOADK.js} +1 -1
  7. package/dist/chunks/{chunk-FVYKLH6I.js → chunk-YJUPKU47.js} +20 -5
  8. package/dist/chunks/{mls-crypto-4DZT2UFH.js → mls-crypto-NZVMSUFU.js} +2 -2
  9. package/dist/cli.js +32 -36
  10. package/dist/drivers/subprocess.d.ts +4 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +6 -6
  13. package/dist/internal/backend-contracts/mlsDevGroup.d.ts +17 -0
  14. package/dist/internal/core/completed-output-journal.d.ts +0 -5
  15. package/dist/internal/core/index.d.ts +3 -9
  16. package/dist/internal/core/retry.d.ts +2 -89
  17. package/dist/internal/core/silent-turn.d.ts +4 -33
  18. package/dist/internal/endpoint/engine.d.ts +3 -0
  19. package/dist/internal/endpoint/mls-dev-groups.d.ts +12 -0
  20. package/dist/internal/endpoint/mls-dev-text.d.ts +29 -0
  21. package/dist/internal/endpoint/transport.d.ts +1 -1
  22. package/dist/media.js +4 -4
  23. package/dist/mls-wasm-host.js +3 -3
  24. package/dist/runner/mls.d.ts +4 -7
  25. package/dist/runner/runner.d.ts +9 -12
  26. package/dist/runner/types.d.ts +31 -0
  27. package/package.json +1 -1
  28. package/dist/internal/core/approval-manager.d.ts +0 -43
  29. package/dist/internal/core/runtime-request-manager.d.ts +0 -283
  30. package/dist/internal/core/turn-verbosity.d.ts +0 -79
@@ -27,12 +27,12 @@ export declare function mlsAudiencePrincipals(value: MlsDevCurrentAudience): str
27
27
  */
28
28
  export declare function mlsAudienceEpoch(value: MlsDevCurrentAudience): string;
29
29
  /** What an encrypted room's text message is to the runner; Canon never learns it (`MlsIds.text`). */
30
- export type MlsTextKind = 'final' | 'failed' | 'restart' | 'said' | 'item';
30
+ export type MlsTextKind = 'final' | 'failed' | 'restart' | 'said' | 'item' | 'part';
31
31
  /**
32
32
  * §6 ids. Canon sees the message id of everything the runner sends to an encrypted room, and a card's request id (its
33
33
  * public binding), so these are keyed with a secret only this installation holds (`privateKey`): HMAC-SHA256 over
34
34
  * domain-separated inputs, cut to 128 bits. Canon can test no guess of the text, question or turn an id names, and every
35
- * text message (a final, a failure or restart notice, a `communicate` send, an item) has the same shape, `msg-<32 hex>`, so none
35
+ * text message (a final, a part of one, a failure or restart notice, a `communicate` send, an item) has the same shape, `msg-<32 hex>`, so none
36
36
  * says what kind it is. The same inputs give the same id after a restart, so journal replay, a repeated `communicate`,
37
37
  * a re-asked card and a restart notice keep theirs.
38
38
  */
@@ -46,14 +46,11 @@ export interface MlsIds {
46
46
  export declare const MLS_ID_KEY_BYTES = 32;
47
47
  export declare function createMlsIds(key: Uint8Array): MlsIds;
48
48
  /**
49
- * Encrypted rooms are for agents whose outbound communication is not closed, in an environment with an MLS profile. Canon
50
- * decides who joins a room under the invitation policies, as for plaintext rooms, and whether that environment runs MLS.
49
+ * Encrypted rooms are for an environment with an MLS profile. Canon decides who joins a room under the invitation policies,
50
+ * as for plaintext rooms, and a closed agent's text needs authority for each reply (`replyGrant` in runner.ts).
51
51
  */
52
52
  export declare function requireMlsSupport(input: {
53
53
  environmentId: string;
54
- agent: {
55
- outboundPolicy: string;
56
- };
57
54
  }): void;
58
55
  /**
59
56
  * Whether `text` @mentions any of `names` (an agent's display name, id or aliases). Encrypted text carries no `mentions[]`,
@@ -33,11 +33,9 @@ export interface RunnerOptions {
33
33
  */
34
34
  mls?: RunnerMlsOptions | false;
35
35
  /**
36
- * Relay mode, the class-C relay (spec §11.4): only encrypted rooms are served, which is what lets a `remote` driver
37
- * (the connector) into them. Plaintext input is cancelled with no turn (the connector's own installation serves it),
38
- * control hints are read only for encrypted rooms, and `relayRead` and `relaySend` serve the relay channel. It publishes
39
- * the runtime descriptor and heartbeat, so the apps show a relayed turn working and offer Stop. It needs the agent's MLS
40
- * device.
36
+ * Relay mode, the class-C relay (spec §11.4): what lets a `remote` driver (the connector) into encrypted rooms, and
37
+ * `relayRead`, `relaySend` and `relayStart` serve the relay channel. It publishes the runtime descriptor and heartbeat,
38
+ * so the apps show a relayed turn working and offer Stop. It needs the agent's MLS device.
41
39
  */
42
40
  relay?: boolean;
43
41
  /** The engine's installation: the relay's reserved one, from its configuration. A store opened under another refuses to start. */
@@ -45,18 +43,17 @@ export interface RunnerOptions {
45
43
  /**
46
44
  * Team rooms: agents the owner trusts. A message from one of them counts as the owner's for tool permissions (the
47
45
  * drivers' guards read `TurnInputMessage.trustedAgent`) only in a room that holds no one but this agent, its owner and
48
- * listed agents, all of which Canon confirms at the start of the turn are active agents of this agent's own owner; in
49
- * a plaintext room only for a final its runner marked as answering the owner or confirmed teammates alone, and in an
50
- * encrypted room never with a relay device in the group. A `remote` runtime has no tools on this host: a relay ignores it.
46
+ * listed agents, all of which Canon confirms at the start of the turn are active agents of this agent's own owner, and
47
+ * never with a relay device in the group. A `remote` runtime has no tools on this host: a relay ignores it.
51
48
  */
52
49
  trustedAgents?: string[];
53
50
  /**
54
- * Encrypted rooms (§6): how many messages from other agents that @mention this agent a room may wake it with before a
55
- * person's message is admitted there again (default 6; 0 never wakes on an agent). Past the cap they are settled with
56
- * no turn, logged once. Plaintext rooms are Canon's to dispatch (RUN-29).
51
+ * How many messages from other agents that @mention this agent a room may wake it with before a person writes there
52
+ * again (default 6; 0 never wakes on an agent). Past the cap they are settled with no turn, logged once. The room's own
53
+ * rules can stop them sooner (`RoomRules`).
57
54
  */
58
55
  agentTurnCap?: number;
59
- /** Encrypted rooms: names besides the agent's display name and id that @mention it, such as a role (`@engineer`). */
56
+ /** Names besides the agent's display name and id that @mention it, such as a role (`@engineer`). */
60
57
  mentionAliases?: string[];
61
58
  /** How long an aborted turn may take to settle before its session is reset (default 10 s). */
62
59
  abortGraceMs?: number;
@@ -201,6 +201,37 @@ export interface TurnInput {
201
201
  readonly errand?: ErrandFacts;
202
202
  /** Open errands that brought the agent into this conversation (§12.6), also at the head of `prompt`. */
203
203
  readonly errands?: ReadonlyArray<ErrandFacts>;
204
+ /** An encrypted room's turn: the room as Canon's records give it, also at the head of `prompt`. A relay's turn has none. */
205
+ readonly roomFacts?: RoomFacts;
206
+ }
207
+ /** What a turn knows about its encrypted room. Names, name and topic are what people typed: data, never instructions. */
208
+ export interface RoomFacts {
209
+ readonly name?: string;
210
+ readonly topic?: string;
211
+ readonly owner: {
212
+ readonly id: string;
213
+ readonly name?: string;
214
+ };
215
+ readonly members: ReadonlyArray<{
216
+ readonly id: string;
217
+ readonly name?: string;
218
+ readonly type: 'human' | 'ai_agent';
219
+ readonly isOwner: boolean;
220
+ readonly isYou: boolean;
221
+ }>;
222
+ /** Absent only when this Canon does not send them yet. */
223
+ readonly rules?: RoomRules;
224
+ }
225
+ /**
226
+ * How the agent takes part in this room, resolved from its owner's defaults and the room's settings. Any admin of the room
227
+ * can set them, so they are never the owner's orders. The runner enforces all but `style`, which it tells the agent.
228
+ */
229
+ export interface RoomRules {
230
+ readonly style: 'natural' | 'collaborative' | 'mention-first' | 'approval-gated' | 'handoff-only' | 'observer';
231
+ readonly requireMentionForGroupReplies: boolean;
232
+ readonly allowAgentToAgent: boolean;
233
+ readonly allowLongRunningCollaboration: boolean;
234
+ readonly maxConsecutiveAgentTurns: number | null;
204
235
  }
205
236
  /** An errand as a turn sees it: why the owner sent the agent, what to do, the recipient and the origin conversation. */
206
237
  export interface ErrandFacts {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/agent-sdk",
3
- "version": "12.6.1",
3
+ "version": "13.0.2",
4
4
  "description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,43 +0,0 @@
1
- import type { CanonClient } from './client.js';
2
- import type { CanonUnifiedDiff } from './types.js';
3
- import type { ApprovalConfig, ApprovalNativeRequestMetadata, ApprovalResult, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRisk } from './approval-types.js';
4
- import { RuntimeRequestManager, type RuntimeRequestOptions } from './runtime-request-manager.js';
5
- interface ApprovalRequestOpts {
6
- riskLevel?: 'normal' | 'destructive';
7
- risk?: ApprovalRisk;
8
- category?: ApprovalRequestCategory;
9
- runtimeId?: string;
10
- turnId?: string;
11
- native?: ApprovalNativeRequestMetadata;
12
- toolSummary?: string;
13
- details?: ApprovalRequestDetail[];
14
- /** File-change preview rendered inline on the approval card (size-disciplined automatically). */
15
- diff?: CanonUnifiedDiff;
16
- ignoreSessionRules?: boolean;
17
- allowSessionRule?: boolean;
18
- /** Human conversation member who triggered this turn and should answer. */
19
- responseUserId?: string;
20
- }
21
- /**
22
- * Platform-agnostic approval protocol for Canon.
23
- *
24
- * Now a thin `RuntimeRequestManager` subclass: the pending map, deadline timers,
25
- * the hybrid poll-plus-push loop, and cancellation live in the generalized
26
- * engine; approval-specific behaviour (session-rule fast path, redacted request
27
- * metadata, owner-authored outcome messages, and session-rule storage) is
28
- * expressed as a single `KindDescriptor`. Behaviour is preserved verbatim.
29
- */
30
- export declare class ApprovalManager extends RuntimeRequestManager {
31
- private config;
32
- constructor(client: CanonClient, agentId: string, ownerId: string, config?: Partial<ApprovalConfig>);
33
- /**
34
- * Request approval for a tool call.
35
- *
36
- * 1. Checks session rules — may resolve immediately.
37
- * 2. Sends a message with approval card metadata.
38
- * 3. Waits for the owner's reply (or timeout).
39
- */
40
- requestApproval(conversationId: string, toolName: string, toolInput: Record<string, unknown>, opts?: ApprovalRequestOpts, runtimeOptions?: RuntimeRequestOptions): Promise<ApprovalResult>;
41
- private buildApprovalDescriptor;
42
- }
43
- export {};
@@ -1,283 +0,0 @@
1
- import type { CanonClient } from './client.js';
2
- import type { SessionRule } from './approval-types.js';
3
- import type { RuntimeCardV1, RuntimeCardNativeMetadata, RuntimeInputAnswers, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputQuestion } from './runtime-cards.js';
4
- /**
5
- * The five runtime request families. `contact` is non-interactive (no pending
6
- * node / no manager loop); the other four flow through {@link RuntimeRequestManager}.
7
- */
8
- export type RuntimeRequestKind = 'contact' | 'approval' | 'input' | 'plan' | 'card';
9
- export interface RuntimeRequestContext {
10
- agentId: string;
11
- ownerId: string;
12
- }
13
- /** Normalized outcome of a single consume poll. */
14
- export type RuntimeConsumeOutcome<Result> = {
15
- state: 'pending';
16
- } | {
17
- state: 'resolved';
18
- result: Result;
19
- } | {
20
- state: 'timeout';
21
- };
22
- /** Outcome message the host emits after a request settles (via `onOutcome`). */
23
- export interface RuntimeOutcomeMessage {
24
- text: string;
25
- metadata: Record<string, unknown>;
26
- }
27
- /**
28
- * Everything the descriptor's create step surfaced to the host, handed to
29
- * `onCreated`. Hosts that must sequence side effects on the server response
30
- * (turn blocks, streaming state, display-vs-poll control flow) read these
31
- * instead of re-deriving them.
32
- */
33
- export interface RuntimeCreateResult {
34
- requestId: string;
35
- messageId?: string;
36
- /** Card family: whether the created card is interactive (a response is pending). */
37
- interactive?: boolean;
38
- expiresAt?: number;
39
- }
40
- /**
41
- * How the built-in input/card descriptors pick `responseUserId` when the payload
42
- * does not set it explicitly. An explicit `payload.responseUserId` always wins.
43
- * - `'owner'` — fall back to `ctx.ownerId` (omit when that is empty).
44
- * - `'infer'` — omit, so the backend targets the owner if present else the sole
45
- * other member (correct for agent→user DMs where the owner is not a member).
46
- */
47
- export type ResponderPolicy = 'owner' | 'infer';
48
- export interface RuntimeRequestOptions {
49
- /** Caller-chosen request id. When omitted the descriptor generates one. */
50
- requestId?: string;
51
- /** Absolute deadline (epoch ms). Overrides `timeoutMs`. */
52
- expiresAt?: number;
53
- timeoutMs?: number;
54
- pollMs?: number;
55
- signal?: AbortSignal;
56
- /** Responder fallback for the built-in input/card create (see {@link ResponderPolicy}). */
57
- responderPolicy?: ResponderPolicy;
58
- /** Host side effects immediately after the server request is created (turn block, typing). */
59
- onCreated?: (created: RuntimeCreateResult) => void | Promise<void>;
60
- /** Host emits the durable outcome message after the request settles. */
61
- onOutcome?: (outcome: RuntimeOutcomeMessage) => void | Promise<void>;
62
- }
63
- /** Error used to reject an in-flight request that is explicitly cancelled. */
64
- export declare class RuntimeRequestCancelledError extends Error {
65
- constructor(message?: string);
66
- }
67
- export interface RuntimeRequestCallInput<Payload, State> {
68
- client: CanonClient;
69
- ctx: RuntimeRequestContext;
70
- conversationId: string;
71
- requestId: string;
72
- payload: Payload;
73
- /** Resolved absolute deadline (epoch ms). */
74
- expiresAt: number;
75
- state: State | undefined;
76
- }
77
- export interface RuntimeRequestPreflightInput<Payload> {
78
- client: CanonClient;
79
- ctx: RuntimeRequestContext;
80
- conversationId: string;
81
- payload: Payload;
82
- options: RuntimeRequestOptions;
83
- }
84
- export interface RuntimeRequestPushInput {
85
- conversationId: string;
86
- message: {
87
- senderId: string;
88
- metadata?: Record<string, unknown>;
89
- };
90
- ctx: RuntimeRequestContext;
91
- }
92
- export interface RuntimeRequestPushMatch {
93
- requestId: string;
94
- }
95
- /**
96
- * Everything that varies per request family. The engine ({@link RuntimeRequestManager})
97
- * owns the pending map, timers, poll/notify/abort loop and cancellation; the
98
- * descriptor supplies only the family-specific pieces.
99
- */
100
- export interface KindDescriptor<Payload = unknown, Result = unknown, State = unknown> {
101
- readonly kind: RuntimeRequestKind;
102
- /** Fresh request id when the caller supplies none. */
103
- generateId(payload: Payload): string;
104
- /** Deadline for this request (epoch ms). Falls back to options / default when omitted. */
105
- resolveExpiry?(input: {
106
- payload: Payload;
107
- options: RuntimeRequestOptions;
108
- }): number | undefined;
109
- /** Poll cadence (ms). Defaults to the manager default. */
110
- pollMs?(payload: Payload): number;
111
- /**
112
- * Optional immediate resolution BEFORE any server request is created (e.g. the
113
- * approval session-rule fast path). Returning a result skips create + poll.
114
- */
115
- preflight?(input: RuntimeRequestPreflightInput<Payload>): Result | null;
116
- /**
117
- * Create the server-side request; returns the effective id + optional per-request
118
- * state, plus any create-response fields the host needs back (surfaced via
119
- * {@link RuntimeCreateResult} to `onCreated`).
120
- */
121
- create(input: RuntimeRequestCallInput<Payload, State> & {
122
- options: RuntimeRequestOptions;
123
- }): Promise<{
124
- requestId: string;
125
- expiresAt?: number;
126
- state?: State;
127
- messageId?: string;
128
- interactive?: boolean;
129
- }>;
130
- /** Poll the server once and interpret the response. */
131
- consume(input: RuntimeRequestCallInput<Payload, State>): Promise<RuntimeConsumeOutcome<Result>>;
132
- /** Best-effort cancellation (abort / explicit cancel / dispose). */
133
- cancel?(input: RuntimeRequestCallInput<Payload, State>): Promise<void>;
134
- /** Result produced when the local deadline fires. */
135
- timeoutResult(input: RuntimeRequestCallInput<Payload, State>): Result;
136
- /**
137
- * Finalization side effects + optional result override. Runs on `replied` /
138
- * `timeout` (never `aborted`). Approval uses this to store the accepted session
139
- * rule and emit its own outcome messages; returning a result lets it narrow the
140
- * accepted rule into the returned value.
141
- */
142
- finalize?(input: RuntimeRequestCallInput<Payload, State> & {
143
- result: Result;
144
- reason: 'replied' | 'timeout';
145
- }): Result | void;
146
- /** Outcome message for the host to emit via `onOutcome` (input/card families). */
147
- buildOutcome?(input: RuntimeRequestCallInput<Payload, State> & {
148
- result: Result;
149
- reason: 'replied' | 'timeout';
150
- }): RuntimeOutcomeMessage | null;
151
- /** Map an inbound push message to a pending request that should poll now. */
152
- matchPush?(input: RuntimeRequestPushInput): RuntimeRequestPushMatch | null;
153
- }
154
- /**
155
- * Platform-agnostic engine for Canon's interactive runtime requests.
156
- *
157
- * Generalizes the former `ApprovalManager`: it owns the pending map, deadline
158
- * timers, the poll-with-abort loop that races an inbound push wakeup, and
159
- * cancellation — all keyed by {@link KindDescriptor}. Approval, runtime input,
160
- * runtime card, and plan families register over the same primitive; the former
161
- * hand-written await-loops collapse into `request()`.
162
- *
163
- * Session-rule storage lives here because the approval descriptor's preflight /
164
- * finalize read and write it; other families ignore it.
165
- */
166
- export declare class RuntimeRequestManager {
167
- protected client: CanonClient;
168
- protected ctx: RuntimeRequestContext;
169
- private descriptors;
170
- private pending;
171
- private rules;
172
- constructor(client: CanonClient, ctx: RuntimeRequestContext);
173
- /** Register (or override) the descriptor for a kind. */
174
- register<Payload, Result, State>(kind: RuntimeRequestKind, descriptor: KindDescriptor<Payload, Result, State>): void;
175
- /** Built-in input, card, and plan descriptors. Subclasses add approval policy. */
176
- protected registerBuiltins(): void;
177
- get pendingCount(): number;
178
- /**
179
- * Run one interactive runtime request end to end:
180
- * preflight → create → onCreated → register pending → poll (racing push wakeup
181
- * and abort) → post-deadline consume → finalize → onOutcome → resolve.
182
- */
183
- request<Payload, Result, State = unknown>(kind: RuntimeRequestKind, conversationId: string, payload: Payload, options?: RuntimeRequestOptions): Promise<Result>;
184
- /** Push short-circuit: wake the pending request's poll to consume immediately. */
185
- notify(kind: RuntimeRequestKind, conversationId: string, requestId: string): void;
186
- /**
187
- * Feed an inbound message to the manager. Returns true when a matching pending
188
- * request was woken to consume canonical state. Receipt metadata never settles
189
- * the request directly. Fails closed on unknown / mismatched ids.
190
- */
191
- handleMessage(conversationId: string, message: {
192
- senderId: string;
193
- metadata?: Record<string, unknown>;
194
- }): boolean;
195
- /** Cancel a specific pending request (rejects its promise, best-effort server cancel). */
196
- cancel(kind: RuntimeRequestKind, conversationId: string, requestId: string): Promise<void>;
197
- checkSessionRules(toolName: string, conversationId?: string): SessionRule | null;
198
- addSessionRule(conversationId: string, rule: SessionRule): void;
199
- getSessionRules(): SessionRule[];
200
- clearSessionRules(): void;
201
- dispose(): void;
202
- protected pruneExpiredRules(): void;
203
- /** Sleep that resolves on timeout, on `notify()` wakeup, or when the request settles. */
204
- private sleep;
205
- }
206
- /** Interactive runtime input (`AskUserQuestion`, secret prompts, choices). */
207
- export interface RuntimeInputRequestPayload {
208
- kind: RuntimeInputKind;
209
- title?: string;
210
- prompt?: string;
211
- choices?: RuntimeInputChoice[];
212
- questions?: RuntimeInputQuestion[];
213
- secretName?: string;
214
- native?: RuntimeInputNativeMetadata;
215
- sensitive?: boolean;
216
- responseUserId?: string;
217
- turnId?: string;
218
- }
219
- export type RuntimeInputRequestResult = {
220
- status: 'submitted';
221
- inputId: string;
222
- value: string;
223
- answers?: RuntimeInputAnswers;
224
- } | {
225
- status: 'cancelled';
226
- inputId: string;
227
- } | {
228
- status: 'timeout';
229
- inputId: string;
230
- };
231
- export declare const runtimeInputDescriptor: KindDescriptor<RuntimeInputRequestPayload, RuntimeInputRequestResult>;
232
- /** Interactive runtime card (canon.card.v1 with an actions block). */
233
- export interface RuntimeCardRequestPayload {
234
- card: RuntimeCardV1;
235
- responseUserId?: string;
236
- runtimeId?: string;
237
- turnId?: string;
238
- native?: RuntimeCardNativeMetadata;
239
- }
240
- export type RuntimeCardRequestResult = {
241
- status: 'submitted';
242
- cardId: string;
243
- actionId?: string;
244
- values?: Record<string, unknown>;
245
- respondedBy?: string;
246
- } | {
247
- status: 'cancelled';
248
- cardId: string;
249
- respondedBy?: string;
250
- } | {
251
- status: 'timeout';
252
- cardId: string;
253
- };
254
- export declare const runtimeCardDescriptor: KindDescriptor<RuntimeCardRequestPayload, RuntimeCardRequestResult>;
255
- /** Blocking plan review produced by coding runtimes. */
256
- export interface RuntimePlanRequestPayload {
257
- title?: string;
258
- summary?: string;
259
- body?: string;
260
- allowedPrompts?: ReadonlyArray<{
261
- tool: string;
262
- prompt: string;
263
- }>;
264
- responseUserId?: string;
265
- turnId?: string;
266
- }
267
- export type RuntimePlanRequestResult = {
268
- status: 'approve' | 'revise' | 'reject';
269
- planId: string;
270
- feedback?: string;
271
- grantedPrompts?: Array<{
272
- tool: string;
273
- prompt: string;
274
- }>;
275
- receiptId?: string;
276
- } | {
277
- status: 'cancelled';
278
- planId: string;
279
- } | {
280
- status: 'timeout';
281
- planId: string;
282
- };
283
- export declare const runtimePlanDescriptor: KindDescriptor<RuntimePlanRequestPayload, RuntimePlanRequestResult>;
@@ -1,79 +0,0 @@
1
- /**
2
- * Turn verbosity — how much of a turn's middle the reader sees.
3
- *
4
- * `quiet` = the thinking indicator and the final message only: no `/streaming`
5
- * narration and no runtime-generated per-tool-call step output. Emission the
6
- * DEVELOPER asks for explicitly is not narration and survives — owner ruling
7
- * D1: `replyProgress(text, { durable: true })` keeps its durable send, and only
8
- * the implicit `/streaming` half is gated. Interaction requests and their
9
- * `control` outcome receipts are real interactions, not steps, and are
10
- * untouched in both modes; the duplicate trail rows that summarize them go with
11
- * the trail (D4).
12
- *
13
- * Owner ruling 5, 2026-07-31 (docs/history/group-behavior-2026-08-01.md): configured
14
- * by the AGENT DEVELOPER per host/SDK, never by Canon and never per
15
- * conversation by users. ONE resolver so five integrations cannot disagree.
16
- *
17
- * This lives in @canonmsg/core rather than @canonmsg/backend-contracts because
18
- * quiet mode has no server participant: it is emission control at the agent
19
- * side. Nothing on the server reads it, no verb carries it, and clients need
20
- * no change — they simply have nothing to render.
21
- *
22
- * Notes for the runtimes that consume this (the guards are per-integration):
23
- * - Suppress by CALL SITE, never by `turnSemantics === 'progress'` (D5): the
24
- * leading parts of a chunked final carry that semantic and are answer body.
25
- * - A quiet turn still clears `/streaming` at turn open (a surviving node from
26
- * an earlier turn would otherwise strand a stale bubble), still writes
27
- * `/turn-state`, and still writes `/typing`. Quiet removes the narration,
28
- * not the fact that the agent is working.
29
- */
30
- /** The resolved mode a turn runs in. Named `turnVerbosity`, never `verbosity` —
31
- * `runtime.verbosity.set` is a different, user-facing primitive. */
32
- export type TurnVerbosity = 'verbose' | 'quiet';
33
- /** What a developer may write in config. `'auto'` === unset. */
34
- export type TurnVerbosityConfig = TurnVerbosity | 'auto';
35
- /**
36
- * A direct chat is `'direct'`; the type is `'unknown'` when the conversation
37
- * fetch failed (host-runtime.ts HostInboundParticipantContext).
38
- */
39
- export type TurnVerbosityConversationType = 'direct' | 'group' | 'unknown';
40
- /** The per-conversation-type defaults. */
41
- export declare const DEFAULT_TURN_VERBOSITY_BY_CONVERSATION_TYPE: {
42
- readonly direct: "verbose";
43
- readonly group: "quiet";
44
- readonly unknown: "verbose";
45
- };
46
- /**
47
- * Folds every spelling a runtime might hand us onto the three keys the
48
- * defaults map has. Accepts a raw string because the value arrives from
49
- * provenance or a conversation fetch.
50
- */
51
- export declare function normalizeTurnVerbosityConversationType(value: string | null | undefined): 'direct' | 'group' | 'unknown';
52
- /**
53
- * An explicit `'verbose'`/`'quiet'` wins outright; `'auto'`, unset and any
54
- * unrecognized value fall through to the per-conversation-type default.
55
- *
56
- * `configured` goes through `parseTurnVerbosityConfig` on the way in, so a
57
- * caller handing over a raw config value gets the same answer as one that
58
- * pre-parsed. That matters because the escape hatch is the whole point of the
59
- * field: an operator who writes `Verbose` in a group is opting OUT of quiet,
60
- * and a byte-exact comparison would drop that back onto the group default —
61
- * i.e. into silence — with nothing anywhere to warn about it.
62
- */
63
- export declare function resolveTurnVerbosity(input: {
64
- configured?: TurnVerbosityConfig | null;
65
- conversationType?: TurnVerbosityConversationType | null;
66
- }): TurnVerbosity;
67
- /**
68
- * Shared parser for CLI flags, env vars and config files, so four TS runtimes
69
- * agree on what a developer typed. Case-insensitive and trimmed.
70
- *
71
- * `null` means absent OR unrecognized — `''`, whitespace, `null` and `undefined`
72
- * land there alongside a genuine typo. A host that warns on `null` must first
73
- * check the raw input was a non-empty string, or a declared-but-empty
74
- * `CANON_TURN_VERBOSITY=` (routine in launchd plists, Docker `ENV` and `.env`
75
- * files) gets reported as a mistake the operator never made. Absent stays `null`
76
- * rather than collapsing to `'auto'` so that the usual flag-then-env fallback,
77
- * `parse(flag) ?? parse(env)`, keeps working.
78
- */
79
- export declare function parseTurnVerbosityConfig(raw: string | null | undefined): TurnVerbosityConfig | null;