@canonmsg/core 0.15.3 → 0.15.5
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.d.ts +0 -3
- package/dist/agent-session.js +0 -16
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +1 -1
- package/dist/client.d.ts +2 -5
- package/dist/client.js +2 -40
- package/dist/host-runtime.d.ts +2 -3
- package/dist/host-runtime.js +6 -6
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/policy.d.ts +0 -11
- package/dist/reach-out.d.ts +5 -1
- package/dist/reach-out.js +49 -5
- package/dist/rtdb-rest.d.ts +0 -7
- package/dist/self-context.d.ts +39 -0
- package/dist/self-context.js +66 -0
- package/dist/types.d.ts +7 -14
- package/package.json +1 -1
- package/dist/work-session.d.ts +0 -88
- package/dist/work-session.js +0 -238
package/dist/agent-session.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { AgentRuntime, AgentSessionSnapshot, SessionConfig, SessionState } from './types.js';
|
|
2
2
|
import type { TurnState } from './turn-protocol.js';
|
|
3
|
-
import { type CanonWorkSessionContext } from './work-session.js';
|
|
4
3
|
export interface BuildAgentSessionSnapshotInput {
|
|
5
4
|
conversationId: string;
|
|
6
5
|
agentId: string;
|
|
@@ -8,8 +7,6 @@ export interface BuildAgentSessionSnapshotInput {
|
|
|
8
7
|
sessionConfig?: SessionConfig | null;
|
|
9
8
|
sessionState?: SessionState | null;
|
|
10
9
|
turnState?: TurnState | null;
|
|
11
|
-
workSession?: CanonWorkSessionContext | null;
|
|
12
|
-
workSessions?: CanonWorkSessionContext[] | null;
|
|
13
10
|
lastHeartbeatAt?: number | null;
|
|
14
11
|
updatedAt?: number | null;
|
|
15
12
|
}
|
package/dist/agent-session.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { mergeWorkSessionContexts, } from './work-session.js';
|
|
2
1
|
function listDescriptorControls(runtime) {
|
|
3
2
|
const descriptor = runtime?.runtimeDescriptor;
|
|
4
3
|
return [
|
|
@@ -16,20 +15,6 @@ function descriptorDefaultValue(runtime, controlId) {
|
|
|
16
15
|
.find((candidate) => candidate.id === controlId);
|
|
17
16
|
return control?.defaultValue ?? undefined;
|
|
18
17
|
}
|
|
19
|
-
function buildWorkSessionSummary(workSession, workSessions) {
|
|
20
|
-
const merged = mergeWorkSessionContexts(workSession, workSessions);
|
|
21
|
-
const primary = merged[0];
|
|
22
|
-
if (!primary?.id) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
return {
|
|
26
|
-
count: merged.length,
|
|
27
|
-
id: primary.id,
|
|
28
|
-
title: primary.title ?? null,
|
|
29
|
-
objective: primary.objective ?? null,
|
|
30
|
-
status: primary.status ?? null,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
18
|
function setControlState(controlState, id, value, source, appliedAt) {
|
|
34
19
|
if (value === undefined)
|
|
35
20
|
return;
|
|
@@ -154,7 +139,6 @@ export function buildAgentSessionSnapshot(input) {
|
|
|
154
139
|
lastHeartbeatAt: input.lastHeartbeatAt
|
|
155
140
|
?? input.runtime?.updatedAt
|
|
156
141
|
?? input.sessionState?.updatedAt,
|
|
157
|
-
workSession: buildWorkSessionSummary(input.workSession, input.workSessions),
|
|
158
142
|
updatedAt: input.updatedAt
|
|
159
143
|
?? input.turnState?.updatedAt
|
|
160
144
|
?? input.sessionState?.updatedAt
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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,
|
|
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, 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
|
-
export type {
|
|
8
|
-
export {
|
|
7
|
+
export type { CanonSelfContext, CanonSelfContextType, SelfContextPromptRenderOptions, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, } from './self-context.js';
|
|
8
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
9
9
|
export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
10
10
|
export { CLAUDE_EFFORT_OPTIONS, EXECUTION_MODE_CONTROL_OPTIONS, buildFirstPartyCodingRuntimeDescriptor, buildRuntimeEffortControl, buildRuntimeExecutionModeControl, buildRuntimeExecutionModeOptions, buildRuntimeModelControl, buildRuntimePermissionModeControl, buildRuntimeWorkspaceControl, buildRuntimeWorkspaceControlOptions, } from './runtime-descriptor.js';
|
|
11
11
|
export type { AgentBehaviorSettings, ParticipationHistoryMessage, ParticipationHistorySnapshot, ParticipationStyle, ResolvedAgentBehaviorPolicy, } from './policy.js';
|
package/dist/browser.js
CHANGED
|
@@ -2,7 +2,7 @@ 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
4
|
export { EXECUTION_ENVIRONMENT_MODES, isExecutionEnvironmentMode, } from './execution-environment-mode.js';
|
|
5
|
-
export {
|
|
5
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
6
6
|
export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
7
7
|
export { CLAUDE_EFFORT_OPTIONS, EXECUTION_MODE_CONTROL_OPTIONS, buildFirstPartyCodingRuntimeDescriptor, buildRuntimeEffortControl, buildRuntimeExecutionModeControl, buildRuntimeExecutionModeOptions, buildRuntimeModelControl, buildRuntimePermissionModeControl, buildRuntimeWorkspaceControl, buildRuntimeWorkspaceControlOptions, } from './runtime-descriptor.js';
|
|
8
8
|
export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots, buildBehaviorPolicyLines, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, evaluateParticipationPolicy, getDefaultParticipationPolicy, resolveAgentBehaviorPolicy, } from './policy.js';
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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 SetStreamingOptions } from './types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SendContextualMessageOptions, SendContextualMessageResult } from './self-context.js';
|
|
3
3
|
import type { InboundDisposition } from './turn-protocol.js';
|
|
4
4
|
/**
|
|
5
5
|
* Thin REST client for Canon's agent API.
|
|
@@ -25,10 +25,7 @@ export declare class CanonClient {
|
|
|
25
25
|
sendMessage(conversationId: string, text: string, options?: SendMessageOptions): Promise<{
|
|
26
26
|
messageId: string;
|
|
27
27
|
}>;
|
|
28
|
-
|
|
29
|
-
getWorkSession(workSessionId: string, conversationId: string): Promise<CanonResolvedWorkSession>;
|
|
30
|
-
upsertWorkSessionConversation(workSessionId: string, conversationId: string, options?: UpdateWorkSessionConversationOptions): Promise<CanonResolvedWorkSession>;
|
|
31
|
-
sendLinkedMessage(options: SendLinkedMessageOptions): Promise<SendLinkedMessageResult>;
|
|
28
|
+
sendContextualMessage(options: SendContextualMessageOptions): Promise<SendContextualMessageResult>;
|
|
32
29
|
createConversation(options: CreateConversationOptions): Promise<{
|
|
33
30
|
conversationId: string;
|
|
34
31
|
}>;
|
package/dist/client.js
CHANGED
|
@@ -82,8 +82,8 @@ export class CanonClient {
|
|
|
82
82
|
throw new CanonApiError(res.status, await res.text());
|
|
83
83
|
return res.json();
|
|
84
84
|
}
|
|
85
|
-
async
|
|
86
|
-
const res = await fetch(`${this.baseUrl}/
|
|
85
|
+
async sendContextualMessage(options) {
|
|
86
|
+
const res = await fetch(`${this.baseUrl}/messages/send-contextual`, {
|
|
87
87
|
method: 'POST',
|
|
88
88
|
headers: this.authHeaders(),
|
|
89
89
|
body: JSON.stringify(options),
|
|
@@ -92,44 +92,6 @@ export class CanonClient {
|
|
|
92
92
|
throw new CanonApiError(res.status, await res.text());
|
|
93
93
|
return res.json();
|
|
94
94
|
}
|
|
95
|
-
async getWorkSession(workSessionId, conversationId) {
|
|
96
|
-
const params = new URLSearchParams({ conversationId });
|
|
97
|
-
const res = await fetch(`${this.baseUrl}/work-sessions/${workSessionId}?${params}`, { headers: this.authHeaders() });
|
|
98
|
-
if (!res.ok)
|
|
99
|
-
throw new CanonApiError(res.status, await res.text());
|
|
100
|
-
return res.json();
|
|
101
|
-
}
|
|
102
|
-
async upsertWorkSessionConversation(workSessionId, conversationId, options) {
|
|
103
|
-
const res = await fetch(`${this.baseUrl}/work-sessions/${workSessionId}/conversations/${conversationId}`, {
|
|
104
|
-
method: 'PUT',
|
|
105
|
-
headers: this.authHeaders(),
|
|
106
|
-
body: JSON.stringify(options ?? {}),
|
|
107
|
-
});
|
|
108
|
-
if (!res.ok)
|
|
109
|
-
throw new CanonApiError(res.status, await res.text());
|
|
110
|
-
return res.json();
|
|
111
|
-
}
|
|
112
|
-
async sendLinkedMessage(options) {
|
|
113
|
-
const res = await fetch(`${this.baseUrl}/messages/send-linked`, {
|
|
114
|
-
method: 'POST',
|
|
115
|
-
headers: this.authHeaders(),
|
|
116
|
-
body: JSON.stringify({
|
|
117
|
-
sourceConversationId: options.sourceConversationId,
|
|
118
|
-
targetConversationId: options.targetConversationId,
|
|
119
|
-
text: options.text,
|
|
120
|
-
...(options.workSessionId ? { workSessionId: options.workSessionId } : {}),
|
|
121
|
-
...(options.createWorkSession
|
|
122
|
-
? { createWorkSession: options.createWorkSession }
|
|
123
|
-
: {}),
|
|
124
|
-
...(options.sourceContext ? { sourceContext: options.sourceContext } : {}),
|
|
125
|
-
...(options.targetContext ? { targetContext: options.targetContext } : {}),
|
|
126
|
-
...(options.messageOptions ? { messageOptions: options.messageOptions } : {}),
|
|
127
|
-
}),
|
|
128
|
-
});
|
|
129
|
-
if (!res.ok)
|
|
130
|
-
throw new CanonApiError(res.status, await res.text());
|
|
131
|
-
return res.json();
|
|
132
|
-
}
|
|
133
95
|
async createConversation(options) {
|
|
134
96
|
const res = await fetch(`${this.baseUrl}/conversations/create`, {
|
|
135
97
|
method: 'POST',
|
package/dist/host-runtime.d.ts
CHANGED
|
@@ -33,8 +33,7 @@ export declare function buildCanonHostPrompt(input: {
|
|
|
33
33
|
conversationId: string;
|
|
34
34
|
participantContext: HostInboundParticipantContext;
|
|
35
35
|
behavior?: ResolvedAgentBehaviorPolicy | null;
|
|
36
|
-
|
|
37
|
-
workSessions?: MessageCreatedPayload['workSessions'];
|
|
36
|
+
selfContexts?: MessageCreatedPayload['selfContexts'];
|
|
38
37
|
buildInboundContextLines: (context: HostInboundParticipantContext) => string[];
|
|
39
38
|
sessionContextLines?: string[];
|
|
40
39
|
}): string;
|
|
@@ -68,7 +67,7 @@ export declare function buildHydratedInboundContext(input: {
|
|
|
68
67
|
}): {
|
|
69
68
|
participantContext: HostInboundParticipantContext;
|
|
70
69
|
behavior?: ResolvedAgentBehaviorPolicy | null;
|
|
71
|
-
|
|
70
|
+
selfContexts: NonNullable<MessageCreatedPayload['selfContexts']>;
|
|
72
71
|
hydratedFromPage: boolean;
|
|
73
72
|
};
|
|
74
73
|
export declare function publishHostAgentRuntime(agentId: string, clientType: AgentClientType, runtime: AgentRuntime): Promise<void>;
|
package/dist/host-runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { buildAgentSessionSnapshot } from './agent-session.js';
|
|
2
2
|
import { buildConversationWorktreeSpec, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, } from './execution-environment.js';
|
|
3
3
|
import { buildBehaviorPolicyLines, buildParticipationHistorySnapshot, } from './policy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
5
5
|
import { rtdbRead } from './rtdb-rest.js';
|
|
6
6
|
import { createRuntimeStatePublisher } from './runtime-state-publisher.js';
|
|
7
7
|
const HOST_INBOUND_CONTACT_CARD_ACTION_CAPABILITIES = Object.freeze({
|
|
@@ -11,18 +11,18 @@ const HOST_INBOUND_CONTACT_CARD_ACTION_CAPABILITIES = Object.freeze({
|
|
|
11
11
|
canRejectPendingContactRequests: false,
|
|
12
12
|
});
|
|
13
13
|
export function buildCanonHostPrompt(input) {
|
|
14
|
-
const
|
|
14
|
+
const resolvedSelfContexts = normalizeSelfContexts(input.selfContexts);
|
|
15
15
|
return [
|
|
16
16
|
`You are connected to Canon messaging through a ${input.hostLabel} host wrapper.`,
|
|
17
17
|
'Only the last assistant message from this turn will be delivered as the permanent Canon reply.',
|
|
18
18
|
'Short intermediate assistant messages may be shown as ephemeral status while you work.',
|
|
19
19
|
...input.buildInboundContextLines(input.participantContext),
|
|
20
20
|
...buildBehaviorPolicyLines(input.behavior),
|
|
21
|
-
...
|
|
21
|
+
...buildSelfContextPromptLines(resolvedSelfContexts),
|
|
22
22
|
'Canon participants may be humans or AI agents.',
|
|
23
23
|
'Honor the Canon behavior policy above when deciding how proactively to participate.',
|
|
24
|
-
...(
|
|
25
|
-
? ['Honor the Canon
|
|
24
|
+
...(resolvedSelfContexts.length > 0
|
|
25
|
+
? ['Honor the Canon self-context above when continuing your own cross-session action.']
|
|
26
26
|
: []),
|
|
27
27
|
...(input.sessionContextLines?.length
|
|
28
28
|
? ['Canon session state:', ...input.sessionContextLines]
|
|
@@ -117,7 +117,7 @@ export function buildHydratedInboundContext(input) {
|
|
|
117
117
|
currentAgentStreakStartedByHuman: history.currentAgentStreakStartedByHuman,
|
|
118
118
|
},
|
|
119
119
|
behavior: input.page?.behavior ?? input.conversation?.behavior,
|
|
120
|
-
|
|
120
|
+
selfContexts: input.page?.selfContexts ?? [],
|
|
121
121
|
hydratedFromPage: input.page != null,
|
|
122
122
|
};
|
|
123
123
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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,
|
|
3
|
-
export type {
|
|
4
|
-
export {
|
|
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, 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
|
+
export type { CanonSelfContext, CanonSelfContextType, SelfContextPromptRenderOptions, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, } from './self-context.js';
|
|
4
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
5
5
|
export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
|
|
6
6
|
export type { ConfiguredWorkspaceRoot, WorkspaceDiscoveryResult, } from './workspace-discovery.js';
|
|
7
7
|
export { CanonClient, CanonApiError } from './client.js';
|
|
@@ -9,7 +9,7 @@ export { buildAgentSessionSnapshot } from './agent-session.js';
|
|
|
9
9
|
export { CLAUDE_EFFORT_OPTIONS, EXECUTION_MODE_CONTROL_OPTIONS, buildFirstPartyCodingRuntimeDescriptor, buildRuntimeEffortControl, buildRuntimeExecutionModeControl, buildRuntimeExecutionModeOptions, buildRuntimeModelControl, buildRuntimePermissionModeControl, buildRuntimeWorkspaceControl, buildRuntimeWorkspaceControlOptions, } from './runtime-descriptor.js';
|
|
10
10
|
export { CanonStream } from './stream.js';
|
|
11
11
|
export type { StreamHandler } from './stream.js';
|
|
12
|
-
export type { PolicyRole, ParticipationStyle, RepresentationMode, PermissionLevel, ConversationScope, AgentBehaviorSettings, Participant, Relationship, ContextOverlay, BehaviorProfile, AdmissionPolicy, RuntimeControlPolicy, ActionApprovalPolicy, ParticipationPolicy,
|
|
12
|
+
export type { PolicyRole, ParticipationStyle, RepresentationMode, PermissionLevel, ConversationScope, AgentBehaviorSettings, Participant, Relationship, ContextOverlay, BehaviorProfile, AdmissionPolicy, RuntimeControlPolicy, ActionApprovalPolicy, ParticipationPolicy, ResolvedPolicy, ResolvedTurnEligibility, ResolvedAgentBehaviorPolicy, ParticipationHistoryMessage, ParticipationHistorySnapshot, ParticipationDecisionInput, ParticipationDecision, } from './policy.js';
|
|
13
13
|
export { buildParticipationHistorySnapshot, buildParticipationHistorySnapshots, buildBehaviorPolicyLines, DEFAULT_PARTICIPATION_HISTORY_FETCH_LIMIT, evaluateParticipationPolicy, getDefaultParticipationPolicy, resolveAgentBehaviorPolicy, } from './policy.js';
|
|
14
14
|
export { DEFAULT_RUNTIME_CAPABILITIES, HOST_ADMISSION_ACTION_CAPABILITIES, HOST_ADMISSION_ACTIONS_DISABLED, FINAL_MESSAGE_HANDOFF_MS, isTurnOpen, normalizeTurnMetadata, normalizeTurnState, resolveTurnMessageSemantics, shouldPromoteConversationMessage, shouldTriggerAgentTurn, } from './turn-protocol.js';
|
|
15
15
|
export type { DeliveryIntent, TurnMessageSemantics, InboundDisposition, TurnLifecycleState, RuntimeCapabilities, HostAdmissionActionCapabilities, TurnState, TurnMetadata, TriggerDecision, } from './turn-protocol.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Types
|
|
2
2
|
export { AGENT_CAPABILITIES, CLAUDE_PERMISSION_MODE_OPTIONS, } from './types.js';
|
|
3
|
-
export {
|
|
3
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
4
4
|
export { buildConfiguredWorkspaceOptionsWithRoots, buildPublicWorkspaceRoots, buildWorkspaceRootId, discoverWorkspaceProjects, } from './workspace-discovery.js';
|
|
5
5
|
// Client
|
|
6
6
|
export { CanonClient, CanonApiError } from './client.js';
|
package/dist/policy.d.ts
CHANGED
|
@@ -67,16 +67,6 @@ export interface ParticipationPolicy {
|
|
|
67
67
|
requireMentionForGroupReplies: boolean;
|
|
68
68
|
maxConsecutiveAgentTurns?: number | null;
|
|
69
69
|
}
|
|
70
|
-
export interface WorkSession {
|
|
71
|
-
id: string;
|
|
72
|
-
conversationId?: string | null;
|
|
73
|
-
label?: string | null;
|
|
74
|
-
objective?: string | null;
|
|
75
|
-
participationStyle?: ParticipationStyle;
|
|
76
|
-
activeParticipantIds: string[];
|
|
77
|
-
overlayIds?: string[];
|
|
78
|
-
status: "active" | "paused" | "completed";
|
|
79
|
-
}
|
|
80
70
|
export interface ResolvedPolicy {
|
|
81
71
|
admission: AdmissionPolicy;
|
|
82
72
|
runtime: RuntimeControlPolicy;
|
|
@@ -90,7 +80,6 @@ export interface ResolvedPolicy {
|
|
|
90
80
|
globalDefault?: string;
|
|
91
81
|
agentDefault?: string;
|
|
92
82
|
relationship?: string;
|
|
93
|
-
workSession?: string;
|
|
94
83
|
messageDirective?: string;
|
|
95
84
|
};
|
|
96
85
|
}
|
package/dist/reach-out.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanonResolveAdmissionResult, CreateContactRequestResult, CreateConversationOptions, SendMessageOptions } from './types.js';
|
|
1
|
+
import type { CanonResolveAdmissionResult, CreateContactRequestResult, CreateConversationOptions, SendMessageOptions, SessionConfig } from './types.js';
|
|
2
2
|
export interface CanonReachOutClient {
|
|
3
3
|
resolveAdmission(targetUserId: string): Promise<CanonResolveAdmissionResult>;
|
|
4
4
|
createConversation(options: CreateConversationOptions): Promise<{
|
|
@@ -14,6 +14,7 @@ export interface CanonReachOutOptions {
|
|
|
14
14
|
text?: string | null;
|
|
15
15
|
requestMessage?: string | null;
|
|
16
16
|
sendMessageOptions?: SendMessageOptions;
|
|
17
|
+
sessionConfig?: SessionConfig | null;
|
|
17
18
|
}
|
|
18
19
|
export type CanonReachOutResult = {
|
|
19
20
|
status: 'messaged';
|
|
@@ -25,6 +26,9 @@ export type CanonReachOutResult = {
|
|
|
25
26
|
} | {
|
|
26
27
|
status: 'pending';
|
|
27
28
|
requestId: string | null;
|
|
29
|
+
} | {
|
|
30
|
+
status: 'setup_required';
|
|
31
|
+
reason: string;
|
|
28
32
|
} | {
|
|
29
33
|
status: 'blocked' | 'unavailable';
|
|
30
34
|
reason: string;
|
package/dist/reach-out.js
CHANGED
|
@@ -11,6 +11,12 @@ function normalizeContactRequestMessage(requestMessage, fallbackText) {
|
|
|
11
11
|
return text;
|
|
12
12
|
return `${text.slice(0, CONTACT_REQUEST_MESSAGE_LIMIT - 3)}...`;
|
|
13
13
|
}
|
|
14
|
+
function optionsForResolvedTarget(options, targetUserType) {
|
|
15
|
+
if (options.sessionConfig && targetUserType === 'human') {
|
|
16
|
+
return { ...options, sessionConfig: null };
|
|
17
|
+
}
|
|
18
|
+
return options;
|
|
19
|
+
}
|
|
14
20
|
function isConnectionRequiredError(error) {
|
|
15
21
|
const status = error && typeof error === 'object' && 'status' in error
|
|
16
22
|
? Number(error.status)
|
|
@@ -18,10 +24,34 @@ function isConnectionRequiredError(error) {
|
|
|
18
24
|
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
19
25
|
return status === 403 && /CONNECTION_REQUIRED|connection required/i.test(message);
|
|
20
26
|
}
|
|
27
|
+
function isSessionSetupRequiredError(error) {
|
|
28
|
+
const status = error && typeof error === 'object' && 'status' in error
|
|
29
|
+
? Number(error.status)
|
|
30
|
+
: null;
|
|
31
|
+
if (status !== 400 && status !== 403)
|
|
32
|
+
return null;
|
|
33
|
+
const rawMessage = error instanceof Error ? error.message : String(error ?? '');
|
|
34
|
+
const message = rawMessage.replace(/^Canon API error \d+:\s*/i, '').trim();
|
|
35
|
+
const parsed = (() => {
|
|
36
|
+
try {
|
|
37
|
+
const value = JSON.parse(message);
|
|
38
|
+
return typeof value.error === 'string' ? value.error : message;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return message;
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
if (/session config|execution mode|coding session|worktree|workspace|permission mode|agent owner|runtime unavailable|unsupported control|invalid .*mode|invalid .*model/i
|
|
45
|
+
.test(parsed)) {
|
|
46
|
+
return parsed || 'Agent session setup is required.';
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
21
50
|
async function openConversationAndMaybeMessage(client, options) {
|
|
22
51
|
const { conversationId } = await client.createConversation({
|
|
23
52
|
type: 'direct',
|
|
24
53
|
targetUserId: options.targetUserId,
|
|
54
|
+
...(options.sessionConfig ? { sessionConfig: options.sessionConfig } : {}),
|
|
25
55
|
});
|
|
26
56
|
const text = normalizeOptionalText(options.text);
|
|
27
57
|
if (text) {
|
|
@@ -35,7 +65,16 @@ async function openConversationAndMaybeMessage(client, options) {
|
|
|
35
65
|
async function requestContact(client, options) {
|
|
36
66
|
const result = await client.createContactRequest(options.targetUserId, normalizeContactRequestMessage(options.requestMessage, options.text));
|
|
37
67
|
if (result.status === 'open') {
|
|
38
|
-
|
|
68
|
+
try {
|
|
69
|
+
return await openConversationAndMaybeMessage(client, { ...options, requestMessage: null });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const setupReason = isSessionSetupRequiredError(error);
|
|
73
|
+
if (setupReason) {
|
|
74
|
+
return { status: 'setup_required', reason: setupReason };
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
39
78
|
}
|
|
40
79
|
if (result.status === 'duplicate') {
|
|
41
80
|
return { status: 'pending', requestId: result.requestId };
|
|
@@ -48,14 +87,19 @@ async function requestContact(client, options) {
|
|
|
48
87
|
* their product behavior is "message if reachable, otherwise request access."
|
|
49
88
|
*/
|
|
50
89
|
export async function reachOutToCanonContact(client, options) {
|
|
51
|
-
const { admission } = await client.resolveAdmission(options.targetUserId);
|
|
90
|
+
const { target, admission } = await client.resolveAdmission(options.targetUserId);
|
|
91
|
+
const resolvedOptions = optionsForResolvedTarget(options, target?.userType);
|
|
52
92
|
if (admission.state === 'allowed' && admission.canMessage) {
|
|
53
93
|
try {
|
|
54
|
-
return await openConversationAndMaybeMessage(client,
|
|
94
|
+
return await openConversationAndMaybeMessage(client, resolvedOptions);
|
|
55
95
|
}
|
|
56
96
|
catch (error) {
|
|
97
|
+
const setupReason = isSessionSetupRequiredError(error);
|
|
98
|
+
if (setupReason) {
|
|
99
|
+
return { status: 'setup_required', reason: setupReason };
|
|
100
|
+
}
|
|
57
101
|
if (isConnectionRequiredError(error)) {
|
|
58
|
-
return requestContact(client,
|
|
102
|
+
return requestContact(client, resolvedOptions);
|
|
59
103
|
}
|
|
60
104
|
throw error;
|
|
61
105
|
}
|
|
@@ -64,7 +108,7 @@ export async function reachOutToCanonContact(client, options) {
|
|
|
64
108
|
return { status: 'pending', requestId: admission.pendingRequestId ?? null };
|
|
65
109
|
}
|
|
66
110
|
if (admission.state === 'request-required' && admission.canRequestContact) {
|
|
67
|
-
return requestContact(client,
|
|
111
|
+
return requestContact(client, resolvedOptions);
|
|
68
112
|
}
|
|
69
113
|
if (admission.state === 'blocked') {
|
|
70
114
|
return { status: 'blocked', reason: 'blocked' };
|
package/dist/rtdb-rest.d.ts
CHANGED
|
@@ -91,13 +91,6 @@ export interface AgentSessionSnapshotPatch {
|
|
|
91
91
|
lastHeartbeatAt?: number | {
|
|
92
92
|
'.sv': 'timestamp';
|
|
93
93
|
};
|
|
94
|
-
workSession?: {
|
|
95
|
-
count: number;
|
|
96
|
-
id: string;
|
|
97
|
-
title?: string | null;
|
|
98
|
-
objective?: string | null;
|
|
99
|
-
status?: string | null;
|
|
100
|
-
} | null;
|
|
101
94
|
updatedAt?: {
|
|
102
95
|
'.sv': 'timestamp';
|
|
103
96
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type CanonSelfContextType = 'cross_session';
|
|
2
|
+
export interface CanonSelfContext {
|
|
3
|
+
id: string;
|
|
4
|
+
type: CanonSelfContextType;
|
|
5
|
+
context: string;
|
|
6
|
+
createdAt?: string | null;
|
|
7
|
+
updatedAt?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface SendContextualSelfContextInput {
|
|
10
|
+
type: CanonSelfContextType;
|
|
11
|
+
context: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SendContextualMessageOptions {
|
|
14
|
+
sourceConversationId: string;
|
|
15
|
+
targetConversationId?: string;
|
|
16
|
+
targetUserId?: string;
|
|
17
|
+
text: string;
|
|
18
|
+
selfContext: SendContextualSelfContextInput;
|
|
19
|
+
sessionConfig?: import('./types.js').SessionConfig | null;
|
|
20
|
+
requestMessage?: string | null;
|
|
21
|
+
messageOptions?: Omit<import('./types.js').SendMessageOptions, 'selfContextId' | 'selfContext'>;
|
|
22
|
+
}
|
|
23
|
+
export type SendContextualMessageResult = {
|
|
24
|
+
status: 'messaged';
|
|
25
|
+
messageId: string;
|
|
26
|
+
conversationId: string;
|
|
27
|
+
selfContextId: string;
|
|
28
|
+
} | {
|
|
29
|
+
status: 'requested' | 'pending';
|
|
30
|
+
requestId: string | null;
|
|
31
|
+
} | {
|
|
32
|
+
status: 'setup_required' | 'blocked' | 'unavailable';
|
|
33
|
+
reason: string;
|
|
34
|
+
};
|
|
35
|
+
export interface SelfContextPromptRenderOptions {
|
|
36
|
+
maxSelfContexts?: number;
|
|
37
|
+
}
|
|
38
|
+
export declare function normalizeSelfContexts(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions): CanonSelfContext[];
|
|
39
|
+
export declare function buildSelfContextPromptLines(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions): string[];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const DEFAULT_SELF_CONTEXT_PROMPT_OPTIONS = {
|
|
2
|
+
maxSelfContexts: 3,
|
|
3
|
+
};
|
|
4
|
+
function normalizeString(value) {
|
|
5
|
+
if (typeof value !== 'string')
|
|
6
|
+
return null;
|
|
7
|
+
const trimmed = value.trim();
|
|
8
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
9
|
+
}
|
|
10
|
+
function resolvePromptOptions(options) {
|
|
11
|
+
return {
|
|
12
|
+
maxSelfContexts: Math.max(1, options?.maxSelfContexts ?? DEFAULT_SELF_CONTEXT_PROMPT_OPTIONS.maxSelfContexts),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function contextSortTime(context) {
|
|
16
|
+
const updatedAt = normalizeString(context.updatedAt);
|
|
17
|
+
if (updatedAt) {
|
|
18
|
+
const parsed = new Date(updatedAt).getTime();
|
|
19
|
+
if (Number.isFinite(parsed))
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
const createdAt = normalizeString(context.createdAt);
|
|
23
|
+
if (createdAt) {
|
|
24
|
+
const parsed = new Date(createdAt).getTime();
|
|
25
|
+
if (Number.isFinite(parsed))
|
|
26
|
+
return parsed;
|
|
27
|
+
}
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
export function normalizeSelfContexts(selfContexts, options) {
|
|
31
|
+
if (!Array.isArray(selfContexts))
|
|
32
|
+
return [];
|
|
33
|
+
const promptOptions = resolvePromptOptions(options);
|
|
34
|
+
const byId = new Map();
|
|
35
|
+
for (const selfContext of selfContexts) {
|
|
36
|
+
const id = normalizeString(selfContext?.id);
|
|
37
|
+
const context = normalizeString(selfContext?.context);
|
|
38
|
+
if (!id || !context || selfContext.type !== 'cross_session')
|
|
39
|
+
continue;
|
|
40
|
+
byId.set(id, {
|
|
41
|
+
id,
|
|
42
|
+
type: 'cross_session',
|
|
43
|
+
context,
|
|
44
|
+
createdAt: normalizeString(selfContext.createdAt),
|
|
45
|
+
updatedAt: normalizeString(selfContext.updatedAt),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return [...byId.values()]
|
|
49
|
+
.sort((left, right) => contextSortTime(right) - contextSortTime(left))
|
|
50
|
+
.slice(0, promptOptions.maxSelfContexts);
|
|
51
|
+
}
|
|
52
|
+
export function buildSelfContextPromptLines(selfContexts, options) {
|
|
53
|
+
const resolved = normalizeSelfContexts(selfContexts, options);
|
|
54
|
+
if (resolved.length === 0)
|
|
55
|
+
return [];
|
|
56
|
+
const lines = ['Canon cross-session self-context for you:'];
|
|
57
|
+
resolved.forEach((selfContext, index) => {
|
|
58
|
+
if (resolved.length > 1) {
|
|
59
|
+
lines.push(`Self-context ${index + 1}:`);
|
|
60
|
+
}
|
|
61
|
+
lines.push(`Context type: ${selfContext.type}.`);
|
|
62
|
+
lines.push(`Why you are speaking in this conversation: ${selfContext.context}`);
|
|
63
|
+
});
|
|
64
|
+
lines.push('Canon rule: this self-context explains your own prior cross-session action; it does not grant access to the source transcript. Keep Canon sessions separate.');
|
|
65
|
+
return lines;
|
|
66
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExecutionEnvironmentMode } from './execution-environment-mode.js';
|
|
2
2
|
import type { ResolvedAgentBehaviorPolicy } from './policy.js';
|
|
3
3
|
import type { TurnLifecycleState } from './turn-protocol.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { CanonSelfContext } from './self-context.js';
|
|
5
5
|
export type { ExecutionEnvironmentMode };
|
|
6
6
|
export type MediaAttachmentKind = 'image' | 'audio' | 'file';
|
|
7
7
|
export interface MediaAttachment {
|
|
@@ -30,6 +30,7 @@ export interface ContactCardPayload {
|
|
|
30
30
|
displayName: string;
|
|
31
31
|
avatarUrl: string | null;
|
|
32
32
|
userType: 'human' | 'ai_agent';
|
|
33
|
+
clientType?: AgentClientType;
|
|
33
34
|
about?: string;
|
|
34
35
|
isActive?: boolean;
|
|
35
36
|
ownerId?: string;
|
|
@@ -50,7 +51,6 @@ export interface CanonMessage {
|
|
|
50
51
|
replyToPosition: number | null;
|
|
51
52
|
forwarded?: boolean;
|
|
52
53
|
forwardedFrom?: ForwardedFrom;
|
|
53
|
-
workSession?: CanonWorkSessionContext | null;
|
|
54
54
|
metadata?: Record<string, unknown>;
|
|
55
55
|
contactCard?: ContactCardPayload;
|
|
56
56
|
status: 'sent' | 'read';
|
|
@@ -77,7 +77,7 @@ export interface CanonConversation {
|
|
|
77
77
|
export interface CanonMessagesPage {
|
|
78
78
|
messages: CanonMessage[];
|
|
79
79
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
80
|
-
|
|
80
|
+
selfContexts?: CanonSelfContext[];
|
|
81
81
|
}
|
|
82
82
|
export type CanonContactRequestStatus = 'pending' | 'approved' | 'rejected' | 'expired';
|
|
83
83
|
export interface CanonContactRequest {
|
|
@@ -354,7 +354,7 @@ export interface AgentContext {
|
|
|
354
354
|
export interface MessageCreatedPayload {
|
|
355
355
|
conversationId: string;
|
|
356
356
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
357
|
-
|
|
357
|
+
selfContexts?: CanonSelfContext[];
|
|
358
358
|
message: {
|
|
359
359
|
id: string;
|
|
360
360
|
senderId: string;
|
|
@@ -371,7 +371,6 @@ export interface MessageCreatedPayload {
|
|
|
371
371
|
forwardedFrom?: ForwardedFrom;
|
|
372
372
|
mentions?: string[];
|
|
373
373
|
createdAt?: string;
|
|
374
|
-
workSession?: CanonWorkSessionContext | null;
|
|
375
374
|
/** Structured metadata for rich UI (approval cards, etc.) */
|
|
376
375
|
metadata?: Record<string, unknown>;
|
|
377
376
|
/** Populated when `contentType === 'contact_card'`. */
|
|
@@ -452,7 +451,7 @@ export interface SendMessageOptions {
|
|
|
452
451
|
attachments?: MediaAttachment[];
|
|
453
452
|
contactCardUserId?: string;
|
|
454
453
|
mentions?: string[];
|
|
455
|
-
|
|
454
|
+
selfContextId?: string;
|
|
456
455
|
/** Structured metadata for rich UI (approval cards, etc.) */
|
|
457
456
|
metadata?: Record<string, unknown>;
|
|
458
457
|
}
|
|
@@ -461,6 +460,8 @@ export interface CreateConversationOptions {
|
|
|
461
460
|
targetUserId?: string;
|
|
462
461
|
memberIds?: string[];
|
|
463
462
|
name?: string;
|
|
463
|
+
/** Required when creating a direct conversation with a first-party coding agent. */
|
|
464
|
+
sessionConfig?: SessionConfig | null;
|
|
464
465
|
}
|
|
465
466
|
export type StreamingStatus = 'thinking' | 'streaming' | 'tool';
|
|
466
467
|
export interface SetStreamingOptions {
|
|
@@ -574,13 +575,6 @@ export interface AgentRuntime {
|
|
|
574
575
|
availableWorkspaces?: WorkspaceOption[];
|
|
575
576
|
updatedAt?: number;
|
|
576
577
|
}
|
|
577
|
-
export interface AgentSessionWorkSessionSummary {
|
|
578
|
-
count: number;
|
|
579
|
-
id: string;
|
|
580
|
-
title?: string | null;
|
|
581
|
-
objective?: string | null;
|
|
582
|
-
status?: CanonWorkSessionContext['status'] | null;
|
|
583
|
-
}
|
|
584
578
|
export interface AgentSessionSnapshot {
|
|
585
579
|
conversationId: string;
|
|
586
580
|
agentId: string;
|
|
@@ -612,7 +606,6 @@ export interface AgentSessionSnapshot {
|
|
|
612
606
|
contextUsage?: SessionState['contextUsage'];
|
|
613
607
|
lastError?: string;
|
|
614
608
|
lastHeartbeatAt?: number;
|
|
615
|
-
workSession?: AgentSessionWorkSessionSummary | null;
|
|
616
609
|
updatedAt?: number;
|
|
617
610
|
}
|
|
618
611
|
export interface RegistrationInput {
|
package/package.json
CHANGED
package/dist/work-session.d.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { RepresentationMode } from './policy.js';
|
|
2
|
-
import type { SendMessageOptions } from './types.js';
|
|
3
|
-
export type CanonWorkSessionStatus = 'active' | 'paused' | 'completed';
|
|
4
|
-
export type CanonWorkSessionConversationRole = 'requester' | 'coordinator' | 'participant' | 'delegate' | 'observer';
|
|
5
|
-
export type CanonWorkSessionDisclosureMode = 'none' | 'summary' | 'full';
|
|
6
|
-
export interface CanonWorkSessionParticipant {
|
|
7
|
-
conversationId?: string | null;
|
|
8
|
-
participantId?: string | null;
|
|
9
|
-
label?: string | null;
|
|
10
|
-
role?: CanonWorkSessionConversationRole | null;
|
|
11
|
-
}
|
|
12
|
-
export interface CanonWorkSessionContext {
|
|
13
|
-
id: string;
|
|
14
|
-
title?: string | null;
|
|
15
|
-
objective?: string | null;
|
|
16
|
-
status?: CanonWorkSessionStatus | null;
|
|
17
|
-
summary?: string | null;
|
|
18
|
-
representation?: RepresentationMode | null;
|
|
19
|
-
currentConversationRole?: CanonWorkSessionConversationRole | null;
|
|
20
|
-
sourceConversationId?: string | null;
|
|
21
|
-
sourceConversationLabel?: string | null;
|
|
22
|
-
sourceParticipantId?: string | null;
|
|
23
|
-
sourceParticipantLabel?: string | null;
|
|
24
|
-
disclosure?: CanonWorkSessionDisclosureMode | null;
|
|
25
|
-
disclosureNotes?: string[];
|
|
26
|
-
visibleFacts?: string[];
|
|
27
|
-
pendingQuestions?: string[];
|
|
28
|
-
participants?: CanonWorkSessionParticipant[];
|
|
29
|
-
updatedAt?: string | null;
|
|
30
|
-
}
|
|
31
|
-
export interface CanonWorkSession {
|
|
32
|
-
id: string;
|
|
33
|
-
title?: string | null;
|
|
34
|
-
objective?: string | null;
|
|
35
|
-
status: CanonWorkSessionStatus;
|
|
36
|
-
createdAt?: string | null;
|
|
37
|
-
updatedAt?: string | null;
|
|
38
|
-
}
|
|
39
|
-
export interface UpdateWorkSessionConversationOptions {
|
|
40
|
-
summary?: string | null;
|
|
41
|
-
representation?: RepresentationMode | null;
|
|
42
|
-
currentConversationRole?: CanonWorkSessionConversationRole | null;
|
|
43
|
-
sourceConversationId?: string | null;
|
|
44
|
-
sourceConversationLabel?: string | null;
|
|
45
|
-
sourceParticipantId?: string | null;
|
|
46
|
-
sourceParticipantLabel?: string | null;
|
|
47
|
-
disclosure?: CanonWorkSessionDisclosureMode | null;
|
|
48
|
-
disclosureNotes?: string[];
|
|
49
|
-
visibleFacts?: string[];
|
|
50
|
-
pendingQuestions?: string[];
|
|
51
|
-
participants?: CanonWorkSessionParticipant[];
|
|
52
|
-
}
|
|
53
|
-
export interface CreateWorkSessionOptions extends UpdateWorkSessionConversationOptions {
|
|
54
|
-
conversationId: string;
|
|
55
|
-
title?: string | null;
|
|
56
|
-
objective?: string | null;
|
|
57
|
-
status?: CanonWorkSessionStatus | null;
|
|
58
|
-
}
|
|
59
|
-
export interface CanonResolvedWorkSession {
|
|
60
|
-
workSession: CanonWorkSession;
|
|
61
|
-
context: CanonWorkSessionContext;
|
|
62
|
-
}
|
|
63
|
-
export interface SendLinkedMessageOptions {
|
|
64
|
-
sourceConversationId: string;
|
|
65
|
-
targetConversationId: string;
|
|
66
|
-
text: string;
|
|
67
|
-
workSessionId?: string;
|
|
68
|
-
createWorkSession?: Omit<CreateWorkSessionOptions, 'conversationId'>;
|
|
69
|
-
sourceContext?: UpdateWorkSessionConversationOptions;
|
|
70
|
-
targetContext?: UpdateWorkSessionConversationOptions;
|
|
71
|
-
messageOptions?: Omit<SendMessageOptions, 'workSessionId'>;
|
|
72
|
-
}
|
|
73
|
-
export interface SendLinkedMessageResult {
|
|
74
|
-
messageId: string;
|
|
75
|
-
workSessionId: string;
|
|
76
|
-
workSessionCreated: boolean;
|
|
77
|
-
}
|
|
78
|
-
export interface WorkSessionPromptRenderOptions {
|
|
79
|
-
maxVisibleFacts?: number;
|
|
80
|
-
maxPendingQuestions?: number;
|
|
81
|
-
maxDisclosureNotes?: number;
|
|
82
|
-
maxParticipants?: number;
|
|
83
|
-
maxDetailedWorkSessions?: number;
|
|
84
|
-
maxOtherWorkSessions?: number;
|
|
85
|
-
}
|
|
86
|
-
export declare function mergeWorkSessionContexts(explicitWorkSession?: CanonWorkSessionContext | null, activeWorkSessions?: CanonWorkSessionContext[] | null): CanonWorkSessionContext[];
|
|
87
|
-
export declare function buildWorkSessionPromptLines(workSession?: CanonWorkSessionContext | null, options?: WorkSessionPromptRenderOptions): string[];
|
|
88
|
-
export declare function buildWorkSessionsPromptLines(workSessions?: CanonWorkSessionContext[] | null, options?: WorkSessionPromptRenderOptions): string[];
|
package/dist/work-session.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
const DEFAULT_WORK_SESSION_PROMPT_OPTIONS = {
|
|
2
|
-
maxVisibleFacts: 3,
|
|
3
|
-
maxPendingQuestions: 2,
|
|
4
|
-
maxDisclosureNotes: 1,
|
|
5
|
-
maxParticipants: 3,
|
|
6
|
-
maxDetailedWorkSessions: 1,
|
|
7
|
-
maxOtherWorkSessions: 3,
|
|
8
|
-
};
|
|
9
|
-
function normalizeString(value) {
|
|
10
|
-
if (typeof value !== 'string')
|
|
11
|
-
return null;
|
|
12
|
-
const trimmed = value.trim();
|
|
13
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
14
|
-
}
|
|
15
|
-
function normalizeStringList(value) {
|
|
16
|
-
if (!Array.isArray(value))
|
|
17
|
-
return [];
|
|
18
|
-
return value
|
|
19
|
-
.map((entry) => normalizeString(entry))
|
|
20
|
-
.filter((entry) => entry != null);
|
|
21
|
-
}
|
|
22
|
-
function mergeStringLists(primary, secondary) {
|
|
23
|
-
const merged = [...normalizeStringList(primary), ...normalizeStringList(secondary)];
|
|
24
|
-
const unique = Array.from(new Set(merged));
|
|
25
|
-
return unique.length > 0 ? unique : undefined;
|
|
26
|
-
}
|
|
27
|
-
function mergeParticipants(primary, secondary) {
|
|
28
|
-
const result = [];
|
|
29
|
-
const seen = new Set();
|
|
30
|
-
const pushParticipant = (participant) => {
|
|
31
|
-
if (!participant)
|
|
32
|
-
return;
|
|
33
|
-
const key = [
|
|
34
|
-
normalizeString(participant.conversationId),
|
|
35
|
-
normalizeString(participant.participantId),
|
|
36
|
-
normalizeString(participant.label),
|
|
37
|
-
normalizeString(participant.role),
|
|
38
|
-
].join('::');
|
|
39
|
-
if (seen.has(key))
|
|
40
|
-
return;
|
|
41
|
-
seen.add(key);
|
|
42
|
-
result.push(participant);
|
|
43
|
-
};
|
|
44
|
-
for (const participant of primary ?? [])
|
|
45
|
-
pushParticipant(participant);
|
|
46
|
-
for (const participant of secondary ?? [])
|
|
47
|
-
pushParticipant(participant);
|
|
48
|
-
return result.length > 0 ? result : undefined;
|
|
49
|
-
}
|
|
50
|
-
function mergeTwoWorkSessions(primary, secondary) {
|
|
51
|
-
const disclosureNotes = mergeStringLists(primary.disclosureNotes, secondary.disclosureNotes);
|
|
52
|
-
const visibleFacts = mergeStringLists(primary.visibleFacts, secondary.visibleFacts);
|
|
53
|
-
const pendingQuestions = mergeStringLists(primary.pendingQuestions, secondary.pendingQuestions);
|
|
54
|
-
const participants = mergeParticipants(primary.participants, secondary.participants);
|
|
55
|
-
return {
|
|
56
|
-
id: primary.id,
|
|
57
|
-
title: primary.title ?? secondary.title ?? null,
|
|
58
|
-
objective: primary.objective ?? secondary.objective ?? null,
|
|
59
|
-
status: primary.status ?? secondary.status ?? null,
|
|
60
|
-
summary: primary.summary ?? secondary.summary ?? null,
|
|
61
|
-
representation: primary.representation ?? secondary.representation ?? null,
|
|
62
|
-
currentConversationRole: primary.currentConversationRole ?? secondary.currentConversationRole ?? null,
|
|
63
|
-
sourceConversationId: primary.sourceConversationId ?? secondary.sourceConversationId ?? null,
|
|
64
|
-
sourceConversationLabel: primary.sourceConversationLabel ?? secondary.sourceConversationLabel ?? null,
|
|
65
|
-
sourceParticipantId: primary.sourceParticipantId ?? secondary.sourceParticipantId ?? null,
|
|
66
|
-
sourceParticipantLabel: primary.sourceParticipantLabel ?? secondary.sourceParticipantLabel ?? null,
|
|
67
|
-
disclosure: primary.disclosure ?? secondary.disclosure ?? null,
|
|
68
|
-
...(disclosureNotes ? { disclosureNotes } : {}),
|
|
69
|
-
...(visibleFacts ? { visibleFacts } : {}),
|
|
70
|
-
...(pendingQuestions ? { pendingQuestions } : {}),
|
|
71
|
-
...(participants ? { participants } : {}),
|
|
72
|
-
updatedAt: primary.updatedAt ?? secondary.updatedAt ?? null,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
export function mergeWorkSessionContexts(explicitWorkSession, activeWorkSessions) {
|
|
76
|
-
const merged = new Map();
|
|
77
|
-
const add = (workSession) => {
|
|
78
|
-
if (!workSession?.id)
|
|
79
|
-
return;
|
|
80
|
-
const existing = merged.get(workSession.id);
|
|
81
|
-
merged.set(workSession.id, existing ? mergeTwoWorkSessions(existing, workSession) : workSession);
|
|
82
|
-
};
|
|
83
|
-
add(explicitWorkSession);
|
|
84
|
-
for (const workSession of activeWorkSessions ?? []) {
|
|
85
|
-
add(workSession);
|
|
86
|
-
}
|
|
87
|
-
return Array.from(merged.values());
|
|
88
|
-
}
|
|
89
|
-
function formatParticipantLabel(participant) {
|
|
90
|
-
const label = normalizeString(participant.label);
|
|
91
|
-
if (label)
|
|
92
|
-
return label;
|
|
93
|
-
const participantId = normalizeString(participant.participantId);
|
|
94
|
-
if (participantId)
|
|
95
|
-
return participantId;
|
|
96
|
-
return normalizeString(participant.conversationId);
|
|
97
|
-
}
|
|
98
|
-
function resolvePromptOptions(options) {
|
|
99
|
-
return {
|
|
100
|
-
maxVisibleFacts: Math.max(0, options?.maxVisibleFacts
|
|
101
|
-
?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxVisibleFacts),
|
|
102
|
-
maxPendingQuestions: Math.max(0, options?.maxPendingQuestions
|
|
103
|
-
?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxPendingQuestions),
|
|
104
|
-
maxDisclosureNotes: Math.max(0, options?.maxDisclosureNotes
|
|
105
|
-
?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxDisclosureNotes),
|
|
106
|
-
maxParticipants: Math.max(0, options?.maxParticipants ?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxParticipants),
|
|
107
|
-
maxDetailedWorkSessions: Math.max(1, options?.maxDetailedWorkSessions
|
|
108
|
-
?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxDetailedWorkSessions),
|
|
109
|
-
maxOtherWorkSessions: Math.max(0, options?.maxOtherWorkSessions
|
|
110
|
-
?? DEFAULT_WORK_SESSION_PROMPT_OPTIONS.maxOtherWorkSessions),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function takeWithHiddenCount(values, maxCount) {
|
|
114
|
-
if (maxCount <= 0) {
|
|
115
|
-
return { visible: [], hiddenCount: values.length };
|
|
116
|
-
}
|
|
117
|
-
return {
|
|
118
|
-
visible: values.slice(0, maxCount),
|
|
119
|
-
hiddenCount: Math.max(0, values.length - maxCount),
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
function buildOriginLabel(workSession) {
|
|
123
|
-
const sourceConversation = normalizeString(workSession.sourceConversationLabel)
|
|
124
|
-
?? normalizeString(workSession.sourceConversationId);
|
|
125
|
-
const sourceParticipant = normalizeString(workSession.sourceParticipantLabel)
|
|
126
|
-
?? normalizeString(workSession.sourceParticipantId);
|
|
127
|
-
if (sourceConversation && sourceParticipant) {
|
|
128
|
-
return `${sourceParticipant} in ${sourceConversation}`;
|
|
129
|
-
}
|
|
130
|
-
return sourceParticipant ?? sourceConversation;
|
|
131
|
-
}
|
|
132
|
-
function formatWorkSessionReference(workSession) {
|
|
133
|
-
const title = normalizeString(workSession.title);
|
|
134
|
-
const objective = normalizeString(workSession.objective);
|
|
135
|
-
if (title)
|
|
136
|
-
return `${title} (${workSession.id})`;
|
|
137
|
-
if (objective)
|
|
138
|
-
return `${objective} (${workSession.id})`;
|
|
139
|
-
return workSession.id;
|
|
140
|
-
}
|
|
141
|
-
export function buildWorkSessionPromptLines(workSession, options) {
|
|
142
|
-
if (!workSession)
|
|
143
|
-
return [];
|
|
144
|
-
const promptOptions = resolvePromptOptions(options);
|
|
145
|
-
const title = normalizeString(workSession.title);
|
|
146
|
-
const objective = normalizeString(workSession.objective);
|
|
147
|
-
const summary = normalizeString(workSession.summary);
|
|
148
|
-
const origin = buildOriginLabel(workSession);
|
|
149
|
-
const visibleFacts = takeWithHiddenCount(normalizeStringList(workSession.visibleFacts), promptOptions.maxVisibleFacts);
|
|
150
|
-
const pendingQuestions = takeWithHiddenCount(normalizeStringList(workSession.pendingQuestions), promptOptions.maxPendingQuestions);
|
|
151
|
-
const disclosureNotes = takeWithHiddenCount(normalizeStringList(workSession.disclosureNotes), promptOptions.maxDisclosureNotes);
|
|
152
|
-
const participants = takeWithHiddenCount(Array.isArray(workSession.participants) ? workSession.participants : [], promptOptions.maxParticipants);
|
|
153
|
-
return [
|
|
154
|
-
`Canon work session ID: ${workSession.id}`,
|
|
155
|
-
...(title ? [`Canon work session title: ${title}`] : []),
|
|
156
|
-
...(objective ? [`Canon work session objective: ${objective}`] : []),
|
|
157
|
-
...(workSession.status
|
|
158
|
-
? [`Canon work session status: ${workSession.status}`]
|
|
159
|
-
: []),
|
|
160
|
-
...(workSession.currentConversationRole
|
|
161
|
-
? [
|
|
162
|
-
`This conversation's role in the work session: ${workSession.currentConversationRole}`,
|
|
163
|
-
]
|
|
164
|
-
: []),
|
|
165
|
-
...(workSession.representation
|
|
166
|
-
? [`Participate in this conversation as: ${workSession.representation}`]
|
|
167
|
-
: []),
|
|
168
|
-
...(origin ? [`Work session origin: ${origin}`] : []),
|
|
169
|
-
...(workSession.disclosure
|
|
170
|
-
? [`Allowed disclosure level in this conversation: ${workSession.disclosure}`]
|
|
171
|
-
: []),
|
|
172
|
-
...(summary ? [`Shared work session summary: ${summary}`] : []),
|
|
173
|
-
...visibleFacts.visible.map((fact, index) => `Shared fact ${index + 1}: ${fact}`),
|
|
174
|
-
...(visibleFacts.hiddenCount > 0
|
|
175
|
-
? [`Additional shared facts omitted for brevity: ${visibleFacts.hiddenCount}`]
|
|
176
|
-
: []),
|
|
177
|
-
...pendingQuestions.visible.map((question, index) => `Open question ${index + 1}: ${question}`),
|
|
178
|
-
...(pendingQuestions.hiddenCount > 0
|
|
179
|
-
? [
|
|
180
|
-
`Additional open questions omitted for brevity: ${pendingQuestions.hiddenCount}`,
|
|
181
|
-
]
|
|
182
|
-
: []),
|
|
183
|
-
...disclosureNotes.visible.map((note, index) => `Disclosure note ${index + 1}: ${note}`),
|
|
184
|
-
...(disclosureNotes.hiddenCount > 0
|
|
185
|
-
? [
|
|
186
|
-
`Additional disclosure notes omitted for brevity: ${disclosureNotes.hiddenCount}`,
|
|
187
|
-
]
|
|
188
|
-
: []),
|
|
189
|
-
...participants.visible.flatMap((participant, index) => {
|
|
190
|
-
const label = formatParticipantLabel(participant);
|
|
191
|
-
if (!label)
|
|
192
|
-
return [];
|
|
193
|
-
const role = normalizeString(participant.role);
|
|
194
|
-
return [
|
|
195
|
-
`Related participant ${index + 1}: ${label}${role ? ` (${role})` : ''}`,
|
|
196
|
-
];
|
|
197
|
-
}),
|
|
198
|
-
...(participants.hiddenCount > 0
|
|
199
|
-
? [
|
|
200
|
-
`Additional related participants omitted for brevity: ${participants.hiddenCount}`,
|
|
201
|
-
]
|
|
202
|
-
: []),
|
|
203
|
-
'Canon rule: this shared work-session context is scoped to this conversation only and does not grant access to other conversation transcripts.',
|
|
204
|
-
];
|
|
205
|
-
}
|
|
206
|
-
export function buildWorkSessionsPromptLines(workSessions, options) {
|
|
207
|
-
const promptOptions = resolvePromptOptions(options);
|
|
208
|
-
if (!Array.isArray(workSessions) || workSessions.length === 0)
|
|
209
|
-
return [];
|
|
210
|
-
if (workSessions.length === 1) {
|
|
211
|
-
return [
|
|
212
|
-
'Canon active work session for this conversation:',
|
|
213
|
-
...buildWorkSessionPromptLines(workSessions[0], promptOptions),
|
|
214
|
-
];
|
|
215
|
-
}
|
|
216
|
-
const detailedWorkSessions = workSessions.slice(0, promptOptions.maxDetailedWorkSessions);
|
|
217
|
-
const hiddenWorkSessions = workSessions.slice(promptOptions.maxDetailedWorkSessions);
|
|
218
|
-
const lines = ['Canon active work sessions for this conversation:'];
|
|
219
|
-
detailedWorkSessions.forEach((workSession, index) => {
|
|
220
|
-
lines.push(detailedWorkSessions.length === 1
|
|
221
|
-
? 'Primary active work session:'
|
|
222
|
-
: `Detailed work session ${index + 1}:`);
|
|
223
|
-
lines.push(...buildWorkSessionPromptLines(workSession, promptOptions));
|
|
224
|
-
});
|
|
225
|
-
if (hiddenWorkSessions.length > 0) {
|
|
226
|
-
lines.push('Other active work sessions linked here:');
|
|
227
|
-
hiddenWorkSessions
|
|
228
|
-
.slice(0, promptOptions.maxOtherWorkSessions)
|
|
229
|
-
.forEach((workSession, index) => {
|
|
230
|
-
lines.push(`Other work session ${index + 1}: ${formatWorkSessionReference(workSession)}`);
|
|
231
|
-
});
|
|
232
|
-
if (hiddenWorkSessions.length > promptOptions.maxOtherWorkSessions) {
|
|
233
|
-
lines.push(`Additional active work sessions omitted for brevity: ${hiddenWorkSessions.length - promptOptions.maxOtherWorkSessions}`);
|
|
234
|
-
}
|
|
235
|
-
lines.push('Canon rule: do not assume the current message refers to another linked work session unless the conversation clearly points to it.');
|
|
236
|
-
}
|
|
237
|
-
return lines;
|
|
238
|
-
}
|