@canonmsg/core 0.24.0 → 1.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.
- package/dist/approval-format.d.ts +0 -5
- package/dist/approval-format.js +0 -65
- package/dist/approval-manager.d.ts +0 -2
- package/dist/approval-manager.js +1 -25
- package/dist/browser.d.ts +5 -3
- package/dist/browser.js +2 -1
- package/dist/client.d.ts +3 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/runtime-cards.d.ts +15 -0
- package/dist/runtime-cards.js +31 -0
- package/dist/runtime-descriptor.d.ts +4 -5
- package/dist/runtime-descriptor.js +0 -1
- package/dist/runtime-presentation.js +0 -3
- package/dist/runtime-state-publisher.d.ts +3 -2
- package/dist/runtime-state-publisher.js +0 -1
- package/dist/streaming.d.ts +3 -2
- package/dist/streaming.js +6 -3
- package/dist/turn-output-controller.d.ts +25 -1
- package/dist/turn-output-controller.js +122 -4
- package/dist/turn-protocol.d.ts +0 -4
- package/dist/turn-protocol.js +5 -8
- package/dist/types.d.ts +23 -6
- package/package.json +1 -1
|
@@ -22,8 +22,3 @@ export declare function buildApprovalReply(approvalId: string, decision: 'allow'
|
|
|
22
22
|
metadata: ApprovalReplyMetadata;
|
|
23
23
|
};
|
|
24
24
|
export declare function buildApprovalOutcome(approvalId: string, toolName: string, toolSummary: string, decision: 'allow' | 'deny', reason: 'replied' | 'timeout' | 'session-rule'): string;
|
|
25
|
-
export declare function parseTextApprovalReply(text: string): {
|
|
26
|
-
decision: 'allow' | 'deny';
|
|
27
|
-
sessionRule?: SessionRule;
|
|
28
|
-
targetApprovalId?: string;
|
|
29
|
-
} | null;
|
package/dist/approval-format.js
CHANGED
|
@@ -104,68 +104,3 @@ export function buildApprovalOutcome(approvalId, toolName, toolSummary, decision
|
|
|
104
104
|
}
|
|
105
105
|
return `${icon} [${approvalId}] -- ${toolName}: ${short}`;
|
|
106
106
|
}
|
|
107
|
-
// ── Parse text-based approval reply (fallback for non-card UIs) ─────
|
|
108
|
-
const ALLOW_WORDS = new Set([
|
|
109
|
-
'approve', 'approved', 'allow', 'yes', 'y', 'ok', 'go', 'do it', 'go ahead',
|
|
110
|
-
]);
|
|
111
|
-
const DENY_WORDS = new Set([
|
|
112
|
-
'deny', 'denied', 'reject', 'no', 'n', 'nope', 'stop', "don't",
|
|
113
|
-
]);
|
|
114
|
-
export function parseTextApprovalReply(text) {
|
|
115
|
-
const trimmed = text.trim().toLowerCase();
|
|
116
|
-
if (!trimmed)
|
|
117
|
-
return null;
|
|
118
|
-
// "approve apr_xxxxx" or "deny apr_xxxxx" — target specific approval
|
|
119
|
-
const idMatch = trimmed.match(/^(approve|deny|allow|reject)\s+(apr_\w+)$/);
|
|
120
|
-
if (idMatch) {
|
|
121
|
-
const decision = idMatch[1] === 'deny' || idMatch[1] === 'reject' ? 'deny' : 'allow';
|
|
122
|
-
return { decision, targetApprovalId: idMatch[2] };
|
|
123
|
-
}
|
|
124
|
-
// "approve all for Xm" — time-limited blanket
|
|
125
|
-
const timeMatch = trimmed.match(/^approve\s+all\s+for\s+(\d+)\s*m(?:in(?:utes?)?)?$/);
|
|
126
|
-
if (timeMatch) {
|
|
127
|
-
const minutes = parseInt(timeMatch[1], 10);
|
|
128
|
-
return {
|
|
129
|
-
decision: 'allow',
|
|
130
|
-
sessionRule: {
|
|
131
|
-
type: 'approve-all',
|
|
132
|
-
expiresAt: new Date(Date.now() + minutes * 60_000).toISOString(),
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
// "approve all <ToolName>" — per-tool blanket
|
|
137
|
-
const toolMatch = trimmed.match(/^approve\s+all\s+(\w+)$/);
|
|
138
|
-
if (toolMatch && toolMatch[1] !== 'for') {
|
|
139
|
-
return {
|
|
140
|
-
decision: 'allow',
|
|
141
|
-
sessionRule: {
|
|
142
|
-
type: 'approve-tool',
|
|
143
|
-
toolPattern: toolMatch[1],
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
// "deny all <ToolName>"
|
|
148
|
-
const denyToolMatch = trimmed.match(/^deny\s+all\s+(\w+)$/);
|
|
149
|
-
if (denyToolMatch) {
|
|
150
|
-
return {
|
|
151
|
-
decision: 'deny',
|
|
152
|
-
sessionRule: {
|
|
153
|
-
type: 'deny-tool',
|
|
154
|
-
toolPattern: denyToolMatch[1],
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
// "approve all" — session blanket
|
|
159
|
-
if (trimmed === 'approve all' || trimmed === 'allow all') {
|
|
160
|
-
return {
|
|
161
|
-
decision: 'allow',
|
|
162
|
-
sessionRule: { type: 'approve-all' },
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
// Simple allow/deny words
|
|
166
|
-
if (ALLOW_WORDS.has(trimmed))
|
|
167
|
-
return { decision: 'allow' };
|
|
168
|
-
if (DENY_WORDS.has(trimmed))
|
|
169
|
-
return { decision: 'deny' };
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
@@ -43,7 +43,6 @@ export declare class ApprovalManager {
|
|
|
43
43
|
*/
|
|
44
44
|
handleMessage(conversationId: string, message: {
|
|
45
45
|
senderId: string;
|
|
46
|
-
text?: string;
|
|
47
46
|
metadata?: Record<string, unknown>;
|
|
48
47
|
}): boolean;
|
|
49
48
|
/** Check if a tool would be auto-resolved by a session rule */
|
|
@@ -53,7 +52,6 @@ export declare class ApprovalManager {
|
|
|
53
52
|
get pendingCount(): number;
|
|
54
53
|
dispose(): void;
|
|
55
54
|
private resolveApproval;
|
|
56
|
-
private findMostRecentPending;
|
|
57
55
|
private pruneExpiredRules;
|
|
58
56
|
private summarizeTool;
|
|
59
57
|
private describeRule;
|
package/dist/approval-manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_APPROVAL_CONFIG, parseApprovalReplyMetadata } from './approval-types.js';
|
|
2
|
-
import { generateApprovalId, buildApprovalRequest, buildApprovalOutcome,
|
|
2
|
+
import { generateApprovalId, buildApprovalRequest, buildApprovalOutcome, redactSecrets, } from './approval-format.js';
|
|
3
3
|
// ── ApprovalManager ─────────────────────────────────────────────────
|
|
4
4
|
/**
|
|
5
5
|
* Platform-agnostic approval protocol for Canon.
|
|
@@ -156,21 +156,6 @@ export class ApprovalManager {
|
|
|
156
156
|
return false;
|
|
157
157
|
return this.resolveApproval(parsed.approvalId, parsed.decision, parsed.sessionRule, conversationId);
|
|
158
158
|
}
|
|
159
|
-
// Fall back to text parsing
|
|
160
|
-
if (message.text) {
|
|
161
|
-
const parsed = parseTextApprovalReply(message.text);
|
|
162
|
-
if (!parsed)
|
|
163
|
-
return false;
|
|
164
|
-
// If the user targeted a specific approval ID
|
|
165
|
-
if (parsed.targetApprovalId) {
|
|
166
|
-
return this.resolveApproval(parsed.targetApprovalId, parsed.decision, parsed.sessionRule, conversationId);
|
|
167
|
-
}
|
|
168
|
-
// Otherwise match the most recent pending in this conversation
|
|
169
|
-
const pending = this.findMostRecentPending(conversationId);
|
|
170
|
-
if (!pending)
|
|
171
|
-
return false;
|
|
172
|
-
return this.resolveApproval(pending.approvalId, parsed.decision, parsed.sessionRule, conversationId);
|
|
173
|
-
}
|
|
174
159
|
return false;
|
|
175
160
|
}
|
|
176
161
|
/** Check if a tool would be auto-resolved by a session rule */
|
|
@@ -258,15 +243,6 @@ export class ApprovalManager {
|
|
|
258
243
|
entry.resolve({ decision, ...(acceptedSessionRule ? { sessionRule: acceptedSessionRule } : {}) });
|
|
259
244
|
return true;
|
|
260
245
|
}
|
|
261
|
-
findMostRecentPending(conversationId) {
|
|
262
|
-
let latest = null;
|
|
263
|
-
for (const p of this.pending.values()) {
|
|
264
|
-
if (p.conversationId === conversationId) {
|
|
265
|
-
latest = p; // Map iterates in insertion order, so last = most recent
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return latest;
|
|
269
|
-
}
|
|
270
246
|
pruneExpiredRules() {
|
|
271
247
|
const now = Date.now();
|
|
272
248
|
this.rules = this.rules.filter(({ rule }) => {
|
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, 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, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeProvenance, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, ResolvedAdmission, SessionConfig, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
4
|
+
export type { AddMemberResult, AgentCapabilities, AgentClientType, AgentSessionSnapshot, 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, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeProvenance, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, ResolvedAdmission, SessionConfig, TurnOutputBlock, TurnOutputBlockKind, TurnOutputBlockStatus, TurnUpdatedPayload, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
5
5
|
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, } from './runtime-presentation.js';
|
|
6
6
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
7
7
|
export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
|
|
@@ -14,8 +14,10 @@ export type { AgentBehaviorSettings, ParticipationHistoryMessage, ParticipationH
|
|
|
14
14
|
export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots, buildBehaviorPolicyLines, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, evaluateParticipationPolicy, getDefaultParticipationPolicy, resolveAgentBehaviorPolicy, } from './policy.js';
|
|
15
15
|
export { DEFAULT_RUNTIME_CAPABILITIES, ACTIVE_TURN_STALE_THRESHOLD_MS, FINAL_MESSAGE_HANDOFF_MS, WAITING_INPUT_STALE_THRESHOLD_MS, getTurnStateStaleThresholdMs, isTurnOpen, isTurnStateStale, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
|
|
16
16
|
export type { DeliveryIntent, InboundDisposition, RuntimeCapabilities, TriggerDecision, TurnLifecycleState, TurnMessageSemantics, TurnMetadata, TurnState, } from './turn-protocol.js';
|
|
17
|
-
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId,
|
|
17
|
+
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId, redactSecrets, } from './approval-format.js';
|
|
18
18
|
export type { ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalNativeRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
19
19
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
20
20
|
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
21
|
-
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
21
|
+
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputAnswers, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputQuestion, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
22
|
+
export { DEFAULT_TURN_TRAIL_MAX_BLOCKS, DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES, buildBoundedTurnTrail, } from './turn-output-controller.js';
|
|
23
|
+
export type { BuildBoundedTurnTrailOptions, TurnOutputBlockInput, } from './turn-output-controller.js';
|
package/dist/browser.js
CHANGED
|
@@ -9,6 +9,7 @@ export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
|
9
9
|
export { CLAUDE_EFFORT_OPTIONS, EXECUTION_MODE_CONTROL_OPTIONS, RUNTIME_NEW_SESSION_ACTION, RUNTIME_STOP_ACTION, RUNTIME_STOP_AND_DROP_ACTION, buildFirstPartyCodingRuntimeDescriptor, buildRuntimeEffortControl, buildRuntimeExecutionModeControl, buildRuntimeExecutionModeOptions, buildRuntimeModelControl, buildRuntimePermissionModeControl, buildRuntimeWorkspaceControl, buildRuntimeWorkspaceControlOptions, } from './runtime-descriptor.js';
|
|
10
10
|
export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots, buildBehaviorPolicyLines, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, evaluateParticipationPolicy, getDefaultParticipationPolicy, resolveAgentBehaviorPolicy, } from './policy.js';
|
|
11
11
|
export { DEFAULT_RUNTIME_CAPABILITIES, ACTIVE_TURN_STALE_THRESHOLD_MS, FINAL_MESSAGE_HANDOFF_MS, WAITING_INPUT_STALE_THRESHOLD_MS, getTurnStateStaleThresholdMs, isTurnOpen, isTurnStateStale, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
|
|
12
|
-
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId,
|
|
12
|
+
export { buildApprovalReply, buildApprovalRequest, buildApprovalOutcome, generateApprovalId, redactSecrets, } from './approval-format.js';
|
|
13
13
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
14
14
|
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
15
|
+
export { DEFAULT_TURN_TRAIL_MAX_BLOCKS, DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES, buildBoundedTurnTrail, } from './turn-output-controller.js';
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type CanonMessage, type CanonConversation, type CanonContact, type CanonContactRequest, type CanonMessagesPage, type CanonResolveAdmissionResult, type AgentContext, type AddMemberResult, type CreateContactRequestResult, type MediaAttachment, type SendMessageOptions, type CreateConversationOptions, type RegistrationStatus, type SetRuntimeTurnOptions, type SetStreamingOptions } from './types.js';
|
|
2
2
|
import type { RuntimeInputKind } from './runtime-cards.js';
|
|
3
3
|
import type { ApprovalNativeRequestMetadata, ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRisk, SessionRule } from './approval-types.js';
|
|
4
|
-
import type { RuntimeInputChoice, RuntimeInputNativeMetadata } from './runtime-cards.js';
|
|
4
|
+
import type { RuntimeInputAnswers, RuntimeInputChoice, RuntimeInputNativeMetadata, RuntimeInputQuestion } from './runtime-cards.js';
|
|
5
5
|
import type { SendContextualMessageOptions, SendContextualMessageResult } from './self-context.js';
|
|
6
6
|
import type { InboundDisposition } from './turn-protocol.js';
|
|
7
7
|
/**
|
|
@@ -65,6 +65,7 @@ export declare class CanonClient {
|
|
|
65
65
|
title?: string;
|
|
66
66
|
prompt?: string;
|
|
67
67
|
choices?: RuntimeInputChoice[];
|
|
68
|
+
questions?: RuntimeInputQuestion[];
|
|
68
69
|
secretName?: string;
|
|
69
70
|
native?: RuntimeInputNativeMetadata;
|
|
70
71
|
sensitive?: boolean;
|
|
@@ -89,6 +90,7 @@ export declare class CanonClient {
|
|
|
89
90
|
inputId: string;
|
|
90
91
|
kind: RuntimeInputKind;
|
|
91
92
|
value: string;
|
|
93
|
+
answers?: RuntimeInputAnswers;
|
|
92
94
|
} | {
|
|
93
95
|
status: 'cancelled';
|
|
94
96
|
inputId: string;
|
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, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonResolveAdmissionResult, ConversationUpdatedPayload, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonRuntimeProvenance, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, SetRuntimeTurnOptions, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
2
|
+
export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonResolveAdmissionResult, ConversationUpdatedPayload, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, CanonRuntimeProvenance, CanonConversation, CanonMessagesPage, CreateContactRequestResult, AgentContext, CanonStreamEvent, AgentSessionSnapshot, ResolvedAdmission, MediaAttachment, MediaAttachmentKind, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload, SendMessageOptions, CreateConversationOptions, RegistrationInput, RegistrationResult, RegistrationStatus, SetRuntimeTurnOptions, StreamingStatus, SetStreamingOptions, SessionControl, SessionState, SessionConfig, AgentRuntime, CanonRuntimeDescriptor, CanonRuntimeActionAvailability, CanonRuntimeActionCategory, CanonRuntimeActionDescriptor, CanonRuntimeActionDispatch, CanonRuntimeActionPlacement, CanonRuntimeCommandArgumentChoice, CanonRuntimeCommandArgumentDescriptor, CanonRuntimeCommandArgumentKind, CanonRuntimeCommandDescriptor, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimePresentationField, CanonRuntimePresentationHint, CanonRuntimePresentationPolicy, CanonRuntimePresentationPreset, CanonRuntimeVisibility, CanonRuntimeActivityItem, CanonRuntimeActivityKind, CanonRuntimeActivityStatus, CanonRuntimeFact, CanonRuntimeFactGroup, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimePrimitiveId, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, TurnOutputBlock, TurnOutputBlockKind, TurnOutputBlockStatus, WorkspaceOption, WorkspaceOptionSource, } from './types.js';
|
|
3
3
|
export { DEFAULT_FIRST_PARTY_RUNTIME_PRESENTATION, RUNTIME_PRESENTATION_FIELDS, buildRuntimePresentationPolicy, getRuntimePresentationHint, isRuntimePresentationField, isRuntimePresentationFieldHidden, redactAgentRuntimeForConversation, redactAgentSessionSnapshotForConversation, redactExecutionMetadataForConversation, redactRuntimeActivityItemForConversation, redactRuntimeDescriptorForConversation, redactRuntimeInfoForConversation, redactSessionStateForConversation, } from './runtime-presentation.js';
|
|
4
4
|
export { buildRuntimeProvenance, resolveRuntimeProvenance, } from './provenance.js';
|
|
5
5
|
export type { CanonSelfContext, CanonSelfContextType, SelfContextPromptRenderOptions, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, } from './self-context.js';
|
|
@@ -17,15 +17,15 @@ export { DEFAULT_RUNTIME_CAPABILITIES, ACTIVE_TURN_STALE_THRESHOLD_MS, HOST_ADMI
|
|
|
17
17
|
export type { DeliveryIntent, TurnMessageSemantics, InboundDisposition, TurnLifecycleState, RuntimeCapabilities, HostAdmissionActionCapabilities, TurnState, TurnMetadata, TriggerDecision, } from './turn-protocol.js';
|
|
18
18
|
export { ackRegistrationApproval, registerAndWaitForApproval, submitRegistrationRequest, waitForRegistrationApproval, } from './registration.js';
|
|
19
19
|
export { ApprovalManager } from './approval-manager.js';
|
|
20
|
-
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome,
|
|
20
|
+
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome, redactSecrets, } from './approval-format.js';
|
|
21
21
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
22
22
|
export type { ApprovalRequestCategory, ApprovalRequestDetail, ApprovalRequestMetadata, ApprovalNativeRequestMetadata, ApprovalRisk, ApprovalReplyMetadata, ApprovalOutcomeMetadata, SessionRule, ApprovalResult, ApprovalConfig, } from './approval-types.js';
|
|
23
23
|
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
24
|
-
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
24
|
+
export type { ClaudeQuestionMetadata, ClaudeQuestionReplyMetadata, PlanApprovalMetadata, PlanApprovalReplyMetadata, RuntimeInputAnswers, RuntimeInputChoice, RuntimeInputKind, RuntimeInputNativeMetadata, RuntimeInputOutcomeMetadata, RuntimeInputQuestion, RuntimeInputReplyMetadata, RuntimeInputReplyStatus, RuntimeInputRequestMetadata, RuntimeInputResolutionStatus, RuntimeQuestionDefinition, RuntimeQuestionOption, } from './runtime-cards.js';
|
|
25
25
|
export { createStreamingHelper } from './streaming.js';
|
|
26
26
|
export type { RTDBHandle, RTDBRef, ServerTimestamp, StreamingHelperOptions, StreamingNode } from './streaming.js';
|
|
27
|
-
export { createTurnOutputController } from './turn-output-controller.js';
|
|
28
|
-
export type { TurnOutputController, TurnOutputControllerOptions, TurnOutputMode, TurnOutputSnapshot, } from './turn-output-controller.js';
|
|
27
|
+
export { DEFAULT_TURN_TRAIL_MAX_BLOCKS, DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES, buildBoundedTurnTrail, createTurnOutputController, } from './turn-output-controller.js';
|
|
28
|
+
export type { BuildBoundedTurnTrailOptions, TurnOutputController, TurnOutputBlockInput, TurnOutputControllerOptions, TurnOutputMode, TurnOutputSnapshot, } from './turn-output-controller.js';
|
|
29
29
|
export { clearPendingRegistration, getOrCreatePendingRegistration, loadPendingRegistrations, loadProfiles, savePendingRegistrations, saveProfiles, updatePendingRegistration, upsertAgentProfile, isProfileLocked, acquireLock, releaseLock, isProcessAlive, CANON_DIR, AGENTS_PATH, LOCKS_DIR, } from './agent-profiles.js';
|
|
30
30
|
export type { AgentProfile, PendingRegistration, ProfileLockHandle } from './agent-profiles.js';
|
|
31
31
|
export { resolveCanonAgent, resolveCanonProfile, getActiveProfile, getActiveProfileLock } from './agent-resolver.js';
|
package/dist/index.js
CHANGED
|
@@ -17,12 +17,12 @@ export { DEFAULT_RUNTIME_CAPABILITIES, ACTIVE_TURN_STALE_THRESHOLD_MS, HOST_ADMI
|
|
|
17
17
|
export { ackRegistrationApproval, registerAndWaitForApproval, submitRegistrationRequest, waitForRegistrationApproval, } from './registration.js';
|
|
18
18
|
// Approval
|
|
19
19
|
export { ApprovalManager } from './approval-manager.js';
|
|
20
|
-
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome,
|
|
20
|
+
export { generateApprovalId, buildApprovalRequest, buildApprovalReply, buildApprovalOutcome, redactSecrets, } from './approval-format.js';
|
|
21
21
|
export { DEFAULT_APPROVAL_CONFIG, parseApprovalRequestMetadata, parseApprovalReplyMetadata, parseSessionRule, } from './approval-types.js';
|
|
22
22
|
export { buildRuntimeInputOutcome, buildRuntimeInputReply, buildRuntimeInputRequest, buildPlanApprovalReply, buildPlanApprovalRequest, buildQuestionReply, buildQuestionRequest, parseRuntimeInputOutcomeMetadata, parseRuntimeInputReplyMetadata, parseRuntimeInputRequestMetadata, } from './runtime-cards.js';
|
|
23
23
|
// Streaming (RTDB helpers)
|
|
24
24
|
export { createStreamingHelper } from './streaming.js';
|
|
25
|
-
export { createTurnOutputController } from './turn-output-controller.js';
|
|
25
|
+
export { DEFAULT_TURN_TRAIL_MAX_BLOCKS, DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES, buildBoundedTurnTrail, createTurnOutputController, } from './turn-output-controller.js';
|
|
26
26
|
// Agent profiles (loading, locking, resolution)
|
|
27
27
|
export { clearPendingRegistration, getOrCreatePendingRegistration, loadPendingRegistrations, loadProfiles, savePendingRegistrations, saveProfiles, updatePendingRegistration, upsertAgentProfile, isProfileLocked, acquireLock, releaseLock, isProcessAlive, CANON_DIR, AGENTS_PATH, LOCKS_DIR, } from './agent-profiles.js';
|
|
28
28
|
// Agent resolver
|
package/dist/runtime-cards.d.ts
CHANGED
|
@@ -47,6 +47,18 @@ export interface RuntimeInputChoice {
|
|
|
47
47
|
value?: string;
|
|
48
48
|
description?: string;
|
|
49
49
|
}
|
|
50
|
+
export interface RuntimeInputQuestion {
|
|
51
|
+
id: string;
|
|
52
|
+
question: string;
|
|
53
|
+
header?: string;
|
|
54
|
+
choices?: RuntimeInputChoice[];
|
|
55
|
+
allowOther?: boolean;
|
|
56
|
+
isSecret?: boolean;
|
|
57
|
+
multiSelect?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export type RuntimeInputAnswers = Record<string, {
|
|
60
|
+
answers: string[];
|
|
61
|
+
}>;
|
|
50
62
|
export interface RuntimeInputNativeMetadata {
|
|
51
63
|
runtime?: string;
|
|
52
64
|
method?: string;
|
|
@@ -64,6 +76,7 @@ export interface RuntimeInputRequestMetadata {
|
|
|
64
76
|
prompt: string;
|
|
65
77
|
title?: string;
|
|
66
78
|
choices?: RuntimeInputChoice[];
|
|
79
|
+
questions?: RuntimeInputQuestion[];
|
|
67
80
|
secretName?: string;
|
|
68
81
|
native?: RuntimeInputNativeMetadata;
|
|
69
82
|
expiresAt: string;
|
|
@@ -75,6 +88,7 @@ export interface RuntimeInputReplyMetadata {
|
|
|
75
88
|
kind?: RuntimeInputKind;
|
|
76
89
|
status: RuntimeInputReplyStatus;
|
|
77
90
|
answerSummary?: string;
|
|
91
|
+
answersSummary?: string;
|
|
78
92
|
sensitive?: boolean;
|
|
79
93
|
}
|
|
80
94
|
export interface RuntimeInputOutcomeMetadata {
|
|
@@ -109,6 +123,7 @@ export declare function buildRuntimeInputRequest(inputId: string, input: Omit<Ru
|
|
|
109
123
|
export declare function buildRuntimeInputReply(inputId: string, status: RuntimeInputReplyStatus, details?: {
|
|
110
124
|
kind?: RuntimeInputKind;
|
|
111
125
|
answerSummary?: string;
|
|
126
|
+
answersSummary?: string;
|
|
112
127
|
sensitive?: boolean;
|
|
113
128
|
}): {
|
|
114
129
|
text: string;
|
package/dist/runtime-cards.js
CHANGED
|
@@ -38,6 +38,30 @@ function normalizeRuntimeInputChoices(value) {
|
|
|
38
38
|
});
|
|
39
39
|
return choices.length > 0 ? choices : undefined;
|
|
40
40
|
}
|
|
41
|
+
function normalizeRuntimeInputQuestions(value) {
|
|
42
|
+
if (!Array.isArray(value))
|
|
43
|
+
return undefined;
|
|
44
|
+
const questions = value.slice(0, 12).flatMap((entry) => {
|
|
45
|
+
if (!isRecord(entry))
|
|
46
|
+
return [];
|
|
47
|
+
const id = normalizeString(entry.id, 120);
|
|
48
|
+
const question = normalizeString(entry.question, 1000);
|
|
49
|
+
if (!id || !/^[a-zA-Z0-9_.:-]{1,120}$/.test(id) || !question)
|
|
50
|
+
return [];
|
|
51
|
+
const header = normalizeString(entry.header, 120) ?? undefined;
|
|
52
|
+
const choices = normalizeRuntimeInputChoices(entry.choices);
|
|
53
|
+
return [{
|
|
54
|
+
id,
|
|
55
|
+
question,
|
|
56
|
+
...(header ? { header } : {}),
|
|
57
|
+
...(choices ? { choices } : {}),
|
|
58
|
+
...(entry.allowOther === true ? { allowOther: true } : {}),
|
|
59
|
+
...(entry.isSecret === true ? { isSecret: true } : {}),
|
|
60
|
+
...(entry.multiSelect === true ? { multiSelect: true } : {}),
|
|
61
|
+
}];
|
|
62
|
+
});
|
|
63
|
+
return questions.length > 0 ? questions : undefined;
|
|
64
|
+
}
|
|
41
65
|
function normalizeRuntimeInputNative(value) {
|
|
42
66
|
if (!isRecord(value))
|
|
43
67
|
return undefined;
|
|
@@ -130,6 +154,7 @@ export function buildRuntimeInputRequest(inputId, input) {
|
|
|
130
154
|
prompt: input.prompt.slice(0, 1000),
|
|
131
155
|
title: title.slice(0, 120),
|
|
132
156
|
...(input.choices?.length ? { choices: input.choices.slice(0, 12) } : {}),
|
|
157
|
+
...(input.questions?.length ? { questions: input.questions.slice(0, 12) } : {}),
|
|
133
158
|
...(input.secretName ? { secretName: input.secretName.slice(0, 120) } : {}),
|
|
134
159
|
...(input.native ? { native: input.native } : {}),
|
|
135
160
|
expiresAt: input.expiresAt,
|
|
@@ -139,6 +164,7 @@ export function buildRuntimeInputRequest(inputId, input) {
|
|
|
139
164
|
}
|
|
140
165
|
export function buildRuntimeInputReply(inputId, status, details) {
|
|
141
166
|
const answerSummary = details?.sensitive ? undefined : details?.answerSummary?.trim().slice(0, 500);
|
|
167
|
+
const answersSummary = details?.sensitive ? undefined : details?.answersSummary?.trim().slice(0, 500);
|
|
142
168
|
return {
|
|
143
169
|
text: status === 'submitted' ? 'Submitted' : 'Cancelled',
|
|
144
170
|
metadata: {
|
|
@@ -147,6 +173,7 @@ export function buildRuntimeInputReply(inputId, status, details) {
|
|
|
147
173
|
...(details?.kind ? { kind: details.kind } : {}),
|
|
148
174
|
status,
|
|
149
175
|
...(answerSummary ? { answerSummary } : {}),
|
|
176
|
+
...(answersSummary ? { answersSummary } : {}),
|
|
150
177
|
...(details?.sensitive ? { sensitive: true } : {}),
|
|
151
178
|
},
|
|
152
179
|
};
|
|
@@ -184,6 +211,7 @@ export function parseRuntimeInputRequestMetadata(value) {
|
|
|
184
211
|
return null;
|
|
185
212
|
const title = normalizeString(value.title, 120) ?? undefined;
|
|
186
213
|
const choices = normalizeRuntimeInputChoices(value.choices);
|
|
214
|
+
const questions = normalizeRuntimeInputQuestions(value.questions);
|
|
187
215
|
const secretName = normalizeString(value.secretName, 120) ?? undefined;
|
|
188
216
|
const native = normalizeRuntimeInputNative(value.native);
|
|
189
217
|
return {
|
|
@@ -194,6 +222,7 @@ export function parseRuntimeInputRequestMetadata(value) {
|
|
|
194
222
|
prompt,
|
|
195
223
|
...(title ? { title } : {}),
|
|
196
224
|
...(choices ? { choices } : {}),
|
|
225
|
+
...(questions ? { questions } : {}),
|
|
197
226
|
...(secretName ? { secretName } : {}),
|
|
198
227
|
...(native ? { native } : {}),
|
|
199
228
|
expiresAt: new Date(expiresMs).toISOString(),
|
|
@@ -211,12 +240,14 @@ export function parseRuntimeInputReplyMetadata(value) {
|
|
|
211
240
|
return null;
|
|
212
241
|
const kind = normalizeRuntimeInputKind(value.kind) ?? undefined;
|
|
213
242
|
const answerSummary = value.sensitive === true ? undefined : normalizeString(value.answerSummary, 500) ?? undefined;
|
|
243
|
+
const answersSummary = value.sensitive === true ? undefined : normalizeString(value.answersSummary, 500) ?? undefined;
|
|
214
244
|
return {
|
|
215
245
|
type: 'runtime_input_reply',
|
|
216
246
|
inputId,
|
|
217
247
|
...(kind ? { kind } : {}),
|
|
218
248
|
status,
|
|
219
249
|
...(answerSummary ? { answerSummary } : {}),
|
|
250
|
+
...(answersSummary ? { answersSummary } : {}),
|
|
220
251
|
...(value.sensitive === true ? { sensitive: true } : {}),
|
|
221
252
|
};
|
|
222
253
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
2
|
-
import { type AgentClientType, type CanonControlDescriptor, type
|
|
2
|
+
import { type AgentClientType, type CanonControlDescriptor, type CanonRuntimeCommandDescriptor, type CanonRuntimeDescriptor, type CanonRuntimeStreamingMode, type CanonWorkspaceRootMetadata, type ModelOption, type PermissionModeOption, type WorkspaceOption } from './types.js';
|
|
3
3
|
import type { CanonRuntimePresentationPolicy } from './types.js';
|
|
4
4
|
import type { HostAdmissionActionCapabilities } from './turn-protocol.js';
|
|
5
5
|
export declare const CLAUDE_EFFORT_OPTIONS: readonly [{
|
|
@@ -37,9 +37,9 @@ export declare function buildRuntimePermissionModeControl(input: {
|
|
|
37
37
|
defaultValue?: string | null;
|
|
38
38
|
}): CanonControlDescriptor;
|
|
39
39
|
export declare function buildRuntimeEffortControl(): CanonControlDescriptor;
|
|
40
|
-
export declare const RUNTIME_STOP_ACTION:
|
|
41
|
-
export declare const RUNTIME_STOP_AND_DROP_ACTION:
|
|
42
|
-
export declare const RUNTIME_NEW_SESSION_ACTION:
|
|
40
|
+
export declare const RUNTIME_STOP_ACTION: CanonRuntimeCommandDescriptor;
|
|
41
|
+
export declare const RUNTIME_STOP_AND_DROP_ACTION: CanonRuntimeCommandDescriptor;
|
|
42
|
+
export declare const RUNTIME_NEW_SESSION_ACTION: CanonRuntimeCommandDescriptor;
|
|
43
43
|
export declare function buildFirstPartyCodingRuntimeDescriptor(input: {
|
|
44
44
|
clientType: Extract<AgentClientType, 'claude-code' | 'codex'>;
|
|
45
45
|
models: ReadonlyArray<ModelOption>;
|
|
@@ -48,7 +48,6 @@ export declare function buildFirstPartyCodingRuntimeDescriptor(input: {
|
|
|
48
48
|
executionModes: ReadonlyArray<ExecutionEnvironmentMode>;
|
|
49
49
|
permissionModes?: ReadonlyArray<PermissionModeOption>;
|
|
50
50
|
defaultPermissionMode?: string | null;
|
|
51
|
-
actions?: ReadonlyArray<CanonRuntimeActionDescriptor>;
|
|
52
51
|
commands?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
53
52
|
streamingTextMode: CanonRuntimeStreamingMode;
|
|
54
53
|
admissionActions?: HostAdmissionActionCapabilities;
|
|
@@ -151,7 +151,6 @@ export function buildFirstPartyCodingRuntimeDescriptor(input) {
|
|
|
151
151
|
...(input.clientType === 'claude-code' ? [buildRuntimeEffortControl()] : []),
|
|
152
152
|
],
|
|
153
153
|
commands: input.commands,
|
|
154
|
-
actions: input.actions,
|
|
155
154
|
workspaceRoots: input.workspaceRoots,
|
|
156
155
|
supportsInterrupt: true,
|
|
157
156
|
supportsInputInterrupt: true,
|
|
@@ -177,14 +177,11 @@ export function redactRuntimeDescriptorForConversation(descriptor) {
|
|
|
177
177
|
.filter((control) => Boolean(control));
|
|
178
178
|
const commands = descriptor.commands?.map((command) => redactAction(command))
|
|
179
179
|
.filter((command) => Boolean(command));
|
|
180
|
-
const actions = descriptor.actions?.map((action) => redactAction(action))
|
|
181
|
-
.filter((action) => Boolean(action));
|
|
182
180
|
return cloneDefined({
|
|
183
181
|
...descriptor,
|
|
184
182
|
coreControls,
|
|
185
183
|
runtimeControls,
|
|
186
184
|
commands,
|
|
187
|
-
actions,
|
|
188
185
|
workspaceRoots: isRuntimePresentationFieldHidden(descriptor, 'workspaceRoot')
|
|
189
186
|
? []
|
|
190
187
|
: descriptor.workspaceRoots,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentClientType, AgentRuntime, CanonRuntimeActivityItem, RuntimeInfoPayload } from './types.js';
|
|
1
|
+
import type { AgentClientType, AgentRuntime, CanonRuntimeActivityItem, RuntimeInfoPayload, TurnOutputBlock } from './types.js';
|
|
2
2
|
import { type AgentSessionSnapshotPatch, type RTDBClientHandle, type SessionStatePayload, type TurnStatePayload } from './rtdb-rest.js';
|
|
3
3
|
export interface RuntimeStatePublisherOptions {
|
|
4
4
|
agentId: string;
|
|
@@ -8,9 +8,10 @@ export interface RuntimeStatePublisherOptions {
|
|
|
8
8
|
}
|
|
9
9
|
export interface RuntimeStreamingPayload {
|
|
10
10
|
text: string;
|
|
11
|
-
status: 'thinking' | 'streaming' | 'tool';
|
|
11
|
+
status: 'thinking' | 'streaming' | 'tool' | 'waiting_input';
|
|
12
12
|
messageId?: string;
|
|
13
13
|
turnId?: string | null;
|
|
14
|
+
blocks?: TurnOutputBlock[];
|
|
14
15
|
updatedAt?: number | {
|
|
15
16
|
'.sv': 'timestamp';
|
|
16
17
|
};
|
|
@@ -25,7 +25,6 @@ function hasPreservableRuntimeState(value) {
|
|
|
25
25
|
return hasNonEmptyArray(runtimeDescriptor.coreControls)
|
|
26
26
|
|| hasNonEmptyArray(runtimeDescriptor.runtimeControls)
|
|
27
27
|
|| hasNonEmptyArray(runtimeDescriptor.commands)
|
|
28
|
-
|| hasNonEmptyArray(runtimeDescriptor.actions)
|
|
29
28
|
|| hasNonEmptyArray(runtimeDescriptor.workspaceRoots)
|
|
30
29
|
|| hasNonEmptyArray(runtimeDescriptor.writableRoots)
|
|
31
30
|
|| hasEnabledAdmissionActions(runtimeDescriptor.admissionActions)
|
package/dist/streaming.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StreamingStatus } from './types.js';
|
|
1
|
+
import type { StreamingStatus, TurnOutputBlock } from './types.js';
|
|
2
2
|
/** Minimal subset of firebase-admin Database to avoid a hard dependency. */
|
|
3
3
|
export interface RTDBHandle {
|
|
4
4
|
ref(path: string): RTDBRef;
|
|
@@ -24,6 +24,7 @@ export interface StreamingNode {
|
|
|
24
24
|
updatedAt: unknown;
|
|
25
25
|
messageId: string;
|
|
26
26
|
turnId?: string | null;
|
|
27
|
+
blocks?: TurnOutputBlock[];
|
|
27
28
|
}
|
|
28
29
|
/**
|
|
29
30
|
* Creates helpers that read/write the RTDB streaming node for a single
|
|
@@ -44,7 +45,7 @@ export declare function createStreamingHelper(opts: StreamingHelperOptions): {
|
|
|
44
45
|
/** Write the initial streaming node (status: "thinking", empty text). */
|
|
45
46
|
start(messageId: string, turnId?: string | null): Promise<void>;
|
|
46
47
|
/** Update the accumulated text and optionally change status. */
|
|
47
|
-
update(text: string, status?: StreamingStatus): Promise<void>;
|
|
48
|
+
update(text: string, status?: StreamingStatus, blocks?: TurnOutputBlock[]): Promise<void>;
|
|
48
49
|
/** Set status without changing text (e.g. switching to "tool"). */
|
|
49
50
|
setStatus(status: StreamingStatus): Promise<void>;
|
|
50
51
|
/** Remove the streaming node (call after final Firestore message is written). */
|
package/dist/streaming.js
CHANGED
|
@@ -32,12 +32,15 @@ export function createStreamingHelper(opts) {
|
|
|
32
32
|
await nodeRef.set(node);
|
|
33
33
|
},
|
|
34
34
|
/** Update the accumulated text and optionally change status. */
|
|
35
|
-
async update(text, status = 'streaming') {
|
|
36
|
-
|
|
35
|
+
async update(text, status = 'streaming', blocks) {
|
|
36
|
+
const update = {
|
|
37
37
|
text,
|
|
38
38
|
status,
|
|
39
39
|
updatedAt: serverTimestamp,
|
|
40
|
-
}
|
|
40
|
+
};
|
|
41
|
+
if (blocks)
|
|
42
|
+
update.blocks = blocks;
|
|
43
|
+
await nodeRef.update(update);
|
|
41
44
|
},
|
|
42
45
|
/** Set status without changing text (e.g. switching to "tool"). */
|
|
43
46
|
async setStatus(status) {
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import type { StreamingStatus } from './types.js';
|
|
1
|
+
import type { StreamingStatus, TurnOutputBlock, TurnOutputBlockKind, TurnOutputBlockStatus } from './types.js';
|
|
2
2
|
export type TurnOutputMode = 'delta' | 'block' | 'snapshot' | 'status';
|
|
3
3
|
export interface TurnOutputSnapshot {
|
|
4
4
|
turnId: string;
|
|
5
5
|
messageId: string;
|
|
6
6
|
text: string;
|
|
7
7
|
status: StreamingStatus;
|
|
8
|
+
blocks?: TurnOutputBlock[];
|
|
9
|
+
}
|
|
10
|
+
export interface TurnOutputBlockInput {
|
|
11
|
+
id: string;
|
|
12
|
+
kind: TurnOutputBlockKind;
|
|
13
|
+
status?: TurnOutputBlockStatus;
|
|
14
|
+
sequence?: number;
|
|
15
|
+
title?: string;
|
|
16
|
+
text?: string;
|
|
17
|
+
summary?: string;
|
|
18
|
+
detail?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface BuildBoundedTurnTrailOptions {
|
|
21
|
+
maxBlocks?: number;
|
|
22
|
+
maxMetadataBytes?: number;
|
|
8
23
|
}
|
|
9
24
|
export interface TurnOutputControllerOptions {
|
|
10
25
|
turnId: string;
|
|
@@ -21,15 +36,24 @@ export interface TurnOutputController {
|
|
|
21
36
|
readonly mode: TurnOutputMode;
|
|
22
37
|
getText(): string;
|
|
23
38
|
getStatus(): StreamingStatus;
|
|
39
|
+
getBlocks(): TurnOutputBlock[];
|
|
40
|
+
getFinalTrail(): TurnOutputBlock[];
|
|
24
41
|
startThinking(text?: string): Promise<void>;
|
|
25
42
|
startStreaming(text?: string): Promise<void>;
|
|
26
43
|
appendDelta(delta: string): void;
|
|
27
44
|
appendBlock(block: string): void;
|
|
28
45
|
replaceSnapshot(text: string, status?: StreamingStatus): Promise<void>;
|
|
29
46
|
setStatus(status: StreamingStatus, text?: string): Promise<void>;
|
|
47
|
+
addBlock(block: TurnOutputBlockInput): Promise<TurnOutputBlock>;
|
|
48
|
+
updateBlock(id: string, patch: Partial<Omit<TurnOutputBlockInput, 'id' | 'sequence'>>): Promise<TurnOutputBlock | null>;
|
|
49
|
+
completeBlock(id: string, patch?: Partial<Omit<TurnOutputBlockInput, 'id' | 'sequence' | 'status'>>): Promise<TurnOutputBlock | null>;
|
|
50
|
+
failBlock(id: string, patch?: Partial<Omit<TurnOutputBlockInput, 'id' | 'sequence' | 'status'>>): Promise<TurnOutputBlock | null>;
|
|
30
51
|
flush(status?: StreamingStatus): Promise<void>;
|
|
31
52
|
waitingInput(): Promise<void>;
|
|
32
53
|
interrupt(): Promise<void>;
|
|
33
54
|
clear(): Promise<void>;
|
|
34
55
|
}
|
|
56
|
+
export declare const DEFAULT_TURN_TRAIL_MAX_BLOCKS = 20;
|
|
57
|
+
export declare const DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES = 2500;
|
|
58
|
+
export declare function buildBoundedTurnTrail(blocks: readonly TurnOutputBlock[], options?: BuildBoundedTurnTrailOptions): TurnOutputBlock[];
|
|
35
59
|
export declare function createTurnOutputController(options: TurnOutputControllerOptions): TurnOutputController;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
const DEFAULT_THROTTLE_MS = 120;
|
|
2
2
|
const DEFAULT_BLOCK_SEPARATOR = '\n\n';
|
|
3
|
+
export const DEFAULT_TURN_TRAIL_MAX_BLOCKS = 20;
|
|
4
|
+
export const DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES = 2_500;
|
|
3
5
|
function normalizeStatus(status) {
|
|
4
|
-
return status === 'thinking'
|
|
6
|
+
return status === 'thinking'
|
|
7
|
+
|| status === 'tool'
|
|
8
|
+
|| status === 'streaming'
|
|
9
|
+
|| status === 'waiting_input'
|
|
5
10
|
? status
|
|
6
11
|
: 'streaming';
|
|
7
12
|
}
|
|
@@ -12,6 +17,46 @@ function appendBlockText(currentText, block, separator) {
|
|
|
12
17
|
const combined = `${currentText}${prefix}${block}`;
|
|
13
18
|
return separator === '\n\n' ? combined.replace(/\n{3,}/g, '\n\n') : combined;
|
|
14
19
|
}
|
|
20
|
+
function trim(value, max) {
|
|
21
|
+
if (!value)
|
|
22
|
+
return undefined;
|
|
23
|
+
return value.length > max ? `${value.slice(0, max - 3)}...` : value;
|
|
24
|
+
}
|
|
25
|
+
function jsonByteLength(value) {
|
|
26
|
+
const serialized = JSON.stringify(value);
|
|
27
|
+
if (typeof TextEncoder !== 'undefined') {
|
|
28
|
+
return new TextEncoder().encode(serialized).length;
|
|
29
|
+
}
|
|
30
|
+
return serialized.length;
|
|
31
|
+
}
|
|
32
|
+
function compactTrailBlock(block) {
|
|
33
|
+
return {
|
|
34
|
+
id: trim(block.id, 120) ?? block.id,
|
|
35
|
+
turnId: trim(block.turnId, 120) ?? block.turnId,
|
|
36
|
+
kind: block.kind,
|
|
37
|
+
status: block.status,
|
|
38
|
+
sequence: block.sequence,
|
|
39
|
+
...(trim(block.title, 80) ? { title: trim(block.title, 80) } : {}),
|
|
40
|
+
...(trim(block.text, 280) ? { text: trim(block.text, 280) } : {}),
|
|
41
|
+
...(trim(block.summary, 120) ? { summary: trim(block.summary, 120) } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function buildBoundedTurnTrail(blocks, options = {}) {
|
|
45
|
+
const maxBlocks = options.maxBlocks ?? DEFAULT_TURN_TRAIL_MAX_BLOCKS;
|
|
46
|
+
const maxMetadataBytes = options.maxMetadataBytes ?? DEFAULT_TURN_TRAIL_METADATA_BUDGET_BYTES;
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const block of [...blocks].sort((left, right) => left.sequence - right.sequence)) {
|
|
49
|
+
if (out.length >= maxBlocks)
|
|
50
|
+
break;
|
|
51
|
+
const candidate = compactTrailBlock(block);
|
|
52
|
+
const next = [...out, candidate];
|
|
53
|
+
if (jsonByteLength({ turnTrail: next }) > maxMetadataBytes) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
out.push(candidate);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
15
60
|
export function createTurnOutputController(options) {
|
|
16
61
|
const schedule = options.schedule ?? setTimeout;
|
|
17
62
|
const cancel = options.cancel ?? clearTimeout;
|
|
@@ -20,6 +65,8 @@ export function createTurnOutputController(options) {
|
|
|
20
65
|
const blockSeparator = options.blockSeparator ?? DEFAULT_BLOCK_SEPARATOR;
|
|
21
66
|
let text = '';
|
|
22
67
|
let status = 'thinking';
|
|
68
|
+
let blocks = [];
|
|
69
|
+
let nextSequence = 1;
|
|
23
70
|
let timer = null;
|
|
24
71
|
let pendingPromise = Promise.resolve();
|
|
25
72
|
const write = (nextStatus = status) => {
|
|
@@ -30,6 +77,7 @@ export function createTurnOutputController(options) {
|
|
|
30
77
|
messageId: options.turnId,
|
|
31
78
|
text,
|
|
32
79
|
status: normalizeStatus(nextStatus),
|
|
80
|
+
...(blocks.length > 0 ? { blocks: [...blocks] } : {}),
|
|
33
81
|
};
|
|
34
82
|
pendingPromise = pendingPromise
|
|
35
83
|
.catch(() => { })
|
|
@@ -64,11 +112,60 @@ export function createTurnOutputController(options) {
|
|
|
64
112
|
cancelTimer();
|
|
65
113
|
text = '';
|
|
66
114
|
status = 'thinking';
|
|
115
|
+
blocks = [];
|
|
116
|
+
nextSequence = 1;
|
|
67
117
|
pendingPromise = pendingPromise
|
|
68
118
|
.catch(() => { })
|
|
69
119
|
.then(() => Promise.resolve(options.clearSnapshot()).catch(() => { }));
|
|
70
120
|
await pendingPromise;
|
|
71
121
|
};
|
|
122
|
+
const normalizeBlock = (block, existing) => {
|
|
123
|
+
const now = Date.now();
|
|
124
|
+
const sequence = existing?.sequence ?? block.sequence ?? nextSequence++;
|
|
125
|
+
if (sequence >= nextSequence)
|
|
126
|
+
nextSequence = sequence + 1;
|
|
127
|
+
return {
|
|
128
|
+
id: block.id,
|
|
129
|
+
turnId: options.turnId,
|
|
130
|
+
kind: block.kind,
|
|
131
|
+
status: block.status ?? existing?.status ?? 'running',
|
|
132
|
+
sequence,
|
|
133
|
+
...(block.title ?? existing?.title ? { title: block.title ?? existing?.title } : {}),
|
|
134
|
+
...(block.text ?? existing?.text ? { text: block.text ?? existing?.text } : {}),
|
|
135
|
+
...(block.summary ?? existing?.summary ? { summary: block.summary ?? existing?.summary } : {}),
|
|
136
|
+
...(block.detail ?? existing?.detail ? { detail: block.detail ?? existing?.detail } : {}),
|
|
137
|
+
createdAt: existing?.createdAt ?? now,
|
|
138
|
+
updatedAt: now,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
const upsertBlock = async (id, patch, fallback) => {
|
|
142
|
+
const index = blocks.findIndex((block) => block.id === id);
|
|
143
|
+
if (index < 0 && !fallback)
|
|
144
|
+
return null;
|
|
145
|
+
const existing = index >= 0 ? blocks[index] : null;
|
|
146
|
+
const next = normalizeBlock({
|
|
147
|
+
id,
|
|
148
|
+
kind: patch.kind ?? existing?.kind ?? fallback.kind,
|
|
149
|
+
status: patch.status ?? existing?.status,
|
|
150
|
+
title: patch.title ?? existing?.title,
|
|
151
|
+
text: patch.text ?? existing?.text,
|
|
152
|
+
summary: patch.summary ?? existing?.summary,
|
|
153
|
+
detail: patch.detail ?? existing?.detail,
|
|
154
|
+
sequence: existing?.sequence,
|
|
155
|
+
}, existing);
|
|
156
|
+
if (index >= 0) {
|
|
157
|
+
blocks = [
|
|
158
|
+
...blocks.slice(0, index),
|
|
159
|
+
next,
|
|
160
|
+
...blocks.slice(index + 1),
|
|
161
|
+
];
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
blocks = [...blocks, next].sort((left, right) => left.sequence - right.sequence);
|
|
165
|
+
}
|
|
166
|
+
await flush(status);
|
|
167
|
+
return next;
|
|
168
|
+
};
|
|
72
169
|
return {
|
|
73
170
|
turnId: options.turnId,
|
|
74
171
|
mode,
|
|
@@ -78,6 +175,12 @@ export function createTurnOutputController(options) {
|
|
|
78
175
|
getStatus() {
|
|
79
176
|
return status;
|
|
80
177
|
},
|
|
178
|
+
getBlocks() {
|
|
179
|
+
return [...blocks];
|
|
180
|
+
},
|
|
181
|
+
getFinalTrail() {
|
|
182
|
+
return buildBoundedTurnTrail(blocks);
|
|
183
|
+
},
|
|
81
184
|
async startThinking(nextText = '') {
|
|
82
185
|
text = nextText;
|
|
83
186
|
status = 'thinking';
|
|
@@ -91,7 +194,7 @@ export function createTurnOutputController(options) {
|
|
|
91
194
|
appendDelta(delta) {
|
|
92
195
|
if (!delta)
|
|
93
196
|
return;
|
|
94
|
-
if (status
|
|
197
|
+
if (status === 'thinking' && (!text || text === 'Thinking...'))
|
|
95
198
|
text = '';
|
|
96
199
|
text += delta;
|
|
97
200
|
status = 'streaming';
|
|
@@ -100,7 +203,7 @@ export function createTurnOutputController(options) {
|
|
|
100
203
|
appendBlock(block) {
|
|
101
204
|
if (!block)
|
|
102
205
|
return;
|
|
103
|
-
if (status
|
|
206
|
+
if (status === 'thinking' && (!text || text === 'Thinking...'))
|
|
104
207
|
text = '';
|
|
105
208
|
text = appendBlockText(text, block, blockSeparator);
|
|
106
209
|
status = 'streaming';
|
|
@@ -117,8 +220,23 @@ export function createTurnOutputController(options) {
|
|
|
117
220
|
status = normalizeStatus(nextStatus);
|
|
118
221
|
await flush(status);
|
|
119
222
|
},
|
|
223
|
+
async addBlock(block) {
|
|
224
|
+
return upsertBlock(block.id, block, { kind: block.kind });
|
|
225
|
+
},
|
|
226
|
+
async updateBlock(id, patch) {
|
|
227
|
+
return upsertBlock(id, patch);
|
|
228
|
+
},
|
|
229
|
+
async completeBlock(id, patch) {
|
|
230
|
+
return upsertBlock(id, { ...(patch ?? {}), status: 'completed' });
|
|
231
|
+
},
|
|
232
|
+
async failBlock(id, patch) {
|
|
233
|
+
return upsertBlock(id, { ...(patch ?? {}), status: 'failed' });
|
|
234
|
+
},
|
|
120
235
|
flush,
|
|
121
|
-
waitingInput
|
|
236
|
+
async waitingInput() {
|
|
237
|
+
status = 'waiting_input';
|
|
238
|
+
await flush('waiting_input');
|
|
239
|
+
},
|
|
122
240
|
interrupt: clear,
|
|
123
241
|
clear,
|
|
124
242
|
};
|
package/dist/turn-protocol.d.ts
CHANGED
|
@@ -30,7 +30,6 @@ export interface TurnMetadata {
|
|
|
30
30
|
turnId?: string | null;
|
|
31
31
|
turnSemantics?: TurnMessageSemantics;
|
|
32
32
|
deliveryIntent?: DeliveryIntent;
|
|
33
|
-
turnComplete?: boolean;
|
|
34
33
|
replyBehavior?: 'allow_auto_reply' | 'suppress_auto_reply';
|
|
35
34
|
inboundDisposition?: InboundDisposition;
|
|
36
35
|
}
|
|
@@ -66,15 +65,12 @@ export declare function isTurnOpen(turnState: Pick<TurnState, 'state' | 'turnUpd
|
|
|
66
65
|
export declare function resolveTurnMessageSemantics(input: {
|
|
67
66
|
senderType: 'human' | 'ai_agent';
|
|
68
67
|
metadata?: unknown;
|
|
69
|
-
senderTurnState?: Pick<TurnState, 'state' | 'turnUpdatedAt' | 'updatedAt' | 'openedAt'> | null;
|
|
70
68
|
}): TurnMessageSemantics;
|
|
71
69
|
export declare function shouldPromoteConversationMessage(input: {
|
|
72
70
|
senderType: 'human' | 'ai_agent';
|
|
73
71
|
metadata?: unknown;
|
|
74
|
-
senderTurnState?: Pick<TurnState, 'state' | 'turnUpdatedAt' | 'updatedAt' | 'openedAt'> | null;
|
|
75
72
|
}): boolean;
|
|
76
73
|
export declare function shouldTriggerAgentTurn(input: {
|
|
77
74
|
senderType: 'human' | 'ai_agent';
|
|
78
75
|
metadata?: unknown;
|
|
79
|
-
senderTurnState?: Pick<TurnState, 'state' | 'turnUpdatedAt' | 'updatedAt' | 'openedAt'> | null;
|
|
80
76
|
}): TriggerDecision;
|
package/dist/turn-protocol.js
CHANGED
|
@@ -79,15 +79,13 @@ export function normalizeTurnMetadata(metadata) {
|
|
|
79
79
|
|| metadata.inboundDisposition === 'cancelled'
|
|
80
80
|
? metadata.inboundDisposition
|
|
81
81
|
: undefined;
|
|
82
|
-
if (!turnId && !turnSemantics && !deliveryIntent &&
|
|
83
|
-
&& !replyBehavior && !inboundDisposition) {
|
|
82
|
+
if (!turnId && !turnSemantics && !deliveryIntent && !replyBehavior && !inboundDisposition) {
|
|
84
83
|
return null;
|
|
85
84
|
}
|
|
86
85
|
return {
|
|
87
86
|
...(turnId ? { turnId } : {}),
|
|
88
87
|
...(turnSemantics ? { turnSemantics } : {}),
|
|
89
88
|
...(deliveryIntent ? { deliveryIntent } : {}),
|
|
90
|
-
...(typeof metadata.turnComplete === 'boolean' ? { turnComplete: metadata.turnComplete } : {}),
|
|
91
89
|
...(replyBehavior ? { replyBehavior } : {}),
|
|
92
90
|
...(inboundDisposition ? { inboundDisposition } : {}),
|
|
93
91
|
};
|
|
@@ -163,13 +161,10 @@ export function resolveTurnMessageSemantics(input) {
|
|
|
163
161
|
if (turnMetadata?.turnSemantics) {
|
|
164
162
|
return turnMetadata.turnSemantics;
|
|
165
163
|
}
|
|
166
|
-
if (turnMetadata?.turnComplete === true) {
|
|
167
|
-
return 'turn_complete';
|
|
168
|
-
}
|
|
169
164
|
if (input.senderType === 'human') {
|
|
170
165
|
return 'turn_complete';
|
|
171
166
|
}
|
|
172
|
-
return
|
|
167
|
+
return 'progress';
|
|
173
168
|
}
|
|
174
169
|
export function shouldPromoteConversationMessage(input) {
|
|
175
170
|
if (isHiddenRuntimeCardMetadata(input.metadata)) {
|
|
@@ -198,7 +193,9 @@ export function shouldTriggerAgentTurn(input) {
|
|
|
198
193
|
return {
|
|
199
194
|
allow: false,
|
|
200
195
|
semantics,
|
|
201
|
-
reason:
|
|
196
|
+
reason: turnMetadata?.turnSemantics === 'progress'
|
|
197
|
+
? 'non-final agent progress does not trigger other agents'
|
|
198
|
+
: 'agent messages require explicit turn_complete semantics',
|
|
202
199
|
};
|
|
203
200
|
}
|
|
204
201
|
return {
|
package/dist/types.d.ts
CHANGED
|
@@ -69,8 +69,10 @@ export interface CanonConversation {
|
|
|
69
69
|
hasUnread?: boolean;
|
|
70
70
|
lastMessage: {
|
|
71
71
|
text: string;
|
|
72
|
+
messageId: string;
|
|
72
73
|
senderId: string;
|
|
73
|
-
senderType
|
|
74
|
+
senderType: 'human' | 'ai_agent';
|
|
75
|
+
contentType: CanonMessage['contentType'];
|
|
74
76
|
timestamp: string;
|
|
75
77
|
} | null;
|
|
76
78
|
createdAt: string;
|
|
@@ -106,9 +108,9 @@ export interface CanonContactRequest {
|
|
|
106
108
|
requesterName: string;
|
|
107
109
|
requesterAvatarUrl: string | null;
|
|
108
110
|
targetId: string;
|
|
109
|
-
targetName
|
|
110
|
-
targetAvatarUrl
|
|
111
|
-
targetUserType
|
|
111
|
+
targetName: string;
|
|
112
|
+
targetAvatarUrl: string | null;
|
|
113
|
+
targetUserType: 'human' | 'ai_agent';
|
|
112
114
|
targetOwnerId?: string | null;
|
|
113
115
|
approverId: string;
|
|
114
116
|
message: string | null;
|
|
@@ -342,7 +344,6 @@ export interface CanonRuntimeDescriptor {
|
|
|
342
344
|
coreControls: ReadonlyArray<CanonControlDescriptor>;
|
|
343
345
|
runtimeControls?: ReadonlyArray<CanonControlDescriptor>;
|
|
344
346
|
commands?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
345
|
-
actions?: ReadonlyArray<CanonRuntimeActionDescriptor>;
|
|
346
347
|
/**
|
|
347
348
|
* Optional setup-time local roots advertised by a runtime. These are
|
|
348
349
|
* metadata only for now; existing session config still selects concrete
|
|
@@ -424,6 +425,21 @@ export interface CanonRuntimeActivityItem {
|
|
|
424
425
|
sensitive?: boolean;
|
|
425
426
|
actions?: ReadonlyArray<CanonRuntimeCommandDescriptor>;
|
|
426
427
|
}
|
|
428
|
+
export type TurnOutputBlockKind = 'text' | 'tool' | 'plan' | 'approval' | 'input' | 'status';
|
|
429
|
+
export type TurnOutputBlockStatus = 'running' | 'completed' | 'failed' | 'pending' | 'blocked';
|
|
430
|
+
export interface TurnOutputBlock {
|
|
431
|
+
id: string;
|
|
432
|
+
turnId: string;
|
|
433
|
+
kind: TurnOutputBlockKind;
|
|
434
|
+
status: TurnOutputBlockStatus;
|
|
435
|
+
sequence: number;
|
|
436
|
+
title?: string;
|
|
437
|
+
text?: string;
|
|
438
|
+
summary?: string;
|
|
439
|
+
detail?: string;
|
|
440
|
+
createdAt?: number;
|
|
441
|
+
updatedAt?: number;
|
|
442
|
+
}
|
|
427
443
|
export interface CanonRuntimeInventoryEntry {
|
|
428
444
|
id: string;
|
|
429
445
|
label: string;
|
|
@@ -607,13 +623,14 @@ export interface CreateConversationOptions {
|
|
|
607
623
|
/** Required when creating a direct conversation with a first-party coding agent. */
|
|
608
624
|
sessionConfig?: SessionConfig | null;
|
|
609
625
|
}
|
|
610
|
-
export type StreamingStatus = 'thinking' | 'streaming' | 'tool';
|
|
626
|
+
export type StreamingStatus = 'thinking' | 'streaming' | 'tool' | 'waiting_input';
|
|
611
627
|
export interface SetStreamingOptions {
|
|
612
628
|
conversationId: string;
|
|
613
629
|
text: string;
|
|
614
630
|
status: StreamingStatus;
|
|
615
631
|
messageId: string;
|
|
616
632
|
turnId?: string | null;
|
|
633
|
+
blocks?: TurnOutputBlock[];
|
|
617
634
|
}
|
|
618
635
|
export interface SetRuntimeTurnOptions {
|
|
619
636
|
conversationId: string;
|