@canonmsg/core 0.16.0 → 0.17.1
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/group-context.d.ts +25 -0
- package/dist/group-context.js +100 -0
- package/dist/host-runtime.d.ts +11 -1
- package/dist/host-runtime.js +26 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/self-context.d.ts +7 -0
- package/dist/self-context.js +17 -0
- package/dist/stream.d.ts +4 -5
- package/dist/stream.js +22 -1
- package/dist/types.d.ts +32 -5
- package/package.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CanonConversation, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonMessage } from './types.js';
|
|
2
|
+
type MessageLike = {
|
|
3
|
+
senderId?: string | null;
|
|
4
|
+
senderName?: string | null;
|
|
5
|
+
senderType?: CanonMessage['senderType'];
|
|
6
|
+
isOwner?: boolean;
|
|
7
|
+
createdAt?: string | null;
|
|
8
|
+
};
|
|
9
|
+
export declare function diffCanonMemberIds(previousMemberIds: unknown[], nextMemberIds: unknown[]): CanonMembershipChange | null;
|
|
10
|
+
export declare function buildCanonKnownRecentParticipants(input: {
|
|
11
|
+
messages: MessageLike[];
|
|
12
|
+
agentId: string;
|
|
13
|
+
ownerId?: string | null;
|
|
14
|
+
maxParticipants?: number;
|
|
15
|
+
}): CanonKnownRecentParticipant[];
|
|
16
|
+
export declare function buildCanonGroupContext(input: {
|
|
17
|
+
conversation: CanonConversation | null | undefined;
|
|
18
|
+
messages: MessageLike[];
|
|
19
|
+
agentId: string;
|
|
20
|
+
ownerId?: string | null;
|
|
21
|
+
ownerName?: string | null;
|
|
22
|
+
membershipChange?: CanonMembershipChange | null;
|
|
23
|
+
}): CanonGroupContext | undefined;
|
|
24
|
+
export declare function buildCompactGroupContextLines(groupContext: CanonGroupContext, mode: CanonGroupContextMode): string[];
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
function uniqueStringIds(ids) {
|
|
2
|
+
return Array.from(new Set(ids.filter((id) => typeof id === 'string' && id.length > 0)));
|
|
3
|
+
}
|
|
4
|
+
export function diffCanonMemberIds(previousMemberIds, nextMemberIds) {
|
|
5
|
+
const previous = new Set(uniqueStringIds(previousMemberIds));
|
|
6
|
+
const next = uniqueStringIds(nextMemberIds);
|
|
7
|
+
const nextSet = new Set(next);
|
|
8
|
+
const addedMemberIds = next.filter((id) => !previous.has(id));
|
|
9
|
+
const removedMemberIds = [...previous].filter((id) => !nextSet.has(id));
|
|
10
|
+
if (addedMemberIds.length === 0 && removedMemberIds.length === 0) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
addedMemberIds,
|
|
15
|
+
removedMemberIds,
|
|
16
|
+
memberCount: next.length,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function buildCanonKnownRecentParticipants(input) {
|
|
20
|
+
const maxParticipants = input.maxParticipants ?? 8;
|
|
21
|
+
const indexed = input.messages
|
|
22
|
+
.map((message, index) => {
|
|
23
|
+
const timestamp = typeof message.createdAt === 'string'
|
|
24
|
+
? Date.parse(message.createdAt)
|
|
25
|
+
: Number.NaN;
|
|
26
|
+
return {
|
|
27
|
+
message,
|
|
28
|
+
index,
|
|
29
|
+
sortKey: Number.isFinite(timestamp) ? timestamp : index,
|
|
30
|
+
};
|
|
31
|
+
})
|
|
32
|
+
.sort((left, right) => right.sortKey - left.sortKey || right.index - left.index);
|
|
33
|
+
const participants = new Map();
|
|
34
|
+
for (const { message } of indexed) {
|
|
35
|
+
if (!message.senderId || participants.has(message.senderId))
|
|
36
|
+
continue;
|
|
37
|
+
const isSelf = message.senderId === input.agentId;
|
|
38
|
+
const isOwner = message.isOwner ?? (typeof input.ownerId === 'string' && input.ownerId.length > 0
|
|
39
|
+
? message.senderId === input.ownerId
|
|
40
|
+
: false);
|
|
41
|
+
participants.set(message.senderId, {
|
|
42
|
+
id: message.senderId,
|
|
43
|
+
name: message.senderName ?? (isSelf ? 'this agent' : message.senderId),
|
|
44
|
+
userType: message.senderType ?? 'unknown',
|
|
45
|
+
isOwner,
|
|
46
|
+
isSelf,
|
|
47
|
+
});
|
|
48
|
+
if (participants.size >= maxParticipants)
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return [...participants.values()];
|
|
52
|
+
}
|
|
53
|
+
export function buildCanonGroupContext(input) {
|
|
54
|
+
if (input.conversation?.type !== 'group')
|
|
55
|
+
return undefined;
|
|
56
|
+
const memberIds = uniqueStringIds(input.conversation.memberIds ?? []);
|
|
57
|
+
const ownerId = input.ownerId ?? '';
|
|
58
|
+
return {
|
|
59
|
+
memberCount: memberIds.length,
|
|
60
|
+
memberIds,
|
|
61
|
+
ownerId,
|
|
62
|
+
ownerName: input.ownerName ?? '',
|
|
63
|
+
ownerPresent: ownerId.length > 0 && memberIds.includes(ownerId),
|
|
64
|
+
knownRecentParticipants: buildCanonKnownRecentParticipants({
|
|
65
|
+
messages: input.messages,
|
|
66
|
+
agentId: input.agentId,
|
|
67
|
+
ownerId,
|
|
68
|
+
}),
|
|
69
|
+
...(input.membershipChange ? { membershipChange: input.membershipChange } : {}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function formatParticipant(participant) {
|
|
73
|
+
const labels = [
|
|
74
|
+
participant.userType === 'ai_agent'
|
|
75
|
+
? 'agent'
|
|
76
|
+
: participant.userType === 'human'
|
|
77
|
+
? 'human'
|
|
78
|
+
: 'unknown type',
|
|
79
|
+
];
|
|
80
|
+
if (participant.isOwner)
|
|
81
|
+
labels.push('owner');
|
|
82
|
+
if (participant.isSelf)
|
|
83
|
+
labels.push('you');
|
|
84
|
+
return `${participant.name} (${labels.join(', ')})`;
|
|
85
|
+
}
|
|
86
|
+
export function buildCompactGroupContextLines(groupContext, mode) {
|
|
87
|
+
if (mode === 'membership_change' && groupContext.membershipChange) {
|
|
88
|
+
const { addedMemberIds, removedMemberIds, memberCount } = groupContext.membershipChange;
|
|
89
|
+
return [
|
|
90
|
+
`Group membership changed: +${addedMemberIds.length}, -${removedMemberIds.length}. Member count now ${memberCount}. Agent owner present: ${groupContext.ownerPresent ? 'yes' : 'no'}.`,
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
const lines = [
|
|
94
|
+
`Group context: ${groupContext.memberCount} members. Agent owner present: ${groupContext.ownerPresent ? 'yes' : 'no'}.`,
|
|
95
|
+
];
|
|
96
|
+
if (groupContext.knownRecentParticipants.length > 0) {
|
|
97
|
+
lines.push(`Known recent participants: ${groupContext.knownRecentParticipants.map(formatParticipant).join(', ')}.`);
|
|
98
|
+
}
|
|
99
|
+
return lines;
|
|
100
|
+
}
|
package/dist/host-runtime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AgentClientType, type AgentRuntime, type CanonConversation, type CanonMessage, type CanonMessagesPage, type MessageCreatedPayload } from './types.js';
|
|
1
|
+
import { type AgentClientType, type AgentRuntime, type CanonConversation, type CanonGroupContext, type CanonGroupContextMode, type CanonMembershipChange, type CanonMessage, type CanonMessagesPage, type MessageCreatedPayload } from './types.js';
|
|
2
2
|
import { type CanonClient } from './client.js';
|
|
3
3
|
import { type SessionWorkspaceConfig } from './execution-environment.js';
|
|
4
4
|
import { type ResolvedAgentBehaviorPolicy } from './policy.js';
|
|
@@ -13,6 +13,8 @@ export interface HostInboundParticipantContext {
|
|
|
13
13
|
senderName: string;
|
|
14
14
|
isOwner: boolean;
|
|
15
15
|
mentionedAgent: boolean;
|
|
16
|
+
groupContext?: CanonGroupContext;
|
|
17
|
+
groupContextMode?: CanonGroupContextMode;
|
|
16
18
|
recentSenderTypes: Array<'human' | 'ai_agent'>;
|
|
17
19
|
recentHumanCount: number;
|
|
18
20
|
recentAgentCount: number;
|
|
@@ -20,6 +22,7 @@ export interface HostInboundParticipantContext {
|
|
|
20
22
|
currentAgentStreakStartedByHuman: boolean;
|
|
21
23
|
}
|
|
22
24
|
type HostInboundMessage = {
|
|
25
|
+
id?: string | null;
|
|
23
26
|
text?: string | null;
|
|
24
27
|
contentType?: CanonMessage['contentType'] | null;
|
|
25
28
|
attachments?: CanonMessage['attachments'];
|
|
@@ -61,12 +64,19 @@ export declare function buildHydratedInboundContext(input: {
|
|
|
61
64
|
agentId: string;
|
|
62
65
|
conversation: CanonConversation | null;
|
|
63
66
|
page?: CanonMessagesPage | null;
|
|
67
|
+
activeSelfContextId?: string | null;
|
|
68
|
+
selfContexts?: MessageCreatedPayload['selfContexts'];
|
|
64
69
|
message: HostInboundMessage;
|
|
65
70
|
senderName: string;
|
|
66
71
|
isOwner: boolean;
|
|
72
|
+
ownerId?: string | null;
|
|
73
|
+
ownerName?: string | null;
|
|
74
|
+
membershipChange?: CanonMembershipChange | null;
|
|
75
|
+
groupContextMode?: CanonGroupContextMode;
|
|
67
76
|
}): {
|
|
68
77
|
participantContext: HostInboundParticipantContext;
|
|
69
78
|
behavior?: ResolvedAgentBehaviorPolicy | null;
|
|
79
|
+
activeSelfContextId: string | null;
|
|
70
80
|
selfContexts: NonNullable<MessageCreatedPayload['selfContexts']>;
|
|
71
81
|
hydratedFromPage: boolean;
|
|
72
82
|
};
|
package/dist/host-runtime.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { buildCanonGroupContext } from './group-context.js';
|
|
1
2
|
import { buildAgentSessionSnapshot } from './agent-session.js';
|
|
2
3
|
import { buildConversationWorktreeSpec, normalizeOptionalString, readSessionWorkspaceConfig, resolveConfiguredWorkspaceCwd, } from './execution-environment.js';
|
|
3
4
|
import { buildBehaviorPolicyLines, buildParticipationHistorySnapshot, } from './policy.js';
|
|
4
|
-
import { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
5
|
+
import { buildSelfContextPromptLines, normalizeSelfContexts, resolveMessageActiveSelfContextId, selectActiveSelfContexts, } from './self-context.js';
|
|
5
6
|
import { rtdbRead } from './rtdb-rest.js';
|
|
6
7
|
import { createRuntimeStatePublisher } from './runtime-state-publisher.js';
|
|
7
8
|
const HOST_INBOUND_CONTACT_CARD_ACTION_CAPABILITIES = Object.freeze({
|
|
@@ -102,6 +103,26 @@ function describeAttachment(attachment, materialized) {
|
|
|
102
103
|
}
|
|
103
104
|
export function buildHydratedInboundContext(input) {
|
|
104
105
|
const history = buildParticipationHistorySnapshot(input.page?.messages ?? [], input.agentId);
|
|
106
|
+
const activeSelfContextId = resolveMessageActiveSelfContextId({
|
|
107
|
+
messageId: input.message.id,
|
|
108
|
+
activeSelfContextId: input.activeSelfContextId,
|
|
109
|
+
activeSelfContextIdByMessageId: input.page?.activeSelfContextIdByMessageId,
|
|
110
|
+
});
|
|
111
|
+
const activeSelfContexts = selectActiveSelfContexts([
|
|
112
|
+
...(input.page?.selfContexts ?? []),
|
|
113
|
+
...(input.selfContexts ?? []),
|
|
114
|
+
], activeSelfContextId);
|
|
115
|
+
const groupContext = buildCanonGroupContext({
|
|
116
|
+
conversation: input.conversation,
|
|
117
|
+
messages: [
|
|
118
|
+
...(input.page?.messages ?? []),
|
|
119
|
+
input.message,
|
|
120
|
+
],
|
|
121
|
+
agentId: input.agentId,
|
|
122
|
+
ownerId: input.ownerId,
|
|
123
|
+
ownerName: input.ownerName,
|
|
124
|
+
membershipChange: input.membershipChange,
|
|
125
|
+
});
|
|
105
126
|
return {
|
|
106
127
|
participantContext: {
|
|
107
128
|
conversationType: input.conversation?.type ?? 'unknown',
|
|
@@ -110,6 +131,8 @@ export function buildHydratedInboundContext(input) {
|
|
|
110
131
|
senderName: input.senderName,
|
|
111
132
|
isOwner: input.isOwner,
|
|
112
133
|
mentionedAgent: Array.isArray(input.message.mentions) && input.message.mentions.includes(input.agentId),
|
|
134
|
+
...(groupContext ? { groupContext } : {}),
|
|
135
|
+
...(groupContext && input.groupContextMode ? { groupContextMode: input.groupContextMode } : {}),
|
|
113
136
|
recentSenderTypes: history.recentSenderTypes,
|
|
114
137
|
recentHumanCount: history.recentHumanCount,
|
|
115
138
|
recentAgentCount: history.recentAgentCount,
|
|
@@ -117,7 +140,8 @@ export function buildHydratedInboundContext(input) {
|
|
|
117
140
|
currentAgentStreakStartedByHuman: history.currentAgentStreakStartedByHuman,
|
|
118
141
|
},
|
|
119
142
|
behavior: input.page?.behavior ?? input.conversation?.behavior,
|
|
120
|
-
|
|
143
|
+
activeSelfContextId: activeSelfContexts.length > 0 ? activeSelfContextId : null,
|
|
144
|
+
selfContexts: activeSelfContexts,
|
|
121
145
|
hydratedFromPage: input.page != null,
|
|
122
146
|
};
|
|
123
147
|
}
|
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, 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';
|
|
2
|
+
export type { AddMemberResult, AgentCapabilities, AgentClientType, CanonControlAvailability, CanonControlDescriptor, CanonControlLiveBehavior, CanonControlSelectionPolicy, CanonControlValue, CanonContact, CanonContactRequest, CanonContactRequestStatus, CanonGroupContext, CanonGroupContextMode, CanonKnownRecentParticipant, CanonMembershipChange, CanonResolveAdmissionResult, ConversationUpdatedPayload, ContactAddedPayload, ContactApprovedPayload, ContactCardPayload, ContactRemovedPayload, ContactRequestPayload, ContactSource, ResolvedAdmissionState, ResolvedAdmissionTargetSummary, ResolvedTargetAdmissionPayload, CanonMessage, 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
3
|
export type { CanonSelfContext, CanonSelfContextType, SelfContextPromptRenderOptions, SendContextualMessageOptions, SendContextualMessageResult, SendContextualSelfContextInput, } from './self-context.js';
|
|
4
|
-
export { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
4
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, resolveMessageActiveSelfContextId, selectActiveSelfContexts, } 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';
|
|
@@ -34,6 +34,7 @@ export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, patchRunt
|
|
|
34
34
|
export type { AgentSessionSnapshotPatch, RTDBClientHandle, RuntimeInfoPayloadData, SessionStatePayload, TurnStatePayload, } from './rtdb-rest.js';
|
|
35
35
|
export { buildCanonHostPrompt, buildHydratedInboundContext, createConversationMetadataLoader, loadHostSessionConfig, publishHostAgentRuntime, publishHostSessionSnapshots, readHostSessionConfig, renderCanonHostInboundContent, resolveHostWorkspaceCwd, } from './host-runtime.js';
|
|
36
36
|
export type { HostInboundParticipantContext, } from './host-runtime.js';
|
|
37
|
+
export { buildCanonGroupContext, buildCanonKnownRecentParticipants, buildCompactGroupContextLines, diffCanonMemberIds, } from './group-context.js';
|
|
37
38
|
export { createRuntimeStatePublisher, } from './runtime-state-publisher.js';
|
|
38
39
|
export type { RuntimeStatePublisher, RuntimeStatePublisherOptions, RuntimeStreamingPayload, } from './runtime-state-publisher.js';
|
|
39
40
|
export { formatCanonMessageAsText } from './message-format.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 { buildSelfContextPromptLines, normalizeSelfContexts, } from './self-context.js';
|
|
3
|
+
export { buildSelfContextPromptLines, normalizeSelfContexts, resolveMessageActiveSelfContextId, selectActiveSelfContexts, } 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';
|
|
@@ -32,6 +32,7 @@ export { buildConfiguredWorkspaceOptions, buildConversationEnvironmentKey, build
|
|
|
32
32
|
export { initRTDBAuth, rtdbWrite, rtdbRead, patchAgentSessionSnapshot, patchRuntimeInfo, writeRuntimeInfo, clearRuntimeInfo, writeSessionState, clearSessionState, writeTurnState, clearTurnState, } from './rtdb-rest.js';
|
|
33
33
|
// Runtime host plumbing
|
|
34
34
|
export { buildCanonHostPrompt, buildHydratedInboundContext, createConversationMetadataLoader, loadHostSessionConfig, publishHostAgentRuntime, publishHostSessionSnapshots, readHostSessionConfig, renderCanonHostInboundContent, resolveHostWorkspaceCwd, } from './host-runtime.js';
|
|
35
|
+
export { buildCanonGroupContext, buildCanonKnownRecentParticipants, buildCompactGroupContextLines, diffCanonMemberIds, } from './group-context.js';
|
|
35
36
|
export { createRuntimeStatePublisher, } from './runtime-state-publisher.js';
|
|
36
37
|
// Message formatting (LLM-facing text projection)
|
|
37
38
|
export { formatCanonMessageAsText } from './message-format.js';
|
package/dist/self-context.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type SendContextualMessageResult = {
|
|
|
28
28
|
} | {
|
|
29
29
|
status: 'requested' | 'pending';
|
|
30
30
|
requestId: string | null;
|
|
31
|
+
deferredIntentId?: string | null;
|
|
31
32
|
} | {
|
|
32
33
|
status: 'setup_required' | 'blocked' | 'unavailable';
|
|
33
34
|
reason: string;
|
|
@@ -36,4 +37,10 @@ export interface SelfContextPromptRenderOptions {
|
|
|
36
37
|
maxSelfContexts?: number;
|
|
37
38
|
}
|
|
38
39
|
export declare function normalizeSelfContexts(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions): CanonSelfContext[];
|
|
40
|
+
export declare function resolveMessageActiveSelfContextId(input: {
|
|
41
|
+
messageId?: string | null;
|
|
42
|
+
activeSelfContextId?: string | null;
|
|
43
|
+
activeSelfContextIdByMessageId?: Record<string, string> | null;
|
|
44
|
+
}): string | null;
|
|
45
|
+
export declare function selectActiveSelfContexts(selfContexts?: CanonSelfContext[] | null, activeSelfContextId?: string | null): CanonSelfContext[];
|
|
39
46
|
export declare function buildSelfContextPromptLines(selfContexts?: CanonSelfContext[] | null, options?: SelfContextPromptRenderOptions): string[];
|
package/dist/self-context.js
CHANGED
|
@@ -49,6 +49,23 @@ export function normalizeSelfContexts(selfContexts, options) {
|
|
|
49
49
|
.sort((left, right) => contextSortTime(right) - contextSortTime(left))
|
|
50
50
|
.slice(0, promptOptions.maxSelfContexts);
|
|
51
51
|
}
|
|
52
|
+
export function resolveMessageActiveSelfContextId(input) {
|
|
53
|
+
const direct = normalizeString(input.activeSelfContextId);
|
|
54
|
+
if (direct)
|
|
55
|
+
return direct;
|
|
56
|
+
const messageId = normalizeString(input.messageId);
|
|
57
|
+
if (!messageId || !input.activeSelfContextIdByMessageId)
|
|
58
|
+
return null;
|
|
59
|
+
return normalizeString(input.activeSelfContextIdByMessageId[messageId]);
|
|
60
|
+
}
|
|
61
|
+
export function selectActiveSelfContexts(selfContexts, activeSelfContextId) {
|
|
62
|
+
const id = normalizeString(activeSelfContextId);
|
|
63
|
+
if (!id)
|
|
64
|
+
return [];
|
|
65
|
+
return normalizeSelfContexts(Array.isArray(selfContexts)
|
|
66
|
+
? selfContexts.filter((selfContext) => normalizeString(selfContext?.id) === id)
|
|
67
|
+
: []);
|
|
68
|
+
}
|
|
52
69
|
export function buildSelfContextPromptLines(selfContexts, options) {
|
|
53
70
|
const resolved = normalizeSelfContexts(selfContexts, options);
|
|
54
71
|
if (resolved.length === 0)
|
package/dist/stream.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentContext, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload } from './types.js';
|
|
1
|
+
import type { AgentContext, ContactAddedPayload, ContactApprovedPayload, ContactRemovedPayload, ContactRequestPayload, ConversationUpdatedPayload, MessageCreatedPayload, TypingPayload, PresencePayload, RuntimeUpdatedPayload, TurnUpdatedPayload } from './types.js';
|
|
2
2
|
export type StreamHandler = {
|
|
3
3
|
onMessage: (payload: MessageCreatedPayload) => void;
|
|
4
4
|
onAgentContext?: (ctx: AgentContext) => void;
|
|
@@ -14,10 +14,7 @@ export type StreamHandler = {
|
|
|
14
14
|
conversationId: string;
|
|
15
15
|
messageId: string;
|
|
16
16
|
}) => void;
|
|
17
|
-
onConversationUpdated?: (payload:
|
|
18
|
-
conversationId: string;
|
|
19
|
-
changes: Record<string, unknown>;
|
|
20
|
-
}) => void;
|
|
17
|
+
onConversationUpdated?: (payload: ConversationUpdatedPayload) => void;
|
|
21
18
|
onConnected?: () => void;
|
|
22
19
|
onDisconnected?: () => void;
|
|
23
20
|
onError?: (error: Error) => void;
|
|
@@ -47,6 +44,8 @@ export declare class CanonStream {
|
|
|
47
44
|
start(): Promise<void>;
|
|
48
45
|
stop(): void;
|
|
49
46
|
isRunning(): boolean;
|
|
47
|
+
private requestedEventFamilies;
|
|
48
|
+
private streamEndpoint;
|
|
50
49
|
private connect;
|
|
51
50
|
private readStream;
|
|
52
51
|
private processFrame;
|
package/dist/stream.js
CHANGED
|
@@ -42,6 +42,27 @@ export class CanonStream {
|
|
|
42
42
|
isRunning() {
|
|
43
43
|
return this.running;
|
|
44
44
|
}
|
|
45
|
+
requestedEventFamilies() {
|
|
46
|
+
const families = new Set(['messages']);
|
|
47
|
+
if (this.handler.onContactRequest
|
|
48
|
+
|| this.handler.onContactApproved
|
|
49
|
+
|| this.handler.onContactAdded
|
|
50
|
+
|| this.handler.onContactRemoved) {
|
|
51
|
+
families.add('contacts');
|
|
52
|
+
}
|
|
53
|
+
if (this.handler.onTyping || this.handler.onPresence) {
|
|
54
|
+
families.add('typing_presence');
|
|
55
|
+
}
|
|
56
|
+
if (this.handler.onRuntimeUpdated || this.handler.onTurnUpdated) {
|
|
57
|
+
families.add('runtime_turn');
|
|
58
|
+
}
|
|
59
|
+
return [...families];
|
|
60
|
+
}
|
|
61
|
+
streamEndpoint() {
|
|
62
|
+
const base = `${this.streamUrl.replace(/\/$/, '')}/agents/stream`;
|
|
63
|
+
const events = encodeURIComponent(this.requestedEventFamilies().join(','));
|
|
64
|
+
return `${base}?events=${events}`;
|
|
65
|
+
}
|
|
45
66
|
// ── SSE connection ────────────────────────────────────────────────────
|
|
46
67
|
async connect() {
|
|
47
68
|
if (!this.running)
|
|
@@ -55,7 +76,7 @@ export class CanonStream {
|
|
|
55
76
|
headers['Last-Event-ID'] = this.lastEventId;
|
|
56
77
|
}
|
|
57
78
|
try {
|
|
58
|
-
const res = await fetch(
|
|
79
|
+
const res = await fetch(this.streamEndpoint(), {
|
|
59
80
|
headers,
|
|
60
81
|
signal: this.abortController.signal,
|
|
61
82
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface ContactCardPayload {
|
|
|
40
40
|
export interface CanonMessage {
|
|
41
41
|
id: string;
|
|
42
42
|
senderId: string;
|
|
43
|
+
senderName?: string;
|
|
43
44
|
senderType: 'human' | 'ai_agent';
|
|
44
45
|
/** Whether the sender is this agent's owner (server-computed, trusted) */
|
|
45
46
|
isOwner: boolean;
|
|
@@ -77,6 +78,7 @@ export interface CanonConversation {
|
|
|
77
78
|
export interface CanonMessagesPage {
|
|
78
79
|
messages: CanonMessage[];
|
|
79
80
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
81
|
+
activeSelfContextIdByMessageId?: Record<string, string>;
|
|
80
82
|
selfContexts?: CanonSelfContext[];
|
|
81
83
|
}
|
|
82
84
|
export type CanonContactRequestStatus = 'pending' | 'approved' | 'rejected' | 'expired';
|
|
@@ -355,6 +357,7 @@ export interface AgentContext {
|
|
|
355
357
|
export interface MessageCreatedPayload {
|
|
356
358
|
conversationId: string;
|
|
357
359
|
behavior?: ResolvedAgentBehaviorPolicy;
|
|
360
|
+
activeSelfContextId?: string | null;
|
|
358
361
|
selfContexts?: CanonSelfContext[];
|
|
359
362
|
message: {
|
|
360
363
|
id: string;
|
|
@@ -401,6 +404,33 @@ export interface TurnUpdatedPayload {
|
|
|
401
404
|
agentId: string;
|
|
402
405
|
turn: import('./turn-protocol.js').TurnState | null;
|
|
403
406
|
}
|
|
407
|
+
export interface CanonMembershipChange {
|
|
408
|
+
addedMemberIds: string[];
|
|
409
|
+
removedMemberIds: string[];
|
|
410
|
+
memberCount: number;
|
|
411
|
+
}
|
|
412
|
+
export interface CanonKnownRecentParticipant {
|
|
413
|
+
id: string;
|
|
414
|
+
name: string;
|
|
415
|
+
userType: 'human' | 'ai_agent' | 'unknown';
|
|
416
|
+
isOwner: boolean;
|
|
417
|
+
isSelf: boolean;
|
|
418
|
+
}
|
|
419
|
+
export interface CanonGroupContext {
|
|
420
|
+
memberCount: number;
|
|
421
|
+
memberIds: string[];
|
|
422
|
+
ownerId: string;
|
|
423
|
+
ownerName: string;
|
|
424
|
+
ownerPresent: boolean;
|
|
425
|
+
knownRecentParticipants: CanonKnownRecentParticipant[];
|
|
426
|
+
membershipChange?: CanonMembershipChange;
|
|
427
|
+
}
|
|
428
|
+
export type CanonGroupContextMode = 'initial' | 'membership_change';
|
|
429
|
+
export interface ConversationUpdatedPayload {
|
|
430
|
+
conversationId: string;
|
|
431
|
+
changes: Record<string, unknown>;
|
|
432
|
+
membershipChange?: CanonMembershipChange;
|
|
433
|
+
}
|
|
404
434
|
export type CanonStreamEvent = {
|
|
405
435
|
type: 'agent.context';
|
|
406
436
|
payload: AgentContext;
|
|
@@ -439,10 +469,7 @@ export type CanonStreamEvent = {
|
|
|
439
469
|
};
|
|
440
470
|
} | {
|
|
441
471
|
type: 'conversation.updated';
|
|
442
|
-
payload:
|
|
443
|
-
conversationId: string;
|
|
444
|
-
changes: Record<string, unknown>;
|
|
445
|
-
};
|
|
472
|
+
payload: ConversationUpdatedPayload;
|
|
446
473
|
};
|
|
447
474
|
export interface SendMessageOptions {
|
|
448
475
|
messageId?: string;
|
|
@@ -452,7 +479,7 @@ export interface SendMessageOptions {
|
|
|
452
479
|
attachments?: MediaAttachment[];
|
|
453
480
|
contactCardUserId?: string;
|
|
454
481
|
mentions?: string[];
|
|
455
|
-
selfContextId?: string;
|
|
482
|
+
selfContextId?: string | null;
|
|
456
483
|
/** Structured metadata for rich UI (approval cards, etc.) */
|
|
457
484
|
metadata?: Record<string, unknown>;
|
|
458
485
|
}
|