@canonmsg/core 0.15.4 → 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/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 +4 -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/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 {
|
|
@@ -51,7 +51,6 @@ export interface CanonMessage {
|
|
|
51
51
|
replyToPosition: number | null;
|
|
52
52
|
forwarded?: boolean;
|
|
53
53
|
forwardedFrom?: ForwardedFrom;
|
|
54
|
-
workSession?: CanonWorkSessionContext | null;
|
|
55
54
|
metadata?: Record<string, unknown>;
|
|
56
55
|
contactCard?: ContactCardPayload;
|
|
57
56
|
status: 'sent' | 'read';
|
|
@@ -78,7 +77,7 @@ export interface CanonConversation {
|
|
|
78
77
|
export interface CanonMessagesPage {
|
|
79
78
|
messages: CanonMessage[];
|
|
80
79
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
81
|
-
|
|
80
|
+
selfContexts?: CanonSelfContext[];
|
|
82
81
|
}
|
|
83
82
|
export type CanonContactRequestStatus = 'pending' | 'approved' | 'rejected' | 'expired';
|
|
84
83
|
export interface CanonContactRequest {
|
|
@@ -355,7 +354,7 @@ export interface AgentContext {
|
|
|
355
354
|
export interface MessageCreatedPayload {
|
|
356
355
|
conversationId: string;
|
|
357
356
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
358
|
-
|
|
357
|
+
selfContexts?: CanonSelfContext[];
|
|
359
358
|
message: {
|
|
360
359
|
id: string;
|
|
361
360
|
senderId: string;
|
|
@@ -372,7 +371,6 @@ export interface MessageCreatedPayload {
|
|
|
372
371
|
forwardedFrom?: ForwardedFrom;
|
|
373
372
|
mentions?: string[];
|
|
374
373
|
createdAt?: string;
|
|
375
|
-
workSession?: CanonWorkSessionContext | null;
|
|
376
374
|
/** Structured metadata for rich UI (approval cards, etc.) */
|
|
377
375
|
metadata?: Record<string, unknown>;
|
|
378
376
|
/** Populated when `contentType === 'contact_card'`. */
|
|
@@ -453,7 +451,7 @@ export interface SendMessageOptions {
|
|
|
453
451
|
attachments?: MediaAttachment[];
|
|
454
452
|
contactCardUserId?: string;
|
|
455
453
|
mentions?: string[];
|
|
456
|
-
|
|
454
|
+
selfContextId?: string;
|
|
457
455
|
/** Structured metadata for rich UI (approval cards, etc.) */
|
|
458
456
|
metadata?: Record<string, unknown>;
|
|
459
457
|
}
|
|
@@ -577,13 +575,6 @@ export interface AgentRuntime {
|
|
|
577
575
|
availableWorkspaces?: WorkspaceOption[];
|
|
578
576
|
updatedAt?: number;
|
|
579
577
|
}
|
|
580
|
-
export interface AgentSessionWorkSessionSummary {
|
|
581
|
-
count: number;
|
|
582
|
-
id: string;
|
|
583
|
-
title?: string | null;
|
|
584
|
-
objective?: string | null;
|
|
585
|
-
status?: CanonWorkSessionContext['status'] | null;
|
|
586
|
-
}
|
|
587
578
|
export interface AgentSessionSnapshot {
|
|
588
579
|
conversationId: string;
|
|
589
580
|
agentId: string;
|
|
@@ -615,7 +606,6 @@ export interface AgentSessionSnapshot {
|
|
|
615
606
|
contextUsage?: SessionState['contextUsage'];
|
|
616
607
|
lastError?: string;
|
|
617
608
|
lastHeartbeatAt?: number;
|
|
618
|
-
workSession?: AgentSessionWorkSessionSummary | null;
|
|
619
609
|
updatedAt?: number;
|
|
620
610
|
}
|
|
621
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
|
-
}
|