@canonmsg/agent-sdk 5.1.0 → 5.1.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.
- package/dist/canon-agent.js +48 -5
- package/dist/types.d.ts +14 -7
- package/package.json +2 -2
package/dist/canon-agent.js
CHANGED
|
@@ -167,6 +167,9 @@ function safeRuntimeCardId(value) {
|
|
|
167
167
|
? normalized
|
|
168
168
|
: `card_${randomUUID()}`;
|
|
169
169
|
}
|
|
170
|
+
function normalizeResponseUserId(value) {
|
|
171
|
+
return value?.trim() || undefined;
|
|
172
|
+
}
|
|
170
173
|
function buildSdkMessageId(parts) {
|
|
171
174
|
const raw = parts
|
|
172
175
|
.map((part) => part == null ? '' : String(part))
|
|
@@ -1310,6 +1313,9 @@ export class CanonAgent {
|
|
|
1310
1313
|
}
|
|
1311
1314
|
}
|
|
1312
1315
|
const latestMessage = hydratedMessages[hydratedMessages.length - 1] ?? null;
|
|
1316
|
+
const triggeringHumanId = latestMessage?.senderType === 'human'
|
|
1317
|
+
? normalizeResponseUserId(latestMessage.senderId)
|
|
1318
|
+
: undefined;
|
|
1313
1319
|
let replyContext = latestMessage
|
|
1314
1320
|
? resolveCanonReplyContext({ message: latestMessage, messages: history })
|
|
1315
1321
|
: null;
|
|
@@ -1473,6 +1479,11 @@ export class CanonAgent {
|
|
|
1473
1479
|
await this.typingSignals.clear(conversationId);
|
|
1474
1480
|
}
|
|
1475
1481
|
catch { }
|
|
1482
|
+
const responseUserId = normalizeResponseUserId(request.responseUserId)
|
|
1483
|
+
?? triggeringHumanId;
|
|
1484
|
+
// Session-wide rules are owner-scoped. The effective responder, not
|
|
1485
|
+
// merely the member who triggered the turn, determines that scope.
|
|
1486
|
+
const mustIsolateSessionRules = Boolean(responseUserId && responseUserId !== agent.ownerId);
|
|
1476
1487
|
const result = await manager.requestApproval(conversationId, request.toolName, request.toolInput ?? {}, {
|
|
1477
1488
|
riskLevel: request.riskLevel,
|
|
1478
1489
|
risk: request.risk,
|
|
@@ -1482,8 +1493,9 @@ export class CanonAgent {
|
|
|
1482
1493
|
native: request.native,
|
|
1483
1494
|
toolSummary: request.toolSummary,
|
|
1484
1495
|
details: request.details,
|
|
1485
|
-
|
|
1486
|
-
|
|
1496
|
+
...(responseUserId ? { responseUserId } : {}),
|
|
1497
|
+
ignoreSessionRules: mustIsolateSessionRules ? true : request.ignoreSessionRules,
|
|
1498
|
+
allowSessionRule: mustIsolateSessionRules ? false : request.allowSessionRule,
|
|
1487
1499
|
});
|
|
1488
1500
|
throwIfAborted();
|
|
1489
1501
|
shouldPersistTurnState = false;
|
|
@@ -1516,6 +1528,15 @@ export class CanonAgent {
|
|
|
1516
1528
|
const expiresAt = new Date(expiresAtMs).toISOString();
|
|
1517
1529
|
let result = { status: 'timeout', inputId };
|
|
1518
1530
|
let requestCreated = false;
|
|
1531
|
+
const ownerOnly = request.kind === 'secret'
|
|
1532
|
+
|| request.kind === 'sudo'
|
|
1533
|
+
|| request.sensitive === true
|
|
1534
|
+
|| Boolean(request.questions?.some((question) => question.isSecret));
|
|
1535
|
+
const responseUserId = ownerOnly
|
|
1536
|
+
? normalizeResponseUserId(agent.ownerId)
|
|
1537
|
+
: normalizeResponseUserId(request.responseUserId)
|
|
1538
|
+
?? triggeringHumanId
|
|
1539
|
+
?? normalizeResponseUserId(agent.ownerId);
|
|
1519
1540
|
shouldPersistTurnState = true;
|
|
1520
1541
|
try {
|
|
1521
1542
|
await this.apiClient.createRuntimeInputRequest({
|
|
@@ -1523,7 +1544,7 @@ export class CanonAgent {
|
|
|
1523
1544
|
inputId,
|
|
1524
1545
|
kind: request.kind,
|
|
1525
1546
|
expiresAt: expiresAtMs,
|
|
1526
|
-
responseUserId:
|
|
1547
|
+
...(responseUserId ? { responseUserId } : {}),
|
|
1527
1548
|
title: request.title,
|
|
1528
1549
|
prompt: request.prompt,
|
|
1529
1550
|
...(request.choices ? { choices: request.choices } : {}),
|
|
@@ -1621,9 +1642,20 @@ export class CanonAgent {
|
|
|
1621
1642
|
const expiresAtMs = explicitExpiresAt && Number.isFinite(explicitExpiresAt)
|
|
1622
1643
|
? explicitExpiresAt
|
|
1623
1644
|
: Date.now() + timeoutMs;
|
|
1645
|
+
const responseUserId = normalizeResponseUserId(request.responseUserId)
|
|
1646
|
+
?? triggeringHumanId;
|
|
1647
|
+
const routedRequest = responseUserId
|
|
1648
|
+
? { ...request, responseUserId }
|
|
1649
|
+
: request;
|
|
1624
1650
|
// Fire-and-forget: post the durable card and return. The backend treats an
|
|
1625
1651
|
// action-less card as display (no pending state, no response expected).
|
|
1626
|
-
await this.apiClient.createRuntimeCardRequest(buildRuntimeCardCreateArgs({
|
|
1652
|
+
await this.apiClient.createRuntimeCardRequest(buildRuntimeCardCreateArgs({
|
|
1653
|
+
request: routedRequest,
|
|
1654
|
+
conversationId,
|
|
1655
|
+
cardId,
|
|
1656
|
+
fallbackTurnId: turnId,
|
|
1657
|
+
expiresAtMs,
|
|
1658
|
+
}));
|
|
1627
1659
|
try {
|
|
1628
1660
|
await turnOutput.addBlock({
|
|
1629
1661
|
id: `card:${cardId}`,
|
|
@@ -1655,12 +1687,23 @@ export class CanonAgent {
|
|
|
1655
1687
|
const expiresAtMs = explicitExpiresAt && Number.isFinite(explicitExpiresAt)
|
|
1656
1688
|
? explicitExpiresAt
|
|
1657
1689
|
: Date.now() + timeoutMs;
|
|
1690
|
+
const responseUserId = normalizeResponseUserId(request.responseUserId)
|
|
1691
|
+
?? triggeringHumanId;
|
|
1692
|
+
const routedRequest = responseUserId
|
|
1693
|
+
? { ...request, responseUserId }
|
|
1694
|
+
: request;
|
|
1658
1695
|
let result = { status: 'timeout', cardId };
|
|
1659
1696
|
let requestCreated = false;
|
|
1660
1697
|
let requestResolved = false;
|
|
1661
1698
|
shouldPersistTurnState = true;
|
|
1662
1699
|
try {
|
|
1663
|
-
await this.apiClient.createRuntimeCardRequest(buildRuntimeCardCreateArgs({
|
|
1700
|
+
await this.apiClient.createRuntimeCardRequest(buildRuntimeCardCreateArgs({
|
|
1701
|
+
request: routedRequest,
|
|
1702
|
+
conversationId,
|
|
1703
|
+
cardId,
|
|
1704
|
+
fallbackTurnId: turnId,
|
|
1705
|
+
expiresAtMs,
|
|
1706
|
+
}));
|
|
1664
1707
|
requestCreated = true;
|
|
1665
1708
|
try {
|
|
1666
1709
|
await turnOutput.addBlock({
|
package/dist/types.d.ts
CHANGED
|
@@ -59,6 +59,8 @@ export interface RuntimeApprovalRequest {
|
|
|
59
59
|
turnId?: string;
|
|
60
60
|
native?: ApprovalNativeRequestMetadata;
|
|
61
61
|
details?: ApprovalRequestDetail[];
|
|
62
|
+
/** Human conversation member who should answer. Defaults to the triggering human. */
|
|
63
|
+
responseUserId?: string;
|
|
62
64
|
/**
|
|
63
65
|
* Ignore in-memory session rules for this approval request. Useful when the
|
|
64
66
|
* action was triggered by someone other than the agent owner.
|
|
@@ -80,6 +82,8 @@ export interface RuntimeInputRequest {
|
|
|
80
82
|
native?: RuntimeInputNativeMetadata;
|
|
81
83
|
inputId?: string;
|
|
82
84
|
timeoutMs?: number;
|
|
85
|
+
/** Human conversation member who should answer. Secret and sudo prompts remain owner-only. */
|
|
86
|
+
responseUserId?: string;
|
|
83
87
|
}
|
|
84
88
|
export interface RuntimeInputResult {
|
|
85
89
|
status: 'submitted' | 'cancelled' | 'timeout';
|
|
@@ -91,6 +95,7 @@ export interface RuntimeCardRequest {
|
|
|
91
95
|
card: RuntimeCardV1;
|
|
92
96
|
cardId?: string;
|
|
93
97
|
expiresAt?: string | number | Date;
|
|
98
|
+
/** Human conversation member who should answer. Defaults to the triggering human. */
|
|
94
99
|
responseUserId?: string;
|
|
95
100
|
timeoutMs?: number;
|
|
96
101
|
runtimeId?: string;
|
|
@@ -102,6 +107,8 @@ export interface RuntimeCardResult {
|
|
|
102
107
|
cardId: string;
|
|
103
108
|
actionId?: string;
|
|
104
109
|
values?: Record<string, unknown>;
|
|
110
|
+
/** Canon-authenticated human who submitted this card response. */
|
|
111
|
+
respondedBy?: string;
|
|
105
112
|
}
|
|
106
113
|
export interface MessageHandlerContext {
|
|
107
114
|
messages: CanonMessage[];
|
|
@@ -155,21 +162,21 @@ export interface MessageHandlerContext {
|
|
|
155
162
|
/** Runtime turn mode requested by the sender for this inbound turn, if any. */
|
|
156
163
|
requestedTurnMode: string | null;
|
|
157
164
|
/**
|
|
158
|
-
* Ask the
|
|
165
|
+
* Ask the triggering human to approve a native runtime action. This only
|
|
159
166
|
* renders Canon's inline approval card; runtimes must explicitly wait for
|
|
160
167
|
* and enforce the returned decision in their own approval hook.
|
|
161
168
|
*/
|
|
162
169
|
requestApproval: (request: RuntimeApprovalRequest) => Promise<ApprovalResult>;
|
|
163
170
|
/**
|
|
164
|
-
* Ask the
|
|
165
|
-
*
|
|
166
|
-
* never persisted in Canon message metadata.
|
|
171
|
+
* Ask the triggering human for runtime input. Secret and sudo prompts remain
|
|
172
|
+
* owner-only. Sensitive values are returned only to the calling runtime and
|
|
173
|
+
* are never persisted in Canon message metadata.
|
|
167
174
|
*/
|
|
168
175
|
requestRuntimeInput: (request: RuntimeInputRequest) => Promise<RuntimeInputResult>;
|
|
169
176
|
/**
|
|
170
|
-
* Ask the
|
|
171
|
-
* card document is redacted for presentation; raw response values
|
|
172
|
-
* only to the calling runtime through Canon's control path.
|
|
177
|
+
* Ask the triggering human to review/respond to a generic rich card. The
|
|
178
|
+
* visible card document is redacted for presentation; raw response values
|
|
179
|
+
* return only to the calling runtime through Canon's control path.
|
|
173
180
|
*/
|
|
174
181
|
requestCard: (request: RuntimeCardRequest) => Promise<RuntimeCardResult>;
|
|
175
182
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonmsg/agent-sdk",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.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",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@canonmsg/core": "^4.
|
|
31
|
+
"@canonmsg/core": "^4.3.0"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|