@axlsdk/axl 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,8 @@ npm install @axlsdk/axl zod@^4
12
12
 
13
13
  > **Note:** `zod` is a peer dependency — your application and Axl share a single Zod instance. Zod v4 (`^4.0.0`) is required.
14
14
 
15
+ > **Migrating from 0.15?** The 0.16.0 unified event model collapses `TraceEvent` and `StreamEvent` into a single `AxlEvent` union, renames `ExecutionInfo.steps` → `.events` and `AxlStream.steps` → `.lifecycle`, removes the deprecated `parentToolCallId` field, and changes `ctx.checkpoint(fn)` to `ctx.checkpoint(name, fn)`. See the [migration guide](../../docs/migration/unified-event-model.md) for the full rename/move table.
16
+
15
17
  ## Project Structure
16
18
 
17
19
  The recommended pattern separates config, tools, agents, workflows, and runtime into their own modules. Dependencies flow one direction: tools → agents → workflows → runtime.
@@ -303,8 +305,8 @@ const result = await runtime.execute('my-workflow', { query: 'Hello' });
303
305
  const stream = runtime.stream('my-workflow', { query: 'Hello' });
304
306
  for await (const event of stream) {
305
307
  if (event.type === 'token') process.stdout.write(event.data);
306
- if (event.type === 'error') console.error('Stream error:', event.message);
307
- if (event.type === 'done') console.log('Result:', event.data);
308
+ if (event.type === 'error') console.error('Stream error:', event.data.message);
309
+ if (event.type === 'done') console.log('Result:', event.data.result);
308
310
  }
309
311
 
310
312
  // Sessions
@@ -370,10 +372,12 @@ const decision = await ctx.awaitHuman({
370
372
  prompt: 'Approve this action?',
371
373
  });
372
374
 
373
- // Durable checkpoint — on first run, executes and saves the result.
374
- // On replay after a restart, returns the saved result without re-executing,
375
- // preventing duplicate side effects (double API calls, double charges, etc.)
376
- const checkpointed = await ctx.checkpoint(async () => expensiveOperation());
375
+ // Durable checkpoint — on first run, executes and saves the result under
376
+ // the given name. On replay after a restart, returns the saved result
377
+ // without re-executing, preventing duplicate side effects (double API
378
+ // calls, double charges, etc.). The name is a stable identifier and must
379
+ // match across runs for replay to work.
380
+ const checkpointed = await ctx.checkpoint('expensive-op', async () => expensiveOperation());
377
381
  ```
378
382
 
379
383
  ### OpenTelemetry Observability
@@ -453,6 +457,25 @@ const relevant = await ctx.recall('knowledge-base', {
453
457
 
454
458
  Vector store implementations: `InMemoryVectorStore` (testing), `SqliteVectorStore` (production, requires `better-sqlite3`).
455
459
 
460
+ **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.
461
+
462
+ **Custom `Embedder` implementations** (breaking change in 0.15.0 — `embed()` previously returned `Promise<number[][]>`):
463
+
464
+ ```typescript
465
+ import type { Embedder, EmbedResult } from '@axlsdk/axl';
466
+
467
+ class MyEmbedder implements Embedder {
468
+ readonly dimensions = 1536;
469
+
470
+ // `signal` is optional but recommended — lets budget hard-stops and user
471
+ // aborts cancel in-flight embedder fetches mid-retry.
472
+ async embed(texts: string[], signal?: AbortSignal): Promise<EmbedResult> {
473
+ const vectors = await myProvider.embed(texts, { signal });
474
+ return { vectors }; // `usage` optional — omit if you don't compute cost
475
+ }
476
+ }
477
+ ```
478
+
456
479
  ### Agent Guardrails
457
480
 
458
481
  Input and output validation at the agent boundary. You define your own validation logic — Axl calls it before and after each LLM turn: