@canonmsg/core 0.14.0 → 0.15.1

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.
@@ -1,4 +1,21 @@
1
1
  import { mergeWorkSessionContexts, } from './work-session.js';
2
+ function listDescriptorControls(runtime) {
3
+ const descriptor = runtime?.runtimeDescriptor;
4
+ return [
5
+ ...(descriptor?.coreControls ?? []),
6
+ ...(descriptor?.runtimeControls ?? []),
7
+ ];
8
+ }
9
+ function descriptorOptions(runtime, controlId) {
10
+ return [...(listDescriptorControls(runtime)
11
+ .find((control) => control.id === controlId)
12
+ ?.options ?? [])];
13
+ }
14
+ function descriptorDefaultValue(runtime, controlId) {
15
+ const control = listDescriptorControls(runtime)
16
+ .find((candidate) => candidate.id === controlId);
17
+ return control?.defaultValue ?? control?.options?.[0]?.value ?? undefined;
18
+ }
2
19
  function buildWorkSessionSummary(workSession, workSessions) {
3
20
  const merged = mergeWorkSessionContexts(workSession, workSessions);
4
21
  const primary = merged[0];
@@ -14,13 +31,14 @@ function buildWorkSessionSummary(workSession, workSessions) {
14
31
  };
15
32
  }
