@canonmsg/core 0.15.1 → 0.15.3
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/agent-session.js +88 -14
- package/dist/browser.d.ts +1 -1
- package/dist/host-runtime.js +2 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/message-format.js +3 -2
- package/dist/reach-out.d.ts +37 -0
- package/dist/reach-out.js +73 -0
- package/dist/rtdb-rest.d.ts +3 -1
- package/dist/rtdb-rest.js +4 -0
- package/dist/types.d.ts +16 -3
- package/package.json +1 -1
package/dist/agent-session.js
CHANGED
|
@@ -14,7 +14,7 @@ function descriptorOptions(runtime, controlId) {
|
|
|
14
14
|
function descriptorDefaultValue(runtime, controlId) {
|
|
15
15
|
const control = listDescriptorControls(runtime)
|
|
16
16
|
.find((candidate) => candidate.id === controlId);
|
|
17
|
-
return control?.defaultValue ??
|
|
17
|
+
return control?.defaultValue ?? undefined;
|
|
18
18
|
}
|
|
19
19
|
function buildWorkSessionSummary(workSession, workSessions) {
|
|
20
20
|
const merged = mergeWorkSessionContexts(workSession, workSessions);
|
|
@@ -30,6 +30,70 @@ function buildWorkSessionSummary(workSession, workSessions) {
|
|
|
30
30
|
status: primary.status ?? null,
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
function setControlState(controlState, id, value, source, appliedAt) {
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return;
|
|
36
|
+
controlState[id] = {
|
|
37
|
+
value,
|
|
38
|
+
source,
|
|
39
|
+
...(source === 'applied' && appliedAt ? { appliedAt } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function buildControlState(input) {
|
|
43
|
+
const controlState = {};
|
|
44
|
+
const appliedAt = input.sessionState?.updatedAt ?? input.lastHeartbeatAt ?? input.updatedAt ?? undefined;
|
|
45
|
+
const modelDefault = descriptorDefaultValue(input.runtime, 'model');
|
|
46
|
+
if (input.sessionState?.model !== undefined) {
|
|
47
|
+
setControlState(controlState, 'model', input.sessionState.model, 'applied', appliedAt);
|
|
48
|
+
}
|
|
49
|
+
else if (input.sessionConfig?.model !== undefined) {
|
|
50
|
+
setControlState(controlState, 'model', input.sessionConfig.model, 'requested');
|
|
51
|
+
}
|
|
52
|
+
else if (modelDefault !== undefined) {
|
|
53
|
+
setControlState(controlState, 'model', modelDefault, 'host-default');
|
|
54
|
+
}
|
|
55
|
+
const permissionDefault = descriptorDefaultValue(input.runtime, 'permissionMode');
|
|
56
|
+
if (input.sessionState?.permissionMode !== undefined) {
|
|
57
|
+
setControlState(controlState, 'permissionMode', input.sessionState.permissionMode, 'applied', appliedAt);
|
|
58
|
+
}
|
|
59
|
+
else if (input.sessionConfig?.permissionMode !== undefined) {
|
|
60
|
+
setControlState(controlState, 'permissionMode', input.sessionConfig.permissionMode, 'requested');
|
|
61
|
+
}
|
|
62
|
+
else if (permissionDefault !== undefined) {
|
|
63
|
+
setControlState(controlState, 'permissionMode', permissionDefault, 'host-default');
|
|
64
|
+
}
|
|
65
|
+
const effortDefault = descriptorDefaultValue(input.runtime, 'effort');
|
|
66
|
+
if (input.sessionState?.effort !== undefined) {
|
|
67
|
+
setControlState(controlState, 'effort', input.sessionState.effort, 'applied', appliedAt);
|
|
68
|
+
}
|
|
69
|
+
else if (input.sessionConfig?.effort !== undefined) {
|
|
70
|
+
setControlState(controlState, 'effort', input.sessionConfig.effort, 'requested');
|
|
71
|
+
}
|
|
72
|
+
else if (effortDefault !== undefined) {
|
|
73
|
+
setControlState(controlState, 'effort', effortDefault, 'host-default');
|
|
74
|
+
}
|
|
75
|
+
const workspaceDefault = descriptorDefaultValue(input.runtime, 'workspace');
|
|
76
|
+
if (input.sessionConfig?.workspaceId !== undefined) {
|
|
77
|
+
setControlState(controlState, 'workspace', input.sessionConfig.workspaceId, 'requested');
|
|
78
|
+
}
|
|
79
|
+
else if (workspaceDefault !== undefined) {
|
|
80
|
+
setControlState(controlState, 'workspace', workspaceDefault, 'host-default');
|
|
81
|
+
}
|
|
82
|
+
if (input.sessionState?.executionMode !== undefined) {
|
|
83
|
+
setControlState(controlState, 'executionMode', input.sessionState.executionMode, 'applied', appliedAt);
|
|
84
|
+
}
|
|
85
|
+
else if (input.sessionConfig?.executionMode !== undefined) {
|
|
86
|
+
setControlState(controlState, 'executionMode', input.sessionConfig.executionMode, 'requested');
|
|
87
|
+
}
|
|
88
|
+
for (const [id, value] of Object.entries(input.sessionConfig?.runtimeControlValues ?? {})) {
|
|
89
|
+
setControlState(controlState, id, value, 'requested');
|
|
90
|
+
}
|
|
91
|
+
for (const [id, value] of Object.entries(input.sessionState?.runtimeControlValues ?? {})) {
|
|
92
|
+
setControlState(controlState, id, value, 'applied', appliedAt);
|
|
93
|
+
}
|
|
94
|
+
Object.assign(controlState, input.sessionState?.controlState ?? {});
|
|
95
|
+
return Object.keys(controlState).length > 0 ? controlState : undefined;
|
|
96
|
+
}
|
|
33
97
|
export function buildAgentSessionSnapshot(input) {
|
|
34
98
|
const modelOptions = input.sessionState?.availableModels?.length
|
|
35
99
|
? input.sessionState.availableModels
|
|
@@ -39,6 +103,22 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
39
103
|
const availableExecutionModes = descriptorOptions(input.runtime, 'executionMode')
|
|
40
104
|
.map((option) => option.value)
|
|
41
105
|
.filter((value) => value === 'worktree' || value === 'locked');
|
|
106
|
+
const model = input.sessionState?.model
|
|
107
|
+
?? input.sessionConfig?.model
|
|
108
|
+
?? descriptorDefaultValue(input.runtime, 'model');
|
|
109
|
+
const permissionMode = input.sessionState?.permissionMode
|
|
110
|
+
?? input.sessionConfig?.permissionMode
|
|
111
|
+
?? descriptorDefaultValue(input.runtime, 'permissionMode');
|
|
112
|
+
const effort = input.sessionState?.effort
|
|
113
|
+
?? input.sessionConfig?.effort
|
|
114
|
+
?? descriptorDefaultValue(input.runtime, 'effort');
|
|
115
|
+
const runtimeControlValues = input.sessionState?.runtimeControlValues
|
|
116
|
+
?? input.sessionConfig?.runtimeControlValues;
|
|
117
|
+
const workspaceId = input.sessionConfig?.workspaceId
|
|
118
|
+
?? descriptorDefaultValue(input.runtime, 'workspace');
|
|
119
|
+
const executionMode = input.sessionState?.executionMode
|
|
120
|
+
?? input.sessionConfig?.executionMode;
|
|
121
|
+
const controlState = buildControlState(input);
|
|
42
122
|
return {
|
|
43
123
|
conversationId: input.conversationId,
|
|
44
124
|
agentId: input.agentId,
|
|
@@ -48,23 +128,17 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
48
128
|
hostMode: Boolean(input.sessionState?.hostMode
|
|
49
129
|
?? input.sessionConfig?.hostMode
|
|
50
130
|
?? input.runtime?.hostMode),
|
|
51
|
-
model
|
|
52
|
-
?? input.sessionConfig?.model
|
|
53
|
-
?? descriptorDefaultValue(input.runtime, 'model'),
|
|
131
|
+
model,
|
|
54
132
|
modelOptions,
|
|
55
|
-
permissionMode
|
|
56
|
-
?? input.sessionConfig?.permissionMode
|
|
57
|
-
?? descriptorDefaultValue(input.runtime, 'permissionMode'),
|
|
133
|
+
permissionMode,
|
|
58
134
|
permissionModeOptions: descriptorOptions(input.runtime, 'permissionMode'),
|
|
59
|
-
effort
|
|
60
|
-
runtimeControlValues
|
|
61
|
-
|
|
135
|
+
effort,
|
|
136
|
+
runtimeControlValues,
|
|
137
|
+
controlState,
|
|
62
138
|
runtimeControlErrors: input.sessionState?.runtimeControlErrors ?? undefined,
|
|
63
|
-
workspaceId
|
|
64
|
-
?? descriptorDefaultValue(input.runtime, 'workspace'),
|
|
139
|
+
workspaceId,
|
|
65
140
|
workspaceOptions,
|
|
66
|
-
executionMode
|
|
67
|
-
?? input.sessionConfig?.executionMode,
|
|
141
|
+
executionMode,
|
|
68
142
|
availableExecutionModes,
|
|
69
143
|
executionBranch: input.sessionState?.executionBranch,
|
|
70
144
|
resolvedWorkspaceLabel: undefined,
|
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, RuntimeControlError, 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, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, RuntimeUpdatedPayload, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, 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';
|
package/dist/host-runtime.js
CHANGED
|
@@ -82,7 +82,7 @@ function describeContactCard(card) {
|
|
|
82
82
|
? 'reject pending requests'
|
|
83
83
|
: null,
|
|
84
84
|
].filter(Boolean).join(', ');
|
|
85
|
-
const hint = `This host can inspect the card, but Canon admission actions
|
|
85
|
+
const hint = `This host can inspect the card, but this wrapper does not expose callable Canon admission actions yet. Missing capabilities here: ${missingCapabilities}. Use an SDK/OpenClaw reach-out surface or another Canon client for userId ${card.userId}.`;
|
|
86
86
|
return `${identity}\n${hint}`;
|
|
87
87
|
}
|
|
88
88
|
function describeAttachment(attachment, materialized) {
|
|
@@ -183,6 +183,7 @@ export async function publishHostSessionSnapshots(input) {
|
|
|
183
183
|
permissionMode: snapshot.permissionMode ?? null,
|
|
184
184
|
effort: snapshot.effort ?? null,
|
|
185
185
|
runtimeControlValues: snapshot.runtimeControlValues ?? null,
|
|
186
|
+
controlState: snapshot.controlState ?? null,
|
|
186
187
|
workspaceId: snapshot.workspaceId ?? null,
|
|
187
188
|
executionMode: snapshot.executionMode ?? null,
|
|
188
189
|
executionBranch,
|
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, RuntimeControlError, 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, CanonRuntimeDetailTier, CanonRuntimeExecutionMetadata, CanonRuntimeInventory, CanonRuntimeInventoryEntry, CanonRuntimeStreamingMode, CanonRuntimeStatusItem, CanonRuntimeSurfaceMode, CanonWorkspaceRootMetadata, ModelOption, PermissionModeOption, RuntimeInfoPayload, RuntimeControlError, RuntimeControlState, RuntimeControlValueSource, 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';
|
|
@@ -37,6 +37,8 @@ export type { HostInboundParticipantContext, } from './host-runtime.js';
|
|
|
37
37
|
export { createRuntimeStatePublisher, } from './runtime-state-publisher.js';
|
|
38
38
|
export type { RuntimeStatePublisher, RuntimeStatePublisherOptions, RuntimeStreamingPayload, } from './runtime-state-publisher.js';
|
|
39
39
|
export { formatCanonMessageAsText } from './message-format.js';
|
|
40
|
+
export { reachOutToCanonContact } from './reach-out.js';
|
|
41
|
+
export type { CanonReachOutClient, CanonReachOutOptions, CanonReachOutResult, } from './reach-out.js';
|
|
40
42
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
41
43
|
export { resolveCanonBaseUrl } from './base-url.js';
|
|
42
44
|
export { handleCliMetadataRequest, isDirectExecution, readCliPackageVersion, runCli, } from './cli-metadata.js';
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,8 @@ export { buildCanonHostPrompt, buildHydratedInboundContext, createConversationMe
|
|
|
35
35
|
export { createRuntimeStatePublisher, } from './runtime-state-publisher.js';
|
|
36
36
|
// Message formatting (LLM-facing text projection)
|
|
37
37
|
export { formatCanonMessageAsText } from './message-format.js';
|
|
38
|
+
// Admission-aware reach-out helpers for runtime clients
|
|
39
|
+
export { reachOutToCanonContact } from './reach-out.js';
|
|
38
40
|
// Constants
|
|
39
41
|
export { DEFAULT_BASE_URL, DEFAULT_STREAM_URL, DEFAULT_RTDB_URL, FIREBASE_WEB_API_KEY } from './constants.js';
|
|
40
42
|
// Base URL resolver
|
package/dist/message-format.js
CHANGED
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
* regression in every consumer plugin.
|
|
11
11
|
*/
|
|
12
12
|
export function formatCanonMessageAsText(message) {
|
|
13
|
+
const trimmedText = typeof message.text === 'string' ? message.text.trim() : '';
|
|
13
14
|
if (message.contentType === 'contact_card' && message.contactCard) {
|
|
14
|
-
|
|
15
|
+
const cardText = formatContactCard(message.contactCard);
|
|
16
|
+
return trimmedText ? `${cardText}\n${trimmedText}` : cardText;
|
|
15
17
|
}
|
|
16
18
|
const attachment = pickPrimaryAttachment(message.attachments);
|
|
17
|
-
const trimmedText = typeof message.text === 'string' ? message.text.trim() : '';
|
|
18
19
|
if (attachment?.kind === 'image') {
|
|
19
20
|
return trimmedText ? `[image] ${trimmedText}` : '[image]';
|
|
20
21
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { CanonResolveAdmissionResult, CreateContactRequestResult, CreateConversationOptions, SendMessageOptions } from './types.js';
|
|
2
|
+
export interface CanonReachOutClient {
|
|
3
|
+
resolveAdmission(targetUserId: string): Promise<CanonResolveAdmissionResult>;
|
|
4
|
+
createConversation(options: CreateConversationOptions): Promise<{
|
|
5
|
+
conversationId: string;
|
|
6
|
+
}>;
|
|
7
|
+
sendMessage(conversationId: string, text: string, options?: SendMessageOptions): Promise<{
|
|
8
|
+
messageId: string;
|
|
9
|
+
}>;
|
|
10
|
+
createContactRequest(targetUserId: string, message?: string | null): Promise<CreateContactRequestResult>;
|
|
11
|
+
}
|
|
12
|
+
export interface CanonReachOutOptions {
|
|
13
|
+
targetUserId: string;
|
|
14
|
+
text?: string | null;
|
|
15
|
+
requestMessage?: string | null;
|
|
16
|
+
sendMessageOptions?: SendMessageOptions;
|
|
17
|
+
}
|
|
18
|
+
export type CanonReachOutResult = {
|
|
19
|
+
status: 'messaged';
|
|
20
|
+
conversationId: string;
|
|
21
|
+
messageId?: string;
|
|
22
|
+
} | {
|
|
23
|
+
status: 'requested';
|
|
24
|
+
requestId: string | null;
|
|
25
|
+
} | {
|
|
26
|
+
status: 'pending';
|
|
27
|
+
requestId: string | null;
|
|
28
|
+
} | {
|
|
29
|
+
status: 'blocked' | 'unavailable';
|
|
30
|
+
reason: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Admission-aware direct reach-out for runtime clients. It deliberately keeps
|
|
34
|
+
* backend conversation creation fail-closed; callers choose this helper when
|
|
35
|
+
* their product behavior is "message if reachable, otherwise request access."
|
|
36
|
+
*/
|
|
37
|
+
export declare function reachOutToCanonContact(client: CanonReachOutClient, options: CanonReachOutOptions): Promise<CanonReachOutResult>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const CONTACT_REQUEST_MESSAGE_LIMIT = 500;
|
|
2
|
+
function normalizeOptionalText(value) {
|
|
3
|
+
const trimmed = typeof value === 'string' ? value.trim() : '';
|
|
4
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
5
|
+
}
|
|
6
|
+
function normalizeContactRequestMessage(requestMessage, fallbackText) {
|
|
7
|
+
const text = normalizeOptionalText(requestMessage) ?? normalizeOptionalText(fallbackText);
|
|
8
|
+
if (!text)
|
|
9
|
+
return null;
|
|
10
|
+
if (text.length <= CONTACT_REQUEST_MESSAGE_LIMIT)
|
|
11
|
+
return text;
|
|
12
|
+
return `${text.slice(0, CONTACT_REQUEST_MESSAGE_LIMIT - 3)}...`;
|
|
13
|
+
}
|
|
14
|
+
function isConnectionRequiredError(error) {
|
|
15
|
+
const status = error && typeof error === 'object' && 'status' in error
|
|
16
|
+
? Number(error.status)
|
|
17
|
+
: null;
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
19
|
+
return status === 403 && /CONNECTION_REQUIRED|connection required/i.test(message);
|
|
20
|
+
}
|
|
21
|
+
async function openConversationAndMaybeMessage(client, options) {
|
|
22
|
+
const { conversationId } = await client.createConversation({
|
|
23
|
+
type: 'direct',
|
|
24
|
+
targetUserId: options.targetUserId,
|
|
25
|
+
});
|
|
26
|
+
const text = normalizeOptionalText(options.text);
|
|
27
|
+
if (text) {
|
|
28
|
+
const { messageId } = options.sendMessageOptions
|
|
29
|
+
? await client.sendMessage(conversationId, text, options.sendMessageOptions)
|
|
30
|
+
: await client.sendMessage(conversationId, text);
|
|
31
|
+
return { status: 'messaged', conversationId, messageId };
|
|
32
|
+
}
|
|
33
|
+
return { status: 'messaged', conversationId };
|
|
34
|
+
}
|
|
35
|
+
async function requestContact(client, options) {
|
|
36
|
+
const result = await client.createContactRequest(options.targetUserId, normalizeContactRequestMessage(options.requestMessage, options.text));
|
|
37
|
+
if (result.status === 'open') {
|
|
38
|
+
return openConversationAndMaybeMessage(client, { ...options, requestMessage: null });
|
|
39
|
+
}
|
|
40
|
+
if (result.status === 'duplicate') {
|
|
41
|
+
return { status: 'pending', requestId: result.requestId };
|
|
42
|
+
}
|
|
43
|
+
return { status: 'requested', requestId: result.requestId };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Admission-aware direct reach-out for runtime clients. It deliberately keeps
|
|
47
|
+
* backend conversation creation fail-closed; callers choose this helper when
|
|
48
|
+
* their product behavior is "message if reachable, otherwise request access."
|
|
49
|
+
*/
|
|
50
|
+
export async function reachOutToCanonContact(client, options) {
|
|
51
|
+
const { admission } = await client.resolveAdmission(options.targetUserId);
|
|
52
|
+
if (admission.state === 'allowed' && admission.canMessage) {
|
|
53
|
+
try {
|
|
54
|
+
return await openConversationAndMaybeMessage(client, options);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (isConnectionRequiredError(error)) {
|
|
58
|
+
return requestContact(client, options);
|
|
59
|
+
}
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (admission.state === 'pending-outbound') {
|
|
64
|
+
return { status: 'pending', requestId: admission.pendingRequestId ?? null };
|
|
65
|
+
}
|
|
66
|
+
if (admission.state === 'request-required' && admission.canRequestContact) {
|
|
67
|
+
return requestContact(client, options);
|
|
68
|
+
}
|
|
69
|
+
if (admission.state === 'blocked') {
|
|
70
|
+
return { status: 'blocked', reason: 'blocked' };
|
|
71
|
+
}
|
|
72
|
+
return { status: 'unavailable', reason: admission.state };
|
|
73
|
+
}
|
package/dist/rtdb-rest.d.ts
CHANGED
|
@@ -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, ModelOption, RuntimeControlError, RuntimeInfoPayload } from './types.js';
|
|
10
|
+
import type { CanonControlValue, ModelOption, RuntimeControlError, RuntimeControlState, 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
|
+
controlState?: Record<string, RuntimeControlState>;
|
|
17
18
|
runtimeControlErrors?: Record<string, RuntimeControlError> | null;
|
|
18
19
|
cwd?: string;
|
|
19
20
|
executionMode?: 'worktree' | 'locked';
|
|
@@ -63,6 +64,7 @@ export interface AgentSessionSnapshotPatch {
|
|
|
63
64
|
}> | null;
|
|
64
65
|
effort?: string | null;
|
|
65
66
|
runtimeControlValues?: Record<string, CanonControlValue> | null;
|
|
67
|
+
controlState?: Record<string, RuntimeControlState> | null;
|
|
66
68
|
runtimeControlErrors?: Record<string, RuntimeControlError> | null;
|
|
67
69
|
workspaceId?: string | null;
|
|
68
70
|
workspaceOptions?: Array<{
|
package/dist/rtdb-rest.js
CHANGED
|
@@ -144,6 +144,9 @@ function createRTDBClientHandle(client, options) {
|
|
|
144
144
|
...(state.runtimeControlValues !== undefined
|
|
145
145
|
? { runtimeControlValues: state.runtimeControlValues }
|
|
146
146
|
: {}),
|
|
147
|
+
...(state.controlState !== undefined
|
|
148
|
+
? { controlState: state.controlState }
|
|
149
|
+
: {}),
|
|
147
150
|
...(state.runtimeControlErrors !== undefined
|
|
148
151
|
? { runtimeControlErrors: state.runtimeControlErrors }
|
|
149
152
|
: {}),
|
|
@@ -173,6 +176,7 @@ function createRTDBClientHandle(client, options) {
|
|
|
173
176
|
state: null,
|
|
174
177
|
waitingForInput: false,
|
|
175
178
|
lastError: null,
|
|
179
|
+
controlState: null,
|
|
176
180
|
executionBranch: null,
|
|
177
181
|
contextUsage: null,
|
|
178
182
|
worktreePath: null,
|
package/dist/types.d.ts
CHANGED
|
@@ -21,9 +21,9 @@ export interface ForwardedFrom {
|
|
|
21
21
|
/**
|
|
22
22
|
* Server-serialized contact-card payload. Emitted on messages with
|
|
23
23
|
* `contentType: 'contact_card'` so agents receive the referenced user's
|
|
24
|
-
* identity alongside the card. Agents use the referenced `userId` with
|
|
25
|
-
*
|
|
26
|
-
* contact, they
|
|
24
|
+
* identity alongside the card. Agents use the referenced `userId` with an
|
|
25
|
+
* admission-aware reach-out path; if the target's inbound policy blocks cold
|
|
26
|
+
* contact, they create a contact request and retry after approval.
|
|
27
27
|
*/
|
|
28
28
|
export interface ContactCardPayload {
|
|
29
29
|
userId: string;
|
|
@@ -212,11 +212,18 @@ export interface CanonWorkspaceRootMetadata {
|
|
|
212
212
|
defaultRelativePath?: string | null;
|
|
213
213
|
}
|
|
214
214
|
export type CanonControlValue = string;
|
|
215
|
+
export type RuntimeControlValueSource = 'applied' | 'requested' | 'host-default' | 'route-default' | 'unknown';
|
|
216
|
+
export interface RuntimeControlState {
|
|
217
|
+
value: CanonControlValue | null;
|
|
218
|
+
source: RuntimeControlValueSource;
|
|
219
|
+
appliedAt?: number;
|
|
220
|
+
}
|
|
215
221
|
export type CanonControlAvailability = 'setup' | 'live' | 'setup_and_live';
|
|
216
222
|
export type CanonControlLiveBehavior = 'immediate' | 'next_turn' | 'none';
|
|
217
223
|
export type CanonControlSelectionPolicy = 'inherit' | 'required_explicit';
|
|
218
224
|
export type CanonRuntimeStreamingMode = 'none' | 'status' | 'snapshot' | 'block' | 'delta';
|
|
219
225
|
export type CanonRuntimeSurfaceMode = 'host' | 'channel' | 'limited_channel' | 'operator';
|
|
226
|
+
export type CanonRuntimeDetailTier = 'primary' | 'detail' | 'diagnostic';
|
|
220
227
|
export type CanonRuntimeInventoryStatus = 'ready' | 'auth_needed' | 'unknown' | 'configured' | 'running' | 'error';
|
|
221
228
|
export type CanonRuntimeStatusTone = 'default' | 'success' | 'warning' | 'danger';
|
|
222
229
|
export type CanonRuntimeActionAvailability = 'idle' | 'busy' | 'busy_with_queue' | 'waiting_input' | 'always';
|
|
@@ -301,6 +308,9 @@ export interface CanonRuntimeStatusItem {
|
|
|
301
308
|
label: string;
|
|
302
309
|
value: string;
|
|
303
310
|
tone?: CanonRuntimeStatusTone;
|
|
311
|
+
tier?: CanonRuntimeDetailTier;
|
|
312
|
+
sensitive?: boolean;
|
|
313
|
+
source?: RuntimeControlValueSource;
|
|
304
314
|
}
|
|
305
315
|
export interface CanonRuntimeInventoryEntry {
|
|
306
316
|
id: string;
|
|
@@ -312,6 +322,7 @@ export interface CanonRuntimeInventory {
|
|
|
312
322
|
id: string;
|
|
313
323
|
label: string;
|
|
314
324
|
entries: ReadonlyArray<CanonRuntimeInventoryEntry>;
|
|
325
|
+
tier?: CanonRuntimeDetailTier;
|
|
315
326
|
}
|
|
316
327
|
export interface RuntimeInfoPayload {
|
|
317
328
|
descriptor: CanonRuntimeDescriptor;
|
|
@@ -479,6 +490,7 @@ export interface SessionState {
|
|
|
479
490
|
permissionMode?: string;
|
|
480
491
|
effort?: string;
|
|
481
492
|
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
493
|
+
controlState?: Record<string, RuntimeControlState>;
|
|
482
494
|
runtimeControlErrors?: Record<string, RuntimeControlError> | null;
|
|
483
495
|
cwd?: string;
|
|
484
496
|
executionMode?: 'worktree' | 'locked';
|
|
@@ -580,6 +592,7 @@ export interface AgentSessionSnapshot {
|
|
|
580
592
|
permissionModeOptions?: PermissionModeOption[];
|
|
581
593
|
effort?: string;
|
|
582
594
|
runtimeControlValues?: Record<string, CanonControlValue>;
|
|
595
|
+
controlState?: Record<string, RuntimeControlState>;
|
|
583
596
|
runtimeControlErrors?: Record<string, RuntimeControlError> | null;
|
|
584
597
|
runtimeDescriptor?: CanonRuntimeDescriptor | null;
|
|
585
598
|
runtimeInfo?: RuntimeInfoPayload | null;
|