@tangle-network/agent-core 0.9.5 → 0.9.7
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/auth/browser.d.ts +1 -1
- package/dist/auth/browser.js +1 -1
- package/dist/auth/index.d.ts +3 -3
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/computer-use/index.d.ts.map +1 -1
- package/dist/computer-use/index.js +4 -3
- package/dist/computer-use/index.js.map +1 -1
- package/dist/{errors-RaBbEzQu.js → errors-GuWACHTg.js} +11 -8
- package/dist/{errors-RaBbEzQu.js.map → errors-GuWACHTg.js.map} +1 -1
- package/dist/events/index.d.ts +2 -2
- package/dist/events/index.js +1 -1
- package/dist/{events-CUWh9qrv.js → events-U7kxNUpM.js} +7 -5
- package/dist/{events-CUWh9qrv.js.map → events-U7kxNUpM.js.map} +1 -1
- package/dist/{index-D59fZ7n3.d.ts → index-BFYASYJk.d.ts} +1 -1
- package/dist/index-BFYASYJk.d.ts.map +1 -0
- package/dist/{index-Bgao-NCe.d.ts → index-BvjA5i93.d.ts} +1 -1
- package/dist/index-BvjA5i93.d.ts.map +1 -0
- package/dist/{index-HMlPCgTI.d.ts → index-CKDeaS7l.d.ts} +2 -3
- package/dist/index-CKDeaS7l.d.ts.map +1 -0
- package/dist/{index-CDLuQTT2.d.ts → index-CQPGv8jg.d.ts} +10 -11
- package/dist/index-CQPGv8jg.d.ts.map +1 -0
- package/dist/{index-C_1MnL24.d.ts → index-CuBvSsBf.d.ts} +1 -1
- package/dist/index-CuBvSsBf.d.ts.map +1 -0
- package/dist/{index-B4yy8ghH.d.ts → index-Dq6SfGaX.d.ts} +1 -1
- package/dist/index-Dq6SfGaX.d.ts.map +1 -0
- package/dist/index.d.ts +8 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -26
- package/dist/index.js.map +1 -1
- package/dist/interactions/index.d.ts +1 -2
- package/dist/interactions/index.d.ts.map +1 -1
- package/dist/interactions/index.js +2 -2
- package/dist/interactions/index.js.map +1 -1
- package/dist/interactions/mcp-server.d.ts +1 -2
- package/dist/interactions/mcp-server.d.ts.map +1 -1
- package/dist/interactions/mcp-server.js +3 -2
- package/dist/interactions/mcp-server.js.map +1 -1
- package/dist/{lifecycle-CXKYetbu.js → lifecycle-BljLcnY5.js} +1 -1
- package/dist/{lifecycle-CXKYetbu.js.map → lifecycle-BljLcnY5.js.map} +1 -1
- package/dist/resilience/index.d.ts +2 -2
- package/dist/resilience/index.js +1 -1
- package/dist/{resilience-v3NFIdDo.js → resilience-Cv5tqIDU.js} +42 -15
- package/dist/resilience-Cv5tqIDU.js.map +1 -0
- package/dist/sse/index.d.ts.map +1 -1
- package/dist/sse/index.js +1 -1
- package/dist/sse/index.js.map +1 -1
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.js +1 -1
- package/dist/{telemetry-x1wNw1P4.js → telemetry-DTOiMSzM.js} +1 -1
- package/dist/{telemetry-x1wNw1P4.js.map → telemetry-DTOiMSzM.js.map} +1 -1
- package/dist/{tokens-browser-EiSc2dah.d.ts → tokens-browser-DCV3-WHc.d.ts} +11 -9
- package/dist/tokens-browser-DCV3-WHc.d.ts.map +1 -0
- package/dist/{tools-D-I3A7Us.d.ts → tools-DeZkIW3h.d.ts} +1 -2
- package/dist/tools-DeZkIW3h.d.ts.map +1 -0
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +1 -1
- package/dist/{transport-XLxpQmUW.js → transport-DAfw3oL0.js} +5 -4
- package/dist/{transport-XLxpQmUW.js.map → transport-DAfw3oL0.js.map} +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +1 -1
- package/dist/{types-Boft7Ohf.js → types--u-Om3vE.js} +6 -2
- package/dist/{types-Boft7Ohf.js.map → types--u-Om3vE.js.map} +1 -1
- package/dist/{types-Ci7hcTnp.js → types-DVN5qATk.js} +1 -1
- package/dist/{types-Ci7hcTnp.js.map → types-DVN5qATk.js.map} +1 -1
- package/package.json +7 -7
- package/dist/index-B4yy8ghH.d.ts.map +0 -1
- package/dist/index-Bgao-NCe.d.ts.map +0 -1
- package/dist/index-CDLuQTT2.d.ts.map +0 -1
- package/dist/index-C_1MnL24.d.ts.map +0 -1
- package/dist/index-D59fZ7n3.d.ts.map +0 -1
- package/dist/index-HMlPCgTI.d.ts.map +0 -1
- package/dist/resilience-v3NFIdDo.js.map +0 -1
- package/dist/tokens-browser-EiSc2dah.d.ts.map +0 -1
- package/dist/tools-D-I3A7Us.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle-
|
|
1
|
+
{"version":3,"file":"lifecycle-BljLcnY5.js","names":[],"sources":["../src/interactions/lifecycle.ts"],"sourcesContent":["type LifecycleState = \"idle\" | \"starting\" | \"running\" | \"stopping\" | \"stopped\";\n\n/** Serialize one transport's single-use start and stop operations. */\nexport class SerializedTransportLifecycle {\n private state: LifecycleState = \"idle\";\n private tail: Promise<void> = Promise.resolve();\n\n start(open: () => Promise<void>): Promise<void> {\n return this.enqueue(async () => {\n if (this.state !== \"idle\") {\n throw new Error(`Interaction transport cannot start while ${this.state}`);\n }\n this.state = \"starting\";\n try {\n await open();\n this.state = \"running\";\n } catch (error) {\n this.state = \"stopped\";\n throw error;\n }\n });\n }\n\n stop(close: () => Promise<void>): Promise<void> {\n return this.enqueue(async () => {\n if (this.state === \"idle\" || this.state === \"stopped\") return;\n this.state = \"stopping\";\n try {\n await close();\n } finally {\n this.state = \"stopped\";\n }\n });\n }\n\n private enqueue(operation: () => Promise<void>): Promise<void> {\n const result = this.tail.then(operation);\n this.tail = result.catch(() => undefined);\n return result;\n }\n}\n\n/** Close active requests gracefully, then force-close a stuck local socket. */\nexport async function closeHttpServer(\n server: import(\"node:http\").Server,\n graceMs = 1_000,\n): Promise<void> {\n await new Promise<void>((resolve) => {\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n clearTimeout(forceClose);\n resolve();\n };\n const forceClose = setTimeout(() => {\n server.closeAllConnections?.();\n finish();\n }, graceMs);\n server.close(finish);\n server.closeIdleConnections?.();\n });\n}\n\n/** Give active work a bounded grace period before transport shutdown. */\nexport async function waitForSettled(\n promises: Iterable<Promise<unknown>>,\n graceMs = 1_000,\n): Promise<void> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n Promise.allSettled([...promises]),\n new Promise<void>((resolve) => {\n timer = setTimeout(resolve, graceMs);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n"],"mappings":";;AAGA,IAAa,+BAAb,MAA0C;CACxC,QAAgC;CAChC,OAA8B,QAAQ,QAAQ;CAE9C,MAAM,MAA0C;EAC9C,OAAO,KAAK,QAAQ,YAAY;GAC9B,IAAI,KAAK,UAAU,QACjB,MAAM,IAAI,MAAM,4CAA4C,KAAK,OAAO;GAE1E,KAAK,QAAQ;GACb,IAAI;IACF,MAAM,KAAK;IACX,KAAK,QAAQ;GACf,SAAS,OAAO;IACd,KAAK,QAAQ;IACb,MAAM;GACR;EACF,CAAC;CACH;CAEA,KAAK,OAA2C;EAC9C,OAAO,KAAK,QAAQ,YAAY;GAC9B,IAAI,KAAK,UAAU,UAAU,KAAK,UAAU,WAAW;GACvD,KAAK,QAAQ;GACb,IAAI;IACF,MAAM,MAAM;GACd,UAAU;IACR,KAAK,QAAQ;GACf;EACF,CAAC;CACH;CAEA,QAAgB,WAA+C;EAC7D,MAAM,SAAS,KAAK,KAAK,KAAK,SAAS;EACvC,KAAK,OAAO,OAAO,YAAY,KAAA,CAAS;EACxC,OAAO;CACT;AACF;;AAGA,eAAsB,gBACpB,QACA,UAAU,KACK;CACf,MAAM,IAAI,SAAe,YAAY;EACnC,IAAI,WAAW;EACf,MAAM,eAAe;GACnB,IAAI,UAAU;GACd,WAAW;GACX,aAAa,UAAU;GACvB,QAAQ;EACV;EACA,MAAM,aAAa,iBAAiB;GAClC,OAAO,sBAAsB;GAC7B,OAAO;EACT,GAAG,OAAO;EACV,OAAO,MAAM,MAAM;EACnB,OAAO,uBAAuB;CAChC,CAAC;AACH;;AAGA,eAAsB,eACpB,UACA,UAAU,KACK;CACf,IAAI;CACJ,IAAI;EACF,MAAM,QAAQ,KAAK,CACjB,QAAQ,WAAW,CAAC,GAAG,QAAQ,CAAC,GAChC,IAAI,SAAe,YAAY;GAC7B,QAAQ,WAAW,SAAS,OAAO;EACrC,CAAC,CACH,CAAC;CACH,UAAU;EACR,IAAI,OAAO,aAAa,KAAK;CAC/B;AACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ProtectionOptions, c as CircuitBreaker, d as CircuitOpenError, f as CircuitState, i as withTimeout, l as CircuitBreakerConfig, n as createTimeoutController, o as createProtectedFn, r as sleep, s as withProtection, t as TimeoutError, u as CircuitBreakerStats } from "../index-
|
|
2
|
-
export { CircuitBreaker, CircuitBreakerConfig, CircuitBreakerStats, CircuitOpenError, CircuitState, ProtectionOptions, TimeoutError, createProtectedFn, createTimeoutController, sleep, withProtection, withTimeout };
|
|
1
|
+
import { a as ProtectionOptions, c as CircuitBreaker, d as CircuitOpenError, f as CircuitState, i as withTimeout, l as CircuitBreakerConfig, n as createTimeoutController, o as createProtectedFn, r as sleep, s as withProtection, t as TimeoutError, u as CircuitBreakerStats } from "../index-CKDeaS7l.js";
|
|
2
|
+
export { CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerStats, CircuitOpenError, type CircuitState, type ProtectionOptions, TimeoutError, createProtectedFn, createTimeoutController, sleep, withProtection, withTimeout };
|
package/dist/resilience/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as sleep, c as CircuitOpenError, i as createTimeoutController, n as withProtection, o as withTimeout, r as TimeoutError, s as CircuitBreaker, t as createProtectedFn } from "../resilience-
|
|
1
|
+
import { a as sleep, c as CircuitOpenError, i as createTimeoutController, n as withProtection, o as withTimeout, r as TimeoutError, s as CircuitBreaker, t as createProtectedFn } from "../resilience-Cv5tqIDU.js";
|
|
2
2
|
export { CircuitBreaker, CircuitOpenError, TimeoutError, createProtectedFn, createTimeoutController, sleep, withProtection, withTimeout };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as SDKError } from "./errors-
|
|
1
|
+
import { t as SDKError } from "./errors-GuWACHTg.js";
|
|
2
2
|
//#region src/resilience/circuit-breaker.ts
|
|
3
3
|
/**
|
|
4
4
|
* Circuit Breaker
|
|
@@ -28,6 +28,8 @@ var CircuitOpenError = class extends SDKError {
|
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
var CircuitBreaker = class {
|
|
31
|
+
name;
|
|
32
|
+
config;
|
|
31
33
|
state = "closed";
|
|
32
34
|
failures = 0;
|
|
33
35
|
successes = 0;
|
|
@@ -145,14 +147,14 @@ var TimeoutError = class extends SDKError {
|
|
|
145
147
|
*/
|
|
146
148
|
function withTimeout(promise, timeoutMs, message) {
|
|
147
149
|
if (timeoutMs <= 0) return promise;
|
|
148
|
-
let
|
|
150
|
+
let clearTimer;
|
|
149
151
|
const timeoutPromise = new Promise((_, reject) => {
|
|
150
|
-
|
|
152
|
+
clearTimer = armTimeout(timeoutMs, () => {
|
|
151
153
|
reject(new TimeoutError(message || `Operation timed out after ${timeoutMs}ms`, timeoutMs));
|
|
152
|
-
}
|
|
154
|
+
});
|
|
153
155
|
});
|
|
154
156
|
return Promise.race([promise, timeoutPromise]).finally(() => {
|
|
155
|
-
|
|
157
|
+
clearTimer?.();
|
|
156
158
|
});
|
|
157
159
|
}
|
|
158
160
|
/**
|
|
@@ -161,14 +163,14 @@ function withTimeout(promise, timeoutMs, message) {
|
|
|
161
163
|
*/
|
|
162
164
|
function createTimeoutController(timeoutMs) {
|
|
163
165
|
const controller = new AbortController();
|
|
164
|
-
let
|
|
165
|
-
if (timeoutMs > 0)
|
|
166
|
+
let clearTimer;
|
|
167
|
+
if (timeoutMs > 0) clearTimer = armTimeout(timeoutMs, () => {
|
|
166
168
|
controller.abort(new TimeoutError("Request timeout", timeoutMs));
|
|
167
|
-
}
|
|
169
|
+
});
|
|
168
170
|
return {
|
|
169
171
|
controller,
|
|
170
172
|
cleanup: () => {
|
|
171
|
-
|
|
173
|
+
clearTimer?.();
|
|
172
174
|
}
|
|
173
175
|
};
|
|
174
176
|
}
|
|
@@ -182,13 +184,38 @@ function sleep(ms, signal) {
|
|
|
182
184
|
reject(signal.reason);
|
|
183
185
|
return;
|
|
184
186
|
}
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
reject(signal
|
|
189
|
-
}
|
|
187
|
+
const onAbort = () => {
|
|
188
|
+
clearTimer();
|
|
189
|
+
signal?.removeEventListener("abort", onAbort);
|
|
190
|
+
reject(signal?.reason);
|
|
191
|
+
};
|
|
192
|
+
const clearTimer = armTimeout(ms, () => {
|
|
193
|
+
signal?.removeEventListener("abort", onAbort);
|
|
194
|
+
resolve();
|
|
195
|
+
});
|
|
196
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
190
197
|
});
|
|
191
198
|
}
|
|
199
|
+
/** Keep one absolute deadline; native timers overflow to 1ms beyond this chunk size. */
|
|
200
|
+
function armTimeout(ms, callback) {
|
|
201
|
+
const deadline = Date.now() + Math.max(0, ms);
|
|
202
|
+
if (!Number.isFinite(ms) || !Number.isSafeInteger(Math.ceil(deadline))) throw new SDKError("Timeout must produce a finite safe deadline", { code: "VALIDATION" });
|
|
203
|
+
let cleared = false;
|
|
204
|
+
let timer;
|
|
205
|
+
const arm = () => {
|
|
206
|
+
if (cleared) return;
|
|
207
|
+
timer = setTimeout(() => {
|
|
208
|
+
if (cleared) return;
|
|
209
|
+
if (Date.now() >= deadline) callback();
|
|
210
|
+
else arm();
|
|
211
|
+
}, Math.min(2147483647, Math.max(0, deadline - Date.now())));
|
|
212
|
+
};
|
|
213
|
+
arm();
|
|
214
|
+
return () => {
|
|
215
|
+
cleared = true;
|
|
216
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
217
|
+
};
|
|
218
|
+
}
|
|
192
219
|
//#endregion
|
|
193
220
|
//#region src/resilience/protection.ts
|
|
194
221
|
/**
|
|
@@ -218,4 +245,4 @@ function createProtectedFn(fn, options) {
|
|
|
218
245
|
//#endregion
|
|
219
246
|
export { sleep as a, CircuitOpenError as c, createTimeoutController as i, withProtection as n, withTimeout as o, TimeoutError as r, CircuitBreaker as s, createProtectedFn as t };
|
|
220
247
|
|
|
221
|
-
//# sourceMappingURL=resilience-
|
|
248
|
+
//# sourceMappingURL=resilience-Cv5tqIDU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilience-Cv5tqIDU.js","names":[],"sources":["../src/resilience/circuit-breaker.ts","../src/resilience/timeout.ts","../src/resilience/protection.ts"],"sourcesContent":["/**\n * Circuit Breaker\n *\n * Implements the circuit breaker pattern for fail-fast behavior when\n * downstream services are unhealthy. Prevents cascade failures by\n * stopping requests to failing services.\n *\n * States:\n * - CLOSED: Normal operation, requests pass through\n * - OPEN: Service unhealthy, requests fail immediately\n * - HALF_OPEN: Testing if service recovered\n */\n\nimport { SDKError } from \"../errors/index.js\";\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit */\n failureThreshold: number;\n /** Time in ms to wait before testing recovery (half-open) */\n resetTimeoutMs: number;\n /** Number of successes in half-open state to close circuit */\n successThreshold: number;\n /** Optional: Only count these error types as failures */\n failureFilter?: (error: unknown) => boolean;\n}\n\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failures: number;\n successes: number;\n lastFailureTime: number | null;\n totalFailures: number;\n totalSuccesses: number;\n totalRejected: number;\n}\n\nexport class CircuitOpenError extends SDKError {\n readonly circuitName: string;\n readonly resetAfterMs: number;\n\n constructor(name: string, resetAfterMs: number) {\n super(`Circuit breaker '${name}' is open`, {\n code: \"SERVER\",\n retryable: true,\n retryAfterMs: resetAfterMs,\n context: { circuitName: name },\n });\n this.name = \"CircuitOpenError\";\n this.circuitName = name;\n this.resetAfterMs = resetAfterMs;\n }\n}\n\nexport class CircuitBreaker {\n private state: CircuitState = \"closed\";\n private failures = 0;\n private successes = 0;\n private lastFailureTime: number | null = null;\n\n // Lifetime stats\n private totalFailures = 0;\n private totalSuccesses = 0;\n private totalRejected = 0;\n\n constructor(\n private readonly name: string,\n private readonly config: CircuitBreakerConfig,\n ) {\n if (config.failureThreshold < 1) {\n throw new Error(\"failureThreshold must be >= 1\");\n }\n if (config.resetTimeoutMs < 0) {\n throw new Error(\"resetTimeoutMs must be >= 0\");\n }\n if (config.successThreshold < 1) {\n throw new Error(\"successThreshold must be >= 1\");\n }\n }\n\n /**\n * Execute a function through the circuit breaker.\n * Throws CircuitOpenError if circuit is open.\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check if we should transition from open to half-open\n if (this.state === \"open\") {\n const timeSinceFailure = this.lastFailureTime\n ? Date.now() - this.lastFailureTime\n : Number.POSITIVE_INFINITY;\n\n if (timeSinceFailure >= this.config.resetTimeoutMs) {\n this.state = \"half-open\";\n this.successes = 0;\n } else {\n this.totalRejected++;\n throw new CircuitOpenError(\n this.name,\n this.config.resetTimeoutMs - timeSinceFailure,\n );\n }\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure(error);\n throw error;\n }\n }\n\n private onSuccess(): void {\n this.totalSuccesses++;\n\n if (this.state === \"half-open\") {\n this.successes++;\n if (this.successes >= this.config.successThreshold) {\n // Service recovered, close circuit\n this.state = \"closed\";\n this.failures = 0;\n this.successes = 0;\n }\n } else if (this.state === \"closed\") {\n // Reset failure count on success\n this.failures = 0;\n }\n }\n\n private onFailure(error: unknown): void {\n // Check if this error should count as a failure\n if (this.config.failureFilter && !this.config.failureFilter(error)) {\n return;\n }\n\n this.totalFailures++;\n this.failures++;\n this.lastFailureTime = Date.now();\n this.successes = 0;\n\n if (this.state === \"half-open\") {\n // Any failure in half-open returns to open\n this.state = \"open\";\n } else if (\n this.state === \"closed\" &&\n this.failures >= this.config.failureThreshold\n ) {\n // Threshold exceeded, open circuit\n this.state = \"open\";\n }\n }\n\n /** Get current circuit state */\n getState(): CircuitState {\n return this.state;\n }\n\n /** Get circuit statistics */\n getStats(): CircuitBreakerStats {\n return {\n state: this.state,\n failures: this.failures,\n successes: this.successes,\n lastFailureTime: this.lastFailureTime,\n totalFailures: this.totalFailures,\n totalSuccesses: this.totalSuccesses,\n totalRejected: this.totalRejected,\n };\n }\n\n /** Check if circuit is allowing requests */\n isAllowingRequests(): boolean {\n if (this.state === \"closed\" || this.state === \"half-open\") {\n return true;\n }\n\n // Check if reset timeout has passed\n const timeSinceFailure = this.lastFailureTime\n ? Date.now() - this.lastFailureTime\n : Number.POSITIVE_INFINITY;\n\n return timeSinceFailure >= this.config.resetTimeoutMs;\n }\n\n /** Manually reset the circuit to closed state */\n reset(): void {\n this.state = \"closed\";\n this.failures = 0;\n this.successes = 0;\n this.lastFailureTime = null;\n }\n\n /** Manually open the circuit */\n open(): void {\n this.state = \"open\";\n this.lastFailureTime = Date.now();\n }\n}\n","/**\n * Timeout Utilities\n *\n * Promise-based timeout handling with proper cleanup.\n */\n\nimport { SDKError } from \"../errors/index.js\";\n\nexport class TimeoutError extends SDKError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number) {\n super(message, {\n code: \"TIMEOUT\",\n retryable: true,\n context: { timeoutMs },\n });\n this.name = \"TimeoutError\";\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Wrap a promise with a timeout.\n * Rejects with TimeoutError if the promise doesn't resolve in time.\n */\nexport function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n message?: string,\n): Promise<T> {\n if (timeoutMs <= 0) {\n return promise;\n }\n\n let clearTimer: (() => void) | undefined;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n clearTimer = armTimeout(timeoutMs, () => {\n reject(\n new TimeoutError(\n message || `Operation timed out after ${timeoutMs}ms`,\n timeoutMs,\n ),\n );\n });\n });\n\n return Promise.race([promise, timeoutPromise]).finally(() => {\n clearTimer?.();\n });\n}\n\n/**\n * Create an AbortController that auto-aborts after a timeout.\n * Returns the controller and a cleanup function.\n */\nexport function createTimeoutController(timeoutMs: number): {\n controller: AbortController;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n let clearTimer: (() => void) | undefined;\n\n if (timeoutMs > 0) {\n clearTimer = armTimeout(timeoutMs, () => {\n controller.abort(new TimeoutError(\"Request timeout\", timeoutMs));\n });\n }\n\n return {\n controller,\n cleanup: () => {\n clearTimer?.();\n },\n };\n}\n\n/**\n * Sleep for a specified duration.\n * Optionally accepts an AbortSignal for cancellation.\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n const onAbort = () => {\n clearTimer();\n signal?.removeEventListener(\"abort\", onAbort);\n reject(signal?.reason);\n };\n const clearTimer = armTimeout(ms, () => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n });\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n\n/** Keep one absolute deadline; native timers overflow to 1ms beyond this chunk size. */\nfunction armTimeout(ms: number, callback: () => void): () => void {\n const deadline = Date.now() + Math.max(0, ms);\n if (!Number.isFinite(ms) || !Number.isSafeInteger(Math.ceil(deadline))) {\n throw new SDKError(\"Timeout must produce a finite safe deadline\", { code: \"VALIDATION\" });\n }\n let cleared = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const arm = () => {\n if (cleared) return;\n timer = setTimeout(() => {\n if (cleared) return;\n if (Date.now() >= deadline) callback();\n else arm();\n }, Math.min(2_147_483_647, Math.max(0, deadline - Date.now())));\n };\n arm();\n return () => {\n cleared = true;\n if (timer !== undefined) clearTimeout(timer);\n };\n}\n","/**\n * Combines timeout + circuit breaker into a single request guard.\n */\n\nimport type { CircuitBreaker } from \"./circuit-breaker.js\";\nimport { withTimeout } from \"./timeout.js\";\n\nexport interface ProtectionOptions {\n /** Timeout in milliseconds (0 or undefined = no timeout) */\n timeoutMs?: number;\n /** Circuit breaker instance (optional) */\n breaker?: CircuitBreaker;\n /** Operation name for error messages */\n operationName?: string;\n}\n\n/**\n * Execute a function with timeout and circuit breaker protection.\n *\n * Order of execution:\n * 1. Circuit breaker check (fail fast if open)\n * 2. Timeout wrapper\n * 3. Execute function\n * 4. Update circuit breaker state\n */\nexport async function withProtection<T>(\n fn: () => Promise<T>,\n options: ProtectionOptions = {},\n): Promise<T> {\n const { timeoutMs, breaker, operationName = \"operation\" } = options;\n\n const execute = async (): Promise<T> => {\n if (timeoutMs && timeoutMs > 0) {\n return withTimeout(fn(), timeoutMs, `${operationName} timed out`);\n }\n return fn();\n };\n\n if (breaker) {\n return breaker.execute(execute);\n }\n\n return execute();\n}\n\n/**\n * Create a protected function that always applies the same protection options.\n */\nexport function createProtectedFn<TArgs extends unknown[], TResult>(\n fn: (...args: TArgs) => Promise<TResult>,\n options: ProtectionOptions,\n): (...args: TArgs) => Promise<TResult> {\n return (...args: TArgs) => withProtection(() => fn(...args), options);\n}\n"],"mappings":"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"}
|
package/dist/sse/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/sse/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/sse/index.ts"],"mappings":";;;;;;;;UAQiB;EACf;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;IACE;IACA;IACA;IACA;;GAGD;;;;;;;;;;;iBAYa,aAAa,kBAAkB;UA+B9B,iBAAiB;;EAEhC;;EAEA,aAAa,gBAAgB;;UAGd,eAAe;EAC9B,MAAM;EACN;EACA;EACA;;;;;;cAOW,eAAe;UAClB;UACA;UACA;EAER,YAAY,UAAS,iBAAiB;EAItC,KAAK,gBAAgB,eAAe;EAOpC,SAAS,eAAe;UAYhB;UA4CA;;;;;iBA2Ca,eAAe,aACpC,QAAQ,eAAe,aACvB,UAAS,iBAAiB,KACzB,eAAe,eAAe;;;;iBA4CX,iBAAiB,aACrC,QAAQ,eAAe,aACvB,UAAU,OAAO,eAAe,aAChC,UAAU,OAAO,gBACjB,UAAS,iBAAiB,KACzB;;UAuCc;EACf;EACA;EACA;EACA;;;UAIe;;EAEf,OAAO;;EAEP;;EAEA;;EAEA;;EAEA,WAAW;;EAEX;;;;;;;;;;;;;;;;;;;cA0BW;UACH;UACA;EAER;;;;EAeA,cAAc;;;;EAUd,aAAa,OAAO,eAAe;;;;;EAoDnC,YAAY;;;;EAeZ,WAAW,SAAS;;;;EAOpB;UAaQ;UAyCA;;;;;iBA4BM,8BAA8B;;;;;;;;;;;;;;iBAiB9B,oBAAoB,UAAU,yBAC5C,WAAW,OAAO;EAElB,WAAW,OAAO;EAClB,gBAAgB;EAChB,WAAW"}
|
package/dist/sse/index.js
CHANGED
|
@@ -156,7 +156,7 @@ async function consumeSSEStream(stream, onEvent, onError, options = {}) {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
/** Event types that contain token information (Anthropic SDK format) */
|
|
159
|
-
const TOKEN_EVENTS = new Set(["message.stop", "content_block_stop"]);
|
|
159
|
+
const TOKEN_EVENTS = /* @__PURE__ */ new Set(["message.stop", "content_block_stop"]);
|
|
160
160
|
/**
|
|
161
161
|
* StreamUsageExtractor - Accumulates token usage from SSE events.
|
|
162
162
|
*
|
package/dist/sse/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/sse/index.ts"],"sourcesContent":["/**\n * SSE Utilities\n *\n * Shared SSE parsing and stream usage extraction for the SDK.\n * Used by sdk-telemetry, sdk-memory, and other consumers.\n */\n\n/** Raw SSE event data from stream */\nexport interface SSEEventData {\n type: string;\n // Tool events\n toolName?: string;\n name?: string;\n callId?: string;\n input?: unknown;\n arguments?: unknown;\n output?: unknown;\n result?: unknown;\n durationMs?: number;\n // Error events\n error?: string;\n message?: string;\n code?: string;\n // Status events\n status?: string;\n // Token/LLM events\n tokens?: number;\n model?: string;\n // Usage fields (Anthropic format)\n inputTokens?: number;\n outputTokens?: number;\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n // Usage object (some providers wrap in usage field)\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n // Generic\n [key: string]: unknown;\n}\n\n/**\n * Parse raw SSE data string into structured event data.\n *\n * Handles the standard SSE format:\n * ```\n * event: eventType\n * data: {\"json\": \"payload\"}\n * ```\n */\nexport function parseSSEData(rawData: string): SSEEventData | null {\n try {\n const lines = rawData.split(\"\\n\");\n let eventType: string | undefined;\n let data: string | undefined;\n\n for (const line of lines) {\n if (line.startsWith(\"event: \")) {\n eventType = line.slice(7).trim();\n } else if (line.startsWith(\"data: \")) {\n data = line.slice(6);\n }\n }\n\n if (data) {\n const parsed = JSON.parse(data);\n return {\n type: eventType || parsed.type || \"unknown\",\n ...parsed,\n };\n }\n } catch {\n // Ignore parse errors (heartbeats, malformed events)\n }\n return null;\n}\n\n// ============================================================================\n// Stream Parsing (chunked SSE)\n// ============================================================================\n\nexport interface SSEParserOptions<T = unknown> {\n /** Log malformed data lines (default: false) */\n logMalformed?: boolean;\n /** Custom data transformer */\n transform?: (raw: string) => T | null;\n}\n\nexport interface ParsedSSEEvent<T = unknown> {\n data: T;\n rawData: string;\n eventId?: string;\n eventType?: string;\n}\n\n/**\n * Incremental SSE parser for chunked streams.\n * Feed decoded string chunks via push(); call flush() on stream end.\n */\nexport class SSEChunkParser<T = unknown> {\n private buffer = \"\";\n private currentEvent: { id?: string; event?: string; data?: string } = {};\n private options: SSEParserOptions<T>;\n\n constructor(options: SSEParserOptions<T> = {}) {\n this.options = options;\n }\n\n push(chunk: string): ParsedSSEEvent<T>[] {\n this.buffer += chunk;\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n return this.processLines(lines);\n }\n\n flush(): ParsedSSEEvent<T>[] {\n const lines = this.buffer ? [this.buffer] : [];\n this.buffer = \"\";\n const events = this.processLines(lines);\n const finalEvent = this.parseCurrentEvent();\n if (finalEvent) {\n events.push(finalEvent);\n this.currentEvent = {};\n }\n return events;\n }\n\n private processLines(lines: string[]): ParsedSSEEvent<T>[] {\n const events: ParsedSSEEvent<T>[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n\n if (line.startsWith(\":\")) {\n continue;\n }\n\n if (line === \"\") {\n const parsed = this.parseCurrentEvent();\n if (parsed) {\n events.push(parsed);\n }\n this.currentEvent = {};\n continue;\n }\n\n if (line.startsWith(\"id:\")) {\n this.currentEvent.id = line.slice(3).trim();\n continue;\n }\n\n if (line.startsWith(\"event:\")) {\n this.currentEvent.event = line.slice(6).trim();\n continue;\n }\n\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n this.currentEvent.data =\n this.currentEvent.data !== undefined\n ? `${this.currentEvent.data}\\n${value}`\n : value;\n }\n }\n\n return events;\n }\n\n private parseCurrentEvent(): ParsedSSEEvent<T> | null {\n if (this.currentEvent.data === undefined) {\n return null;\n }\n\n const rawData = this.currentEvent.data.trim();\n if (!rawData) {\n return null;\n }\n\n let data: T;\n if (this.options.transform) {\n const transformed = this.options.transform(rawData);\n if (transformed === null) {\n if (this.options.logMalformed) {\n console.warn(\"SSE transform returned null:\", rawData.slice(0, 100));\n }\n return null;\n }\n data = transformed;\n } else {\n try {\n data = JSON.parse(rawData) as T;\n } catch {\n if (this.options.logMalformed) {\n console.warn(\"SSE parse failed:\", rawData.slice(0, 100));\n }\n data = rawData as unknown as T;\n }\n }\n\n return {\n data,\n rawData,\n eventId: this.currentEvent.id,\n eventType: this.currentEvent.event,\n };\n }\n}\n\n/**\n * Parse SSE stream into typed events via async iteration.\n */\nexport async function* parseSSEStream<T = unknown>(\n stream: ReadableStream<Uint8Array>,\n options: SSEParserOptions<T> = {},\n): AsyncGenerator<ParsedSSEEvent<T>> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const parser = new SSEChunkParser<T>(options);\n let chunkCount = 0;\n let totalBytes = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n console.log(\n `[agent-core:sse] Stream reader done after ${chunkCount} chunks, ${totalBytes} bytes`,\n );\n break;\n }\n\n chunkCount++;\n totalBytes += value?.length ?? 0;\n const chunk = decoder.decode(value, { stream: true });\n\n // Log every chunk for debugging\n if (chunkCount <= 3 || chunkCount % 10 === 0) {\n console.log(\n `[agent-core:sse] Chunk ${chunkCount}: ${value?.length ?? 0} bytes, preview: ${chunk.slice(0, 100).replace(/\\n/g, \"\\\\n\")}`,\n );\n }\n\n for (const event of parser.push(chunk)) {\n yield event;\n }\n }\n\n for (const event of parser.flush()) {\n yield event;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Consume SSE stream with callbacks.\n */\nexport async function consumeSSEStream<T = unknown>(\n stream: ReadableStream<Uint8Array>,\n onEvent: (event: ParsedSSEEvent<T>) => void,\n onError: (error: Error) => void,\n options: SSEParserOptions<T> = {},\n): Promise<void> {\n let eventCount = 0;\n try {\n for await (const event of parseSSEStream<T>(stream, options)) {\n eventCount++;\n onEvent(event);\n }\n // Stream finished normally\n console.log(\n `[agent-core:sse] Stream ended normally, total events: ${eventCount}`,\n );\n } catch (error) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n const isAbortError =\n normalizedError.name === \"AbortError\" ||\n normalizedError.message.toLowerCase().includes(\"abort\");\n\n if (isAbortError) {\n console.log(\n `[agent-core:sse] Stream aborted normally after ${eventCount} events`,\n );\n onError(normalizedError);\n return;\n }\n\n console.error(\n `[agent-core:sse] Stream error after ${eventCount} events:`,\n normalizedError,\n );\n onError(normalizedError);\n }\n}\n\n// ============================================================================\n// Stream Usage Extraction\n// ============================================================================\n\n/** Token usage extracted from stream */\nexport interface StreamTokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n}\n\n/** Accumulated usage from a stream session */\nexport interface StreamUsageAccumulator {\n /** Total tokens from all events */\n usage: StreamTokenUsage;\n /** Number of LLM response events */\n responseCount: number;\n /** Number of tool calls */\n toolCallCount: number;\n /** Model ID if detected from events */\n modelId?: string;\n /** Start time of accumulation */\n startedAt: Date;\n /** Duration in ms (set on finalize) */\n durationMs?: number;\n}\n\n/** Event types that contain token information (Anthropic SDK format) */\nconst TOKEN_EVENTS = new Set([\"message.stop\", \"content_block_stop\"]);\n\n/** Event types for tool calls - now handled via message.part.updated */\nconst _TOOL_CALL_EVENTS = new Set<string>();\n\n/**\n * StreamUsageExtractor - Accumulates token usage from SSE events.\n *\n * Usage:\n * ```typescript\n * const extractor = createStreamUsageExtractor();\n *\n * // In your stream callback\n * for await (const event of stream) {\n * extractor.processEvent(event);\n * // ... handle event\n * }\n *\n * const usage = extractor.finalize();\n * billingService.recordUsage({ usage: usage.usage, ... });\n * ```\n */\nexport class StreamUsageExtractor {\n private accumulator: StreamUsageAccumulator;\n private finalized = false;\n\n constructor() {\n this.accumulator = {\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n responseCount: 0,\n toolCallCount: 0,\n startedAt: new Date(),\n };\n }\n\n /**\n * Process a raw SSE string (event: xxx\\ndata: {...}).\n */\n processRawSSE(raw: string): void {\n const parsed = parseSSEData(raw);\n if (parsed) {\n this.processEvent(parsed);\n }\n }\n\n /**\n * Process a parsed SSE event object.\n */\n processEvent(event: SSEEventData | Record<string, unknown>): void {\n if (this.finalized) {\n throw new Error(\"StreamUsageExtractor already finalized\");\n }\n\n const eventType = (event as SSEEventData).type ?? event.type;\n\n // Handle message.part.updated (canonical event for all part types)\n if (eventType === \"message.part.updated\") {\n const part = (event as { part?: { type?: string; tool?: string } }).part;\n const partType = part?.type;\n\n // Text and reasoning parts count as LLM responses\n if (partType === \"text\" || partType === \"reasoning\") {\n this.extractTokens(event);\n this.accumulator.responseCount++;\n }\n\n // Tool parts count as tool calls\n if (partType === \"tool\" && part?.tool) {\n this.accumulator.toolCallCount++;\n }\n\n return;\n }\n\n // Extract token counts from Anthropic SDK format events\n if (TOKEN_EVENTS.has(eventType as string)) {\n this.extractTokens(event);\n this.accumulator.responseCount++;\n }\n\n // Extract model ID if present\n if (!this.accumulator.modelId && event.model) {\n this.accumulator.modelId = String(event.model);\n }\n\n // Handle usage summary events (some providers send final usage)\n if (eventType === \"usage\" || event.usage) {\n this.extractUsageSummary(event);\n }\n\n // Handle message_stop with usage (Anthropic format)\n if (eventType === \"message_stop\" && event.usage) {\n this.extractUsageSummary(event);\n }\n }\n\n /**\n * Finalize and return accumulated usage.\n * Sets duration and marks extractor as complete.\n */\n finalize(): StreamUsageAccumulator {\n if (this.finalized) {\n return this.accumulator;\n }\n\n this.finalized = true;\n this.accumulator.durationMs =\n Date.now() - this.accumulator.startedAt.getTime();\n\n return this.accumulator;\n }\n\n /**\n * Get current accumulated usage (without finalizing).\n */\n current(): Readonly<StreamUsageAccumulator> {\n return this.accumulator;\n }\n\n /**\n * Reset the extractor for reuse.\n */\n reset(): void {\n this.accumulator = {\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n responseCount: 0,\n toolCallCount: 0,\n startedAt: new Date(),\n };\n this.finalized = false;\n }\n\n private extractTokens(event: Record<string, unknown>): void {\n // Direct token count (simple format)\n if (typeof event.tokens === \"number\") {\n this.accumulator.usage.outputTokens += event.tokens;\n }\n\n // Output tokens (explicit)\n if (typeof event.outputTokens === \"number\") {\n this.accumulator.usage.outputTokens += event.outputTokens;\n }\n if (typeof event.output_tokens === \"number\") {\n this.accumulator.usage.outputTokens += event.output_tokens;\n }\n\n // Input tokens (usually from final summary)\n if (typeof event.inputTokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n event.inputTokens,\n );\n }\n if (typeof event.input_tokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n event.input_tokens,\n );\n }\n\n // Cache tokens (Anthropic format)\n if (typeof event.cache_read_input_tokens === \"number\") {\n this.accumulator.usage.cacheReadTokens =\n (this.accumulator.usage.cacheReadTokens ?? 0) +\n event.cache_read_input_tokens;\n }\n if (typeof event.cache_creation_input_tokens === \"number\") {\n this.accumulator.usage.cacheWriteTokens =\n (this.accumulator.usage.cacheWriteTokens ?? 0) +\n event.cache_creation_input_tokens;\n }\n }\n\n private extractUsageSummary(event: Record<string, unknown>): void {\n const usage = (event.usage as Record<string, unknown>) ?? event;\n\n if (typeof usage.input_tokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n usage.input_tokens,\n );\n }\n if (typeof usage.output_tokens === \"number\") {\n this.accumulator.usage.outputTokens = Math.max(\n this.accumulator.usage.outputTokens,\n usage.output_tokens,\n );\n }\n if (typeof usage.cache_read_input_tokens === \"number\") {\n this.accumulator.usage.cacheReadTokens = usage.cache_read_input_tokens;\n }\n if (typeof usage.cache_creation_input_tokens === \"number\") {\n this.accumulator.usage.cacheWriteTokens =\n usage.cache_creation_input_tokens;\n }\n }\n}\n\n/**\n * Create a new StreamUsageExtractor.\n */\nexport function createStreamUsageExtractor(): StreamUsageExtractor {\n return new StreamUsageExtractor();\n}\n\n/**\n * Create a callback wrapper that extracts usage while forwarding events.\n *\n * Usage:\n * ```typescript\n * const { callback, getUsage } = createUsageCallback((event) => {\n * // your event handler\n * });\n *\n * await orchestrator.executeAgentStream(projectRef, request, callback);\n * const usage = getUsage();\n * ```\n */\nexport function createUsageCallback<T extends Record<string, unknown>>(\n forward?: (event: T) => void,\n): {\n callback: (event: T) => void;\n getUsage: () => StreamUsageAccumulator;\n extractor: StreamUsageExtractor;\n} {\n const extractor = createStreamUsageExtractor();\n\n return {\n callback: (event: T) => {\n extractor.processEvent(event);\n forward?.(event);\n },\n getUsage: () => extractor.finalize(),\n extractor,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/sse/index.ts"],"sourcesContent":["/**\n * SSE Utilities\n *\n * Shared SSE parsing and stream usage extraction for the SDK.\n * Used by sdk-telemetry, sdk-memory, and other consumers.\n */\n\n/** Raw SSE event data from stream */\nexport interface SSEEventData {\n type: string;\n // Tool events\n toolName?: string;\n name?: string;\n callId?: string;\n input?: unknown;\n arguments?: unknown;\n output?: unknown;\n result?: unknown;\n durationMs?: number;\n // Error events\n error?: string;\n message?: string;\n code?: string;\n // Status events\n status?: string;\n // Token/LLM events\n tokens?: number;\n model?: string;\n // Usage fields (Anthropic format)\n inputTokens?: number;\n outputTokens?: number;\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n // Usage object (some providers wrap in usage field)\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n // Generic\n [key: string]: unknown;\n}\n\n/**\n * Parse raw SSE data string into structured event data.\n *\n * Handles the standard SSE format:\n * ```\n * event: eventType\n * data: {\"json\": \"payload\"}\n * ```\n */\nexport function parseSSEData(rawData: string): SSEEventData | null {\n try {\n const lines = rawData.split(\"\\n\");\n let eventType: string | undefined;\n let data: string | undefined;\n\n for (const line of lines) {\n if (line.startsWith(\"event: \")) {\n eventType = line.slice(7).trim();\n } else if (line.startsWith(\"data: \")) {\n data = line.slice(6);\n }\n }\n\n if (data) {\n const parsed = JSON.parse(data);\n return {\n type: eventType || parsed.type || \"unknown\",\n ...parsed,\n };\n }\n } catch {\n // Ignore parse errors (heartbeats, malformed events)\n }\n return null;\n}\n\n// ============================================================================\n// Stream Parsing (chunked SSE)\n// ============================================================================\n\nexport interface SSEParserOptions<T = unknown> {\n /** Log malformed data lines (default: false) */\n logMalformed?: boolean;\n /** Custom data transformer */\n transform?: (raw: string) => T | null;\n}\n\nexport interface ParsedSSEEvent<T = unknown> {\n data: T;\n rawData: string;\n eventId?: string;\n eventType?: string;\n}\n\n/**\n * Incremental SSE parser for chunked streams.\n * Feed decoded string chunks via push(); call flush() on stream end.\n */\nexport class SSEChunkParser<T = unknown> {\n private buffer = \"\";\n private currentEvent: { id?: string; event?: string; data?: string } = {};\n private options: SSEParserOptions<T>;\n\n constructor(options: SSEParserOptions<T> = {}) {\n this.options = options;\n }\n\n push(chunk: string): ParsedSSEEvent<T>[] {\n this.buffer += chunk;\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n return this.processLines(lines);\n }\n\n flush(): ParsedSSEEvent<T>[] {\n const lines = this.buffer ? [this.buffer] : [];\n this.buffer = \"\";\n const events = this.processLines(lines);\n const finalEvent = this.parseCurrentEvent();\n if (finalEvent) {\n events.push(finalEvent);\n this.currentEvent = {};\n }\n return events;\n }\n\n private processLines(lines: string[]): ParsedSSEEvent<T>[] {\n const events: ParsedSSEEvent<T>[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n\n if (line.startsWith(\":\")) {\n continue;\n }\n\n if (line === \"\") {\n const parsed = this.parseCurrentEvent();\n if (parsed) {\n events.push(parsed);\n }\n this.currentEvent = {};\n continue;\n }\n\n if (line.startsWith(\"id:\")) {\n this.currentEvent.id = line.slice(3).trim();\n continue;\n }\n\n if (line.startsWith(\"event:\")) {\n this.currentEvent.event = line.slice(6).trim();\n continue;\n }\n\n if (line.startsWith(\"data:\")) {\n let value = line.slice(5);\n if (value.startsWith(\" \")) {\n value = value.slice(1);\n }\n this.currentEvent.data =\n this.currentEvent.data !== undefined\n ? `${this.currentEvent.data}\\n${value}`\n : value;\n }\n }\n\n return events;\n }\n\n private parseCurrentEvent(): ParsedSSEEvent<T> | null {\n if (this.currentEvent.data === undefined) {\n return null;\n }\n\n const rawData = this.currentEvent.data.trim();\n if (!rawData) {\n return null;\n }\n\n let data: T;\n if (this.options.transform) {\n const transformed = this.options.transform(rawData);\n if (transformed === null) {\n if (this.options.logMalformed) {\n console.warn(\"SSE transform returned null:\", rawData.slice(0, 100));\n }\n return null;\n }\n data = transformed;\n } else {\n try {\n data = JSON.parse(rawData) as T;\n } catch {\n if (this.options.logMalformed) {\n console.warn(\"SSE parse failed:\", rawData.slice(0, 100));\n }\n data = rawData as unknown as T;\n }\n }\n\n return {\n data,\n rawData,\n eventId: this.currentEvent.id,\n eventType: this.currentEvent.event,\n };\n }\n}\n\n/**\n * Parse SSE stream into typed events via async iteration.\n */\nexport async function* parseSSEStream<T = unknown>(\n stream: ReadableStream<Uint8Array>,\n options: SSEParserOptions<T> = {},\n): AsyncGenerator<ParsedSSEEvent<T>> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const parser = new SSEChunkParser<T>(options);\n let chunkCount = 0;\n let totalBytes = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n console.log(\n `[agent-core:sse] Stream reader done after ${chunkCount} chunks, ${totalBytes} bytes`,\n );\n break;\n }\n\n chunkCount++;\n totalBytes += value?.length ?? 0;\n const chunk = decoder.decode(value, { stream: true });\n\n // Log every chunk for debugging\n if (chunkCount <= 3 || chunkCount % 10 === 0) {\n console.log(\n `[agent-core:sse] Chunk ${chunkCount}: ${value?.length ?? 0} bytes, preview: ${chunk.slice(0, 100).replace(/\\n/g, \"\\\\n\")}`,\n );\n }\n\n for (const event of parser.push(chunk)) {\n yield event;\n }\n }\n\n for (const event of parser.flush()) {\n yield event;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Consume SSE stream with callbacks.\n */\nexport async function consumeSSEStream<T = unknown>(\n stream: ReadableStream<Uint8Array>,\n onEvent: (event: ParsedSSEEvent<T>) => void,\n onError: (error: Error) => void,\n options: SSEParserOptions<T> = {},\n): Promise<void> {\n let eventCount = 0;\n try {\n for await (const event of parseSSEStream<T>(stream, options)) {\n eventCount++;\n onEvent(event);\n }\n // Stream finished normally\n console.log(\n `[agent-core:sse] Stream ended normally, total events: ${eventCount}`,\n );\n } catch (error) {\n const normalizedError =\n error instanceof Error ? error : new Error(String(error));\n const isAbortError =\n normalizedError.name === \"AbortError\" ||\n normalizedError.message.toLowerCase().includes(\"abort\");\n\n if (isAbortError) {\n console.log(\n `[agent-core:sse] Stream aborted normally after ${eventCount} events`,\n );\n onError(normalizedError);\n return;\n }\n\n console.error(\n `[agent-core:sse] Stream error after ${eventCount} events:`,\n normalizedError,\n );\n onError(normalizedError);\n }\n}\n\n// ============================================================================\n// Stream Usage Extraction\n// ============================================================================\n\n/** Token usage extracted from stream */\nexport interface StreamTokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n}\n\n/** Accumulated usage from a stream session */\nexport interface StreamUsageAccumulator {\n /** Total tokens from all events */\n usage: StreamTokenUsage;\n /** Number of LLM response events */\n responseCount: number;\n /** Number of tool calls */\n toolCallCount: number;\n /** Model ID if detected from events */\n modelId?: string;\n /** Start time of accumulation */\n startedAt: Date;\n /** Duration in ms (set on finalize) */\n durationMs?: number;\n}\n\n/** Event types that contain token information (Anthropic SDK format) */\nconst TOKEN_EVENTS = new Set([\"message.stop\", \"content_block_stop\"]);\n\n/** Event types for tool calls - now handled via message.part.updated */\nconst _TOOL_CALL_EVENTS = new Set<string>();\n\n/**\n * StreamUsageExtractor - Accumulates token usage from SSE events.\n *\n * Usage:\n * ```typescript\n * const extractor = createStreamUsageExtractor();\n *\n * // In your stream callback\n * for await (const event of stream) {\n * extractor.processEvent(event);\n * // ... handle event\n * }\n *\n * const usage = extractor.finalize();\n * billingService.recordUsage({ usage: usage.usage, ... });\n * ```\n */\nexport class StreamUsageExtractor {\n private accumulator: StreamUsageAccumulator;\n private finalized = false;\n\n constructor() {\n this.accumulator = {\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n responseCount: 0,\n toolCallCount: 0,\n startedAt: new Date(),\n };\n }\n\n /**\n * Process a raw SSE string (event: xxx\\ndata: {...}).\n */\n processRawSSE(raw: string): void {\n const parsed = parseSSEData(raw);\n if (parsed) {\n this.processEvent(parsed);\n }\n }\n\n /**\n * Process a parsed SSE event object.\n */\n processEvent(event: SSEEventData | Record<string, unknown>): void {\n if (this.finalized) {\n throw new Error(\"StreamUsageExtractor already finalized\");\n }\n\n const eventType = (event as SSEEventData).type ?? event.type;\n\n // Handle message.part.updated (canonical event for all part types)\n if (eventType === \"message.part.updated\") {\n const part = (event as { part?: { type?: string; tool?: string } }).part;\n const partType = part?.type;\n\n // Text and reasoning parts count as LLM responses\n if (partType === \"text\" || partType === \"reasoning\") {\n this.extractTokens(event);\n this.accumulator.responseCount++;\n }\n\n // Tool parts count as tool calls\n if (partType === \"tool\" && part?.tool) {\n this.accumulator.toolCallCount++;\n }\n\n return;\n }\n\n // Extract token counts from Anthropic SDK format events\n if (TOKEN_EVENTS.has(eventType as string)) {\n this.extractTokens(event);\n this.accumulator.responseCount++;\n }\n\n // Extract model ID if present\n if (!this.accumulator.modelId && event.model) {\n this.accumulator.modelId = String(event.model);\n }\n\n // Handle usage summary events (some providers send final usage)\n if (eventType === \"usage\" || event.usage) {\n this.extractUsageSummary(event);\n }\n\n // Handle message_stop with usage (Anthropic format)\n if (eventType === \"message_stop\" && event.usage) {\n this.extractUsageSummary(event);\n }\n }\n\n /**\n * Finalize and return accumulated usage.\n * Sets duration and marks extractor as complete.\n */\n finalize(): StreamUsageAccumulator {\n if (this.finalized) {\n return this.accumulator;\n }\n\n this.finalized = true;\n this.accumulator.durationMs =\n Date.now() - this.accumulator.startedAt.getTime();\n\n return this.accumulator;\n }\n\n /**\n * Get current accumulated usage (without finalizing).\n */\n current(): Readonly<StreamUsageAccumulator> {\n return this.accumulator;\n }\n\n /**\n * Reset the extractor for reuse.\n */\n reset(): void {\n this.accumulator = {\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n responseCount: 0,\n toolCallCount: 0,\n startedAt: new Date(),\n };\n this.finalized = false;\n }\n\n private extractTokens(event: Record<string, unknown>): void {\n // Direct token count (simple format)\n if (typeof event.tokens === \"number\") {\n this.accumulator.usage.outputTokens += event.tokens;\n }\n\n // Output tokens (explicit)\n if (typeof event.outputTokens === \"number\") {\n this.accumulator.usage.outputTokens += event.outputTokens;\n }\n if (typeof event.output_tokens === \"number\") {\n this.accumulator.usage.outputTokens += event.output_tokens;\n }\n\n // Input tokens (usually from final summary)\n if (typeof event.inputTokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n event.inputTokens,\n );\n }\n if (typeof event.input_tokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n event.input_tokens,\n );\n }\n\n // Cache tokens (Anthropic format)\n if (typeof event.cache_read_input_tokens === \"number\") {\n this.accumulator.usage.cacheReadTokens =\n (this.accumulator.usage.cacheReadTokens ?? 0) +\n event.cache_read_input_tokens;\n }\n if (typeof event.cache_creation_input_tokens === \"number\") {\n this.accumulator.usage.cacheWriteTokens =\n (this.accumulator.usage.cacheWriteTokens ?? 0) +\n event.cache_creation_input_tokens;\n }\n }\n\n private extractUsageSummary(event: Record<string, unknown>): void {\n const usage = (event.usage as Record<string, unknown>) ?? event;\n\n if (typeof usage.input_tokens === \"number\") {\n this.accumulator.usage.inputTokens = Math.max(\n this.accumulator.usage.inputTokens,\n usage.input_tokens,\n );\n }\n if (typeof usage.output_tokens === \"number\") {\n this.accumulator.usage.outputTokens = Math.max(\n this.accumulator.usage.outputTokens,\n usage.output_tokens,\n );\n }\n if (typeof usage.cache_read_input_tokens === \"number\") {\n this.accumulator.usage.cacheReadTokens = usage.cache_read_input_tokens;\n }\n if (typeof usage.cache_creation_input_tokens === \"number\") {\n this.accumulator.usage.cacheWriteTokens =\n usage.cache_creation_input_tokens;\n }\n }\n}\n\n/**\n * Create a new StreamUsageExtractor.\n */\nexport function createStreamUsageExtractor(): StreamUsageExtractor {\n return new StreamUsageExtractor();\n}\n\n/**\n * Create a callback wrapper that extracts usage while forwarding events.\n *\n * Usage:\n * ```typescript\n * const { callback, getUsage } = createUsageCallback((event) => {\n * // your event handler\n * });\n *\n * await orchestrator.executeAgentStream(projectRef, request, callback);\n * const usage = getUsage();\n * ```\n */\nexport function createUsageCallback<T extends Record<string, unknown>>(\n forward?: (event: T) => void,\n): {\n callback: (event: T) => void;\n getUsage: () => StreamUsageAccumulator;\n extractor: StreamUsageExtractor;\n} {\n const extractor = createStreamUsageExtractor();\n\n return {\n callback: (event: T) => {\n extractor.processEvent(event);\n forward?.(event);\n },\n getUsage: () => extractor.finalize(),\n extractor,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as CONTENT_KEY_FIELD, A as TANGLE_SUBJECT_KEY, B as GEN_AI_MODEL_KEYS, C as RUN_KEY_ATTRS, D as TANGLE_RUN_ID_KEY, E as TANGLE_RUN_ID_CAMEL_KEY, F as TRIGGER_ID_ATTRS, G as GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, H as GEN_AI_OUTPUT_TOKEN_KEYS, I as TRIGGER_SOURCE_ATTRS, J as GEN_AI_USAGE_OUTPUT_TOKENS, K as GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, L as WORKFLOW_MARKER_ATTRS, M as TANGLE_TRIGGER_KIND_KEY, N as TANGLE_TRIGGER_SOURCE_KEY, O as TANGLE_RUN_KIND_KEY, P as TANGLE_WORKFLOW_ID_KEY, Q as CONTENT_KEYS, R as GEN_AI_CONVERSATION_ID, S as PARENT_RUN_KEY_ATTRS, T as SUBJECT_KEY_ATTRS, U as GEN_AI_REQUEST_MODEL, V as GEN_AI_OPERATION_NAME, W as GEN_AI_RESPONSE_MODEL, X as genAiUsageAttributes, Y as GenAiUsage, Z as CONTENT_COMPLETION_KEY, _ as promptTokens, a as TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, at as DeclaredIntentMatch, b as tokenCount, c as TOKEN_USAGE_COST_KEYS, ct as asContentField, d as TOKEN_USAGE_OUTPUT_KEYS, dt as declaredTaskText, et as CONTENT_PROMPT_KEY, f as TokenUsageCounts, ft as extractContent, g as firstUsageCostUsd, gt as resolveDeclaredIntent, h as firstTokenCount, ht as normalizeContentAttributes, i as TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, it as ContentField, j as TANGLE_TRIGGER_ID_KEY, k as TANGLE_RUN_PARENT_ID_KEY, l as TOKEN_USAGE_DETAIL_KEYS, lt as asContentString, m as cacheHitRate, mt as logRecordContentBag, n as TOKEN_USAGE_CACHE_BAG_READ_KEYS, nt as CONTENT_TOOL_NAME_KEY, o as TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, ot as INDEXED_CONTENT_KEY_LIKE_PATTERNS, p as addTokenUsage, pt as hasContent, q as GEN_AI_USAGE_INPUT_TOKENS, r as TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, rt as CONTENT_TOOL_RESULT_KEY, s as TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, st as NormalizedContent, t as TOKEN_USAGE_CACHE_BAG_KEYS, tt as CONTENT_TOOL_ARGS_KEY, u as TOKEN_USAGE_INPUT_KEYS, ut as classifyAgent, v as readTokenCostUsd, w as RUN_KIND_ATTRS, x as tokenUsageSource, y as readTokenUsage, z as GEN_AI_INPUT_TOKEN_KEYS } from "../index-
|
|
2
|
-
export { CONTENT_COMPLETION_KEY, CONTENT_KEYS, CONTENT_KEY_FIELD, CONTENT_PROMPT_KEY, CONTENT_TOOL_ARGS_KEY, CONTENT_TOOL_NAME_KEY, CONTENT_TOOL_RESULT_KEY, ContentField, DeclaredIntentMatch, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GenAiUsage, INDEXED_CONTENT_KEY_LIKE_PATTERNS, NormalizedContent, PARENT_RUN_KEY_ATTRS, RUN_KEY_ATTRS, RUN_KIND_ATTRS, SUBJECT_KEY_ATTRS, TANGLE_RUN_ID_CAMEL_KEY, TANGLE_RUN_ID_KEY, TANGLE_RUN_KIND_KEY, TANGLE_RUN_PARENT_ID_KEY, TANGLE_SUBJECT_KEY, TANGLE_TRIGGER_ID_KEY, TANGLE_TRIGGER_KIND_KEY, TANGLE_TRIGGER_SOURCE_KEY, TANGLE_WORKFLOW_ID_KEY, TOKEN_USAGE_CACHE_BAG_KEYS, TOKEN_USAGE_CACHE_BAG_READ_KEYS, TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_DETAIL_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TRIGGER_ID_ATTRS, TRIGGER_SOURCE_ATTRS, TokenUsageCounts, WORKFLOW_MARKER_ATTRS, addTokenUsage, asContentField, asContentString, cacheHitRate, classifyAgent, declaredTaskText, extractContent, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, hasContent, logRecordContentBag, normalizeContentAttributes, promptTokens, readTokenCostUsd, readTokenUsage, resolveDeclaredIntent, tokenCount, tokenUsageSource };
|
|
1
|
+
import { $ as CONTENT_KEY_FIELD, A as TANGLE_SUBJECT_KEY, B as GEN_AI_MODEL_KEYS, C as RUN_KEY_ATTRS, D as TANGLE_RUN_ID_KEY, E as TANGLE_RUN_ID_CAMEL_KEY, F as TRIGGER_ID_ATTRS, G as GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, H as GEN_AI_OUTPUT_TOKEN_KEYS, I as TRIGGER_SOURCE_ATTRS, J as GEN_AI_USAGE_OUTPUT_TOKENS, K as GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, L as WORKFLOW_MARKER_ATTRS, M as TANGLE_TRIGGER_KIND_KEY, N as TANGLE_TRIGGER_SOURCE_KEY, O as TANGLE_RUN_KIND_KEY, P as TANGLE_WORKFLOW_ID_KEY, Q as CONTENT_KEYS, R as GEN_AI_CONVERSATION_ID, S as PARENT_RUN_KEY_ATTRS, T as SUBJECT_KEY_ATTRS, U as GEN_AI_REQUEST_MODEL, V as GEN_AI_OPERATION_NAME, W as GEN_AI_RESPONSE_MODEL, X as genAiUsageAttributes, Y as GenAiUsage, Z as CONTENT_COMPLETION_KEY, _ as promptTokens, a as TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, at as DeclaredIntentMatch, b as tokenCount, c as TOKEN_USAGE_COST_KEYS, ct as asContentField, d as TOKEN_USAGE_OUTPUT_KEYS, dt as declaredTaskText, et as CONTENT_PROMPT_KEY, f as TokenUsageCounts, ft as extractContent, g as firstUsageCostUsd, gt as resolveDeclaredIntent, h as firstTokenCount, ht as normalizeContentAttributes, i as TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, it as ContentField, j as TANGLE_TRIGGER_ID_KEY, k as TANGLE_RUN_PARENT_ID_KEY, l as TOKEN_USAGE_DETAIL_KEYS, lt as asContentString, m as cacheHitRate, mt as logRecordContentBag, n as TOKEN_USAGE_CACHE_BAG_READ_KEYS, nt as CONTENT_TOOL_NAME_KEY, o as TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, ot as INDEXED_CONTENT_KEY_LIKE_PATTERNS, p as addTokenUsage, pt as hasContent, q as GEN_AI_USAGE_INPUT_TOKENS, r as TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, rt as CONTENT_TOOL_RESULT_KEY, s as TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, st as NormalizedContent, t as TOKEN_USAGE_CACHE_BAG_KEYS, tt as CONTENT_TOOL_ARGS_KEY, u as TOKEN_USAGE_INPUT_KEYS, ut as classifyAgent, v as readTokenCostUsd, w as RUN_KIND_ATTRS, x as tokenUsageSource, y as readTokenUsage, z as GEN_AI_INPUT_TOKEN_KEYS } from "../index-BvjA5i93.js";
|
|
2
|
+
export { CONTENT_COMPLETION_KEY, CONTENT_KEYS, CONTENT_KEY_FIELD, CONTENT_PROMPT_KEY, CONTENT_TOOL_ARGS_KEY, CONTENT_TOOL_NAME_KEY, CONTENT_TOOL_RESULT_KEY, type ContentField, type DeclaredIntentMatch, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, type GenAiUsage, INDEXED_CONTENT_KEY_LIKE_PATTERNS, type NormalizedContent, PARENT_RUN_KEY_ATTRS, RUN_KEY_ATTRS, RUN_KIND_ATTRS, SUBJECT_KEY_ATTRS, TANGLE_RUN_ID_CAMEL_KEY, TANGLE_RUN_ID_KEY, TANGLE_RUN_KIND_KEY, TANGLE_RUN_PARENT_ID_KEY, TANGLE_SUBJECT_KEY, TANGLE_TRIGGER_ID_KEY, TANGLE_TRIGGER_KIND_KEY, TANGLE_TRIGGER_SOURCE_KEY, TANGLE_WORKFLOW_ID_KEY, TOKEN_USAGE_CACHE_BAG_KEYS, TOKEN_USAGE_CACHE_BAG_READ_KEYS, TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_DETAIL_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TRIGGER_ID_ATTRS, TRIGGER_SOURCE_ATTRS, type TokenUsageCounts, WORKFLOW_MARKER_ATTRS, addTokenUsage, asContentField, asContentString, cacheHitRate, classifyAgent, declaredTaskText, extractContent, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, hasContent, logRecordContentBag, normalizeContentAttributes, promptTokens, readTokenCostUsd, readTokenUsage, resolveDeclaredIntent, tokenCount, tokenUsageSource };
|
package/dist/telemetry/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as CONTENT_TOOL_ARGS_KEY, A as TANGLE_TRIGGER_ID_KEY, B as GEN_AI_OPERATION_NAME, C as RUN_KIND_ATTRS, D as TANGLE_RUN_KIND_KEY, E as TANGLE_RUN_ID_KEY, F as TRIGGER_SOURCE_ATTRS, G as GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, H as GEN_AI_REQUEST_MODEL, I as WORKFLOW_MARKER_ATTRS, J as genAiUsageAttributes, K as GEN_AI_USAGE_INPUT_TOKENS, L as GEN_AI_CONVERSATION_ID, M as TANGLE_TRIGGER_SOURCE_KEY, N as TANGLE_WORKFLOW_ID_KEY, O as TANGLE_RUN_PARENT_ID_KEY, P as TRIGGER_ID_ATTRS, Q as CONTENT_PROMPT_KEY, R as GEN_AI_INPUT_TOKEN_KEYS, S as RUN_KEY_ATTRS, T as TANGLE_RUN_ID_CAMEL_KEY, U as GEN_AI_RESPONSE_MODEL, V as GEN_AI_OUTPUT_TOKEN_KEYS, W as GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, X as CONTENT_KEYS, Y as CONTENT_COMPLETION_KEY, Z as CONTENT_KEY_FIELD, _ as readTokenCostUsd, a as TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, at as classifyAgent, b as tokenUsageSource, c as TOKEN_USAGE_COST_KEYS, ct as hasContent, d as TOKEN_USAGE_OUTPUT_KEYS, dt as resolveDeclaredIntent, et as CONTENT_TOOL_NAME_KEY, f as addTokenUsage, g as promptTokens, h as firstUsageCostUsd, i as TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, it as asContentString, j as TANGLE_TRIGGER_KIND_KEY, k as TANGLE_SUBJECT_KEY, l as TOKEN_USAGE_DETAIL_KEYS, lt as logRecordContentBag, m as firstTokenCount, n as TOKEN_USAGE_CACHE_BAG_READ_KEYS, nt as INDEXED_CONTENT_KEY_LIKE_PATTERNS, o as TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, ot as declaredTaskText, p as cacheHitRate, q as GEN_AI_USAGE_OUTPUT_TOKENS, r as TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, rt as asContentField, s as TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, st as extractContent, t as TOKEN_USAGE_CACHE_BAG_KEYS, tt as CONTENT_TOOL_RESULT_KEY, u as TOKEN_USAGE_INPUT_KEYS, ut as normalizeContentAttributes, v as readTokenUsage, w as SUBJECT_KEY_ATTRS, x as PARENT_RUN_KEY_ATTRS, y as tokenCount, z as GEN_AI_MODEL_KEYS } from "../telemetry-
|
|
1
|
+
import { $ as CONTENT_TOOL_ARGS_KEY, A as TANGLE_TRIGGER_ID_KEY, B as GEN_AI_OPERATION_NAME, C as RUN_KIND_ATTRS, D as TANGLE_RUN_KIND_KEY, E as TANGLE_RUN_ID_KEY, F as TRIGGER_SOURCE_ATTRS, G as GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, H as GEN_AI_REQUEST_MODEL, I as WORKFLOW_MARKER_ATTRS, J as genAiUsageAttributes, K as GEN_AI_USAGE_INPUT_TOKENS, L as GEN_AI_CONVERSATION_ID, M as TANGLE_TRIGGER_SOURCE_KEY, N as TANGLE_WORKFLOW_ID_KEY, O as TANGLE_RUN_PARENT_ID_KEY, P as TRIGGER_ID_ATTRS, Q as CONTENT_PROMPT_KEY, R as GEN_AI_INPUT_TOKEN_KEYS, S as RUN_KEY_ATTRS, T as TANGLE_RUN_ID_CAMEL_KEY, U as GEN_AI_RESPONSE_MODEL, V as GEN_AI_OUTPUT_TOKEN_KEYS, W as GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, X as CONTENT_KEYS, Y as CONTENT_COMPLETION_KEY, Z as CONTENT_KEY_FIELD, _ as readTokenCostUsd, a as TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, at as classifyAgent, b as tokenUsageSource, c as TOKEN_USAGE_COST_KEYS, ct as hasContent, d as TOKEN_USAGE_OUTPUT_KEYS, dt as resolveDeclaredIntent, et as CONTENT_TOOL_NAME_KEY, f as addTokenUsage, g as promptTokens, h as firstUsageCostUsd, i as TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, it as asContentString, j as TANGLE_TRIGGER_KIND_KEY, k as TANGLE_SUBJECT_KEY, l as TOKEN_USAGE_DETAIL_KEYS, lt as logRecordContentBag, m as firstTokenCount, n as TOKEN_USAGE_CACHE_BAG_READ_KEYS, nt as INDEXED_CONTENT_KEY_LIKE_PATTERNS, o as TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, ot as declaredTaskText, p as cacheHitRate, q as GEN_AI_USAGE_OUTPUT_TOKENS, r as TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, rt as asContentField, s as TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, st as extractContent, t as TOKEN_USAGE_CACHE_BAG_KEYS, tt as CONTENT_TOOL_RESULT_KEY, u as TOKEN_USAGE_INPUT_KEYS, ut as normalizeContentAttributes, v as readTokenUsage, w as SUBJECT_KEY_ATTRS, x as PARENT_RUN_KEY_ATTRS, y as tokenCount, z as GEN_AI_MODEL_KEYS } from "../telemetry-DTOiMSzM.js";
|
|
2
2
|
export { CONTENT_COMPLETION_KEY, CONTENT_KEYS, CONTENT_KEY_FIELD, CONTENT_PROMPT_KEY, CONTENT_TOOL_ARGS_KEY, CONTENT_TOOL_NAME_KEY, CONTENT_TOOL_RESULT_KEY, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, INDEXED_CONTENT_KEY_LIKE_PATTERNS, PARENT_RUN_KEY_ATTRS, RUN_KEY_ATTRS, RUN_KIND_ATTRS, SUBJECT_KEY_ATTRS, TANGLE_RUN_ID_CAMEL_KEY, TANGLE_RUN_ID_KEY, TANGLE_RUN_KIND_KEY, TANGLE_RUN_PARENT_ID_KEY, TANGLE_SUBJECT_KEY, TANGLE_TRIGGER_ID_KEY, TANGLE_TRIGGER_KIND_KEY, TANGLE_TRIGGER_SOURCE_KEY, TANGLE_WORKFLOW_ID_KEY, TOKEN_USAGE_CACHE_BAG_KEYS, TOKEN_USAGE_CACHE_BAG_READ_KEYS, TOKEN_USAGE_CACHE_BAG_WRITE_KEYS, TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS, TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_DETAIL_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TRIGGER_ID_ATTRS, TRIGGER_SOURCE_ATTRS, WORKFLOW_MARKER_ATTRS, addTokenUsage, asContentField, asContentString, cacheHitRate, classifyAgent, declaredTaskText, extractContent, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, hasContent, logRecordContentBag, normalizeContentAttributes, promptTokens, readTokenCostUsd, readTokenUsage, resolveDeclaredIntent, tokenCount, tokenUsageSource };
|
|
@@ -1093,4 +1093,4 @@ function cacheHitRate(usage) {
|
|
|
1093
1093
|
//#endregion
|
|
1094
1094
|
export { CONTENT_TOOL_ARGS_KEY as $, TANGLE_TRIGGER_ID_KEY as A, GEN_AI_OPERATION_NAME as B, RUN_KIND_ATTRS as C, TANGLE_RUN_KIND_KEY as D, TANGLE_RUN_ID_KEY as E, TRIGGER_SOURCE_ATTRS as F, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS as G, GEN_AI_REQUEST_MODEL as H, WORKFLOW_MARKER_ATTRS as I, genAiUsageAttributes as J, GEN_AI_USAGE_INPUT_TOKENS as K, GEN_AI_CONVERSATION_ID as L, TANGLE_TRIGGER_SOURCE_KEY as M, TANGLE_WORKFLOW_ID_KEY as N, TANGLE_RUN_PARENT_ID_KEY as O, TRIGGER_ID_ATTRS as P, CONTENT_PROMPT_KEY as Q, GEN_AI_INPUT_TOKEN_KEYS as R, RUN_KEY_ATTRS as S, TANGLE_RUN_ID_CAMEL_KEY as T, GEN_AI_RESPONSE_MODEL as U, GEN_AI_OUTPUT_TOKEN_KEYS as V, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS as W, CONTENT_KEYS as X, CONTENT_COMPLETION_KEY as Y, CONTENT_KEY_FIELD as Z, readTokenCostUsd as _, TOKEN_USAGE_CACHE_READ_INCLUSIVE_KEYS as a, classifyAgent as at, tokenUsageSource as b, TOKEN_USAGE_COST_KEYS as c, hasContent as ct, TOKEN_USAGE_OUTPUT_KEYS as d, resolveDeclaredIntent as dt, CONTENT_TOOL_NAME_KEY as et, addTokenUsage as f, promptTokens as g, firstUsageCostUsd as h, TOKEN_USAGE_CACHE_READ_EXCLUSIVE_KEYS as i, asContentString as it, TANGLE_TRIGGER_KIND_KEY as j, TANGLE_SUBJECT_KEY as k, TOKEN_USAGE_DETAIL_KEYS as l, logRecordContentBag as lt, firstTokenCount as m, TOKEN_USAGE_CACHE_BAG_READ_KEYS as n, INDEXED_CONTENT_KEY_LIKE_PATTERNS as nt, TOKEN_USAGE_CACHE_WRITE_EXCLUSIVE_KEYS as o, declaredTaskText as ot, cacheHitRate as p, GEN_AI_USAGE_OUTPUT_TOKENS as q, TOKEN_USAGE_CACHE_BAG_WRITE_KEYS as r, asContentField as rt, TOKEN_USAGE_CACHE_WRITE_INCLUSIVE_KEYS as s, extractContent as st, TOKEN_USAGE_CACHE_BAG_KEYS as t, CONTENT_TOOL_RESULT_KEY as tt, TOKEN_USAGE_INPUT_KEYS as u, normalizeContentAttributes as ut, readTokenUsage as v, SUBJECT_KEY_ATTRS as w, PARENT_RUN_KEY_ATTRS as x, tokenCount as y, GEN_AI_MODEL_KEYS as z };
|
|
1095
1095
|
|
|
1096
|
-
//# sourceMappingURL=telemetry-
|
|
1096
|
+
//# sourceMappingURL=telemetry-DTOiMSzM.js.map
|