@canonmsg/agent-sdk 11.2.1 → 12.0.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.
Files changed (188) hide show
  1. package/README.md +171 -536
  2. package/dist/chunks/chunk-6VK4UZHJ.js +2806 -0
  3. package/dist/chunks/chunk-FPQFTTND.js +4899 -0
  4. package/dist/chunks/chunk-OLJ7H4E2.js +14705 -0
  5. package/dist/chunks/mls-crypto-NZDNSPAO.js +10 -0
  6. package/dist/cli.js +198 -0
  7. package/dist/drivers/claude.d.ts +36 -0
  8. package/dist/drivers/code.d.ts +18 -0
  9. package/dist/drivers/codex.d.ts +37 -0
  10. package/dist/index.d.ts +12 -25
  11. package/dist/index.js +69 -13
  12. package/dist/internal/backend-contracts/agentBehaviorPolicy.d.ts +122 -0
  13. package/dist/internal/backend-contracts/agentDirectory.d.ts +32 -0
  14. package/dist/internal/backend-contracts/agentOrigin.d.ts +23 -0
  15. package/dist/internal/backend-contracts/agentSearch.d.ts +17 -0
  16. package/dist/internal/backend-contracts/api-origins.generated.d.ts +4 -0
  17. package/dist/internal/backend-contracts/apiErrors.d.ts +1 -0
  18. package/dist/internal/backend-contracts/artifactActions.d.ts +159 -0
  19. package/dist/internal/backend-contracts/artifacts.d.ts +386 -0
  20. package/dist/internal/backend-contracts/communication.d.ts +131 -0
  21. package/dist/internal/backend-contracts/conversationMembership.d.ts +28 -0
  22. package/dist/internal/backend-contracts/deliveryObservation.d.ts +23 -0
  23. package/dist/internal/backend-contracts/diffRedaction.d.ts +6 -0
  24. package/dist/internal/backend-contracts/endpoint-unread.d.ts +4 -0
  25. package/dist/internal/backend-contracts/endpoint.d.ts +103 -0
  26. package/dist/internal/backend-contracts/endpointContentPolicy.d.ts +37 -0
  27. package/dist/internal/backend-contracts/environment.d.ts +20 -0
  28. package/dist/internal/backend-contracts/externalInbound.d.ts +24 -0
  29. package/dist/internal/backend-contracts/firestoreValues.d.ts +9 -0
  30. package/dist/internal/backend-contracts/index.d.ts +48 -0
  31. package/dist/internal/backend-contracts/media-url.d.ts +6 -0
  32. package/dist/internal/backend-contracts/media.d.ts +51 -0
  33. package/dist/internal/backend-contracts/mediaDelivery.d.ts +46 -0
  34. package/dist/internal/backend-contracts/mediaTransferProtocol.d.ts +17 -0
  35. package/dist/internal/backend-contracts/membershipChange.d.ts +21 -0
  36. package/dist/internal/backend-contracts/message.d.ts +86 -0
  37. package/dist/internal/backend-contracts/messageText.d.ts +6 -0
  38. package/dist/internal/backend-contracts/mlsDevApplication.d.ts +73 -0
  39. package/dist/internal/backend-contracts/mlsDevCredential.d.ts +75 -0
  40. package/dist/internal/backend-contracts/mlsDevCredentialReconciliation.d.ts +45 -0
  41. package/dist/internal/backend-contracts/mlsDevDeviceCustody.d.ts +51 -0
  42. package/dist/internal/backend-contracts/mlsDevEnrollment.d.ts +74 -0
  43. package/dist/internal/backend-contracts/mlsDevGroup.d.ts +197 -0
  44. package/dist/internal/backend-contracts/mlsDevGroupFeed.d.ts +47 -0
  45. package/dist/internal/backend-contracts/mlsDevKeyPackage.d.ts +42 -0
  46. package/dist/internal/backend-contracts/mlsDevKeyPackages.d.ts +55 -0
  47. package/dist/internal/backend-contracts/moderation.d.ts +7 -0
  48. package/dist/internal/backend-contracts/plaintextProcessors.d.ts +63 -0
  49. package/dist/internal/backend-contracts/preparedContent.d.ts +54 -0
  50. package/dist/internal/backend-contracts/replyAuthority.d.ts +14 -0
  51. package/dist/internal/backend-contracts/runtimeCardFields.d.ts +66 -0
  52. package/dist/internal/backend-contracts/runtimeCardStorage.d.ts +3 -0
  53. package/dist/internal/backend-contracts/runtimeDescriptor.d.ts +88 -0
  54. package/dist/internal/backend-contracts/selfContext.d.ts +9 -0
  55. package/dist/internal/backend-contracts/turnProtocol.d.ts +43 -0
  56. package/dist/internal/backend-contracts/verbContract.d.ts +848 -0
  57. package/dist/internal/backend-contracts/verbSchemas.d.ts +1707 -0
  58. package/dist/internal/backend-contracts/verbWire.d.ts +493 -0
  59. package/dist/internal/backend-contracts/webAuth.d.ts +8 -0
  60. package/dist/internal/backend-contracts/workSessions.d.ts +205 -0
  61. package/dist/internal/core/agent-profiles.d.ts +69 -0
  62. package/dist/internal/core/agent-resolver.d.ts +49 -0
  63. package/dist/internal/core/agent-session.d.ts +12 -0
  64. package/dist/internal/core/approval-format.d.ts +26 -0
  65. package/dist/internal/core/approval-manager.d.ts +43 -0
  66. package/dist/internal/core/approval-types.d.ts +74 -0
  67. package/dist/internal/core/artifacts.d.ts +262 -0
  68. package/dist/internal/core/attached-native-session.d.ts +174 -0
  69. package/dist/internal/core/attached-session-file-store.d.ts +3 -0
  70. package/dist/internal/core/base-url.d.ts +1 -0
  71. package/dist/internal/core/cli-metadata.d.ts +13 -0
  72. package/dist/internal/core/client.d.ts +486 -0
  73. package/dist/internal/core/completed-output-journal.d.ts +39 -0
  74. package/dist/internal/core/constants.d.ts +4 -0
  75. package/dist/internal/core/control-poller.d.ts +221 -0
  76. package/dist/internal/core/endpoint-client.d.ts +43 -0
  77. package/dist/internal/core/exclusive-json-file-store.d.ts +7 -0
  78. package/dist/internal/core/execution-environment-mode.d.ts +8 -0
  79. package/dist/internal/core/execution-environment.d.ts +55 -0
  80. package/dist/internal/core/gifs.d.ts +35 -0
  81. package/dist/internal/core/group-context.d.ts +25 -0
  82. package/dist/internal/core/host-runtime.d.ts +257 -0
  83. package/dist/internal/core/inbound-frame.d.ts +64 -0
  84. package/dist/internal/core/index.d.ts +107 -0
  85. package/dist/internal/core/local-runtime-catalog.d.ts +131 -0
  86. package/dist/internal/core/message-format.d.ts +13 -0
  87. package/dist/internal/core/native-session-interaction.d.ts +44 -0
  88. package/dist/internal/core/node-media.d.ts +6 -0
  89. package/dist/internal/core/policy.d.ts +2 -0
  90. package/dist/internal/core/provenance.d.ts +31 -0
  91. package/dist/internal/core/registration-cli.d.ts +40 -0
  92. package/dist/internal/core/registration-profile.d.ts +10 -0
  93. package/dist/internal/core/registration-session.d.ts +55 -0
  94. package/dist/internal/core/registration.d.ts +21 -0
  95. package/dist/internal/core/retry.d.ts +122 -0
  96. package/dist/internal/core/rtdb-rest.d.ts +145 -0
  97. package/dist/internal/core/runtime-cards.d.ts +331 -0
  98. package/dist/internal/core/runtime-descriptor.d.ts +75 -0
  99. package/dist/internal/core/runtime-endpoints.d.ts +26 -0
  100. package/dist/internal/core/runtime-heartbeat.d.ts +29 -0
  101. package/dist/internal/core/runtime-presentation.d.ts +35 -0
  102. package/dist/internal/core/runtime-request-manager.d.ts +284 -0
  103. package/dist/internal/core/runtime-state-publisher.d.ts +42 -0
  104. package/dist/internal/core/self-context.d.ts +61 -0
  105. package/dist/internal/core/silent-turn.d.ts +86 -0
  106. package/dist/internal/core/stream.d.ts +77 -0
  107. package/dist/internal/core/turn-output-controller.d.ts +69 -0
  108. package/dist/internal/core/turn-protocol.d.ts +33 -0
  109. package/dist/internal/core/turn-verbosity.d.ts +97 -0
  110. package/dist/internal/core/types.d.ts +1075 -0
  111. package/dist/internal/core/typing-status-publisher.d.ts +14 -0
  112. package/dist/internal/core/unified-diff.d.ts +35 -0
  113. package/dist/internal/core/work-session-provider.d.ts +29 -0
  114. package/dist/internal/core/workspace-discovery.d.ts +17 -0
  115. package/dist/internal/endpoint/artifact-images.d.ts +60 -0
  116. package/dist/internal/endpoint/artifact-reducer.d.ts +35 -0
  117. package/dist/internal/endpoint/artifact-views.d.ts +113 -0
  118. package/dist/internal/endpoint/artifacts.d.ts +75 -0
  119. package/dist/internal/endpoint/delivery.d.ts +47 -0
  120. package/dist/internal/endpoint/engine.d.ts +219 -0
  121. package/dist/internal/endpoint/ephemeral.d.ts +8 -0
  122. package/dist/internal/endpoint/events.d.ts +32 -0
  123. package/dist/internal/endpoint/external-inbound.d.ts +36 -0
  124. package/dist/internal/endpoint/handoff.d.ts +50 -0
  125. package/dist/internal/endpoint/history.d.ts +22 -0
  126. package/dist/internal/endpoint/image-generation-errors.d.ts +2 -0
  127. package/dist/internal/endpoint/inbound.d.ts +29 -0
  128. package/dist/internal/endpoint/index.d.ts +32 -0
  129. package/dist/internal/endpoint/media.d.ts +172 -0
  130. package/dist/internal/endpoint/migration.d.ts +50 -0
  131. package/dist/internal/endpoint/mls-crypto.d.ts +25 -0
  132. package/dist/internal/endpoint/mls-dev-client.d.ts +44 -0
  133. package/dist/internal/endpoint/mls-dev-device.d.ts +67 -0
  134. package/dist/internal/endpoint/mls-dev-groups.d.ts +114 -0
  135. package/dist/internal/endpoint/mls-dev-key-package-service.d.ts +33 -0
  136. package/dist/internal/endpoint/mls-dev-key-packages.d.ts +42 -0
  137. package/dist/internal/endpoint/mls-dev-transport.d.ts +37 -0
  138. package/dist/internal/endpoint/node-mls-custody-protocol.d.ts +24 -0
  139. package/dist/internal/endpoint/node-mls-custody.d.ts +15 -0
  140. package/dist/internal/endpoint/node.d.ts +7 -0
  141. package/dist/internal/endpoint/observe-query.d.ts +17 -0
  142. package/dist/internal/endpoint/portable-node-mls-custody.d.ts +23 -0
  143. package/dist/internal/endpoint/queue.d.ts +22 -0
  144. package/dist/internal/endpoint/recovery.d.ts +27 -0
  145. package/dist/internal/endpoint/retention.d.ts +7 -0
  146. package/dist/internal/endpoint/store.d.ts +22 -0
  147. package/dist/internal/endpoint/sync.d.ts +33 -0
  148. package/dist/internal/endpoint/transient-publisher.d.ts +8 -0
  149. package/dist/internal/endpoint/transport.d.ts +58 -0
  150. package/dist/media.d.ts +1 -1
  151. package/dist/media.js +42 -541
  152. package/dist/runner/runner.d.ts +37 -0
  153. package/dist/runner/types.d.ts +168 -0
  154. package/package.json +18 -5
  155. package/dist/attached-session.d.ts +0 -58
  156. package/dist/attached-session.js +0 -638
  157. package/dist/bounded-file-read.d.ts +0 -14
  158. package/dist/bounded-file-read.js +0 -34
  159. package/dist/canon-agent.d.ts +0 -236
  160. package/dist/canon-agent.js +0 -2531
  161. package/dist/debouncer.d.ts +0 -18
  162. package/dist/debouncer.js +0 -133
  163. package/dist/inbound-handoff.d.ts +0 -6
  164. package/dist/inbound-handoff.js +0 -17
  165. package/dist/managed-session-host.d.ts +0 -27
  166. package/dist/managed-session-host.js +0 -195
  167. package/dist/managed-session-setup.d.ts +0 -99
  168. package/dist/managed-session-setup.js +0 -234
  169. package/dist/realtime.d.ts +0 -62
  170. package/dist/realtime.js +0 -193
  171. package/dist/runtime-card.d.ts +0 -48
  172. package/dist/runtime-card.js +0 -64
  173. package/dist/session-manager.d.ts +0 -77
  174. package/dist/session-manager.js +0 -285
  175. package/dist/turn-streaming-request.d.ts +0 -17
  176. package/dist/turn-streaming-request.js +0 -22
  177. package/dist/turn-verbosity-option.d.ts +0 -33
  178. package/dist/turn-verbosity-option.js +0 -23
  179. package/dist/types.d.ts +0 -387
  180. package/dist/types.js +0 -1
  181. package/dist/work-session-coordination.d.ts +0 -21
  182. package/dist/work-session-coordination.js +0 -53
  183. package/dist/work-session-host.d.ts +0 -31
  184. package/dist/work-session-host.js +0 -617
  185. package/dist/work-session-interactions.d.ts +0 -12
  186. package/dist/work-session-interactions.js +0 -173
  187. package/dist/work-session-state.d.ts +0 -36
  188. package/dist/work-session-state.js +0 -62