16
33
  export function buildAgentSessionSnapshot(input) {
17
- const modelOptions = input.sessionState?.availableModels
18
- ?? input.sessionConfig?.availableModels
19
- ?? input.runtime?.availableModels
20
- ?? [];
21
- const workspaceOptions = input.sessionConfig?.workspaceOptions
22
- ?? input.runtime?.availableWorkspaces
23
- ?? [];
34
+ const modelOptions = input.sessionState?.availableModels?.length
35
+ ? input.sessionState.availableModels
36
+ : descriptorOptions(input.runtime, 'model');
37
+ const workspaceOptions = descriptorOptions(input.runtime, 'workspace')
38
+ .map((option) => ({ id: option.value, label: option.label }));
39
+ const availableExecutionModes = descriptorOptions(input.runtime, 'executionMode')
40
+ .map((option) => option.value)
41
+ .filter((value) => value === 'worktree' || value === 'locked');
24
42
  return {
25
43
  conversationId: input.conversationId,
26
44
  agentId: input.agentId,
@@ -32,36 +50,31 @@ export function buildAgentSessionSnapshot(input) {
32
50
  ?? input.runtime?.hostMode),
33
51
  model: input.sessionState?.model
34
52
  ?? input.sessionConfig?.model
35
- ?? input.runtime?.defaultModel
36
- ?? modelOptions[0]?.value,
53
+ ?? descriptorDefaultValue(input.runtime, 'model'),
37
54
  modelOptions,
38
55
  permissionMode: input.sessionState?.permissionMode
39
56
  ?? input.sessionConfig?.permissionMode
40
- ?? input.runtime?.defaultPermissionMode,
41
- permissionModeOptions: input.runtime?.availablePermissionModes ?? [],
57
+ ?? descriptorDefaultValue(input.runtime, 'permissionMode'),
58
+ permissionModeOptions: descriptorOptions(input.runtime, 'permissionMode'),
42
59
  effort: input.sessionState?.effort ?? input.sessionConfig?.effort,
43
60
  runtimeControlValues: input.sessionState?.runtimeControlValues
44
61
  ?? input.sessionConfig?.runtimeControlValues,
62
+ runtimeControlErrors: input.sessionState?.runtimeControlErrors ?? undefined,
45
63
  workspaceId: input.sessionConfig?.workspaceId
46
- ?? input.runtime?.defaultWorkspaceId
47
- ?? workspaceOptions[0]?.id,
64
+ ?? descriptorDefaultValue(input.runtime, 'workspace'),
48
65
  workspaceOptions,
49
66
  executionMode: input.sessionState?.executionMode
50
67
  ?? input.sessionConfig?.executionMode,
51
- availableExecutionModes: input.sessionConfig?.availableExecutionModes
52
- ?? input.runtime?.availableExecutionModes
53
- ?? [],
68
+ availableExecutionModes,
54
69
  executionBranch: input.sessionState?.executionBranch,
55
70
  resolvedWorkspaceLabel: undefined,
56
71
  resolvedCwd: input.sessionState?.cwd,
57
72
  worktreePath: input.sessionState?.worktreePath,
58
73
  executionFallbackReason: input.sessionState?.executionFallbackReason,
59
- state: input.sessionState?.state,
60
74
  turnState: input.turnState?.state,
61
75
  supportsQueue: input.turnState?.capabilities?.supportsQueue,
62
76
  queueDepth: input.turnState?.queueDepth ?? 0,
63
- waitingForInput: input.turnState?.state === 'waiting_input'
64
- || input.sessionState?.state === 'requires_action',
77
+ waitingForInput: input.turnState?.state === 'waiting_input',
65
78
  contextUsage: input.sessionState?.contextUsage,
66
79
  lastError: input.sessionState?.lastError,
67
80
  lastHeartbeatAt: input.lastHeartbeatAt
package/dist/browser.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
2
2
  export { resolveCanonBaseUrl } from './base-url.js';
3
3
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
4
- export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
4
+ export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, AgentSessionWorkSessionSummary, AgentRuntime, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonStreamEvent, CreateContactRequestResult, MediaAttachment, MediaAttachmentKind, ModelOption, PermissionModeOption, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
5
5
  export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
6
6
  export type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
7
7
  export type { CanonResolvedWorkSession, CanonWorkSession, CanonWorkSessionContext, CanonWorkSessionConversationRole, CanonWorkSessionDisclosureMode, CanonWorkSessionParticipant, CanonWorkSessionStatus, CreateWorkSessionOptions, SendLinkedMessageOptions, SendLinkedMessageResult, UpdateWorkSessionConversationOptions, WorkSessionPromptRenderOptions, } from './work-session.js';
@@ -0,0 +1,13 @@
1
+ export interface CliMetadata {
2
+ name: string;
3
+ description?: string;
4
+ help: string;
5
+ version?: string;
6
+ }
7
+ export interface RunCliMetadataOptions extends CliMetadata {
8
+ argv?: string[];
9
+ }
10
+ export declare function isDirectExecution(moduleUrl: string): boolean;
11
+ export declare function readCliPackageVersion(moduleUrl: string): string | null;
12
+ export declare function handleCliMetadataRequest(moduleUrl: string, metadata: RunCliMetadataOptions): boolean;
13
+ export declare function runCli(moduleUrl: string, main: () => void | Promise<void>, onError: (error: unknown) => void, metadata?: RunCliMetadataOptions): void;
@@ -0,0 +1,60 @@
1
+ import { readFileSync, realpathSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
+ export function isDirectExecution(moduleUrl) {
5
+ const entry = process.argv[1];
6
+ if (!entry)
7
+ return false;
8
+ const abs = resolve(entry);
9
+ let real = abs;
10
+ try {
11
+ real = realpathSync(abs);
12
+ }
13
+ catch {
14
+ // argv[1] may not exist on disk in rare harnesses; fall back to abs.
15
+ }
16
+ return (pathToFileURL(real).href === moduleUrl
17
+ || pathToFileURL(abs).href === moduleUrl);
18
+ }
19
+ export function readCliPackageVersion(moduleUrl) {
20
+ let current = dirname(fileURLToPath(moduleUrl));
21
+ while (true) {
22
+ try {
23
+ const manifest = JSON.parse(readFileSync(resolve(current, 'package.json'), 'utf8'));
24
+ return typeof manifest.version === 'string' ? manifest.version : null;
25
+ }
26
+ catch {
27
+ const parent = dirname(current);
28
+ if (parent === current)
29
+ return null;
30
+ current = parent;
31
+ }
32
+ }
33
+ }
34
+ function hasArg(argv, long, short) {
35
+ return argv.includes(long) || argv.includes(short);
36
+ }
37
+ export function handleCliMetadataRequest(moduleUrl, metadata) {
38
+ const argv = metadata.argv ?? process.argv.slice(2);
39
+ if (hasArg(argv, '--help', '-h')) {
40
+ process.stdout.write(`${metadata.help.trimEnd()}\n`);
41
+ return true;
42
+ }
43
+ if (hasArg(argv, '--version', '-V')) {
44
+ const version = metadata.version ?? readCliPackageVersion(moduleUrl) ?? 'unknown';
45
+ process.stdout.write(`${metadata.name} ${version}\n`);
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ export function runCli(moduleUrl, main, onError, metadata) {
51
+ if (!isDirectExecution(moduleUrl)) {
52
+ return;
53
+ }
54
+ if (metadata && handleCliMetadataRequest(moduleUrl, metadata)) {
55
+ return;
56
+ }
57
+ Promise.resolve()
58
+ .then(() => main())
59
+ .catch(onError);
60
+ }
@@ -36,6 +36,7 @@ export declare function buildCanonHostPrompt(input: {
36
36
  workSession?: MessageCreatedPayload['message']['workSession'];
37
37
  workSessions?: MessageCreatedPayload['workSessions'];
38
38
  buildInboundContextLines: (context: HostInboundParticipantContext) => string[];
39
+ sessionContextLines?: string[];
39
40
  }): string;
40
41
  /**
41
42
  * Render the **text portion** of an inbound Canon message. Images are
@@ -24,6 +24,9 @@ export function buildCanonHostPrompt(input) {
24
24
  ...(resolvedWorkSessions.length > 0
25
25
  ? ['Honor the Canon work-session context above within its stated disclosure limits.']
26
26
  : []),
27
+ ...(input.sessionContextLines?.length
28
+ ? ['Canon session state:', ...input.sessionContextLines]
29
+ : []),
27
30
  `Conversation ID: ${input.conversationId}`,
28
31
  '',
29
32
  'New Canon message:',
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
2
- export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, AgentSessionWorkSessionSummary, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
2
+ export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonResolveAdmissionResult, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, AgentSessionWorkSessionSummary, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
3
3
  export type { CanonResolvedWorkSession, CanonWorkSession, CanonWorkSessionContext, CanonWorkSessionConversationRole, CreateWorkSessionOptions, CanonWorkSessionDisclosureMode, CanonWorkSessionParticipant, CanonWorkSessionStatus, SendLinkedMessageOptions, SendLinkedMessageResult, UpdateWorkSessionConversationOptions, WorkSessionPromptRenderOptions, } from './work-session.js';
4
4
  export { buildWorkSessionPromptLines, buildWorkSessionsPromptLines, mergeWorkSessionContexts, } from './work-session.js';
5
5
  export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
@@ -39,3 +39,5 @@ export type { RuntimeStatePublisher, RuntimeStatePublisherOptions, RuntimeStream
39
39
  export { formatCanonMessageAsText } from './message-format.js';
40
40
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
41
41
  export { resolveCanonBaseUrl } from './base-url.js';
42
+ export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, runCli, } from './cli-metadata.js';
43
+ export type { CliMetadata, RunCliMetadataOptions, } from './cli-metadata.js';
package/dist/index.js CHANGED
@@ -39,3 +39,5 @@ export { formatCanonMessageAsText } from './message-format.js';
39
39
  export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
40
40
  // Base URL resolver
41
41
  export { resolveCanonBaseUrl } from './base-url.js';
42
+ // CLI metadata helpers for Node entrypoints
43
+ export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, runCli, } from './cli-metadata.js';
@@ -7,6 +7,7 @@ export interface LocalRuntimeSessionState {
7
7
  workspaceId?: string;
8
8
  baseCwd: string;
9
9
  executionMode?: ExecutionEnvironmentMode;
10
+ codexPolicyFingerprint?: string;
10
11
  threadId?: string;
11
12
  claudeSessionId?: string;
12
13
  lastInboundMessageId?: string;
@@ -165,7 +165,7 @@ export function clearRuntimeSessionState(runtimeId, input) {
165
165
  delete sessions[key];
166
166
  }
167
167
  }
168
- upsertLocalRuntimeEntry({ ...entry, sessions });
168
+ writeJsonAtomic(runtimePath(entry.id), { ...entry, sessions });
169
169
  }
170
170
  function migrateLegacyCodexSessions(runtimeId) {
171
171
  if (!existsSync(LEGACY_CODEX_SESSIONS_PATH))
@@ -7,13 +7,14 @@
7
7
  */
8
8
  import type { CanonClient } from './client.js';
9
9
  import type { DeliveryIntent, RuntimeCapabilities, TurnLifecycleState } from './turn-protocol.js';
10
- import type { CanonControlValue, RuntimeInfoPayload } from './types.js';
10
+ import type { CanonControlValue, ModelOption, RuntimeControlError, RuntimeInfoPayload } from './types.js';
11
11
  export interface SessionStatePayload {
12
12
  lastError?: string;
13
13
  model?: string;
14
14
  permissionMode?: string;
15
15
  effort?: string;
16
16
  runtimeControlValues?: Record<string, CanonControlValue>;
17
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
17
18
  cwd?: string;
18
19
  executionMode?: 'worktree' | 'locked';
19
20
  executionBranch?: string;
@@ -22,16 +23,12 @@ export interface SessionStatePayload {
22
23
  hostMode?: boolean;
23
24
  clientType?: string;
24
25
  isActive: boolean;
25
- state?: 'idle' | 'running' | 'requires_action';
26
26
  contextUsage?: {
27
27
  percentage: number;
28
28
  totalTokens: number;
29
29
  maxTokens: number;
30
30
  };
31
- availableModels?: Array<{
32
- value: string;
33
- label: string;
34
- }>;
31
+ availableModels?: ModelOption[];
35
32
  updatedAt: {
36
33
  '.sv': 'timestamp';
37
34
  };
@@ -58,10 +55,7 @@ export interface AgentSessionSnapshotPatch {
58
55
  clientType?: string;
59
56
  hostMode?: boolean;
60
57
  model?: string | null;
61
- modelOptions?: Array<{
62
- value: string;
63
- label: string;
64
- }> | null;
58
+ modelOptions?: ModelOption[] | null;
65
59
  permissionMode?: string | null;
66
60
  permissionModeOptions?: Array<{
67
61
  value: string;
@@ -69,6 +63,7 @@ export interface AgentSessionSnapshotPatch {
69
63
  }> | null;
70
64
  effort?: string | null;
71
65
  runtimeControlValues?: Record<string, CanonControlValue> | null;
66
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
72
67
  workspaceId?: string | null;
73
68
  workspaceOptions?: Array<{
74
69
  id: string;
@@ -80,7 +75,7 @@ export interface AgentSessionSnapshotPatch {
80
75
  resolvedCwd?: string | null;
81
76
  worktreePath?: string | null;
82
77
  executionFallbackReason?: string | null;
83
- state?: 'idle' | 'running' | 'requires_action' | null;
78
+ state?: null;
84
79
  turnState?: TurnLifecycleState | null;
85
80
  supportsQueue?: boolean | null;
86
81
  queueDepth?: number;
package/dist/rtdb-rest.js CHANGED
@@ -144,7 +144,9 @@ function createRTDBClientHandle(client, options) {
144
144
  ...(state.runtimeControlValues !== undefined
145
145
  ? { runtimeControlValues: state.runtimeControlValues }
146
146
  : {}),
147
- ...(state.availableModels !== undefined ? { modelOptions: state.availableModels } : {}),
147
+ ...(state.runtimeControlErrors !== undefined
148
+ ? { runtimeControlErrors: state.runtimeControlErrors }
149
+ : {}),
148
150
  ...(state.cwd !== undefined ? { resolvedCwd: state.cwd } : {}),
149
151
  ...(state.executionMode !== undefined ? { executionMode: state.executionMode } : {}),
150
152
  ...(state.executionBranch !== undefined ? { executionBranch: state.executionBranch } : {}),
@@ -152,9 +154,10 @@ function createRTDBClientHandle(client, options) {
152
154
  ...(state.executionFallbackReason !== undefined
153
155
  ? { executionFallbackReason: state.executionFallbackReason }
154
156
  : {}),
155
- ...(state.state !== undefined ? { state: state.state } : {}),
156
- waitingForInput: state.state === 'requires_action',
157
+ state: null,
158
+ waitingForInput: false,
157
159
  ...(state.contextUsage !== undefined ? { contextUsage: state.contextUsage } : {}),
160
+ ...(state.availableModels !== undefined ? { modelOptions: state.availableModels } : {}),
158
161
  ...(state.lastError !== undefined ? { lastError: state.lastError } : {}),
159
162
  lastHeartbeatAt: { '.sv': 'timestamp' },
160
163
  updatedAt: { '.sv': 'timestamp' },
@@ -167,7 +170,7 @@ function createRTDBClientHandle(client, options) {
167
170
  updatedAt: { '.sv': 'timestamp' },
168
171
  });
169
172
  await patch(buildAgentSessionPath(conversationId, agentId), {
170
- state: 'idle',
173
+ state: null,
171
174
  waitingForInput: false,
172
175
  lastError: null,
173
176
  executionBranch: null,
package/dist/types.d.ts CHANGED
@@ -434,6 +434,7 @@ export type CanonStreamEvent = {
434
434
  };
435
435
  };
436
436
  export interface SendMessageOptions {
437
+ messageId?: string;
437
438
  contentType?: 'text' | 'audio' | 'image' | 'file' | 'contact_card';
438
439
  replyTo?: string;
439
440
  replyToPosition?: number;
@@ -466,6 +467,11 @@ export interface SessionControl {
466
467
  updatedAt: number;
467
468
  updatedBy: string;
468
469
  }
470
+ export interface RuntimeControlError {
471
+ value: string;
472
+ message: string;
473
+ updatedAt: number;
474
+ }
469
475
  /** Written by agent to /session-state/{convoId}/{agentId} in RTDB */
470
476
  export interface SessionState {
471
477
  lastError?: string;
@@ -473,6 +479,7 @@ export interface SessionState {
473
479
  permissionMode?: string;
474
480
  effort?: string;
475
481
  runtimeControlValues?: Record<string, CanonControlValue>;
482
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
476
483
  cwd?: string;
477
484
  executionMode?: 'worktree' | 'locked';
478
485
  executionBranch?: string;
@@ -482,7 +489,6 @@ export interface SessionState {
482
489
  /** True when the agent is running under the host wrapper (host.ts) which can apply control signals */
483
490
  hostMode?: boolean;
484
491
  isActive: boolean;
485
- state?: 'idle' | 'running' | 'requires_action';
486
492
  contextUsage?: {
487
493
  percentage: number;
488
494
  totalTokens: number;
@@ -574,6 +580,7 @@ export interface AgentSessionSnapshot {
574
580
  permissionModeOptions?: PermissionModeOption[];
575
581
  effort?: string;
576
582
  runtimeControlValues?: Record<string, CanonControlValue>;
583
+ runtimeControlErrors?: Record<string, RuntimeControlError> | null;
577
584
  runtimeDescriptor?: CanonRuntimeDescriptor | null;
578
585
  runtimeInfo?: RuntimeInfoPayload | null;
579
586
  workspaceId?: string;
@@ -585,7 +592,6 @@ export interface AgentSessionSnapshot {
585
592
  resolvedCwd?: string | null;
586
593
  worktreePath?: string | null;
587
594
  executionFallbackReason?: string | null;
588
- state?: SessionState['state'];
589
595
  turnState?: TurnLifecycleState;
590
596
  supportsQueue?: boolean;
591
597
  queueDepth: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonmsg/core",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "Canon core — shared types, REST client, SSE stream, and registration for Canon messaging",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",