@agentick/connector 0.5.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.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # @agentick/connector
2
+
3
+ Bridge external platforms to Agentick sessions. Handles content filtering,
4
+ delivery timing, rate limiting, and tool confirmations so platform adapters
5
+ only need to handle I/O.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @agentick/connector
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { createConnector } from "@agentick/connector";
17
+ import { TelegramPlatform } from "@agentick/connector-telegram";
18
+
19
+ const connector = createConnector(
20
+ client,
21
+ new TelegramPlatform({
22
+ token: process.env.TELEGRAM_BOT_TOKEN!,
23
+ }),
24
+ {
25
+ sessionId: "main",
26
+ contentPolicy: "summarized",
27
+ deliveryStrategy: "on-idle",
28
+ },
29
+ );
30
+
31
+ await connector.start();
32
+ ```
33
+
34
+ ## How It Works
35
+
36
+ ```
37
+ External Platform
38
+ |
39
+ v
40
+ ConnectorPlatform.start(bridge)
41
+ |
42
+ |-- inbound: bridge.send("user message")
43
+ | |
44
+ | v
45
+ | RateLimiter --> ConnectorSession.send() --> AgentickClient
46
+ |
47
+ +-- outbound: bridge.onDeliver(handler)
48
+ ^
49
+ |
50
+ DeliveryBuffer (timing) --> ContentPipeline (filter) --> MessageLog
51
+ ```
52
+
53
+ `createConnector` wires a `ConnectorPlatform` to a `ConnectorSession`. The
54
+ session composes `MessageLog` and `ToolConfirmations` from `@agentick/client`
55
+ with `subscribe: false`, adding content filtering and delivery timing on top.
56
+
57
+ ## Content Policy
58
+
59
+ Controls what content reaches the platform.
60
+
61
+ ```typescript
62
+ type ContentPolicy = "full" | "text-only" | "summarized" | ContentPolicyFn;
63
+ ```
64
+
65
+ - **`"text-only"`** (default) — Strip tool_use and tool_result blocks, keep
66
+ text and images.
67
+ - **`"summarized"`** — Collapse tool calls into brief summaries
68
+ (`[Read config.ts]`, `[Ran: npm test]`), keep text.
69
+ - **`"full"`** — Pass through unchanged.
70
+ - **Function** — Full control. Receives a `ChatMessage`, returns it
71
+ transformed or `null` to drop.
72
+
73
+ ### Custom Tool Summaries
74
+
75
+ Override the built-in summaries for the `"summarized"` policy:
76
+
77
+ ```typescript
78
+ import { createToolSummarizer } from "@agentick/connector";
79
+
80
+ const summarizer = createToolSummarizer({
81
+ my_search: (input) => `[Searched: ${input.query}]`,
82
+ deploy: () => `[Deploying...]`,
83
+ });
84
+
85
+ createConnector(client, platform, {
86
+ sessionId: "main",
87
+ contentPolicy: "summarized",
88
+ toolSummarizer: summarizer,
89
+ });
90
+ ```
91
+
92
+ Built-in summaries: `glob`, `grep`, `read_file`/`ReadFile`, `write_file`/
93
+ `WriteFile`, `edit_file`/`EditFile`, `shell`. Unknown tools get `[Used name]`.
94
+
95
+ ## Delivery Strategy
96
+
97
+ Controls when messages are delivered to the platform.
98
+
99
+ ```typescript
100
+ type DeliveryStrategy = "immediate" | "on-idle" | "debounced";
101
+ ```
102
+
103
+ - **`"on-idle"`** (default) — Deliver only when execution completes. Produces
104
+ clean, complete messages. Best for iMessage.
105
+ - **`"debounced"`** — Deliver after `debounceMs` (default: 1500) of no new
106
+ content. Good for Telegram message editing.
107
+ - **`"immediate"`** — Deliver on every state change. For platforms that render
108
+ incrementally.
109
+
110
+ ## Rate Limiting
111
+
112
+ Throttle inbound messages with sliding-window per-minute and daily caps.
113
+
114
+ ```typescript
115
+ createConnector(client, platform, {
116
+ sessionId: "main",
117
+ rateLimit: {
118
+ maxPerMinute: 10,
119
+ maxPerDay: 200,
120
+ onLimited: ({ remaining, resetMs }) => `Slow down! Try again in ${Math.ceil(resetMs / 1000)}s.`,
121
+ },
122
+ });
123
+ ```
124
+
125
+ When `onLimited` returns a string, it's delivered as a synthetic message.
126
+ Return `void` to silently drop.
127
+
128
+ ## Tool Confirmations
129
+
130
+ When the agent requests tool approval, connectors receive the confirmation
131
+ through `bridge.onConfirmation()`. The platform presents it to the user
132
+ (inline keyboard, text prompt, etc.) and calls `respond()` with the result.
133
+
134
+ The full response text is passed as `reason` so the model can interpret
135
+ nuanced answers like "yes but skip the tests".
136
+
137
+ ```typescript
138
+ import { parseTextConfirmation, formatConfirmationMessage } from "@agentick/connector";
139
+
140
+ const message = formatConfirmationMessage(request);
141
+ // "Allow shell to execute?\n\n command: rm -rf /tmp/test"
142
+
143
+ const response = parseTextConfirmation("yes but only in /tmp");
144
+ // { approved: true, reason: "yes but only in /tmp" }
145
+ ```
146
+
147
+ ## ConnectorSession
148
+
149
+ Use `ConnectorSession` directly for more control:
150
+
151
+ ```typescript
152
+ import { ConnectorSession } from "@agentick/connector";
153
+
154
+ const session = new ConnectorSession(client, {
155
+ sessionId: "main",
156
+ contentPolicy: "summarized",
157
+ deliveryStrategy: "on-idle",
158
+ });
159
+
160
+ session.onDeliver((output) => {
161
+ for (const msg of output.messages) {
162
+ sendToUser(extractText(msg.content));
163
+ }
164
+ if (output.isComplete) {
165
+ showTypingIndicator(false);
166
+ }
167
+ });
168
+
169
+ session.onConfirmation((request, respond) => {
170
+ promptUser(formatConfirmationMessage(request), (answer) => {
171
+ respond(parseTextConfirmation(answer));
172
+ });
173
+ });
174
+
175
+ session.send("Hello agent!");
176
+ ```
177
+
178
+ ## Writing a Platform Adapter
179
+
180
+ Implement `ConnectorPlatform` — two methods, one interface:
181
+
182
+ ```typescript
183
+ import type { ConnectorPlatform, ConnectorBridge } from "@agentick/connector";
184
+
185
+ export class MyPlatform implements ConnectorPlatform {
186
+ async start(bridge: ConnectorBridge): Promise<void> {
187
+ // 1. Subscribe to your platform's inbound messages
188
+ this.onMessage((text) => bridge.send(text));
189
+
190
+ // 2. Handle outbound delivery
191
+ bridge.onDeliver((output) => {
192
+ for (const msg of output.messages) {
193
+ this.sendToUser(extractText(msg.content));
194
+ }
195
+ });
196
+
197
+ // 3. Handle tool confirmations
198
+ bridge.onConfirmation((request, respond) => {
199
+ this.promptUser(request, (answer) => {
200
+ respond(parseTextConfirmation(answer));
201
+ });
202
+ });
203
+ }
204
+
205
+ async stop(): Promise<void> {
206
+ // Clean up connections, timers, etc.
207
+ }
208
+ }
209
+ ```
210
+
211
+ The bridge provides:
212
+
213
+ | Method | Direction | Purpose |
214
+ | -------------------------------- | --------- | ---------------------------------- |
215
+ | `bridge.send(text)` | Inbound | Push a user message to the agent |
216
+ | `bridge.sendInput(input)` | Inbound | Push a rich `SendInput` |
217
+ | `bridge.onDeliver(handler)` | Outbound | Receive filtered, timed messages |
218
+ | `bridge.onConfirmation(handler)` | Outbound | Receive tool confirmation requests |
219
+ | `bridge.abort(reason?)` | Control | Cancel current execution |
220
+ | `bridge.destroy()` | Control | Tear down the session |
221
+
222
+ All outbound messages are already filtered by the content policy and timed by
223
+ the delivery strategy. The platform just handles I/O.
224
+
225
+ ## Config Reference
226
+
227
+ ```typescript
228
+ interface ConnectorConfig {
229
+ sessionId: string;
230
+ contentPolicy?: ContentPolicy; // default: "text-only"
231
+ deliveryStrategy?: DeliveryStrategy; // default: "on-idle"
232
+ debounceMs?: number; // default: 1500 (for "debounced")
233
+ toolSummarizer?: ToolSummarizer; // custom summaries for "summarized"
234
+ rateLimit?: RateLimitConfig;
235
+ autoSubscribe?: boolean; // default: true
236
+ }
237
+ ```
238
+
239
+ ## Exports
240
+
241
+ ```typescript
242
+ // Core
243
+ export { ConnectorSession } from "./connector-session.js";
244
+ export { createConnector } from "./create-connector.js";
245
+
246
+ // Content pipeline
247
+ export {
248
+ buildContentFilter,
249
+ applyContentPolicy,
250
+ createToolSummarizer,
251
+ } from "./content-pipeline.js";
252
+ export type { ToolSummarizer } from "./content-pipeline.js";
253
+
254
+ // Delivery + rate limiting
255
+ export { DeliveryBuffer, RateLimiter } from "./delivery-buffer.js";
256
+
257
+ // Text utilities
258
+ export { parseTextConfirmation, formatConfirmationMessage } from "./text-utils.js";
259
+ export { extractText } from "@agentick/shared"; // re-exported for convenience
260
+
261
+ // Types
262
+ export type {
263
+ ContentPolicy,
264
+ ContentPolicyFn,
265
+ DeliveryStrategy,
266
+ RateLimitConfig,
267
+ ConnectorConfig,
268
+ ConnectorOutput,
269
+ ConnectorPlatform,
270
+ ConnectorBridge,
271
+ } from "./types.js";
272
+ ```
@@ -0,0 +1,56 @@
1
+ import type { AgentickClient } from "@agentick/client";
2
+ import type { SendInput, ToolConfirmationResponse } from "@agentick/shared";
3
+ import type { ToolConfirmationRequest } from "@agentick/shared";
4
+ import type { ConnectorConfig, ConnectorOutput, ConnectorStatus, ConnectorStatusEvent } from "./types.js";
5
+ /**
6
+ * Bridges an Agentick session to a connector platform.
7
+ *
8
+ * Composes `MessageLog` + `ToolConfirmations` with `subscribe: false`
9
+ * and a single event fan-out — same pattern as `ChatSession`, but
10
+ * without UI concerns (MessageSteering, LineEditor, AttachmentManager).
11
+ *
12
+ * Adds content pipeline (filtering/transformation) and delivery strategy
13
+ * (buffered outbound) on top.
14
+ */
15
+ export declare class ConnectorSession {
16
+ private readonly _messageLog;
17
+ private readonly _confirmations;
18
+ private readonly _contentFilter;
19
+ private readonly _deliveryBuffer;
20
+ private readonly _rateLimiter;
21
+ private readonly _retryConfig;
22
+ private readonly _accessor;
23
+ private _isExecuting;
24
+ private _destroyed;
25
+ private _lastDeliveredCount;
26
+ private _status;
27
+ private _deliverListeners;
28
+ private _confirmationListeners;
29
+ private _statusListeners;
30
+ private _executionStartListeners;
31
+ private _executionEndListeners;
32
+ private _retryTimers;
33
+ private _unsubscribeEvents;
34
+ private _unsubscribeConfirmations;
35
+ constructor(client: AgentickClient, config: ConnectorConfig);
36
+ get status(): ConnectorStatus;
37
+ send(text: string): void;
38
+ sendInput(input: SendInput): void;
39
+ respondToConfirmation(response: ToolConfirmationResponse): void;
40
+ abort(reason?: string): void;
41
+ reportStatus(status: ConnectorStatus, error?: Error): void;
42
+ onStatus(handler: (event: ConnectorStatusEvent) => void): () => void;
43
+ onDeliver(handler: (output: ConnectorOutput) => void | Promise<void>): () => void;
44
+ onConfirmation(handler: (request: ToolConfirmationRequest, respond: (r: ToolConfirmationResponse) => void) => void): () => void;
45
+ onExecutionStart(handler: () => void): () => void;
46
+ onExecutionEnd(handler: () => void): () => void;
47
+ destroy(): void;
48
+ /** Returns true if rate-limited (caller should bail). */
49
+ private _checkRateLimit;
50
+ private _hasNewContent;
51
+ private _emitDelivery;
52
+ private _deliverWithRetry;
53
+ private _handleDeliveryError;
54
+ private _emitSyntheticMessage;
55
+ }
56
+ //# sourceMappingURL=connector-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector-session.d.ts","sourceRoot":"","sources":["../src/connector-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAe,SAAS,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EACf,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAcpB;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAE3B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,OAAO,CAAmC;IAElD,OAAO,CAAC,iBAAiB,CAAgE;IACzF,OAAO,CAAC,sBAAsB,CAE1B;IACJ,OAAO,CAAC,gBAAgB,CAAoD;IAC5E,OAAO,CAAC,wBAAwB,CAAyB;IACzD,OAAO,CAAC,sBAAsB,CAAyB;IAEvD,OAAO,CAAC,YAAY,CAA4C;IAChE,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,yBAAyB,CAA6B;gBAElD,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe;IA8F3D,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAKjC,qBAAqB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IAI/D,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAa1D,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI;IAKpE,SAAS,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI;IAKjF,cAAc,CACZ,OAAO,EAAE,CACP,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,CAAC,CAAC,EAAE,wBAAwB,KAAK,IAAI,KAC3C,IAAI,GACR,MAAM,IAAI;IAKb,gBAAgB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAKjD,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAK/C,OAAO,IAAI,IAAI;IAkBf,yDAAyD;IACzD,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,oBAAoB;IAuB5B,OAAO,CAAC,qBAAqB;CAoB9B"}
@@ -0,0 +1,271 @@
1
+ import { MessageLog, ToolConfirmations } from "@agentick/client";
2
+ import { buildContentFilter, applyContentPolicy } from "./content-pipeline.js";
3
+ import { DeliveryBuffer, RateLimiter } from "./delivery-buffer.js";
4
+ let syntheticIdCounter = 0;
5
+ /**
6
+ * Bridges an Agentick session to a connector platform.
7
+ *
8
+ * Composes `MessageLog` + `ToolConfirmations` with `subscribe: false`
9
+ * and a single event fan-out — same pattern as `ChatSession`, but
10
+ * without UI concerns (MessageSteering, LineEditor, AttachmentManager).
11
+ *
12
+ * Adds content pipeline (filtering/transformation) and delivery strategy
13
+ * (buffered outbound) on top.
14
+ */
15
+ export class ConnectorSession {
16
+ _messageLog;
17
+ _confirmations;
18
+ _contentFilter;
19
+ _deliveryBuffer;
20
+ _rateLimiter;
21
+ _retryConfig;
22
+ _accessor;
23
+ _isExecuting = false;
24
+ _destroyed = false;
25
+ _lastDeliveredCount = 0;
26
+ _status = "disconnected";
27
+ _deliverListeners = new Set();
28
+ _confirmationListeners = new Set();
29
+ _statusListeners = new Set();
30
+ _executionStartListeners = new Set();
31
+ _executionEndListeners = new Set();
32
+ _retryTimers = new Set();
33
+ _unsubscribeEvents = null;
34
+ _unsubscribeConfirmations = null;
35
+ constructor(client, config) {
36
+ const sessionId = config.sessionId;
37
+ this._contentFilter = buildContentFilter(config.contentPolicy ?? "text-only", config.toolSummarizer);
38
+ this._rateLimiter = config.rateLimit ? new RateLimiter(config.rateLimit) : null;
39
+ const retry = config.retry ?? {};
40
+ this._retryConfig = {
41
+ maxAttempts: retry.maxAttempts ?? 3,
42
+ baseDelay: retry.baseDelay ?? 1000,
43
+ maxDelay: retry.maxDelay ?? 30_000,
44
+ onExhausted: retry.onExhausted,
45
+ };
46
+ // Create primitives in externally-driven mode
47
+ this._messageLog = new MessageLog(client, {
48
+ sessionId,
49
+ renderMode: config.renderMode ?? "message",
50
+ subscribe: false,
51
+ });
52
+ this._confirmations = new ToolConfirmations(client, {
53
+ sessionId,
54
+ policy: config.confirmationPolicy,
55
+ subscribe: false,
56
+ });
57
+ // Delivery buffer controls outbound timing
58
+ this._deliveryBuffer = new DeliveryBuffer({
59
+ strategy: config.deliveryStrategy ?? "on-idle",
60
+ debounceMs: config.debounceMs ?? 1500,
61
+ onDeliver: () => this._emitDelivery(),
62
+ });
63
+ // Single event subscription — fan out to message log + delivery buffer
64
+ const accessor = client.session(sessionId);
65
+ this._accessor = accessor;
66
+ if (config.autoSubscribe !== false) {
67
+ accessor.subscribe();
68
+ }
69
+ this._unsubscribeEvents = accessor.onEvent((event) => {
70
+ this._messageLog.processEvent(event);
71
+ if (event.type === "execution_start") {
72
+ this._isExecuting = true;
73
+ for (const listener of this._executionStartListeners) {
74
+ try {
75
+ listener();
76
+ }
77
+ catch (e) {
78
+ console.error("Error in execution start listener:", e);
79
+ }
80
+ }
81
+ }
82
+ if (event.type === "execution_end") {
83
+ this._isExecuting = false;
84
+ for (const listener of this._executionEndListeners) {
85
+ try {
86
+ listener();
87
+ }
88
+ catch (e) {
89
+ console.error("Error in execution end listener:", e);
90
+ }
91
+ }
92
+ this._deliveryBuffer.markIdle();
93
+ return;
94
+ }
95
+ // Poke delivery buffer on message changes
96
+ if (this._hasNewContent()) {
97
+ this._deliveryBuffer.poke();
98
+ }
99
+ });
100
+ this._unsubscribeConfirmations = accessor.onToolConfirmation((request, respond) => {
101
+ this._confirmations.handleConfirmation(request, respond);
102
+ // Notify connector listeners
103
+ for (const listener of this._confirmationListeners) {
104
+ try {
105
+ listener(request, respond);
106
+ }
107
+ catch (e) {
108
+ console.error("Error in connector confirmation listener:", e);
109
+ }
110
+ }
111
+ });
112
+ }
113
+ // --- Public API ---
114
+ get status() {
115
+ return this._status;
116
+ }
117
+ send(text) {
118
+ if (this._checkRateLimit())
119
+ return;
120
+ this._accessor.send({ messages: [{ role: "user", content: [{ type: "text", text }] }] });
121
+ }
122
+ sendInput(input) {
123
+ if (this._checkRateLimit())
124
+ return;
125
+ this._accessor.send(input);
126
+ }
127
+ respondToConfirmation(response) {
128
+ this._confirmations.respond(response);
129
+ }
130
+ abort(reason) {
131
+ this._accessor.abort(reason);
132
+ }
133
+ reportStatus(status, error) {
134
+ this._status = status;
135
+ const event = { status };
136
+ if (error)
137
+ event.error = error;
138
+ for (const listener of this._statusListeners) {
139
+ try {
140
+ listener(event);
141
+ }
142
+ catch (e) {
143
+ console.error("Error in connector status listener:", e);
144
+ }
145
+ }
146
+ }
147
+ onStatus(handler) {
148
+ this._statusListeners.add(handler);
149
+ return () => this._statusListeners.delete(handler);
150
+ }
151
+ onDeliver(handler) {
152
+ this._deliverListeners.add(handler);
153
+ return () => this._deliverListeners.delete(handler);
154
+ }
155
+ onConfirmation(handler) {
156
+ this._confirmationListeners.add(handler);
157
+ return () => this._confirmationListeners.delete(handler);
158
+ }
159
+ onExecutionStart(handler) {
160
+ this._executionStartListeners.add(handler);
161
+ return () => this._executionStartListeners.delete(handler);
162
+ }
163
+ onExecutionEnd(handler) {
164
+ this._executionEndListeners.add(handler);
165
+ return () => this._executionEndListeners.delete(handler);
166
+ }
167
+ destroy() {
168
+ this._destroyed = true;
169
+ this._unsubscribeEvents?.();
170
+ this._unsubscribeConfirmations?.();
171
+ this._messageLog.destroy();
172
+ this._confirmations.destroy();
173
+ this._deliveryBuffer.destroy();
174
+ for (const timer of this._retryTimers)
175
+ clearTimeout(timer);
176
+ this._retryTimers.clear();
177
+ this._deliverListeners.clear();
178
+ this._confirmationListeners.clear();
179
+ this._statusListeners.clear();
180
+ this._executionStartListeners.clear();
181
+ this._executionEndListeners.clear();
182
+ }
183
+ // --- Private ---
184
+ /** Returns true if rate-limited (caller should bail). */
185
+ _checkRateLimit() {
186
+ if (!this._rateLimiter)
187
+ return false;
188
+ const check = this._rateLimiter.check();
189
+ if (check.allowed)
190
+ return false;
191
+ if (check.reply)
192
+ this._emitSyntheticMessage(check.reply);
193
+ return true;
194
+ }
195
+ _hasNewContent() {
196
+ return this._messageLog.messages.length > this._lastDeliveredCount;
197
+ }
198
+ _emitDelivery() {
199
+ const allMessages = this._messageLog.messages;
200
+ const newMessages = allMessages.slice(this._lastDeliveredCount);
201
+ this._lastDeliveredCount = allMessages.length;
202
+ if (newMessages.length === 0)
203
+ return;
204
+ // Only deliver assistant messages — user messages originated from an input
205
+ // source and should never be echoed back to the platform.
206
+ const assistantOnly = newMessages.filter((m) => m.role === "assistant");
207
+ if (assistantOnly.length === 0 && this._isExecuting)
208
+ return;
209
+ const filtered = applyContentPolicy(assistantOnly, this._contentFilter);
210
+ const isComplete = !this._isExecuting;
211
+ if (filtered.length === 0 && !isComplete)
212
+ return;
213
+ const output = {
214
+ messages: filtered,
215
+ isComplete,
216
+ };
217
+ for (const listener of this._deliverListeners) {
218
+ this._deliverWithRetry(listener, output);
219
+ }
220
+ }
221
+ _deliverWithRetry(listener, output, attempt = 0) {
222
+ try {
223
+ const result = listener(output);
224
+ if (result && typeof result.then === "function") {
225
+ result.then(undefined, (err) => {
226
+ this._handleDeliveryError(err, listener, output, attempt);
227
+ });
228
+ }
229
+ }
230
+ catch (err) {
231
+ this._handleDeliveryError(err, listener, output, attempt);
232
+ }
233
+ }
234
+ _handleDeliveryError(err, listener, output, attempt) {
235
+ if (this._destroyed)
236
+ return;
237
+ const nextAttempt = attempt + 1;
238
+ if (nextAttempt >= this._retryConfig.maxAttempts) {
239
+ console.error(`Delivery failed after ${this._retryConfig.maxAttempts} attempts:`, err);
240
+ this._retryConfig.onExhausted?.(err, output);
241
+ return;
242
+ }
243
+ const delay = Math.min(this._retryConfig.baseDelay * 2 ** attempt, this._retryConfig.maxDelay);
244
+ const timer = setTimeout(() => {
245
+ this._retryTimers.delete(timer);
246
+ this._deliverWithRetry(listener, output, nextAttempt);
247
+ }, delay);
248
+ this._retryTimers.add(timer);
249
+ }
250
+ _emitSyntheticMessage(text) {
251
+ const output = {
252
+ messages: [
253
+ {
254
+ id: `synthetic_${++syntheticIdCounter}`,
255
+ role: "assistant",
256
+ content: text,
257
+ },
258
+ ],
259
+ isComplete: true,
260
+ };
261
+ for (const listener of this._deliverListeners) {
262
+ try {
263
+ listener(output);
264
+ }
265
+ catch (e) {
266
+ console.error("Error in connector delivery listener:", e);
267
+ }
268
+ }
269
+ }
270
+ }
271
+ //# sourceMappingURL=connector-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector-session.js","sourceRoot":"","sources":["../src/connector-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ChatMessage } from "@agentick/client";
2
+ import type { ContentPolicy, ContentPolicyFn } from "./types.js";
3
+ /**
4
+ * Summarize a tool call as human-readable text.
5
+ * Connectors can override this per-tool via ContentPolicy functions,
6
+ * or provide a custom `summarizeTool` in ConnectorConfig.
7
+ */
8
+ export type ToolSummarizer = (name: string, input: Record<string, unknown>) => string;
9
+ /**
10
+ * Create a tool summarizer with optional custom overrides.
11
+ * Custom summaries are checked first, then defaults, then generic fallback.
12
+ */
13
+ export declare function createToolSummarizer(custom?: Record<string, (input: Record<string, unknown>) => string>): ToolSummarizer;
14
+ /**
15
+ * Build a filter function from a ContentPolicy.
16
+ */
17
+ export declare function buildContentFilter(policy: ContentPolicy, toolSummarizer?: ToolSummarizer): ContentPolicyFn;
18
+ /**
19
+ * Apply the content filter to a batch of messages.
20
+ * Returns only messages that survive filtering.
21
+ */
22
+ export declare function applyContentPolicy(messages: readonly ChatMessage[], filter: ContentPolicyFn): ChatMessage[];
23
+ //# sourceMappingURL=content-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-pipeline.d.ts","sourceRoot":"","sources":["../src/content-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;AAsCtF;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,GAClE,cAAc,CAchB;AAKD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,CAajB;AAgDD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,MAAM,EAAE,eAAe,GACtB,WAAW,EAAE,CAYf"}