@anuma/sdk 6.33.1 → 6.33.2
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/design/index.cjs +0 -2
- package/dist/design/index.d.mts +0 -7
- package/dist/design/index.d.ts +0 -7
- package/dist/design/index.mjs +0 -2
- package/dist/expo/{chunk-XD6WOQ5I.mjs → chunk-GQBTAM6Y.mjs} +0 -70
- package/dist/expo/{consolidate-7DBUHQRK.mjs → consolidate-3H2WY3FU.mjs} +1 -8
- package/dist/expo/index.cjs +15394 -16278
- package/dist/expo/index.d.mts +5734 -6660
- package/dist/expo/index.d.ts +5734 -6660
- package/dist/expo/index.mjs +15231 -16034
- package/dist/index.cjs +2258 -2411
- package/dist/index.d.mts +914 -1054
- package/dist/index.d.ts +914 -1054
- package/dist/index.mjs +2258 -2409
- package/dist/memory/context.d.mts +0 -73
- package/dist/memory/context.d.ts +0 -73
- package/dist/next/index.cjs +1 -8
- package/dist/next/index.mjs +1 -8
- package/dist/pii/transformers.d.mts +0 -32
- package/dist/pii/transformers.d.ts +0 -32
- package/dist/react/{chunk-XNQRJBIH.mjs → chunk-UFO4W3JX.mjs} +0 -70
- package/dist/react/{consolidate-5DVINCUE.mjs → consolidate-RHIAUBT4.mjs} +1 -8
- package/dist/react/index.cjs +32415 -33395
- package/dist/react/index.d.mts +13354 -14553
- package/dist/react/index.d.ts +13354 -14553
- package/dist/react/index.mjs +32556 -33457
- package/dist/server/{chunk-KSYV7UO2.mjs → chunk-4RGGAOAJ.mjs} +835 -905
- package/dist/server/{consolidate-MCNBSUXD.mjs → consolidate-YEGACWLR.mjs} +1 -8
- package/dist/server/index.cjs +22313 -23120
- package/dist/server/index.d.mts +5353 -6300
- package/dist/server/index.d.ts +5353 -6300
- package/dist/server/index.mjs +18789 -19531
- package/dist/telemetry/index.cjs +0 -9
- package/dist/telemetry/index.d.mts +88 -198
- package/dist/telemetry/index.d.ts +88 -198
- package/dist/telemetry/index.mjs +0 -9
- package/dist/tools/index.cjs +13036 -13347
- package/dist/tools/index.d.mts +2434 -2729
- package/dist/tools/index.d.ts +2434 -2729
- package/dist/tools/index.mjs +13036 -13347
- package/dist/tools/selection/index.cjs +0 -116
- package/dist/tools/selection/index.d.mts +0 -159
- package/dist/tools/selection/index.d.ts +0 -159
- package/dist/tools/selection/index.mjs +0 -116
- package/package.json +1 -1
package/dist/telemetry/index.cjs
CHANGED
|
@@ -213,16 +213,7 @@ function createRecallDiagnosticsHandler(sink) {
|
|
|
213
213
|
usedBudget: diagnostics.usedBudget,
|
|
214
214
|
reranked: diagnostics.reranked,
|
|
215
215
|
candidateCount: diagnostics.candidateCount,
|
|
216
|
-
// What the caller actually GOT. `candidateCount` is what was considered,
|
|
217
|
-
// and the two are routinely far apart — the fact lane pulls `limit * 2`
|
|
218
|
-
// when fusing — so a consumer reading candidateCount as "memories this
|
|
219
|
-
// turn received" overcounts.
|
|
220
216
|
admittedCount: diagnostics.admittedCount,
|
|
221
|
-
// Both ends of the admitted range, and the lane counts, ride the EVENT as
|
|
222
|
-
// well as the metrics: a track-only sink is a supported configuration
|
|
223
|
-
// (the module's own PostHog example is exactly that shape), and it could
|
|
224
|
-
// otherwise see neither the bottom of the score range nor which side lane
|
|
225
|
-
// contributed.
|
|
226
217
|
topScore: diagnostics.topScore,
|
|
227
218
|
lowestAdmittedScore: diagnostics.lowestAdmittedScore,
|
|
228
219
|
minScoreApplied: diagnostics.minScoreApplied,
|
|
@@ -96,17 +96,6 @@ type LlmapiChatCompletionTool = {
|
|
|
96
96
|
[key: string]: unknown;
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Lifecycle hooks for runToolLoop. All hooks are optional and observer
|
|
101
|
-
* errors are swallowed (sync throws and async rejections both) so a buggy
|
|
102
|
-
* hook can't crash the loop. Hook names match the Claude Agent SDK shape
|
|
103
|
-
* (camelCase).
|
|
104
|
-
*
|
|
105
|
-
* Hooks are awaited synchronously at each fire site, so slow hooks
|
|
106
|
-
* serialize into loop latency — keep them fast and do any heavy work
|
|
107
|
-
* (network exports, file IO) asynchronously inside your own queue.
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
99
|
type LlmTokenUsage = {
|
|
111
100
|
inputTokens?: number;
|
|
112
101
|
outputTokens?: number;
|
|
@@ -228,156 +217,6 @@ type RunHooks = {
|
|
|
228
217
|
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
229
218
|
};
|
|
230
219
|
|
|
231
|
-
/**
|
|
232
|
-
* Telemetry sink contract for the observability adapter.
|
|
233
|
-
*
|
|
234
|
-
* The SDK never talks to a vendor directly — it emits structured events and
|
|
235
|
-
* metrics through this interface, and the app adapts it to PostHog, Datadog,
|
|
236
|
-
* OpenTelemetry, etc. Both methods are optional so a sink that only cares
|
|
237
|
-
* about events (or only about metrics) can implement half the surface.
|
|
238
|
-
*
|
|
239
|
-
* Implementations must be fast and must not throw: hooks are awaited
|
|
240
|
-
* synchronously inside the tool loop (see `runHooks.ts`), so a slow or
|
|
241
|
-
* throwing sink serializes into run latency or — worse — surfaces as a run
|
|
242
|
-
* error. Queue network exports asynchronously inside your sink.
|
|
243
|
-
*
|
|
244
|
-
* @example
|
|
245
|
-
* ```ts
|
|
246
|
-
* import { createMetricsHooks, type TelemetrySink } from "@anuma/sdk/telemetry";
|
|
247
|
-
*
|
|
248
|
-
* // posthog-js: capture(event, properties)
|
|
249
|
-
* const sink: TelemetrySink = {
|
|
250
|
-
* track: (event, properties) => posthog.capture(event, properties),
|
|
251
|
-
* metric: (name, value, tags) => statsd.histogram(name, value, tags),
|
|
252
|
-
* };
|
|
253
|
-
*
|
|
254
|
-
* // posthog-node takes ONE object, so the arguments do not line up:
|
|
255
|
-
* // track: (event, properties) => posthog.capture({ distinctId, event, properties })
|
|
256
|
-
*
|
|
257
|
-
* const hooks = createMetricsHooks(sink);
|
|
258
|
-
* // pass `hooks` wherever RunHooks are accepted, or compose with your own:
|
|
259
|
-
* // composeHooks([hooks, myTracingHooks])
|
|
260
|
-
* ```
|
|
261
|
-
*/
|
|
262
|
-
interface TelemetrySink {
|
|
263
|
-
/**
|
|
264
|
-
* Record a discrete event (run started, tool failed, recall degraded…).
|
|
265
|
-
* `properties` are flat, JSON-serializable, and free of message contents —
|
|
266
|
-
* only identifiers, counts, and timings.
|
|
267
|
-
*/
|
|
268
|
-
track?: (event: string, properties: Record<string, unknown>) => void;
|
|
269
|
-
/**
|
|
270
|
-
* Record a numeric measurement (latency, duration, token count). `tags`
|
|
271
|
-
* are low-cardinality string dimensions (model, toolName, outcome, lane).
|
|
272
|
-
*/
|
|
273
|
-
metric?: (name: string, value: number, tags: Record<string, string>) => void;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Default sink that discards everything. Useful as a fallback when telemetry
|
|
277
|
-
* is configured off, and as the base for sinks that override one method.
|
|
278
|
-
*
|
|
279
|
-
* Frozen. It is a published singleton, and `createMetricsHooks` closes over the
|
|
280
|
-
* object rather than its methods, so one module assigning `noopTelemetrySink.track`
|
|
281
|
-
* would reroute every already-constructed adapter that shares the reference — a
|
|
282
|
-
* test stub that forgets to restore changes behaviour for the rest of the suite.
|
|
283
|
-
* Freezing now rather than later: adding it later is the breaking direction,
|
|
284
|
-
* because it turns a silent assignment into a strict-mode TypeError.
|
|
285
|
-
*/
|
|
286
|
-
declare const noopTelemetrySink: TelemetrySink;
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* {@link RunHooks} adapter that turns tool-loop lifecycle hooks into
|
|
290
|
-
* telemetry events and metrics on a {@link TelemetrySink}.
|
|
291
|
-
*
|
|
292
|
-
* Events emitted (all with `runId`; no message contents or tool arguments):
|
|
293
|
-
*
|
|
294
|
-
* - `run.started` — `{ runId, model }`
|
|
295
|
-
* - `run.completed` — `{ runId, totalSteps, durationMs }`
|
|
296
|
-
* - `run.failed` — `{ runId, durationMs, errorType, stage }`
|
|
297
|
-
* - `model.call.completed` — `{ runId, stepIndex, latencyMs, model?, inputTokens?, outputTokens?, finishReason? }`
|
|
298
|
-
* - `model.call.failed` — `{ runId, stepIndex, latencyMs, model? }`
|
|
299
|
-
* - `tool.call.completed` — `{ runId, stepIndex, toolCallId, toolName, durationMs }`
|
|
300
|
-
* - `tool.call.failed` — `{ runId, stepIndex, toolCallId, toolName, durationMs, errorType }`
|
|
301
|
-
*
|
|
302
|
-
* The raw `error` message string is NOT reported unless the caller opts in
|
|
303
|
-
* with {@link MetricsHooksOptions.includeErrorMessages} — see that option for
|
|
304
|
-
* why. `errorType` is always safe and always reported where the source event
|
|
305
|
-
* carries one.
|
|
306
|
-
*
|
|
307
|
-
* Metrics emitted:
|
|
308
|
-
*
|
|
309
|
-
* - `run.duration` (ms, tags: model?, outcome)
|
|
310
|
-
* - `model.call.latency` (ms, tags: model?, outcome)
|
|
311
|
-
* - `model.call.tokens` (count, tags: direction: input|output) when usage is present
|
|
312
|
-
* - `tool.call.duration` (ms, tags: toolName, outcome, errorType?)
|
|
313
|
-
*
|
|
314
|
-
* Pairing notes (mirrors the contract documented in `runHooks.ts`):
|
|
315
|
-
*
|
|
316
|
-
* - `onRunEnd` / `onRunError` are mutually exclusive and fire exactly once per
|
|
317
|
-
* run, so every started run resolves to exactly one terminal event.
|
|
318
|
-
* - Server-side tools routed via `onToolCall` get `beforeToolUse` with no
|
|
319
|
-
* `afterToolUse`. The adapter therefore never emits a completion for a tool
|
|
320
|
-
* it saw only start; the pending timer is dropped when the run terminates.
|
|
321
|
-
* - `afterToolUse` without a matching `beforeToolUse` (defensive — not a
|
|
322
|
-
* documented case) is still reported, with `durationMs` omitted.
|
|
323
|
-
* - Per-run state is keyed by `runId` and cleared on the terminal hook, so
|
|
324
|
-
* concurrent runs and long-lived adapter instances do not leak timers. The
|
|
325
|
-
* `after*` hooks read that state without creating it, so a hook arriving
|
|
326
|
-
* after the terminal one cannot resurrect an entry nothing would delete
|
|
327
|
-
* again.
|
|
328
|
-
*/
|
|
329
|
-
|
|
330
|
-
interface MetricsHooksOptions {
|
|
331
|
-
/**
|
|
332
|
-
* Override the clock used for every duration this adapter reports.
|
|
333
|
-
*
|
|
334
|
-
* The default is monotonic where the runtime has `performance.now()`
|
|
335
|
-
* (browser / RN / Node), falling back to `Date.now()`. That is about
|
|
336
|
-
* monotonicity, not precision: `Date.now()` steps BACKWARD on an NTP
|
|
337
|
-
* correction, a VM resume from snapshot, or a container host clock sync, and
|
|
338
|
-
* a step landing mid-run makes `now() - startedAt` negative. dogstatsd
|
|
339
|
-
* accepts a negative histogram sample, so it is ingested and corrupts the
|
|
340
|
-
* min/p50/p95 for that bucket — silently wrong data, which is the one thing
|
|
341
|
-
* this module exists to prevent.
|
|
342
|
-
*
|
|
343
|
-
* Supply your own only to make durations deterministic in a test.
|
|
344
|
-
*/
|
|
345
|
-
now?: () => number;
|
|
346
|
-
/**
|
|
347
|
-
* Report the raw `error` message string on `run.failed`,
|
|
348
|
-
* `model.call.failed`, and `tool.call.failed`. Default `false`.
|
|
349
|
-
*
|
|
350
|
-
* Off by default because those strings are free text and routinely quote
|
|
351
|
-
* the input that caused the failure. `JSON.parse` echoes the offending tool
|
|
352
|
-
* arguments verbatim (`Unexpected token 'h', "hunter2pass"... is not valid
|
|
353
|
-
* JSON`), `executeToolCall` wraps whatever a host executor threw, and an
|
|
354
|
-
* executor with `deAnonymizeArgs` runs on de-redacted PII. Sending them to
|
|
355
|
-
* a sink contradicts {@link TelemetrySink}, which states that properties
|
|
356
|
-
* carry only identifiers, counts, and timings.
|
|
357
|
-
*
|
|
358
|
-
* Turn it on when the sink is infrastructure you own and you accept the
|
|
359
|
-
* exposure. Prefer `errorType`, which is always reported and always safe.
|
|
360
|
-
*/
|
|
361
|
-
includeErrorMessages?: boolean;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Build {@link RunHooks} that report run lifecycle, model calls, and tool
|
|
365
|
-
* calls to `sink`. The returned hooks are synchronous and never throw — a
|
|
366
|
-
* throwing sink method is swallowed with a console-free `noop` (the tool loop
|
|
367
|
-
* already swallows hook errors; we avoid double-logging here).
|
|
368
|
-
*/
|
|
369
|
-
declare function createMetricsHooks(sink: TelemetrySink, opts?: MetricsHooksOptions): RunHooks;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Unified memory layer types — the Recall / Retain API.
|
|
373
|
-
*
|
|
374
|
-
* This module defines the public surface for the new unified memory layer
|
|
375
|
-
* that sits above `memoryVault` (curated facts) and `memoryEngine` (raw
|
|
376
|
-
* conversation chunks). Callers should prefer these types over the legacy
|
|
377
|
-
* `VaultSearchResult` / `ChunkSearchResult` shapes; the underlying stores
|
|
378
|
-
* may converge later, the API will not.
|
|
379
|
-
*/
|
|
380
|
-
|
|
381
220
|
/**
|
|
382
221
|
* Budget controls retrieval depth/cost. Higher budgets enable more
|
|
383
222
|
* candidate sources and the cross-encoder reranker.
|
|
@@ -594,51 +433,102 @@ interface RecallDiagnostics {
|
|
|
594
433
|
}
|
|
595
434
|
|
|
596
435
|
/**
|
|
597
|
-
*
|
|
598
|
-
* {@link RecallOptions}) into telemetry events and metrics on a
|
|
599
|
-
* {@link TelemetrySink}.
|
|
600
|
-
*
|
|
601
|
-
* Events emitted:
|
|
436
|
+
* Telemetry sink contract for the observability adapter.
|
|
602
437
|
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
438
|
+
* The SDK never talks to a vendor directly — it emits structured events and
|
|
439
|
+
* metrics through this interface, and the app adapts it to PostHog, Datadog,
|
|
440
|
+
* OpenTelemetry, etc. Both methods are optional so a sink that only cares
|
|
441
|
+
* about events (or only about metrics) can implement half the surface.
|
|
607
442
|
*
|
|
608
|
-
*
|
|
443
|
+
* Implementations must be fast and must not throw: hooks are awaited
|
|
444
|
+
* synchronously inside the tool loop (see `runHooks.ts`), so a slow or
|
|
445
|
+
* throwing sink serializes into run latency or — worse — surfaces as a run
|
|
446
|
+
* error. Queue network exports asynchronously inside your sink.
|
|
609
447
|
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
* - `recall.candidates` (count), `recall.facts` (count), `recall.chunks` (count)
|
|
614
|
-
* - `recall.vault.size`, `recall.vault.rows_decrypted`,
|
|
615
|
-
* `recall.vault.rows_embedded` when the fact lane reported them.
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* import { createMetricsHooks, type TelemetrySink } from "@anuma/sdk/telemetry";
|
|
616
451
|
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
* `degraded` for themselves — the recall tool (`lib/memory/recallTool.ts`) and
|
|
623
|
-
* the vault search tool (`lib/memoryVault/searchTool.ts`). Neither forwards a
|
|
624
|
-
* caller's callback, and neither exposes the slot on its own options.
|
|
452
|
+
* // posthog-js: capture(event, properties)
|
|
453
|
+
* const sink: TelemetrySink = {
|
|
454
|
+
* track: (event, properties) => posthog.capture(event, properties),
|
|
455
|
+
* metric: (name, value, tags) => statsd.histogram(name, value, tags),
|
|
456
|
+
* };
|
|
625
457
|
*
|
|
626
|
-
*
|
|
458
|
+
* // posthog-node takes ONE object, so the arguments do not line up:
|
|
459
|
+
* // track: (event, properties) => posthog.capture({ distinctId, event, properties })
|
|
627
460
|
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
461
|
+
* const hooks = createMetricsHooks(sink);
|
|
462
|
+
* // pass `hooks` wherever RunHooks are accepted, or compose with your own:
|
|
463
|
+
* // composeHooks([hooks, myTracingHooks])
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
interface TelemetrySink {
|
|
467
|
+
/**
|
|
468
|
+
* Record a discrete event (run started, tool failed, recall degraded…).
|
|
469
|
+
* `properties` are flat, JSON-serializable, and free of message contents —
|
|
470
|
+
* only identifiers, counts, and timings.
|
|
471
|
+
*/
|
|
472
|
+
track?: (event: string, properties: Record<string, unknown>) => void;
|
|
473
|
+
/**
|
|
474
|
+
* Record a numeric measurement (latency, duration, token count). `tags`
|
|
475
|
+
* are low-cardinality string dimensions (model, toolName, outcome, lane).
|
|
476
|
+
*/
|
|
477
|
+
metric?: (name: string, value: number, tags: Record<string, string>) => void;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Default sink that discards everything. Useful as a fallback when telemetry
|
|
481
|
+
* is configured off, and as the base for sinks that override one method.
|
|
636
482
|
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
483
|
+
* Frozen. It is a published singleton, and `createMetricsHooks` closes over the
|
|
484
|
+
* object rather than its methods, so one module assigning `noopTelemetrySink.track`
|
|
485
|
+
* would reroute every already-constructed adapter that shares the reference — a
|
|
486
|
+
* test stub that forgets to restore changes behaviour for the rest of the suite.
|
|
487
|
+
* Freezing now rather than later: adding it later is the breaking direction,
|
|
488
|
+
* because it turns a silent assignment into a strict-mode TypeError.
|
|
641
489
|
*/
|
|
490
|
+
declare const noopTelemetrySink: TelemetrySink;
|
|
491
|
+
|
|
492
|
+
interface MetricsHooksOptions {
|
|
493
|
+
/**
|
|
494
|
+
* Override the clock used for every duration this adapter reports.
|
|
495
|
+
*
|
|
496
|
+
* The default is monotonic where the runtime has `performance.now()`
|
|
497
|
+
* (browser / RN / Node), falling back to `Date.now()`. That is about
|
|
498
|
+
* monotonicity, not precision: `Date.now()` steps BACKWARD on an NTP
|
|
499
|
+
* correction, a VM resume from snapshot, or a container host clock sync, and
|
|
500
|
+
* a step landing mid-run makes `now() - startedAt` negative. dogstatsd
|
|
501
|
+
* accepts a negative histogram sample, so it is ingested and corrupts the
|
|
502
|
+
* min/p50/p95 for that bucket — silently wrong data, which is the one thing
|
|
503
|
+
* this module exists to prevent.
|
|
504
|
+
*
|
|
505
|
+
* Supply your own only to make durations deterministic in a test.
|
|
506
|
+
*/
|
|
507
|
+
now?: () => number;
|
|
508
|
+
/**
|
|
509
|
+
* Report the raw `error` message string on `run.failed`,
|
|
510
|
+
* `model.call.failed`, and `tool.call.failed`. Default `false`.
|
|
511
|
+
*
|
|
512
|
+
* Off by default because those strings are free text and routinely quote
|
|
513
|
+
* the input that caused the failure. `JSON.parse` echoes the offending tool
|
|
514
|
+
* arguments verbatim (`Unexpected token 'h', "hunter2pass"... is not valid
|
|
515
|
+
* JSON`), `executeToolCall` wraps whatever a host executor threw, and an
|
|
516
|
+
* executor with `deAnonymizeArgs` runs on de-redacted PII. Sending them to
|
|
517
|
+
* a sink contradicts {@link TelemetrySink}, which states that properties
|
|
518
|
+
* carry only identifiers, counts, and timings.
|
|
519
|
+
*
|
|
520
|
+
* Turn it on when the sink is infrastructure you own and you accept the
|
|
521
|
+
* exposure. Prefer `errorType`, which is always reported and always safe.
|
|
522
|
+
*/
|
|
523
|
+
includeErrorMessages?: boolean;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Build {@link RunHooks} that report run lifecycle, model calls, and tool
|
|
527
|
+
* calls to `sink`. The returned hooks are synchronous and never throw — a
|
|
528
|
+
* throwing sink method is swallowed with a console-free `noop` (the tool loop
|
|
529
|
+
* already swallows hook errors; we avoid double-logging here).
|
|
530
|
+
*/
|
|
531
|
+
declare function createMetricsHooks(sink: TelemetrySink, opts?: MetricsHooksOptions): RunHooks;
|
|
642
532
|
|
|
643
533
|
/**
|
|
644
534
|
* Build an `onDiagnostics` callback that forwards recall diagnostics to
|
|
@@ -96,17 +96,6 @@ type LlmapiChatCompletionTool = {
|
|
|
96
96
|
[key: string]: unknown;
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Lifecycle hooks for runToolLoop. All hooks are optional and observer
|
|
101
|
-
* errors are swallowed (sync throws and async rejections both) so a buggy
|
|
102
|
-
* hook can't crash the loop. Hook names match the Claude Agent SDK shape
|
|
103
|
-
* (camelCase).
|
|
104
|
-
*
|
|
105
|
-
* Hooks are awaited synchronously at each fire site, so slow hooks
|
|
106
|
-
* serialize into loop latency — keep them fast and do any heavy work
|
|
107
|
-
* (network exports, file IO) asynchronously inside your own queue.
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
99
|
type LlmTokenUsage = {
|
|
111
100
|
inputTokens?: number;
|
|
112
101
|
outputTokens?: number;
|
|
@@ -228,156 +217,6 @@ type RunHooks = {
|
|
|
228
217
|
afterToolUse?: (e: ToolUseEndEvent) => Promise<void> | void;
|
|
229
218
|
};
|
|
230
219
|
|
|
231
|
-
/**
|
|
232
|
-
* Telemetry sink contract for the observability adapter.
|
|
233
|
-
*
|
|
234
|
-
* The SDK never talks to a vendor directly — it emits structured events and
|
|
235
|
-
* metrics through this interface, and the app adapts it to PostHog, Datadog,
|
|
236
|
-
* OpenTelemetry, etc. Both methods are optional so a sink that only cares
|
|
237
|
-
* about events (or only about metrics) can implement half the surface.
|
|
238
|
-
*
|
|
239
|
-
* Implementations must be fast and must not throw: hooks are awaited
|
|
240
|
-
* synchronously inside the tool loop (see `runHooks.ts`), so a slow or
|
|
241
|
-
* throwing sink serializes into run latency or — worse — surfaces as a run
|
|
242
|
-
* error. Queue network exports asynchronously inside your sink.
|
|
243
|
-
*
|
|
244
|
-
* @example
|
|
245
|
-
* ```ts
|
|
246
|
-
* import { createMetricsHooks, type TelemetrySink } from "@anuma/sdk/telemetry";
|
|
247
|
-
*
|
|
248
|
-
* // posthog-js: capture(event, properties)
|
|
249
|
-
* const sink: TelemetrySink = {
|
|
250
|
-
* track: (event, properties) => posthog.capture(event, properties),
|
|
251
|
-
* metric: (name, value, tags) => statsd.histogram(name, value, tags),
|
|
252
|
-
* };
|
|
253
|
-
*
|
|
254
|
-
* // posthog-node takes ONE object, so the arguments do not line up:
|
|
255
|
-
* // track: (event, properties) => posthog.capture({ distinctId, event, properties })
|
|
256
|
-
*
|
|
257
|
-
* const hooks = createMetricsHooks(sink);
|
|
258
|
-
* // pass `hooks` wherever RunHooks are accepted, or compose with your own:
|
|
259
|
-
* // composeHooks([hooks, myTracingHooks])
|
|
260
|
-
* ```
|
|
261
|
-
*/
|
|
262
|
-
interface TelemetrySink {
|
|
263
|
-
/**
|
|
264
|
-
* Record a discrete event (run started, tool failed, recall degraded…).
|
|
265
|
-
* `properties` are flat, JSON-serializable, and free of message contents —
|
|
266
|
-
* only identifiers, counts, and timings.
|
|
267
|
-
*/
|
|
268
|
-
track?: (event: string, properties: Record<string, unknown>) => void;
|
|
269
|
-
/**
|
|
270
|
-
* Record a numeric measurement (latency, duration, token count). `tags`
|
|
271
|
-
* are low-cardinality string dimensions (model, toolName, outcome, lane).
|
|
272
|
-
*/
|
|
273
|
-
metric?: (name: string, value: number, tags: Record<string, string>) => void;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Default sink that discards everything. Useful as a fallback when telemetry
|
|
277
|
-
* is configured off, and as the base for sinks that override one method.
|
|
278
|
-
*
|
|
279
|
-
* Frozen. It is a published singleton, and `createMetricsHooks` closes over the
|
|
280
|
-
* object rather than its methods, so one module assigning `noopTelemetrySink.track`
|
|
281
|
-
* would reroute every already-constructed adapter that shares the reference — a
|
|
282
|
-
* test stub that forgets to restore changes behaviour for the rest of the suite.
|
|
283
|
-
* Freezing now rather than later: adding it later is the breaking direction,
|
|
284
|
-
* because it turns a silent assignment into a strict-mode TypeError.
|
|
285
|
-
*/
|
|
286
|
-
declare const noopTelemetrySink: TelemetrySink;
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* {@link RunHooks} adapter that turns tool-loop lifecycle hooks into
|
|
290
|
-
* telemetry events and metrics on a {@link TelemetrySink}.
|
|
291
|
-
*
|
|
292
|
-
* Events emitted (all with `runId`; no message contents or tool arguments):
|
|
293
|
-
*
|
|
294
|
-
* - `run.started` — `{ runId, model }`
|
|
295
|
-
* - `run.completed` — `{ runId, totalSteps, durationMs }`
|
|
296
|
-
* - `run.failed` — `{ runId, durationMs, errorType, stage }`
|
|
297
|
-
* - `model.call.completed` — `{ runId, stepIndex, latencyMs, model?, inputTokens?, outputTokens?, finishReason? }`
|
|
298
|
-
* - `model.call.failed` — `{ runId, stepIndex, latencyMs, model? }`
|
|
299
|
-
* - `tool.call.completed` — `{ runId, stepIndex, toolCallId, toolName, durationMs }`
|
|
300
|
-
* - `tool.call.failed` — `{ runId, stepIndex, toolCallId, toolName, durationMs, errorType }`
|
|
301
|
-
*
|
|
302
|
-
* The raw `error` message string is NOT reported unless the caller opts in
|
|
303
|
-
* with {@link MetricsHooksOptions.includeErrorMessages} — see that option for
|
|
304
|
-
* why. `errorType` is always safe and always reported where the source event
|
|
305
|
-
* carries one.
|
|
306
|
-
*
|
|
307
|
-
* Metrics emitted:
|
|
308
|
-
*
|
|
309
|
-
* - `run.duration` (ms, tags: model?, outcome)
|
|
310
|
-
* - `model.call.latency` (ms, tags: model?, outcome)
|
|
311
|
-
* - `model.call.tokens` (count, tags: direction: input|output) when usage is present
|
|
312
|
-
* - `tool.call.duration` (ms, tags: toolName, outcome, errorType?)
|
|
313
|
-
*
|
|
314
|
-
* Pairing notes (mirrors the contract documented in `runHooks.ts`):
|
|
315
|
-
*
|
|
316
|
-
* - `onRunEnd` / `onRunError` are mutually exclusive and fire exactly once per
|
|
317
|
-
* run, so every started run resolves to exactly one terminal event.
|
|
318
|
-
* - Server-side tools routed via `onToolCall` get `beforeToolUse` with no
|
|
319
|
-
* `afterToolUse`. The adapter therefore never emits a completion for a tool
|
|
320
|
-
* it saw only start; the pending timer is dropped when the run terminates.
|
|
321
|
-
* - `afterToolUse` without a matching `beforeToolUse` (defensive — not a
|
|
322
|
-
* documented case) is still reported, with `durationMs` omitted.
|
|
323
|
-
* - Per-run state is keyed by `runId` and cleared on the terminal hook, so
|
|
324
|
-
* concurrent runs and long-lived adapter instances do not leak timers. The
|
|
325
|
-
* `after*` hooks read that state without creating it, so a hook arriving
|
|
326
|
-
* after the terminal one cannot resurrect an entry nothing would delete
|
|
327
|
-
* again.
|
|
328
|
-
*/
|
|
329
|
-
|
|
330
|
-
interface MetricsHooksOptions {
|
|
331
|
-
/**
|
|
332
|
-
* Override the clock used for every duration this adapter reports.
|
|
333
|
-
*
|
|
334
|
-
* The default is monotonic where the runtime has `performance.now()`
|
|
335
|
-
* (browser / RN / Node), falling back to `Date.now()`. That is about
|
|
336
|
-
* monotonicity, not precision: `Date.now()` steps BACKWARD on an NTP
|
|
337
|
-
* correction, a VM resume from snapshot, or a container host clock sync, and
|
|
338
|
-
* a step landing mid-run makes `now() - startedAt` negative. dogstatsd
|
|
339
|
-
* accepts a negative histogram sample, so it is ingested and corrupts the
|
|
340
|
-
* min/p50/p95 for that bucket — silently wrong data, which is the one thing
|
|
341
|
-
* this module exists to prevent.
|
|
342
|
-
*
|
|
343
|
-
* Supply your own only to make durations deterministic in a test.
|
|
344
|
-
*/
|
|
345
|
-
now?: () => number;
|
|
346
|
-
/**
|
|
347
|
-
* Report the raw `error` message string on `run.failed`,
|
|
348
|
-
* `model.call.failed`, and `tool.call.failed`. Default `false`.
|
|
349
|
-
*
|
|
350
|
-
* Off by default because those strings are free text and routinely quote
|
|
351
|
-
* the input that caused the failure. `JSON.parse` echoes the offending tool
|
|
352
|
-
* arguments verbatim (`Unexpected token 'h', "hunter2pass"... is not valid
|
|
353
|
-
* JSON`), `executeToolCall` wraps whatever a host executor threw, and an
|
|
354
|
-
* executor with `deAnonymizeArgs` runs on de-redacted PII. Sending them to
|
|
355
|
-
* a sink contradicts {@link TelemetrySink}, which states that properties
|
|
356
|
-
* carry only identifiers, counts, and timings.
|
|
357
|
-
*
|
|
358
|
-
* Turn it on when the sink is infrastructure you own and you accept the
|
|
359
|
-
* exposure. Prefer `errorType`, which is always reported and always safe.
|
|
360
|
-
*/
|
|
361
|
-
includeErrorMessages?: boolean;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Build {@link RunHooks} that report run lifecycle, model calls, and tool
|
|
365
|
-
* calls to `sink`. The returned hooks are synchronous and never throw — a
|
|
366
|
-
* throwing sink method is swallowed with a console-free `noop` (the tool loop
|
|
367
|
-
* already swallows hook errors; we avoid double-logging here).
|
|
368
|
-
*/
|
|
369
|
-
declare function createMetricsHooks(sink: TelemetrySink, opts?: MetricsHooksOptions): RunHooks;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Unified memory layer types — the Recall / Retain API.
|
|
373
|
-
*
|
|
374
|
-
* This module defines the public surface for the new unified memory layer
|
|
375
|
-
* that sits above `memoryVault` (curated facts) and `memoryEngine` (raw
|
|
376
|
-
* conversation chunks). Callers should prefer these types over the legacy
|
|
377
|
-
* `VaultSearchResult` / `ChunkSearchResult` shapes; the underlying stores
|
|
378
|
-
* may converge later, the API will not.
|
|
379
|
-
*/
|
|
380
|
-
|
|
381
220
|
/**
|
|
382
221
|
* Budget controls retrieval depth/cost. Higher budgets enable more
|
|
383
222
|
* candidate sources and the cross-encoder reranker.
|
|
@@ -594,51 +433,102 @@ interface RecallDiagnostics {
|
|
|
594
433
|
}
|
|
595
434
|
|
|
596
435
|
/**
|
|
597
|
-
*
|
|
598
|
-
* {@link RecallOptions}) into telemetry events and metrics on a
|
|
599
|
-
* {@link TelemetrySink}.
|
|
600
|
-
*
|
|
601
|
-
* Events emitted:
|
|
436
|
+
* Telemetry sink contract for the observability adapter.
|
|
602
437
|
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
438
|
+
* The SDK never talks to a vendor directly — it emits structured events and
|
|
439
|
+
* metrics through this interface, and the app adapts it to PostHog, Datadog,
|
|
440
|
+
* OpenTelemetry, etc. Both methods are optional so a sink that only cares
|
|
441
|
+
* about events (or only about metrics) can implement half the surface.
|
|
607
442
|
*
|
|
608
|
-
*
|
|
443
|
+
* Implementations must be fast and must not throw: hooks are awaited
|
|
444
|
+
* synchronously inside the tool loop (see `runHooks.ts`), so a slow or
|
|
445
|
+
* throwing sink serializes into run latency or — worse — surfaces as a run
|
|
446
|
+
* error. Queue network exports asynchronously inside your sink.
|
|
609
447
|
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
* - `recall.candidates` (count), `recall.facts` (count), `recall.chunks` (count)
|
|
614
|
-
* - `recall.vault.size`, `recall.vault.rows_decrypted`,
|
|
615
|
-
* `recall.vault.rows_embedded` when the fact lane reported them.
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* import { createMetricsHooks, type TelemetrySink } from "@anuma/sdk/telemetry";
|
|
616
451
|
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
* `degraded` for themselves — the recall tool (`lib/memory/recallTool.ts`) and
|
|
623
|
-
* the vault search tool (`lib/memoryVault/searchTool.ts`). Neither forwards a
|
|
624
|
-
* caller's callback, and neither exposes the slot on its own options.
|
|
452
|
+
* // posthog-js: capture(event, properties)
|
|
453
|
+
* const sink: TelemetrySink = {
|
|
454
|
+
* track: (event, properties) => posthog.capture(event, properties),
|
|
455
|
+
* metric: (name, value, tags) => statsd.histogram(name, value, tags),
|
|
456
|
+
* };
|
|
625
457
|
*
|
|
626
|
-
*
|
|
458
|
+
* // posthog-node takes ONE object, so the arguments do not line up:
|
|
459
|
+
* // track: (event, properties) => posthog.capture({ distinctId, event, properties })
|
|
627
460
|
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
461
|
+
* const hooks = createMetricsHooks(sink);
|
|
462
|
+
* // pass `hooks` wherever RunHooks are accepted, or compose with your own:
|
|
463
|
+
* // composeHooks([hooks, myTracingHooks])
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
interface TelemetrySink {
|
|
467
|
+
/**
|
|
468
|
+
* Record a discrete event (run started, tool failed, recall degraded…).
|
|
469
|
+
* `properties` are flat, JSON-serializable, and free of message contents —
|
|
470
|
+
* only identifiers, counts, and timings.
|
|
471
|
+
*/
|
|
472
|
+
track?: (event: string, properties: Record<string, unknown>) => void;
|
|
473
|
+
/**
|
|
474
|
+
* Record a numeric measurement (latency, duration, token count). `tags`
|
|
475
|
+
* are low-cardinality string dimensions (model, toolName, outcome, lane).
|
|
476
|
+
*/
|
|
477
|
+
metric?: (name: string, value: number, tags: Record<string, string>) => void;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Default sink that discards everything. Useful as a fallback when telemetry
|
|
481
|
+
* is configured off, and as the base for sinks that override one method.
|
|
636
482
|
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
483
|
+
* Frozen. It is a published singleton, and `createMetricsHooks` closes over the
|
|
484
|
+
* object rather than its methods, so one module assigning `noopTelemetrySink.track`
|
|
485
|
+
* would reroute every already-constructed adapter that shares the reference — a
|
|
486
|
+
* test stub that forgets to restore changes behaviour for the rest of the suite.
|
|
487
|
+
* Freezing now rather than later: adding it later is the breaking direction,
|
|
488
|
+
* because it turns a silent assignment into a strict-mode TypeError.
|
|
641
489
|
*/
|
|
490
|
+
declare const noopTelemetrySink: TelemetrySink;
|
|
491
|
+
|
|
492
|
+
interface MetricsHooksOptions {
|
|
493
|
+
/**
|
|
494
|
+
* Override the clock used for every duration this adapter reports.
|
|
495
|
+
*
|
|
496
|
+
* The default is monotonic where the runtime has `performance.now()`
|
|
497
|
+
* (browser / RN / Node), falling back to `Date.now()`. That is about
|
|
498
|
+
* monotonicity, not precision: `Date.now()` steps BACKWARD on an NTP
|
|
499
|
+
* correction, a VM resume from snapshot, or a container host clock sync, and
|
|
500
|
+
* a step landing mid-run makes `now() - startedAt` negative. dogstatsd
|
|
501
|
+
* accepts a negative histogram sample, so it is ingested and corrupts the
|
|
502
|
+
* min/p50/p95 for that bucket — silently wrong data, which is the one thing
|
|
503
|
+
* this module exists to prevent.
|
|
504
|
+
*
|
|
505
|
+
* Supply your own only to make durations deterministic in a test.
|
|
506
|
+
*/
|
|
507
|
+
now?: () => number;
|
|
508
|
+
/**
|
|
509
|
+
* Report the raw `error` message string on `run.failed`,
|
|
510
|
+
* `model.call.failed`, and `tool.call.failed`. Default `false`.
|
|
511
|
+
*
|
|
512
|
+
* Off by default because those strings are free text and routinely quote
|
|
513
|
+
* the input that caused the failure. `JSON.parse` echoes the offending tool
|
|
514
|
+
* arguments verbatim (`Unexpected token 'h', "hunter2pass"... is not valid
|
|
515
|
+
* JSON`), `executeToolCall` wraps whatever a host executor threw, and an
|
|
516
|
+
* executor with `deAnonymizeArgs` runs on de-redacted PII. Sending them to
|
|
517
|
+
* a sink contradicts {@link TelemetrySink}, which states that properties
|
|
518
|
+
* carry only identifiers, counts, and timings.
|
|
519
|
+
*
|
|
520
|
+
* Turn it on when the sink is infrastructure you own and you accept the
|
|
521
|
+
* exposure. Prefer `errorType`, which is always reported and always safe.
|
|
522
|
+
*/
|
|
523
|
+
includeErrorMessages?: boolean;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Build {@link RunHooks} that report run lifecycle, model calls, and tool
|
|
527
|
+
* calls to `sink`. The returned hooks are synchronous and never throw — a
|
|
528
|
+
* throwing sink method is swallowed with a console-free `noop` (the tool loop
|
|
529
|
+
* already swallows hook errors; we avoid double-logging here).
|
|
530
|
+
*/
|
|
531
|
+
declare function createMetricsHooks(sink: TelemetrySink, opts?: MetricsHooksOptions): RunHooks;
|
|
642
532
|
|
|
643
533
|
/**
|
|
644
534
|
* Build an `onDiagnostics` callback that forwards recall diagnostics to
|