@axlsdk/axl 0.23.3 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/{chunk-NVPA4RY6.js → chunk-PJROX3XU.js} +4 -1
- package/dist/{chunk-NVPA4RY6.js.map → chunk-PJROX3XU.js.map} +1 -1
- package/dist/index.cjs +3965 -683
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1872 -134
- package/dist/index.d.ts +1872 -134
- package/dist/index.js +3952 -669
- package/dist/index.js.map +1 -1
- package/dist/span-manager-L4H6ZCRQ.js +10 -0
- package/package.json +2 -2
- package/dist/span-manager-74ZCGELO.js +0 -7
- /package/dist/{span-manager-74ZCGELO.js.map → span-manager-L4H6ZCRQ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ agent({ model: 'ollama:llama3' }); // local — no key, $
|
|
|
69
69
|
|
|
70
70
|
Presets: `openrouter`, `azure`, `xai`, `deepseek`, `mistral`, `groq`, `bedrock`, and self-hosted `ollama` / `vllm` / `lmstudio` / `llamacpp` / `sglang`. The unified `effort` knob and per-call cost tracking work across them. OpenAI Responses, Anthropic, Google, and OpenRouter accept image input, and OpenAI Chat Completions, Google, and OpenRouter accept general recorded-audio input, without hard-coding a model catalog; the selected upstream model remains authoritative. Completed-file transcription is a separate, narrower contract. Build your own compatible provider by cloning a `ProviderProfile`; see [provider details](../../docs/providers.md) and [multimodal input](../../docs/multimodal-input.md).
|
|
71
71
|
|
|
72
|
-
Each provider also accepts an opt-in `rateLimit` (`{ maxConcurrent?, minIntervalMs?, acquireTimeoutMs? }`) for proactive client-side pacing on top of the automatic 429/503/529
|
|
72
|
+
On every built-in chat provider, a rate-limit 429 pauses every call on that account and model for an exponential backoff (lengthened by a longer `Retry-After`, never shortened), retries on its own budget and paces the scope adaptively until it stops being throttled. First-party OpenAI and Anthropic (their own endpoints, not a proxy `baseUrl`) also fail a spend-cap 429 fast; elsewhere every 429 is treated as a rate limit. `rateLimit: { adaptive: false }` turns this off. Each provider also accepts an opt-in `rateLimit` (`{ maxConcurrent?, minIntervalMs?, acquireTimeoutMs?, adaptive?, maxRateLimitRetries? }`) for proactive client-side pacing on top of the automatic 429/503/529 handling — useful when a large fan-out (e.g. an eval) shares one API key. It caps in-flight request concurrency (not token throughput) for that provider's chat calls. See [Providers → Rate limiting](../../docs/providers.md#rate-limiting).
|
|
73
73
|
|
|
74
74
|
Built-in providers require HTTPS for remote endpoints and never follow redirects.
|
|
75
75
|
Literal loopback HTTP remains automatic for local inference; Docker service names,
|
|
@@ -585,6 +585,23 @@ const relevant = await ctx.recall('knowledge-base', {
|
|
|
585
585
|
|
|
586
586
|
Vector store implementations: `InMemoryVectorStore` (testing), `SqliteVectorStore` (production, requires `better-sqlite3`).
|
|
587
587
|
|
|
588
|
+
**Captured requests (opt-in).** Configure `diagnostics.artifacts` with a `root`
|
|
589
|
+
(or your own `DiagnosticArtifactStore`) and an eval run can record the
|
|
590
|
+
provider-neutral request Axl submitted for every model call — including the
|
|
591
|
+
repaired message list on a retry turn and the prompt a judge built for itself.
|
|
592
|
+
It is off by default, bounded per record / run / queue, redacted when
|
|
593
|
+
`trace.redact` is on, and strictly separate from accounting: a capture that
|
|
594
|
+
fails or hits a limit changes no number. Artifacts are committed only after the
|
|
595
|
+
eval history row that owns them is saved, deleted with it, and reclaimed by a
|
|
596
|
+
startup pass plus a periodic sweep. See
|
|
597
|
+
[observability.md](../../docs/observability.md#captured-requests-opt-in) and
|
|
598
|
+
[integration.md](../../docs/integration.md#diagnostic-artifact-storage).
|
|
599
|
+
|
|
600
|
+
Compatible loaded ESM/CJS copies share accounting, admission, and capture in
|
|
601
|
+
one JavaScript realm. Cross-copy work emits one warning identifying both copies;
|
|
602
|
+
see [accounting completeness](../../docs/observability.md#completeness-and-reasons)
|
|
603
|
+
for protocol compatibility and upgrade guidance.
|
|
604
|
+
|
|
588
605
|
**Embedder cost attribution.** `OpenAIEmbedder` reports `{ tokens, cost, model }` on every embed call — computed from the response's `prompt_tokens` and a pricing table (`text-embedding-3-small` $0.02/1M, `-large` $0.13/1M, `ada-002` $0.10/1M). The cost flows through `runtime.trackExecution()` the same way agent-call cost does, counts against `ctx.budget()`, and shows up in Studio's Cost Dashboard under "Memory (Embedder)". See [observability.md](../../docs/observability.md#event-types) for the trace-event shape.
|
|
589
606
|
|
|
590
607
|
**Custom `Embedder` implementations** (breaking change in 0.15.0 — `embed()` previously returned `Promise<number[][]>`):
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { createRequire as __axlCreateRequire } from 'node:module';
|
|
2
|
+
const require = __axlCreateRequire(import.meta.url);
|
|
3
|
+
const __AXL_BUILD_PATH__ = import.meta.url;
|
|
1
4
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
5
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
6
|
}) : x)(function(x) {
|
|
@@ -78,4 +81,4 @@ export {
|
|
|
78
81
|
__require,
|
|
79
82
|
OTelSpanManager
|
|
80
83
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
84
|
+
//# sourceMappingURL=chunk-PJROX3XU.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry/span-manager.ts"],"sourcesContent":["import type { SpanHandle, SpanManager, TelemetryConfig } from './types.js';\n\n/** Minimal interface for an OTel span. */\ninterface OTelSpan {\n setAttribute(key: string, value: string | number | boolean): void;\n addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;\n setStatus(status: { code: unknown; message?: string }): void;\n end(): void;\n}\n\n/** Minimal interface for an OTel tracer. */\ninterface OTelTracer {\n startActiveSpan<T>(\n name: string,\n options: { attributes: Record<string, string | number | boolean> },\n fn: (span: OTelSpan) => Promise<T>,\n ): Promise<T>;\n}\n\n/** Minimal interface for an OTel tracer provider. */\ninterface OTelTracerProvider {\n getTracer(name: string): OTelTracer;\n shutdown?(): Promise<void>;\n}\n\n/** Minimal interface for the @opentelemetry/api module. */\ninterface OTelApi {\n SpanStatusCode: { UNSET: unknown; OK: unknown; ERROR: unknown };\n trace: {\n getTracerProvider(): OTelTracerProvider;\n getActiveSpan?(): OTelSpan | undefined;\n };\n}\n\n/**\n * OpenTelemetry-backed SpanManager.\n * Dynamically imports @opentelemetry/api to avoid hard dependency.\n */\nexport class OTelSpanManager implements SpanManager {\n private tracer: OTelTracer;\n private otelApi: OTelApi;\n private tracerProvider: OTelTracerProvider;\n\n private constructor(otelApi: OTelApi, tracer: OTelTracer, tracerProvider: OTelTracerProvider) {\n this.otelApi = otelApi;\n this.tracer = tracer;\n this.tracerProvider = tracerProvider;\n }\n\n static async create(config: TelemetryConfig): Promise<OTelSpanManager> {\n let otelApi: OTelApi;\n try {\n otelApi = (await import('@opentelemetry/api')) as unknown as OTelApi;\n } catch {\n throw new Error(\n '@opentelemetry/api is required for telemetry. Install it with: npm install @opentelemetry/api',\n );\n }\n\n const tracerProvider =\n (config.tracerProvider as OTelTracerProvider | undefined) ??\n otelApi.trace.getTracerProvider();\n const serviceName = config.serviceName ?? 'axl';\n const tracer = tracerProvider.getTracer(serviceName);\n\n return new OTelSpanManager(otelApi, tracer, tracerProvider);\n }\n\n async withSpanAsync<T>(\n name: string,\n attributes: Record<string, string | number | boolean>,\n fn: (span: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const otelApi = this.otelApi;\n\n return this.tracer.startActiveSpan(name, { attributes }, async (otelSpan: OTelSpan) => {\n let statusWasSet = false;\n const handle: SpanHandle = {\n setAttribute(key: string, value: string | number | boolean) {\n otelSpan.setAttribute(key, value);\n },\n addEvent(eventName: string, attrs?: Record<string, string | number | boolean>) {\n otelSpan.addEvent(eventName, attrs);\n },\n setStatus(code: 'unset' | 'ok' | 'error', message?: string) {\n statusWasSet = true;\n const statusCode =\n code === 'ok'\n ? otelApi.SpanStatusCode.OK\n : code === 'error'\n ? otelApi.SpanStatusCode.ERROR\n : otelApi.SpanStatusCode.UNSET;\n otelSpan.setStatus({ code: statusCode, message });\n },\n end() {\n otelSpan.end();\n },\n };\n\n try {\n const result = await fn(handle);\n if (!statusWasSet) handle.setStatus('ok');\n return result;\n } catch (err) {\n // Error text can contain provider, prompt, or sensitive tool data.\n // Keep exported status structural; host diagnostics remain in Axl's\n // own error and redacted event channels.\n handle.setStatus('error');\n throw err;\n } finally {\n handle.end();\n }\n });\n }\n\n addEventToActiveSpan(name: string, attributes?: Record<string, string | number | boolean>): void {\n const activeSpan = this.otelApi.trace.getActiveSpan?.();\n if (activeSpan) {\n activeSpan.addEvent(name, attributes);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.tracerProvider && typeof this.tracerProvider.shutdown === 'function') {\n await this.tracerProvider.shutdown();\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/telemetry/span-manager.ts"],"sourcesContent":["import type { SpanHandle, SpanManager, TelemetryConfig } from './types.js';\n\n/** Minimal interface for an OTel span. */\ninterface OTelSpan {\n setAttribute(key: string, value: string | number | boolean): void;\n addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;\n setStatus(status: { code: unknown; message?: string }): void;\n end(): void;\n}\n\n/** Minimal interface for an OTel tracer. */\ninterface OTelTracer {\n startActiveSpan<T>(\n name: string,\n options: { attributes: Record<string, string | number | boolean> },\n fn: (span: OTelSpan) => Promise<T>,\n ): Promise<T>;\n}\n\n/** Minimal interface for an OTel tracer provider. */\ninterface OTelTracerProvider {\n getTracer(name: string): OTelTracer;\n shutdown?(): Promise<void>;\n}\n\n/** Minimal interface for the @opentelemetry/api module. */\ninterface OTelApi {\n SpanStatusCode: { UNSET: unknown; OK: unknown; ERROR: unknown };\n trace: {\n getTracerProvider(): OTelTracerProvider;\n getActiveSpan?(): OTelSpan | undefined;\n };\n}\n\n/**\n * OpenTelemetry-backed SpanManager.\n * Dynamically imports @opentelemetry/api to avoid hard dependency.\n */\nexport class OTelSpanManager implements SpanManager {\n private tracer: OTelTracer;\n private otelApi: OTelApi;\n private tracerProvider: OTelTracerProvider;\n\n private constructor(otelApi: OTelApi, tracer: OTelTracer, tracerProvider: OTelTracerProvider) {\n this.otelApi = otelApi;\n this.tracer = tracer;\n this.tracerProvider = tracerProvider;\n }\n\n static async create(config: TelemetryConfig): Promise<OTelSpanManager> {\n let otelApi: OTelApi;\n try {\n otelApi = (await import('@opentelemetry/api')) as unknown as OTelApi;\n } catch {\n throw new Error(\n '@opentelemetry/api is required for telemetry. Install it with: npm install @opentelemetry/api',\n );\n }\n\n const tracerProvider =\n (config.tracerProvider as OTelTracerProvider | undefined) ??\n otelApi.trace.getTracerProvider();\n const serviceName = config.serviceName ?? 'axl';\n const tracer = tracerProvider.getTracer(serviceName);\n\n return new OTelSpanManager(otelApi, tracer, tracerProvider);\n }\n\n async withSpanAsync<T>(\n name: string,\n attributes: Record<string, string | number | boolean>,\n fn: (span: SpanHandle) => Promise<T>,\n ): Promise<T> {\n const otelApi = this.otelApi;\n\n return this.tracer.startActiveSpan(name, { attributes }, async (otelSpan: OTelSpan) => {\n let statusWasSet = false;\n const handle: SpanHandle = {\n setAttribute(key: string, value: string | number | boolean) {\n otelSpan.setAttribute(key, value);\n },\n addEvent(eventName: string, attrs?: Record<string, string | number | boolean>) {\n otelSpan.addEvent(eventName, attrs);\n },\n setStatus(code: 'unset' | 'ok' | 'error', message?: string) {\n statusWasSet = true;\n const statusCode =\n code === 'ok'\n ? otelApi.SpanStatusCode.OK\n : code === 'error'\n ? otelApi.SpanStatusCode.ERROR\n : otelApi.SpanStatusCode.UNSET;\n otelSpan.setStatus({ code: statusCode, message });\n },\n end() {\n otelSpan.end();\n },\n };\n\n try {\n const result = await fn(handle);\n if (!statusWasSet) handle.setStatus('ok');\n return result;\n } catch (err) {\n // Error text can contain provider, prompt, or sensitive tool data.\n // Keep exported status structural; host diagnostics remain in Axl's\n // own error and redacted event channels.\n handle.setStatus('error');\n throw err;\n } finally {\n handle.end();\n }\n });\n }\n\n addEventToActiveSpan(name: string, attributes?: Record<string, string | number | boolean>): void {\n const activeSpan = this.otelApi.trace.getActiveSpan?.();\n if (activeSpan) {\n activeSpan.addEvent(name, attributes);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.tracerProvider && typeof this.tracerProvider.shutdown === 'function') {\n await this.tracerProvider.shutdown();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;AAsCO,IAAM,kBAAN,MAAM,iBAAuC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAkB,QAAoB,gBAAoC;AAC5F,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,aAAa,OAAO,QAAmD;AACrE,QAAI;AACJ,QAAI;AACF,gBAAW,MAAM,OAAO,oBAAoB;AAAA,IAC9C,QAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,iBACH,OAAO,kBACR,QAAQ,MAAM,kBAAkB;AAClC,UAAM,cAAc,OAAO,eAAe;AAC1C,UAAM,SAAS,eAAe,UAAU,WAAW;AAEnD,WAAO,IAAI,iBAAgB,SAAS,QAAQ,cAAc;AAAA,EAC5D;AAAA,EAEA,MAAM,cACJ,MACA,YACA,IACY;AACZ,UAAM,UAAU,KAAK;AAErB,WAAO,KAAK,OAAO,gBAAgB,MAAM,EAAE,WAAW,GAAG,OAAO,aAAuB;AACrF,UAAI,eAAe;AACnB,YAAM,SAAqB;AAAA,QACzB,aAAa,KAAa,OAAkC;AAC1D,mBAAS,aAAa,KAAK,KAAK;AAAA,QAClC;AAAA,QACA,SAAS,WAAmB,OAAmD;AAC7E,mBAAS,SAAS,WAAW,KAAK;AAAA,QACpC;AAAA,QACA,UAAU,MAAgC,SAAkB;AAC1D,yBAAe;AACf,gBAAM,aACJ,SAAS,OACL,QAAQ,eAAe,KACvB,SAAS,UACP,QAAQ,eAAe,QACvB,QAAQ,eAAe;AAC/B,mBAAS,UAAU,EAAE,MAAM,YAAY,QAAQ,CAAC;AAAA,QAClD;AAAA,QACA,MAAM;AACJ,mBAAS,IAAI;AAAA,QACf;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,GAAG,MAAM;AAC9B,YAAI,CAAC,aAAc,QAAO,UAAU,IAAI;AACxC,eAAO;AAAA,MACT,SAAS,KAAK;AAIZ,eAAO,UAAU,OAAO;AACxB,cAAM;AAAA,MACR,UAAE;AACA,eAAO,IAAI;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,qBAAqB,MAAc,YAA8D;AAC/F,UAAM,aAAa,KAAK,QAAQ,MAAM,gBAAgB;AACtD,QAAI,YAAY;AACd,iBAAW,SAAS,MAAM,UAAU;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,WAA0B;AAC9B,QAAI,KAAK,kBAAkB,OAAO,KAAK,eAAe,aAAa,YAAY;AAC7E,YAAM,KAAK,eAAe,SAAS;AAAA,IACrC;AAAA,EACF;AACF;","names":[]}
|