@@ -0,0 +1,26 @@
1
+ import { type CanonEnvironmentId } from '../backend-contracts/index.js';
2
+ export interface CanonRuntimeEndpointDefaults {
3
+ apiBaseUrl: string;
4
+ streamUrl: string;
5
+ rtdbUrl: string;
6
+ firebaseWebApiKey: string;
7
+ }
8
+ export interface CanonRuntimeConnectionOptions {
9
+ environmentId: string;
10
+ apiBaseUrl?: string | null;
11
+ streamUrl?: string | null;
12
+ rtdbUrl?: string | null;
13
+ firebaseWebApiKey?: string | null;
14
+ }
15
+ export interface CanonRuntimeConnection extends CanonRuntimeEndpointDefaults {
16
+ environmentId: CanonEnvironmentId;
17
+ projectId: string;
18
+ region: string;
19
+ }
20
+ export declare const CANON_RUNTIME_ENDPOINT_DEFAULTS: Readonly<Partial<Record<CanonEnvironmentId, CanonRuntimeEndpointDefaults>>>;
21
+ export declare const DEFAULT_CANON_ENVIRONMENT_ID: "canon-dev-v1" | "canon-prod-v1";
22
+ export declare function getCanonRuntimeEndpointDefaults(environmentId: string): CanonRuntimeEndpointDefaults | null;
23
+ export declare function requireCanonRuntimeEndpointDefaults(environmentId: string): CanonRuntimeEndpointDefaults;
24
+ export declare function resolveCanonRuntimeConnection(options: CanonRuntimeConnectionOptions): CanonRuntimeConnection;
25
+ export declare function verifyCanonRuntimeConnection(connection: CanonRuntimeConnection, fetchImpl?: typeof fetch): Promise<void>;
26
+ export declare const DEFAULT_CANON_RUNTIME_ENDPOINTS: CanonRuntimeEndpointDefaults;
@@ -0,0 +1,29 @@
1
+ import type { RuntimeStatePublisher } from './runtime-state-publisher.js';
2
+ import type { AgentRuntime } from './types.js';
3
+ export type RuntimeHeartbeatOperation = 'publish' | 'refresh-details' | 'clear' | 'clear-details';
4
+ export interface RuntimeHeartbeatOptions {
5
+ /** Retain one publisher so clearing preserves its last public descriptor. */
6
+ publisher: Pick<RuntimeStatePublisher, 'publishAgentRuntime' | 'clearAgentRuntime'>;
7
+ getRuntime: () => AgentRuntime;
8
+ intervalMs?: number;
9
+ /** Slow work has its own serialized lane; observe cancellation before writing. */
10
+ refreshDetails?: (signal: AbortSignal) => Promise<void>;
11
+ /** Runs after any in-flight detail refresh, including during disposal. */
12
+ clearDetails?: () => Promise<void>;
13
+ onError: (error: unknown, operation: RuntimeHeartbeatOperation) => void;
14
+ }
15
+ export interface RuntimeHeartbeat {
16
+ connect(): void;
17
+ disconnect(): Promise<void>;
18
+ /** Publish a changed descriptor and request fresh details while connected. */
19
+ refresh(): void;
20
+ /** Terminal, idempotent cleanup. Create a new controller to restart. */
21
+ dispose(): Promise<void>;
22
+ }
23
+ /**
24
+ * Connection-scoped publication over a retained runtime publisher. Liveness
25
+ * and slow details have independent lanes, each with at most one queued refresh.
26
+ * Connection generations discard obsolete queued work; in-flight writes finish
27
+ * before the next clear/publish so a late write cannot restore stale liveness.
28
+ */
29
+ export declare function createRuntimeHeartbeat(options: RuntimeHeartbeatOptions): RuntimeHeartbeat;
@@ -0,0 +1,35 @@
1
+ import type { AgentRuntime, AgentSessionSnapshot, CanonRuntimeActivityItem, CanonRuntimeDescriptor, CanonRuntimePresentationField, CanonRuntimePresentationPolicy, RuntimeInfoPayload } from './types.js';
2
+ export declare const RUNTIME_PRESENTATION_FIELDS: readonly ["model", "permissionMode", "effort", "workspace", "executionMode", "contextUsage", "cwd", "branch", "worktreePath", "workspaceRoot", "workspaceRelativePath", "fallbackReason"];
3
+ export declare const DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION: CanonRuntimePresentationPolicy;
4
+ export declare function isRuntimePresentationField(value: string): value is CanonRuntimePresentationField;
5
+ export declare function buildRuntimePresentationPolicy(input?: {
6
+ preset?: CanonRuntimePresentationPolicy['preset'];
7
+ show?: ReadonlyArray<string>;
8
+ hide?: ReadonlyArray<string>;
9
+ base?: CanonRuntimePresentationPolicy;
10
+ }): CanonRuntimePresentationPolicy;
11
+ export declare function isRuntimePresentationFieldHidden(descriptor: CanonRuntimeDescriptor | null | undefined, field: CanonRuntimePresentationField): boolean;
12
+ export declare function redactRuntimeActivityItemForConversation(item: CanonRuntimeActivityItem): CanonRuntimeActivityItem | null;
13
+ export declare function redactRuntimeInfoForConversation<T extends Partial<Omit<RuntimeInfoPayload, 'updatedAt'>> | RuntimeInfoPayload>(payload: T, options?: {
14
+ descriptor?: CanonRuntimeDescriptor | null;
15
+ }): T;
16
+ export declare function redactAgentRuntimeForConversation(runtime: AgentRuntime): AgentRuntime;
17
+ type SessionStatePresentationLike = {
18
+ model?: unknown;
19
+ permissionMode?: unknown;
20
+ effort?: unknown;
21
+ cwd?: unknown;
22
+ executionMode?: unknown;
23
+ executionBranch?: unknown;
24
+ worktreePath?: unknown;
25
+ executionFallbackReason?: unknown;
26
+ contextUsage?: unknown;
27
+ availableModels?: unknown;
28
+ runtimeControlValues?: Record<string, unknown>;
29
+ controlState?: Record<string, unknown>;
30
+ };
31
+ export declare function redactSessionStateForConversation<T extends SessionStatePresentationLike>(descriptor: CanonRuntimeDescriptor | null | undefined, state: T): T;
32
+ export declare function redactAgentSessionSnapshotForConversation(descriptor: CanonRuntimeDescriptor | null | undefined, snapshot: Partial<AgentSessionSnapshot> & Record<string, unknown>, options?: {
33
+ patch?: boolean;
34
+ }): Partial<AgentSessionSnapshot> & Record<string, unknown>;
35
+ export {};
@@ -0,0 +1,284 @@
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
+ export type RuntimeResolveReason = 'replied' | 'timeout' | 'aborted';
14
+ /** Normalized outcome of a single consume poll. */
15
+ export type RuntimeConsumeOutcome<Result> = {
16
+ state: 'pending';
17
+ } | {
18
+ state: 'resolved';
19
+ result: Result;
20
+ } | {
21
+ state: 'timeout';
22
+ };
23
+ /** Outcome message the host emits after a request settles (via `onOutcome`). */
24
+ export interface RuntimeOutcomeMessage {
25
+ text: string;
26
+ metadata: Record<string, unknown>;
27
+ }
28
+ /**
29
+ * Everything the descriptor's create step surfaced to the host, handed to
30
+ * `onCreated`. Hosts that must sequence side effects on the server response
31
+ * (turn blocks, streaming state, display-vs-poll control flow) read these
32
+ * instead of re-deriving them.
33
+ */
34
+ export interface RuntimeCreateResult {
35
+ requestId: string;
36
+ messageId?: string;
37
+ /** Card family: whether the created card is interactive (a response is pending). */
38
+ interactive?: boolean;
39
+ expiresAt?: number;
40
+ }
41
+ /**
42
+ * How the built-in input/card descriptors pick `responseUserId` when the payload
43
+ * does not set it explicitly. An explicit `payload.responseUserId` always wins.
44
+ * - `'owner'` — fall back to `ctx.ownerId` (omit when that is empty).
45
+ * - `'infer'` — omit, so the backend targets the owner if present else the sole
46
+ * other member (correct for agent→user DMs where the owner is not a member).
47
+ */
48
+ export type ResponderPolicy = 'owner' | 'infer';
49
+ export interface RuntimeRequestOptions {
50
+ /** Caller-chosen request id. When omitted the descriptor generates one. */
51
+ requestId?: string;
52
+ /** Absolute deadline (epoch ms). Overrides `timeoutMs`. */
53
+ expiresAt?: number;
54
+ timeoutMs?: number;
55
+ pollMs?: number;
56
+ signal?: AbortSignal;
57
+ /** Responder fallback for the built-in input/card create (see {@link ResponderPolicy}). */
58
+ responderPolicy?: ResponderPolicy;
59
+ /** Host side effects immediately after the server request is created (turn block, typing). */
60
+ onCreated?: (created: RuntimeCreateResult) => void | Promise<void>;
61
+ /** Host emits the durable outcome message after the request settles. */
62
+ onOutcome?: (outcome: RuntimeOutcomeMessage) => void | Promise<void>;
63
+ }
64
+ /** Error used to reject an in-flight request that is explicitly cancelled. */
65
+ export declare class RuntimeRequestCancelledError extends Error {
66
+ constructor(message?: string);
67
+ }
68
+ export interface RuntimeRequestCallInput<Payload, State> {
69
+ client: CanonClient;
70
+ ctx: RuntimeRequestContext;
71
+ conversationId: string;
72
+ requestId: string;
73
+ payload: Payload;
74
+ /** Resolved absolute deadline (epoch ms). */
75
+ expiresAt: number;
76
+ state: State | undefined;
77
+ }
78
+ export interface RuntimeRequestPreflightInput<Payload> {
79
+ client: CanonClient;
80
+ ctx: RuntimeRequestContext;
81
+ conversationId: string;
82
+ payload: Payload;
83
+ options: RuntimeRequestOptions;
84
+ }
85
+ export interface RuntimeRequestPushInput {
86
+ conversationId: string;
87
+ message: {
88
+ senderId: string;
89
+ metadata?: Record<string, unknown>;
90
+ };
91
+ ctx: RuntimeRequestContext;
92
+ }
93
+ export interface RuntimeRequestPushMatch {
94
+ requestId: string;
95
+ }
96
+ /**
97
+ * Everything that varies per request family. The engine ({@link RuntimeRequestManager})
98
+ * owns the pending map, timers, poll/notify/abort loop and cancellation; the
99
+ * descriptor supplies only the family-specific pieces.
100
+ */
101
+ export interface KindDescriptor<Payload = unknown, Result = unknown, State = unknown> {
102
+ readonly kind: RuntimeRequestKind;
103
+ /** Fresh request id when the caller supplies none. */
104
+ generateId(payload: Payload): string;
105
+ /** Deadline for this request (epoch ms). Falls back to options / default when omitted. */
106
+ resolveExpiry?(input: {
107
+ payload: Payload;
108
+ options: RuntimeRequestOptions;
109
+ }): number | undefined;
110
+ /** Poll cadence (ms). Defaults to the manager default. */
111
+ pollMs?(payload: Payload): number;
112
+ /**
113
+ * Optional immediate resolution BEFORE any server request is created (e.g. the
114
+ * approval session-rule fast path). Returning a result skips create + poll.
115
+ */
116
+ preflight?(input: RuntimeRequestPreflightInput<Payload>): Result | null;
117
+ /**
118
+ * Create the server-side request; returns the effective id + optional per-request
119
+ * state, plus any create-response fields the host needs back (surfaced via
120
+ * {@link RuntimeCreateResult} to `onCreated`).
121
+ */
122
+ create(input: RuntimeRequestCallInput<Payload, State> & {
123
+ options: RuntimeRequestOptions;
124
+ }): Promise<{
125
+ requestId: string;
126
+ expiresAt?: number;
127
+ state?: State;
128
+ messageId?: string;
129
+ interactive?: boolean;
130
+ }>;
131
+ /** Poll the server once and interpret the response. */
132
+ consume(input: RuntimeRequestCallInput<Payload, State>): Promise<RuntimeConsumeOutcome<Result>>;
133
+ /** Best-effort cancellation (abort / explicit cancel / dispose). */
134
+ cancel?(input: RuntimeRequestCallInput<Payload, State>): Promise<void>;
135
+ /** Result produced when the local deadline fires. */
136
+ timeoutResult(input: RuntimeRequestCallInput<Payload, State>): Result;
137
+ /**
138
+ * Finalization side effects + optional result override. Runs on `replied` /
139
+ * `timeout` (never `aborted`). Approval uses this to store the accepted session
140
+ * rule and emit its own outcome messages; returning a result lets it narrow the
141
+ * accepted rule into the returned value.
142
+ */
143
+ finalize?(input: RuntimeRequestCallInput<Payload, State> & {
144
+ result: Result;
145
+ reason: 'replied' | 'timeout';
146
+ }): Result | void;
147
+ /** Outcome message for the host to emit via `onOutcome` (input/card families). */
148
+ buildOutcome?(input: RuntimeRequestCallInput<Payload, State> & {
149
+ result: Result;
150
+ reason: 'replied' | 'timeout';
151
+ }): RuntimeOutcomeMessage | null;
152
+ /** Map an inbound push message to a pending request that should poll now. */
153
+ matchPush?(input: RuntimeRequestPushInput): RuntimeRequestPushMatch | null;
154
+ }
155
+ /**
156
+ * Platform-agnostic engine for Canon's interactive runtime requests.
157
+ *
158
+ * Generalizes the former `ApprovalManager`: it owns the pending map, deadline
159
+ * timers, the poll-with-abort loop that races an inbound push wakeup, and
160
+ * cancellation — all keyed by {@link KindDescriptor}. Approval, runtime input,
161
+ * runtime card, and plan families register over the same primitive; the former
162
+ * hand-written await-loops collapse into `request()`.
163
+ *
164
+ * Session-rule storage lives here because the approval descriptor's preflight /
165
+ * finalize read and write it; other families ignore it.
166
+ */
167
+ export declare class RuntimeRequestManager {
168
+ protected client: CanonClient;
169
+ protected ctx: RuntimeRequestContext;
170
+ private descriptors;
171
+ private pending;
172
+ private rules;
173
+ constructor(client: CanonClient, ctx: RuntimeRequestContext);
174
+ /** Register (or override) the descriptor for a kind. */
175
+ register<Payload, Result, State>(kind: RuntimeRequestKind, descriptor: KindDescriptor<Payload, Result, State>): void;
176
+ /** Built-in input, card, and plan descriptors. Subclasses add approval policy. */
177
+ protected registerBuiltins(): void;
178
+ get pendingCount(): number;
179
+ /**
180
+ * Run one interactive runtime request end to end:
181
+ * preflight → create → onCreated → register pending → poll (racing push wakeup
182
+ * and abort) → post-deadline consume → finalize → onOutcome → resolve.
183
+ */
184
+ request<Payload, Result, State = unknown>(kind: RuntimeRequestKind, conversationId: string, payload: Payload, options?: RuntimeRequestOptions): Promise<Result>;
185
+ /** Push short-circuit: wake the pending request's poll to consume immediately. */
186
+ notify(kind: RuntimeRequestKind, conversationId: string, requestId: string): void;
187
+ /**
188
+ * Feed an inbound message to the manager. Returns true when a matching pending
189
+ * request was woken to consume canonical state. Receipt metadata never settles
190
+ * the request directly. Fails closed on unknown / mismatched ids.
191
+ */
192
+ handleMessage(conversationId: string, message: {
193
+ senderId: string;
194
+ metadata?: Record<string, unknown>;
195
+ }): boolean;
196
+ /** Cancel a specific pending request (rejects its promise, best-effort server cancel). */
197
+ cancel(kind: RuntimeRequestKind, conversationId: string, requestId: string): Promise<void>;
198
+ checkSessionRules(toolName: string, conversationId?: string): SessionRule | null;
199
+ addSessionRule(conversationId: string, rule: SessionRule): void;
200
+ getSessionRules(): SessionRule[];
201
+ clearSessionRules(): void;
202
+ dispose(): void;
203
+ protected pruneExpiredRules(): void;
204
+ /** Sleep that resolves on timeout, on `notify()` wakeup, or when the request settles. */
205
+ private sleep;
206
+ }
207
+ /** Interactive runtime input (`AskUserQuestion`, secret prompts, choices). */
208
+ export interface RuntimeInputRequestPayload {
209
+ kind: RuntimeInputKind;
210
+ title?: string;
211
+ prompt?: string;
212
+ choices?: RuntimeInputChoice[];
213
+ questions?: RuntimeInputQuestion[];
214
+ secretName?: string;
215
+ native?: RuntimeInputNativeMetadata;
216
+ sensitive?: boolean;
217
+ responseUserId?: string;
218
+ turnId?: string;
219
+ }
220
+ export type RuntimeInputRequestResult = {
221
+ status: 'submitted';
222
+ inputId: string;
223
+ value: string;
224
+ answers?: RuntimeInputAnswers;
225
+ } | {
226
+ status: 'cancelled';
227
+ inputId: string;
228
+ } | {
229
+ status: 'timeout';
230
+ inputId: string;
231
+ };
232
+ export declare const runtimeInputDescriptor: KindDescriptor<RuntimeInputRequestPayload, RuntimeInputRequestResult>;
233
+ /** Interactive runtime card (canon.card.v1 with an actions block). */
234
+ export interface RuntimeCardRequestPayload {
235
+ card: RuntimeCardV1;
236
+ responseUserId?: string;
237
+ runtimeId?: string;
238
+ turnId?: string;
239
+ native?: RuntimeCardNativeMetadata;
240
+ }
241
+ export type RuntimeCardRequestResult = {
242
+ status: 'submitted';
243
+ cardId: string;
244
+ actionId?: string;
245
+ values?: Record<string, unknown>;
246
+ respondedBy?: string;
247
+ } | {
248
+ status: 'cancelled';
249
+ cardId: string;
250
+ respondedBy?: string;
251
+ } | {
252
+ status: 'timeout';
253
+ cardId: string;
254
+ };
255
+ export declare const runtimeCardDescriptor: KindDescriptor<RuntimeCardRequestPayload, RuntimeCardRequestResult>;
256
+ /** Blocking plan review produced by coding runtimes. */
257
+ export interface RuntimePlanRequestPayload {
258
+ title?: string;
259
+ summary?: string;
260
+ body?: string;
261
+ allowedPrompts?: ReadonlyArray<{
262
+ tool: string;
263
+ prompt: string;
264
+ }>;
265
+ responseUserId?: string;
266
+ turnId?: string;
267
+ }
268
+ export type RuntimePlanRequestResult = {
269
+ status: 'approve' | 'revise' | 'reject';
270
+ planId: string;
271
+ feedback?: string;
272
+ grantedPrompts?: Array<{
273
+ tool: string;
274
+ prompt: string;
275
+ }>;
276
+ receiptId?: string;
277
+ } | {
278
+ status: 'cancelled';
279
+ planId: string;
280
+ } | {
281
+ status: 'timeout';
282
+ planId: string;
283
+ };
284
+ export declare const runtimePlanDescriptor: KindDescriptor<RuntimePlanRequestPayload, RuntimePlanRequestResult>;
@@ -0,0 +1,42 @@
1
+ import type { AgentClientType, AgentRuntime, CanonRuntimeActivityItem, RuntimeInfoPayload, TurnOutputBlock } from './types.js';
2
+ import { type AgentSessionSnapshotPatch, type RTDBClientHandle, type SessionStatePayload, type TurnStatePayload } from './rtdb-rest.js';
3
+ export interface RuntimeStatePublisherOptions {
4
+ agentId: string;
5
+ clientType: AgentClientType;
6
+ hostMode: boolean;
7
+ /** Scoped endpoint-backed runtime-state handle from `initRTDBAuth`. */
8
+ rtdb: RTDBClientHandle;
9
+ }
10
+ export interface RuntimeStreamingPayload {
11
+ text: string;
12
+ status: 'thinking' | 'streaming' | 'tool' | 'waiting_input';
13
+ messageId?: string;
14
+ turnId?: string | null;
15
+ blocks?: TurnOutputBlock[];
16
+ updatedAt?: number | {
17
+ '.sv': 'timestamp';
18
+ };
19
+ }
20
+ export interface ClearRuntimeActivityOptions {
21
+ itemIds?: ReadonlyArray<string>;
22
+ terminalOnly?: boolean;
23
+ olderThanMs?: number;
24
+ all?: boolean;
25
+ }
26
+ export interface RuntimeStatePublisher {
27
+ publishAgentRuntime(runtime: AgentRuntime): Promise<void>;
28
+ clearAgentRuntime(): Promise<void>;
29
+ writeSessionState(conversationId: string, state: Omit<SessionStatePayload, 'updatedAt'>): Promise<void>;
30
+ clearSessionState(conversationId: string): Promise<void>;
31
+ writeTurnState(conversationId: string, state: Omit<TurnStatePayload, 'updatedAt'>): Promise<void>;
32
+ clearTurnState(conversationId: string): Promise<void>;
33
+ patchAgentSessionSnapshot(conversationId: string, snapshot: Omit<AgentSessionSnapshotPatch, 'updatedAt'>): Promise<void>;
34
+ writeRuntimeInfo(conversationId: string, payload: Omit<RuntimeInfoPayload, 'updatedAt'>): Promise<void>;
35
+ patchRuntimeInfo(conversationId: string, payload: Partial<Omit<RuntimeInfoPayload, 'updatedAt'>>): Promise<void>;
36
+ clearRuntimeInfo(conversationId: string): Promise<void>;
37
+ writeRuntimeActivity(conversationId: string, item: CanonRuntimeActivityItem): Promise<void>;
38
+ clearRuntimeActivity(conversationId: string, options?: ClearRuntimeActivityOptions): Promise<void>;
39
+ writeStreaming(conversationId: string, payload: RuntimeStreamingPayload): Promise<void>;
40
+ clearStreaming(conversationId: string): Promise<void>;
41
+ }
42
+ export declare function createRuntimeStatePublisher(options: RuntimeStatePublisherOptions): RuntimeStatePublisher;
@@ -0,0 +1,61 @@
1
+ export type CanonSelfContextType = 'cross_session';
2
+ export interface CanonSelfContext {
3
+ id: string;
4
+ type: CanonSelfContextType;
5
+ context: string;
6
+ /** Public message sent with this private explanation. */
7
+ targetMessageId?: string | null;
8
+ /** The Canon room that originated an older cross-session action. */
9
+ sourceConversationId?: string | null;
10
+ /** A local task may originate an action without having its own Canon room. */
11
+ externalSource?: {
12
+ kind: 'external';
13
+ integration: 'codex';
14
+ label?: string;
15
+ } | null;
16
+ /** Public target text hydrated from this room; never stored in the private note. */
17
+ targetMessageText?: string | null;
18
+ /** Public message time hydrated at delivery, used to order recent actions. */
19
+ targetMessageCreatedAt?: string | null;
20
+ createdAt?: string | null;
21
+ updatedAt?: string | null;
22
+ }
23
+ export interface SelfContextPromptRenderOptions {
24
+ maxSelfContexts?: number;
25
+ }
26
+ export declare function normalizeSelfContexts(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions): CanonSelfContext[];
27
+ export declare function resolveMessageActiveSelfContextId(input: {
28
+ messageId?: string | null;
29
+ activeSelfContextId?: string | null;
30
+ activeSelfContextIdByMessageId?: Record<string, string> | null;
31
+ }): string | null;
32
+ export declare function selectActiveSelfContexts(selfContexts?: CanonSelfContext[] | null, activeSelfContextId?: string | null): CanonSelfContext[];
33
+ /**
34
+ * Select private explanations for one inbound turn. A reply can activate only
35
+ * the explanation attached to its exact target. Other recent explanations are
36
+ * background, not a claim that the incoming message answers any one of them.
37
+ */
38
+ export declare function selectInboundSelfContexts(input: {
39
+ selfContexts?: CanonSelfContext[] | null;
40
+ replyTo?: string | null;
41
+ /** Backend-validated association for this inbound message, when available. */
42
+ linkedSelfContextId?: string | null;
43
+ messages?: ReadonlyArray<{
44
+ id?: string | null;
45
+ text?: string | null;
46
+ createdAt?: string | null;
47
+ deleted?: boolean | null;
48
+ }> | null;
49
+ replyContext?: {
50
+ messageId: string;
51
+ text?: string | null;
52
+ found: boolean;
53
+ } | null;
54
+ maxSelfContexts?: number;
55
+ }): {
56
+ activeSelfContextId: string | null;
57
+ selfContexts: CanonSelfContext[];
58
+ };
59
+ export declare function buildSelfContextPromptLines(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions & {
60
+ activeSelfContextId?: string | null;
61
+ }): string[];
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Deliberate silence — the shared half of the `no_reply` verb.
3
+ *
4
+ * A turn that calls `no_reply` must end without posting anything: the trigger
5
+ * gate is message-driven, so no message means no other agent is woken. Every
6
+ * host wires its own teardown, but they all ask the same question here.
7
+ */
8
+ /**
9
+ * The model-facing closure sentence, re-exported so a runtime that answers
10
+ * `no_reply` locally reads it from the same definition the server sends. It is
11
+ * DEFINED in @canonmsg/backend-contracts because that is the only package both
12
+ * the server and the hosts depend on.
13
+ */
14
+ export { NO_REPLY_ACK_NOTE } from '../backend-contracts/index.js';
15
+ import { type CanonVerbWireRequest } from '../backend-contracts/index.js';
16
+ /** The one client capability the outcome report needs. */
17
+ export interface NoReplyReportClient {
18
+ executeVerbWire(wire: CanonVerbWireRequest): Promise<unknown>;
19
+ }
20
+ /**
21
+ * What `reportNoReplyOutcome` puts on the wire in place of any caller-supplied
22
+ * reason text. The server stores only `hasReason` and discards the text, so
23
+ * transmitting the model- or handler-authored sentence would be pure exposure:
24
+ * the sentinel preserves the server's `hasReason` signal without moving the
25
+ * text. The reason a binding was handed never leaves its process.
26
+ */
27
+ export declare const NO_REPLY_REASON_SENTINEL = "given";
28
+ /**
29
+ * Report a locally-answered `no_reply` to the server, fire-and-forget.
30
+ *
31
+ * Four of the five runtimes answer the silence tool inside their own process
32
+ * and never reach `POST /agent/verbs/no_reply`, so Canon's durable record of
33
+ * deliberate silence (`/runtime-silence/{convoId}/{agentId}`) would otherwise
34
+ * cover Claude turns only. This is telemetry, not behavior: the silence flag
35
+ * is already set locally before this is called, so a failed or unreachable
36
+ * report degrades to exactly the pre-report behavior — never to a posted
37
+ * message and never to a failed turn.
38
+ *
39
+ * `params.reason` is read only for its presence: the wire carries
40
+ * `NO_REPLY_REASON_SENTINEL` in its place, never the caller's text.
41
+ *
42
+ * The Claude host must NOT call this helper: its binding already POSTs the
43
+ * verb via agent-tools, so calling both would double-record the silence.
44
+ */
45
+ export declare function reportNoReplyOutcome(client: NoReplyReportClient, params: {
46
+ conversationId: string;
47
+ messageId?: string;
48
+ reason?: string;
49
+ now?: number;
50
+ }): void;
51
+ /**
52
+ * Owner ruling 2026-07-31 (docs/history/group-behavior-2026-08-01.md), as
53
+ * implemented. `strict` (default): a no_reply call suppresses the final
54
+ * unconditionally. `advisory`: non-empty final text overrides the sentinel.
55
+ * ONE switch, so the ruling can be flipped without touching five hosts.
56
+ */
57
+ export type SilentTurnPrecedence = 'strict' | 'advisory';
58
+ export declare const DEFAULT_SILENT_TURN_PRECEDENCE: SilentTurnPrecedence;
59
+ export declare function resolveSilentTurnDelivery(input: {
60
+ silenced: boolean;
61
+ finalText: string | null | undefined;
62
+ precedence?: SilentTurnPrecedence;
63
+ }): 'deliver' | 'suppress';
64
+ /**
65
+ * Whether SILENCE is what withholds this turn's own output — the single
66
+ * question every consumer of the ruling asks, so they cannot disagree.
67
+ *
68
+ * `resolveSilentTurnDelivery` answers "is there anything to deliver", which
69
+ * also returns `suppress` for an ordinary turn that simply produced no text.
70
+ * A caller deciding what ELSE a silenced turn withholds — its workspace
71
+ * artifacts, its plan card — needs the narrower question, and deriving it by
72
+ * hand (`silenced && ...`) is how a second, independent reading of
73
+ * `DEFAULT_SILENT_TURN_PRECEDENCE` creeps in. Flipping that constant to
74
+ * `advisory` must move a turn's text and its artifacts together: a turn that
75
+ * talks about the chart it made and then ships no chart is worse than either
76
+ * consistent behaviour.
77
+ *
78
+ * `finalText` is the MODEL's own text for the turn — never Canon's failure
79
+ * notice, which is a host diagnostic rather than something the model said, and
80
+ * which is delivered whether the turn went silent or not.
81
+ */
82
+ export declare function isSilentTurnSuppressed(input: {
83
+ silenced: boolean;
84
+ finalText: string | null | undefined;
85
+ precedence?: SilentTurnPrecedence;
86
+ }): boolean;
@@ -0,0 +1,77 @@
1
+ import type { CanonEndpoint } from './endpoint-client.js';
2
+ import type { AgentContext, ContactAddedPayload, ContactRemovedPayload, ConversationUpdatedPayload, MessageCreatedPayload, MessageUpdatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, RuntimeControlEventPayload, TurnUpdatedPayload, ParticipationSuppressedPayload, VoiceSessionEventPayload } from './types.js';
3
+ export interface CanonStreamErrorPayload {
4
+ code?: string;
5
+ message?: string;
6
+ retryAfterMs?: number;
7
+ activeConnections?: number;
8
+ maxConnections?: number;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface ReplayExpiredPayload {
12
+ /** Oldest event id still available in the server's replay buffer, if any. */
13
+ lastAvailableId?: string | null;
14
+ message?: string;
15
+ [key: string]: unknown;
16
+ }
17
+ export declare class CanonStreamError extends Error {
18
+ readonly code?: string;
19
+ readonly retryAfterMs?: number;
20
+ readonly payload: CanonStreamErrorPayload;
21
+ constructor(payload: CanonStreamErrorPayload, fallbackMessage: string);
22
+ }
23
+ export type StreamHandler = {
24
+ onMessage: (payload: MessageCreatedPayload) => void;
25
+ onMessageUpdated?: (payload: MessageUpdatedPayload) => void;
26
+ onAgentContext?: (ctx: AgentContext) => void;
27
+ onContactAdded?: (payload: ContactAddedPayload) => void;
28
+ onContactRemoved?: (payload: ContactRemovedPayload) => void;
29
+ onTyping?: (data: TypingPayload) => void;
30
+ onPresence?: (data: PresencePayload) => void;
31
+ onRuntimeUpdated?: (payload: RuntimeUpdatedPayload) => void;
32
+ onTurnUpdated?: (payload: TurnUpdatedPayload) => void;
33
+ /** Observe-only: the participation gate suppressed a turn for this agent. */
34
+ onParticipationSuppressed?: (payload: ParticipationSuppressedPayload) => void;
35
+ onRuntimeControl?: (payload: RuntimeControlEventPayload) => void;
36
+ onVoiceSessionStarted?: (payload: VoiceSessionEventPayload) => void;
37
+ onVoiceSessionEnded?: (payload: VoiceSessionEventPayload) => void;
38
+ onMessageDeleted?: (payload: {
39
+ conversationId: string;
40
+ messageId: string;
41
+ }) => void;
42
+ onConversationUpdated?: (payload: ConversationUpdatedPayload) => void;
43
+ onConnected?: () => void;
44
+ onDisconnected?: () => void;
45
+ /**
46
+ * Fired when the server reports the replay window expired (`replay.expired`):
47
+ * the reconnect cursor was evicted, so events in the gap were NOT replayed
48
+ * and must be recovered out-of-band (e.g. via the REST API). The transport
49
+ * stays policy-free — it only clears its cursor and surfaces the expiry.
50
+ *
51
+ * When this handler is provided it REPLACES the synthetic
52
+ * `Replay expired — some messages may have been missed` error on `onError`;
53
+ * raw consumers that only register `onError` keep the existing behavior.
54
+ */
55
+ onReplayExpired?: (payload: ReplayExpiredPayload) => void;
56
+ onError?: (error: Error) => void;
57
+ };
58
+ /** Typed agent event projection; the endpoint owns authentication, SSE and reconnect. */
59
+ export declare class CanonStream {
60
+ private readonly endpoint;
61
+ private readonly agentId;
62
+ private readonly handler;
63
+ private unsubscribe?;
64
+ private releaseRecovery?;
65
+ private running;
66
+ private generation;
67
+ private resolveStopped?;
68
+ constructor(options: {
69
+ endpoint: CanonEndpoint;
70
+ agentId: string;
71
+ handler: StreamHandler;
72
+ });
73
+ start(): Promise<void>;
74
+ private forwardPlaintextMessage;
75
+ stop(): void;
76
+ isRunning(): boolean;
77
+ }