@canonmsg/agent-sdk 4.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,214 @@
1
+ import { type AddMemberResult, type CanonContact, type CanonConversation, type CreateConversationResult, type CanonRuntimeActivityItem, type CanonRuntimeCommandDescriptor, type CanonRuntimeFact, type CanonRuntimePrimitiveId, type ContactCardPayload, type ClearRuntimeActivityOptions, type CreateContactRequestResult } from '@canonmsg/core';
2
+ import type { CanonAgentOptions, ContactAddedHandler, ContactRemovedHandler, CreateConversationOptions, MessageHandler, MessageUpdatedHandler, ReachOutOptions, ReachOutResult, ContactRequestHandler, RuntimeSignalHandler, RuntimePrimitiveHandler } from './types.js';
3
+ /**
4
+ * Contact-graph operations exposed under `agent.contacts`. Wraps the REST
5
+ * endpoints in CanonClient — the same surface a human user would hit through
6
+ * the app — so plugin runtimes can treat them as natural-language tools.
7
+ */
8
+ export interface AgentContactsAPI {
9
+ list(): Promise<CanonContact[]>;
10
+ get(contactId: string): Promise<CanonContact | null>;
11
+ remove(contactId: string): Promise<void>;
12
+ request(targetUserId: string, message?: string | null): Promise<CreateContactRequestResult>;
13
+ }
14
+ /**
15
+ * User-level moderation actions exposed under `agent.users`.
16
+ */
17
+ export interface AgentUsersAPI {
18
+ block(userId: string): Promise<void>;
19
+ unblock(userId: string): Promise<void>;
20
+ }
21
+ export interface AgentConversationsAPI {
22
+ list(options?: {
23
+ targetUserId?: string;
24
+ }): Promise<CanonConversation[]>;
25
+ }
26
+ export declare class CanonAgent {
27
+ private options;
28
+ private apiClient;
29
+ private authManager;
30
+ private debouncer;
31
+ private realtimeManager;
32
+ private sessionManager;
33
+ private handler;
34
+ private contactRequestHandler;
35
+ private contactApprovedHandler;
36
+ private contactAddedHandler;
37
+ private contactRemovedHandler;
38
+ private messageUpdatedHandler;
39
+ private interruptHandler;
40
+ private stopAndDropHandler;
41
+ private newSessionHandler;
42
+ private readonly primitiveHandlers;
43
+ private primitiveFallbackHandler;
44
+ /** Contact-graph operations (`agent.contacts.*`). Initialized in the constructor. */
45
+ readonly contacts: AgentContactsAPI;
46
+ /** Block/unblock operations (`agent.users.*`). Initialized in the constructor. */
47
+ readonly users: AgentUsersAPI;
48
+ /** Conversation discovery for choosing existing sessions intentionally. */
49
+ readonly conversations: AgentConversationsAPI;
50
+ private readonly reachOutInFlight;
51
+ private agentId;
52
+ private agentContext;
53
+ private approvalManager;
54
+ private approvalManagerAgentId;
55
+ private approvalManagerOwnerId;
56
+ /**
57
+ * Shared poll/timeout/abort engine for interactive runtime input + card
58
+ * requests. The server request is still created inline (host-specific
59
+ * `native`/`responseUserId`), so the descriptors register a no-op `create`
60
+ * but keep the built-in `cancel`: passing the turn's abort `signal` lets the
61
+ * manager fire `consume({ cancel: true })` on interrupt, so the hosts no
62
+ * longer hand-roll a `cancelPendingRequest`.
63
+ */
64
+ private runtimeRequestManager;
65
+ private cachedConversationIds;
66
+ private running;
67
+ private runtimeHeartbeatTimer;
68
+ private rtdbHandle;
69
+ private controlPoller;
70
+ private readonly activeAbortControllers;
71
+ private readonly activeTurns;
72
+ private readonly conversationMemberIds;
73
+ private readonly pendingMembershipChanges;
74
+ private readonly typingSignals;
75
+ private sseConnectedLogged;
76
+ constructor(options: CanonAgentOptions);
77
+ private ensureApprovalManager;
78
+ /**
79
+ * Shared engine for interactive runtime input + card polling. Unlike approval,
80
+ * these families do not need an owner (the request is created inline with the
81
+ * caller's own `responseUserId` policy), so the manager is always available.
82
+ * The registered descriptors keep the built-in poll/consume/timeout logic and
83
+ * the built-in `cancel` (best-effort `consume({ cancel: true })`), replacing
84
+ * only `create` with a no-op because the request is already created inline.
85
+ * On abort the manager runs that cancel via the passed `signal`.
86
+ */
87
+ private ensureRuntimeRequestManager;
88
+ private filterApprovalReplyMessages;
89
+ on(event: 'message', handler: MessageHandler): void;
90
+ on(event: 'messageUpdated', handler: MessageUpdatedHandler): void;
91
+ on(event: 'contactRequest', handler: ContactRequestHandler): void;
92
+ on(event: 'contactApproved', handler: ContactRequestHandler): void;
93
+ on(event: 'contactAdded', handler: ContactAddedHandler): void;
94
+ on(event: 'contactRemoved', handler: ContactRemovedHandler): void;
95
+ on(event: 'interrupt', handler: RuntimeSignalHandler): void;
96
+ on(event: 'stopAndDrop', handler: RuntimeSignalHandler): void;
97
+ on(event: 'newSession', handler: RuntimeSignalHandler): void;
98
+ onPrimitive(primitive: CanonRuntimePrimitiveId | '*', handler: RuntimePrimitiveHandler): void;
99
+ describeCommands(_provider?: string): ReadonlyArray<CanonRuntimeCommandDescriptor>;
100
+ publishRuntimeFacts(conversationId: string, facts: ReadonlyArray<CanonRuntimeFact>): Promise<void>;
101
+ publishRuntimeActivity(conversationId: string, item: CanonRuntimeActivityItem): Promise<void>;
102
+ clearRuntimeActivity(conversationId: string, options?: ClearRuntimeActivityOptions): Promise<void>;
103
+ /**
104
+ * Resolve admission live for a target user (typically read off a shared
105
+ * contact card) and route into either an immediate message or a contact
106
+ * request. Never reads `card.accessLevel` — that snapshot is stale by the
107
+ * time an LLM acts on it. Instead defers to `resolveAdmission` so the
108
+ * answer reflects the target's *current* inbound policy.
109
+ */
110
+ reachOut(card: ContactCardPayload, options?: ReachOutOptions): Promise<ReachOutResult>;
111
+ private executeReachOut;
112
+ start(): Promise<void>;
113
+ createConversation(options: CreateConversationOptions): Promise<CreateConversationResult>;
114
+ updateTopic(conversationId: string, topic: string): Promise<void>;
115
+ leaveConversation(conversationId: string): Promise<void>;
116
+ updateConversationName(conversationId: string, name: string): Promise<void>;
117
+ /**
118
+ * Add a member to a group conversation.
119
+ *
120
+ * Outcome depends on the target's `groupJoinPolicy` and the relationship
121
+ * graph:
122
+ * - `{ status: 'added' }` — the member was added immediately.
123
+ * - `{ status: 'pending', requestId }` — the target requires approval; the
124
+ * server created a contact-request (kind: 'group_invite') routed to the
125
+ * approver. The actual group join happens when that request is approved
126
+ * (you can listen for `contact.approved` SSE events to know when).
127
+ *
128
+ * Throws `CanonApiError` for hard failures (block, inactive, owner-only,
129
+ * member cap, requester not authorized).
130
+ */
131
+ addMember(conversationId: string, userId: string): Promise<AddMemberResult>;
132
+ removeMember(conversationId: string, userId: string): Promise<void>;
133
+ uploadMedia(conversationId: string, data: string, mimeType: string, fileName?: string): Promise<{
134
+ url: string;
135
+ attachment: import('@canonmsg/core').MediaAttachment;
136
+ }>;
137
+ private handleContactRequestEvent;
138
+ private handleContactGraphEvent;
139
+ private handleMessageUpdatedEvent;
140
+ stop(): Promise<void>;
141
+ private hasInterruptSupport;
142
+ private hasStopAndDropSupport;
143
+ private hasNewSessionSupport;
144
+ private hasRuntimeSignalSupport;
145
+ private hasRuntimePrimitiveSupport;
146
+ private hasRuntimeControlSupport;
147
+ private supportsInputInterrupt;
148
+ private buildRuntimeDescriptor;
149
+ private buildRuntimeCapabilities;
150
+ private publishAgentRuntime;
151
+ private startRuntimeHeartbeat;
152
+ private stopRuntimeHeartbeat;
153
+ private clearAgentRuntime;
154
+ private rememberConversationId;
155
+ private rememberConversationMembers;
156
+ private handleConversationUpdated;
157
+ private buildGroupContext;
158
+ /**
159
+ * Shared `/control` channel poller, configured to the agent-sdk host
160
+ * profile pinned by core's characterization tests: flat 2s single-flight
161
+ * cadence, parallel conversations, signal + primitive keys (no session),
162
+ * eager signal baseline, and TTL'd primitive dedupe released on successful
163
+ * consume. The poller talks only to the scoped RTDB handle captured in
164
+ * start() — never the module-global default client.
165
+ */
166
+ private ensureControlPoller;
167
+ private baselineRuntimeControlSignals;
168
+ private startRuntimeControlPolling;
169
+ private stopRuntimeControlPolling;
170
+ private handleRuntimePrimitiveEvent;
171
+ private handleRuntimeSignalEvent;
172
+ private firstActiveTurn;
173
+ private publishAcceptedRuntimeSignal;
174
+ private abortActiveTurns;
175
+ private resolveBatchDeliveryIntent;
176
+ private markQueuedMessagesAccepted;
177
+ private notifyMessageInterrupt;
178
+ /**
179
+ * Builds a runtime-state publisher bound to this agent's scoped RTDB
180
+ * handle (captured in start()). Threading the handle keeps every
181
+ * publish on this agent's own credentials — without it the publisher
182
+ * would fall back to core's deprecated module-global RTDB client,
183
+ * where the last-started agent's token wins in multi-agent processes.
184
+ */
185
+ private createRuntimeStatePublisher;
186
+ private requireRuntimeStatePublisher;
187
+ private handleMessages;
188
+ private executeHandler;
189
+ static register(options: {
190
+ name: string;
191
+ description: string;
192
+ ownerPhone: string;
193
+ developerInfo: string;
194
+ avatarUrl?: string;
195
+ baseUrl?: string;
196
+ }): Promise<{
197
+ requestId: string;
198
+ pollToken?: string;
199
+ }>;
200
+ static checkStatus(requestId: string, options?: string | {
201
+ baseUrl?: string;
202
+ pollToken?: string;
203
+ }): Promise<{
204
+ status: string;
205
+ agentName: string;
206
+ agentId?: string;
207
+ apiKey?: string;
208
+ apiKeyDelivered?: boolean;
209
+ }>;
210
+ static ackStatus(requestId: string, options?: string | {
211
+ baseUrl?: string;
212
+ pollToken?: string;
213
+ }): Promise<void>;
214
+ }