@canonmsg/agent-sdk 1.5.3 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canon-agent.js +157 -2
- package/dist/index.d.ts +2 -2
- package/dist/types.d.ts +29 -2
- package/package.json +2 -2
package/dist/canon-agent.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApprovalManager, CanonClient, buildCanonGroupContext, createRuntimeStatePublisher, diffCanonMemberIds, FINAL_MESSAGE_HANDOFF_MS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, initRTDBAuth, rtdbRead, rtdbWrite, normalizeTurnMetadata, reachOutToCanonContact, resolveCanonReplyContext, resolveMessageActiveSelfContextId, resolveRuntimeProvenance, selectActiveSelfContexts, } from '@canonmsg/core';
|
|
1
|
+
import { ApprovalManager, CanonClient, buildCanonGroupContext, createRuntimeStatePublisher, diffCanonMemberIds, FINAL_MESSAGE_HANDOFF_MS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildRuntimeInputOutcome, buildRuntimeInputRequest, initRTDBAuth, rtdbRead, rtdbWrite, normalizeTurnMetadata, reachOutToCanonContact, resolveCanonReplyContext, resolveMessageActiveSelfContextId, resolveRuntimeProvenance, selectActiveSelfContexts, } from '@canonmsg/core';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { AuthManager } from './auth.js';
|
|
4
4
|
import { Debouncer } from './debouncer.js';
|
|
@@ -7,6 +7,9 @@ import { SessionManager } from './session-manager.js';
|
|
|
7
7
|
const AGENT_RUNTIME_HEARTBEAT_MS = 30_000;
|
|
8
8
|
const RUNTIME_PRIMITIVE_DEDUPE_TTL_MS = 5 * 60 * 1000;
|
|
9
9
|
const RUNTIME_PRIMITIVE_DEDUPE_MAX = 1_000;
|
|
10
|
+
const DEFAULT_RUNTIME_INPUT_TIMEOUT_MS = 5 * 60_000;
|
|
11
|
+
const RUNTIME_INPUT_POLL_MS = 1_000;
|
|
12
|
+
const RUNTIME_INPUT_ID_PATTERN = /^[A-Za-z0-9_.:-]{1,160}$/;
|
|
10
13
|
const SDK_RUNTIME_CAPABILITIES = {
|
|
11
14
|
supportsInterrupt: false,
|
|
12
15
|
supportsInputInterrupt: false,
|
|
@@ -125,6 +128,24 @@ const STANDARD_PRIMITIVE_COMMANDS = {
|
|
|
125
128
|
function sleep(ms) {
|
|
126
129
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
127
130
|
}
|
|
131
|
+
function sleepWithAbort(ms, signal) {
|
|
132
|
+
if (signal.aborted)
|
|
133
|
+
return Promise.reject(createTurnAbortError());
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
const timer = setTimeout(resolve, ms);
|
|
136
|
+
signal.addEventListener('abort', () => {
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
reject(createTurnAbortError());
|
|
139
|
+
}, { once: true });
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function safeRuntimeInputId(value, kind) {
|
|
143
|
+
const raw = value?.trim() || `${kind}_${randomUUID()}`;
|
|
144
|
+
const normalized = raw.replace(/[.#$\[\]\/\s]+/g, '_').slice(0, 160);
|
|
145
|
+
return RUNTIME_INPUT_ID_PATTERN.test(normalized)
|
|
146
|
+
? normalized
|
|
147
|
+
: `${kind}_${randomUUID()}`;
|
|
148
|
+
}
|
|
128
149
|
function isRuntimePrimitiveId(value) {
|
|
129
150
|
return value === 'runtime.status'
|
|
130
151
|
|| value === 'runtime.reasoning.set'
|
|
@@ -227,6 +248,7 @@ export class CanonAgent {
|
|
|
227
248
|
debounceMs: 2000,
|
|
228
249
|
historyLimit: 50,
|
|
229
250
|
autoMarkRead: true,
|
|
251
|
+
runtimeControlSurface: 'agent',
|
|
230
252
|
...options,
|
|
231
253
|
};
|
|
232
254
|
this.apiClient = new CanonClient(this.options.apiKey, this.options.baseUrl);
|
|
@@ -1001,7 +1023,7 @@ export class CanonAgent {
|
|
|
1001
1023
|
return createRuntimeStatePublisher({
|
|
1002
1024
|
agentId: this.agentId,
|
|
1003
1025
|
clientType: this.options.clientType ?? 'generic',
|
|
1004
|
-
hostMode:
|
|
1026
|
+
hostMode: this.options.runtimeControlSurface === 'host',
|
|
1005
1027
|
});
|
|
1006
1028
|
}
|
|
1007
1029
|
requireRuntimeStatePublisher() {
|
|
@@ -1337,6 +1359,138 @@ export class CanonAgent {
|
|
|
1337
1359
|
return { decision: 'deny' };
|
|
1338
1360
|
}
|
|
1339
1361
|
};
|
|
1362
|
+
const requestRuntimeInput = async (request) => {
|
|
1363
|
+
throwIfAborted();
|
|
1364
|
+
const inputId = safeRuntimeInputId(request.inputId, request.kind);
|
|
1365
|
+
const timeoutMs = Math.max(1_000, request.timeoutMs ?? DEFAULT_RUNTIME_INPUT_TIMEOUT_MS);
|
|
1366
|
+
const expiresAtMs = Date.now() + timeoutMs;
|
|
1367
|
+
const expiresAt = new Date(expiresAtMs).toISOString();
|
|
1368
|
+
let result = { status: 'timeout', inputId };
|
|
1369
|
+
let requestCreated = false;
|
|
1370
|
+
let requestResolved = false;
|
|
1371
|
+
const cancelPendingRequest = async () => {
|
|
1372
|
+
if (!requestCreated || requestResolved)
|
|
1373
|
+
return;
|
|
1374
|
+
try {
|
|
1375
|
+
await this.apiClient.consumeRuntimeInputResponse({
|
|
1376
|
+
conversationId,
|
|
1377
|
+
inputId,
|
|
1378
|
+
cancel: true,
|
|
1379
|
+
});
|
|
1380
|
+
requestResolved = true;
|
|
1381
|
+
}
|
|
1382
|
+
catch { }
|
|
1383
|
+
};
|
|
1384
|
+
shouldPersistTurnState = true;
|
|
1385
|
+
try {
|
|
1386
|
+
await this.apiClient.createRuntimeInputRequest({
|
|
1387
|
+
conversationId,
|
|
1388
|
+
inputId,
|
|
1389
|
+
kind: request.kind,
|
|
1390
|
+
expiresAt: expiresAtMs,
|
|
1391
|
+
});
|
|
1392
|
+
requestCreated = true;
|
|
1393
|
+
try {
|
|
1394
|
+
await this.apiClient.clearStreaming(conversationId);
|
|
1395
|
+
}
|
|
1396
|
+
catch { }
|
|
1397
|
+
await writeTurn('waiting_input');
|
|
1398
|
+
try {
|
|
1399
|
+
await this.apiClient.setTyping(conversationId, false);
|
|
1400
|
+
}
|
|
1401
|
+
catch { }
|
|
1402
|
+
const card = buildRuntimeInputRequest(inputId, {
|
|
1403
|
+
kind: request.kind,
|
|
1404
|
+
title: request.title,
|
|
1405
|
+
prompt: request.prompt,
|
|
1406
|
+
...(request.choices ? { choices: request.choices } : {}),
|
|
1407
|
+
...(request.secretName ? { secretName: request.secretName } : {}),
|
|
1408
|
+
...(request.native ? { native: request.native } : {}),
|
|
1409
|
+
expiresAt,
|
|
1410
|
+
...(request.sensitive !== undefined ? { sensitive: request.sensitive } : {}),
|
|
1411
|
+
});
|
|
1412
|
+
await this.apiClient.sendMessage(conversationId, card.text, {
|
|
1413
|
+
metadata: {
|
|
1414
|
+
...card.metadata,
|
|
1415
|
+
turnId: request.turnId ?? turnId,
|
|
1416
|
+
turnSemantics: 'control',
|
|
1417
|
+
replyBehavior: 'suppress_auto_reply',
|
|
1418
|
+
},
|
|
1419
|
+
});
|
|
1420
|
+
while (Date.now() < expiresAtMs) {
|
|
1421
|
+
throwIfAborted();
|
|
1422
|
+
try {
|
|
1423
|
+
const response = await this.apiClient.consumeRuntimeInputResponse({
|
|
1424
|
+
conversationId,
|
|
1425
|
+
inputId,
|
|
1426
|
+
});
|
|
1427
|
+
if (response.status === 'submitted') {
|
|
1428
|
+
requestResolved = true;
|
|
1429
|
+
result = {
|
|
1430
|
+
status: 'submitted',
|
|
1431
|
+
value: response.value,
|
|
1432
|
+
inputId,
|
|
1433
|
+
};
|
|
1434
|
+
break;
|
|
1435
|
+
}
|
|
1436
|
+
if (response.status === 'cancelled' || response.status === 'timeout') {
|
|
1437
|
+
requestResolved = true;
|
|
1438
|
+
result = { status: response.status, inputId };
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
catch {
|
|
1443
|
+
// Transient consume failures should not leak sensitive input or
|
|
1444
|
+
// break the runtime; keep waiting until the explicit timeout.
|
|
1445
|
+
}
|
|
1446
|
+
await sleepWithAbort(Math.min(RUNTIME_INPUT_POLL_MS, Math.max(1, expiresAtMs - Date.now())), abortController.signal);
|
|
1447
|
+
}
|
|
1448
|
+
if (!requestResolved) {
|
|
1449
|
+
try {
|
|
1450
|
+
const response = await this.apiClient.consumeRuntimeInputResponse({
|
|
1451
|
+
conversationId,
|
|
1452
|
+
inputId,
|
|
1453
|
+
});
|
|
1454
|
+
if (response.status === 'submitted') {
|
|
1455
|
+
result = { status: 'submitted', value: response.value, inputId };
|
|
1456
|
+
}
|
|
1457
|
+
else if (response.status === 'cancelled' || response.status === 'timeout') {
|
|
1458
|
+
result = { status: response.status, inputId };
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
catch { }
|
|
1462
|
+
requestResolved = true;
|
|
1463
|
+
}
|
|
1464
|
+
const outcome = buildRuntimeInputOutcome(inputId, result.status, {
|
|
1465
|
+
kind: request.kind,
|
|
1466
|
+
reason: result.status,
|
|
1467
|
+
});
|
|
1468
|
+
await this.apiClient.sendMessage(conversationId, outcome.text, {
|
|
1469
|
+
metadata: {
|
|
1470
|
+
...outcome.metadata,
|
|
1471
|
+
turnId: request.turnId ?? turnId,
|
|
1472
|
+
turnSemantics: 'control',
|
|
1473
|
+
replyBehavior: 'suppress_auto_reply',
|
|
1474
|
+
},
|
|
1475
|
+
});
|
|
1476
|
+
throwIfAborted();
|
|
1477
|
+
shouldPersistTurnState = false;
|
|
1478
|
+
try {
|
|
1479
|
+
await this.apiClient.setTyping(conversationId, true, 'thinking');
|
|
1480
|
+
}
|
|
1481
|
+
catch { }
|
|
1482
|
+
await setLiveState('thinking', 'Thinking...', 'thinking');
|
|
1483
|
+
return result;
|
|
1484
|
+
}
|
|
1485
|
+
catch (error) {
|
|
1486
|
+
await cancelPendingRequest();
|
|
1487
|
+
if (abortController.signal.aborted || isAbortLikeError(error)) {
|
|
1488
|
+
throw error;
|
|
1489
|
+
}
|
|
1490
|
+
shouldPersistTurnState = false;
|
|
1491
|
+
return result;
|
|
1492
|
+
}
|
|
1493
|
+
};
|
|
1340
1494
|
const uploadFile = (filePath, options) => uploadMediaFile(this.apiClient, conversationId, filePath, options);
|
|
1341
1495
|
const replyWithFile = async (filePath, text = '', options) => {
|
|
1342
1496
|
throwIfAborted();
|
|
@@ -1399,6 +1553,7 @@ export class CanonAgent {
|
|
|
1399
1553
|
selfContexts,
|
|
1400
1554
|
provenance,
|
|
1401
1555
|
requestApproval,
|
|
1556
|
+
requestRuntimeInput,
|
|
1402
1557
|
abortSignal: abortController.signal,
|
|
1403
1558
|
media: {
|
|
1404
1559
|
materialize: (message = hydratedMessages[hydratedMessages.length - 1], options) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { CanonAgent } from './canon-agent.js';
|
|
2
2
|
export type { AgentContactsAPI, AgentUsersAPI } from './canon-agent.js';
|
|
3
3
|
export { ApprovalManager, buildApprovalOutcome, buildApprovalReply, buildApprovalRequest, CanonApiError, DEFAULT_APPROVAL_CONFIG, generateApprovalId, HOST_ADMISSION_ACTION_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, parseApprovalReplyMetadata, parseApprovalRequestMetadata, parseSessionRule, parseTextApprovalReply, redactSecrets, } from '@canonmsg/core';
|
|
4
|
-
export type { ApprovalConfig, ApprovalNativeRequestMetadata, ApprovalOutcomeMetadata, ApprovalReplyMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalResult, ApprovalRisk, CanonContact, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonResolveAdmissionResult, ContactAddedPayload, ContactCardPayload, ContactRemovedPayload, ContactSource, HostAdmissionActionCapabilities, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, SessionRule, } from '@canonmsg/core';
|
|
4
|
+
export type { ApprovalConfig, ApprovalNativeRequestMetadata, ApprovalOutcomeMetadata, ApprovalReplyMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalResult, ApprovalRisk, CanonContact, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonResolveAdmissionResult, ContactAddedPayload, ContactCardPayload, ContactRemovedPayload, ContactSource, HostAdmissionActionCapabilities, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, SessionRule, } from '@canonmsg/core';
|
|
5
5
|
export { SessionManager } from './session-manager.js';
|
|
6
6
|
export { DEFAULT_MEDIA_CACHE_DIR, getCodexImagePath, getMessageAttachments, inferUploadMimeType, isAnthropicImageAttachment, materializeAttachment, materializeMessageMedia, materializeReplyContextMedia, resolveAttachmentMimeType, sendMediaFileMessage, toAnthropicImageBlock, uploadMediaFile, } from './media.js';
|
|
7
7
|
export type { AnthropicImageBlock, AnthropicImageMimeType, MaterializeMediaOptions, MaterializedCanonAttachment, MaterializedCanonReplyContext, ReplyWithFileOptions, UploadMediaFileOptions, } from './media.js';
|
|
8
8
|
export type { SessionConfig, Session } from './session-manager.js';
|
|
9
9
|
export type { AgentContext, CanonGroupContext, CanonKnownRecentParticipant, CanonMembershipChange, CanonContactRequest, CanonMessage, CanonConversation, CanonReplyContext, CanonSelfContext, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, SendMessageOptions, CreateConversationOptions, } from '@canonmsg/core';
|
|
10
|
-
export type { CanonAgentOptions, ContactAddedHandler, ContactRemovedHandler, ContactRequestHandler, MessageHandler, MessageHandlerContext, ProgressMessageOptions, ProgressMessageResult, ReachOutOptions, ReachOutResult, RuntimeApprovalRequest, RuntimePrimitiveContext, RuntimePrimitiveHandler, RuntimePrimitiveHandlers, SessionInfo, SessionOptions, DeliveryMode, } from './types.js';
|
|
10
|
+
export type { CanonAgentOptions, ContactAddedHandler, ContactRemovedHandler, ContactRequestHandler, MessageHandler, MessageHandlerContext, ProgressMessageOptions, ProgressMessageResult, ReachOutOptions, ReachOutResult, RuntimeApprovalRequest, RuntimeInputRequest, RuntimeInputResult, RuntimeControlSurface, RuntimePrimitiveContext, RuntimePrimitiveHandler, RuntimePrimitiveHandlers, SessionInfo, SessionOptions, DeliveryMode, } from './types.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type { AddMemberResult, AgentClientType, CanonGroupContext, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeDescriptor, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimePrimitiveId, CanonRuntimeProvenance, CanonMessage, CanonConversation, CanonReplyContext, CanonContact, CanonContactRequest, CanonResolveAdmissionResult, ContactAddedPayload, ContactRemovedPayload, ContactSource, AgentContext, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonSelfContext, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, SendMessageOptions, SessionConfig, CreateConversationOptions, TurnLifecycleState, ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, } from '@canonmsg/core';
|
|
2
|
-
import type { AddMemberResult, CanonGroupContext, CanonMessage, CanonConversation, CanonReplyContext, ContactCardPayload, CanonRuntimeActionDispatch, CanonRuntimePrimitiveId, CanonRuntimeProvenance, ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalResult, ApprovalRisk, SendMessageOptions, SendContextualSelfContextInput, SessionConfig } from '@canonmsg/core';
|
|
1
|
+
export type { AddMemberResult, AgentClientType, CanonGroupContext, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeDescriptor, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimePrimitiveId, CanonRuntimeProvenance, CanonMessage, CanonConversation, CanonReplyContext, CanonContact, CanonContactRequest, CanonResolveAdmissionResult, ContactAddedPayload, ContactRemovedPayload, ContactSource, AgentContext, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonSelfContext, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, SendMessageOptions, SessionConfig, CreateConversationOptions, TurnLifecycleState, ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, SessionRule, ApprovalResult, } from '@canonmsg/core';
|
|
2
|
+
import type { AddMemberResult, CanonGroupContext, CanonMessage, CanonConversation, CanonReplyContext, ContactCardPayload, CanonRuntimeActionDispatch, CanonRuntimePrimitiveId, CanonRuntimeProvenance, ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalResult, ApprovalRisk, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, SendMessageOptions, SendContextualSelfContextInput, SessionConfig } from '@canonmsg/core';
|
|
3
3
|
import type { MaterializeMediaOptions, MaterializedCanonAttachment, ReplyWithFileOptions, UploadMediaFileOptions } from './media.js';
|
|
4
4
|
export interface ProgressMessageOptions extends SendMessageOptions {
|
|
5
5
|
/**
|
|
@@ -56,6 +56,24 @@ export interface RuntimeApprovalRequest {
|
|
|
56
56
|
/** Whether an approval reply may set an in-memory session rule. */
|
|
57
57
|
allowSessionRule?: boolean;
|
|
58
58
|
}
|
|
59
|
+
export interface RuntimeInputRequest {
|
|
60
|
+
kind: RuntimeInputKind;
|
|
61
|
+
title: string;
|
|
62
|
+
prompt: string;
|
|
63
|
+
choices?: RuntimeInputChoice[];
|
|
64
|
+
secretName?: string;
|
|
65
|
+
sensitive?: boolean;
|
|
66
|
+
runtimeId?: string;
|
|
67
|
+
turnId?: string;
|
|
68
|
+
native?: RuntimeInputNativeMetadata;
|
|
69
|
+
inputId?: string;
|
|
70
|
+
timeoutMs?: number;
|
|
71
|
+
}
|
|
72
|
+
export interface RuntimeInputResult {
|
|
73
|
+
status: 'submitted' | 'cancelled' | 'timeout';
|
|
74
|
+
value?: string;
|
|
75
|
+
inputId: string;
|
|
76
|
+
}
|
|
59
77
|
export interface MessageHandlerContext {
|
|
60
78
|
messages: CanonMessage[];
|
|
61
79
|
history: CanonMessage[];
|
|
@@ -109,6 +127,12 @@ export interface MessageHandlerContext {
|
|
|
109
127
|
* and enforce the returned decision in their own approval hook.
|
|
110
128
|
*/
|
|
111
129
|
requestApproval: (request: RuntimeApprovalRequest) => Promise<ApprovalResult>;
|
|
130
|
+
/**
|
|
131
|
+
* Ask the agent owner for runtime input such as clarification, sudo, or a
|
|
132
|
+
* secret. Sensitive values are returned only to the calling runtime and are
|
|
133
|
+
* never persisted in Canon message metadata.
|
|
134
|
+
*/
|
|
135
|
+
requestRuntimeInput: (request: RuntimeInputRequest) => Promise<RuntimeInputResult>;
|
|
112
136
|
/** Canon-managed local media access for the current conversation. */
|
|
113
137
|
media: {
|
|
114
138
|
materialize: (message?: CanonMessage, options?: Omit<MaterializeMediaOptions, 'agentId' | 'conversationId' | 'messageId'>) => Promise<MaterializedCanonAttachment[]>;
|
|
@@ -155,6 +179,7 @@ export interface RuntimeControlHandlers {
|
|
|
155
179
|
onStopAndDrop?: RuntimeSignalHandler;
|
|
156
180
|
onNewSession?: RuntimeSignalHandler;
|
|
157
181
|
}
|
|
182
|
+
export type RuntimeControlSurface = 'agent' | 'host';
|
|
158
183
|
export interface RuntimePrimitiveContext {
|
|
159
184
|
conversationId: string;
|
|
160
185
|
primitive: CanonRuntimePrimitiveId;
|
|
@@ -186,6 +211,8 @@ export interface CanonAgentOptions {
|
|
|
186
211
|
runtimeDescriptor?: import('@canonmsg/core').CanonRuntimeDescriptor;
|
|
187
212
|
/** Optional Canon runtime signal handlers. Enables interrupt controls when provided. */
|
|
188
213
|
runtimeControls?: RuntimeControlHandlers;
|
|
214
|
+
/** Runtime publishing surface. Use `host` when this agent owns live runtime controls. */
|
|
215
|
+
runtimeControlSurface?: RuntimeControlSurface;
|
|
189
216
|
/** Optional typed runtime primitive handlers. Enables descriptor-backed command controls when provided. */
|
|
190
217
|
runtimePrimitives?: RuntimePrimitiveHandlers;
|
|
191
218
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/agent-sdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "Canon Agent SDK — build AI agents that participate in Canon conversations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@canonmsg/core": "^0.20.
|
|
31
|
+
"@canonmsg/core": "^0.20.1"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|