@hamak/ai-agent-backend 0.9.1 → 0.9.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.
@@ -3,7 +3,7 @@
3
3
  * SSE surface backed by a server-side `AgentService` (hosted provider + durable
4
4
  * memory). Mirrors the `event-channel-backend` route/SSE conventions.
5
5
  *
6
- * POST /chat → SSE: `token` deltas, then `turn-end`
6
+ * POST /chat → SSE: `token` deltas + `usage`, then `turn-end`
7
7
  * GET /conversations?agent= → ConversationSummary[]
8
8
  * DELETE /conversations/:id?agent= → { ok: true }
9
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-routes.d.ts","sourceRoot":"","sources":["../src/agent-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,UAAU,GAAG;IACX,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC1C;AACD,UAAU,GAAG;IACX,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC;IACZ,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,IAAI,IAAI,CAAC;CACvB;AACD,UAAU,UAAU;IAClB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,CAAC;IAChB,iEAAiE;IACjE,MAAM,EAAE,MAAM,UAAU,CAAC;IACzB,yEAAyE;IACzE,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;CACpF;AAWD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,UAAU,CAkGvE"}
1
+ {"version":3,"file":"agent-routes.d.ts","sourceRoot":"","sources":["../src/agent-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,UAAU,GAAG;IACX,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC1C;AACD,UAAU,GAAG;IACX,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC;IACZ,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,IAAI,IAAI,CAAC;CACvB;AACD,UAAU,UAAU;IAClB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,CAAC;IAChB,iEAAiE;IACjE,MAAM,EAAE,MAAM,UAAU,CAAC;IACzB,yEAAyE;IACzE,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;CACpF;AAWD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,UAAU,CAyGvE"}
@@ -3,7 +3,7 @@
3
3
  * SSE surface backed by a server-side `AgentService` (hosted provider + durable
4
4
  * memory). Mirrors the `event-channel-backend` route/SSE conventions.
5
5
  *
6
- * POST /chat → SSE: `token` deltas, then `turn-end`
6
+ * POST /chat → SSE: `token` deltas + `usage`, then `turn-end`
7
7
  * GET /conversations?agent= → ConversationSummary[]
8
8
  * DELETE /conversations/:id?agent= → { ok: true }
9
9
  *
@@ -47,12 +47,20 @@ export function createAgentRoutes(config) {
47
47
  }
48
48
  };
49
49
  hooks.on('ai:token', onToken);
50
+ // Relay per-step usage (and the conversation's running total) as it lands.
51
+ const onUsage = (payload) => {
52
+ const p = payload;
53
+ if (p?.sessionId === sid)
54
+ sse(res, 'usage', payload);
55
+ };
56
+ hooks.on('ai:usage', onUsage);
50
57
  let done = false;
51
58
  const cleanup = () => {
52
59
  if (done)
53
60
  return;
54
61
  done = true;
55
62
  hooks.off('ai:token', onToken);
63
+ hooks.off('ai:usage', onUsage);
56
64
  };
57
65
  req.on('close', cleanup);
58
66
  service
@@ -16,7 +16,7 @@
16
16
  * Note: Opus 4.8 / 4.7 reject `temperature`/`top_p` (400), so `temperature` is
17
17
  * sent only when explicitly configured. Default model: claude-opus-4-8.
18
18
  */
19
- import type { AgentEvent, AgentMessage, AgentResult, CompleteOpts, IAgentProvider } from '@hamak/ai-agent';
19
+ import type { AgentEvent, AgentMessage, AgentResult, CompleteOpts, IAgentProvider, RetryConfig } from '@hamak/ai-agent';
20
20
  export interface AnthropicProviderConfig {
21
21
  /** API key; falls back to `process.env.ANTHROPIC_API_KEY`. */
22
22
  apiKey?: string;
@@ -26,12 +26,15 @@ export interface AnthropicProviderConfig {
26
26
  id?: string;
27
27
  /** Custom fetch (tests inject this); defaults to global `fetch`. */
28
28
  fetchImpl?: typeof fetch;
29
+ /** Backoff for transient failures (429/529/network). Default 3 attempts. */
30
+ retry?: RetryConfig;
29
31
  }
30
32
  export declare class AnthropicProvider implements IAgentProvider {
31
33
  readonly id: string;
32
34
  private readonly apiKey;
33
35
  private readonly url;
34
36
  private readonly fetchImpl;
37
+ private readonly retry;
35
38
  constructor(config?: AnthropicProviderConfig);
36
39
  private headers;
37
40
  private body;
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../src/anthropic-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACf,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AA4BD,qBAAa,iBAAkB,YAAW,cAAc;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,MAAM,GAAE,uBAA4B;IAahD,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,IAAI;IAYN,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAgC3E,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC;CA+CvF"}
1
+ {"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../src/anthropic-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAOzB,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AA4BD,qBAAa,iBAAkB,YAAW,cAAc;IACtD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAExB,MAAM,GAAE,uBAA4B;IAchD,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,IAAI;IAYN,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAgC3E,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC;CAgDvF"}
@@ -16,6 +16,7 @@
16
16
  * Note: Opus 4.8 / 4.7 reject `temperature`/`top_p` (400), so `temperature` is
17
17
  * sent only when explicitly configured. Default model: claude-opus-4-8.
18
18
  */
19
+ import { fetchWithRetry } from '@hamak/ai-agent';
19
20
  const ANTHROPIC_URL = 'https://api.anthropic.com/v1/messages';
20
21
  const ANTHROPIC_VERSION = '2023-06-01';
21
22
  const DEFAULT_MAX_TOKENS = 4096;
@@ -44,6 +45,7 @@ export class AnthropicProvider {
44
45
  this.id = config.id ?? 'anthropic';
45
46
  this.apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY ?? '';
46
47
  this.url = config.baseURL ?? ANTHROPIC_URL;
48
+ this.retry = config.retry ?? {};
47
49
  const resolved = config.fetchImpl ??
48
50
  (typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : undefined);
49
51
  if (!resolved) {
@@ -73,12 +75,12 @@ export class AnthropicProvider {
73
75
  });
74
76
  }
75
77
  async complete(messages, opts) {
76
- const res = await this.fetchImpl(this.url, {
78
+ const res = await fetchWithRetry(this.fetchImpl, this.url, {
77
79
  method: 'POST',
78
80
  headers: this.headers(),
79
81
  body: this.body(messages, opts, false),
80
82
  signal: opts.signal,
81
- });
83
+ }, this.retry);
82
84
  if (!res.ok) {
83
85
  throw new Error(`[anthropic] ${res.status} ${res.statusText}: ${await safeText(res)}`);
84
86
  }
@@ -101,12 +103,13 @@ export class AnthropicProvider {
101
103
  };
102
104
  }
103
105
  async *stream(messages, opts) {
104
- const res = await this.fetchImpl(this.url, {
106
+ // Only the initial request retries; a started stream cannot be resumed.
107
+ const res = await fetchWithRetry(this.fetchImpl, this.url, {
105
108
  method: 'POST',
106
109
  headers: this.headers(),
107
110
  body: this.body(messages, opts, true),
108
111
  signal: opts.signal,
109
- });
112
+ }, this.retry);
110
113
  if (!res.ok || !res.body) {
111
114
  throw new Error(`[anthropic] ${res.status} ${res.statusText}: ${await safeText(res)}`);
112
115
  }
@@ -4,7 +4,7 @@
4
4
  * relays from. Hosts that prefer the microkernel can wire these pieces by hand;
5
5
  * this helper covers the common Express-server case.
6
6
  */
7
- import { AgentService, Registry, RemoteToolBridge, type AgentPluginConfig, type IAgentProvider, type IAgentTool } from '@hamak/ai-agent';
7
+ import { AgentService, Registry, RemoteToolBridge, type AgentPluginConfig, type IAgentProvider, type IAgentTool, type IToolAuthorizer } from '@hamak/ai-agent';
8
8
  import { type AnthropicProviderConfig } from './anthropic-provider.js';
9
9
  import { FileAgentMemory } from './file-agent-memory.js';
10
10
  import { type HooksBus } from './hooks-bus.js';
@@ -20,6 +20,12 @@ export interface AgentBackendConfig {
20
20
  providers?: IAgentProvider[];
21
21
  /** Backend-side tools. */
22
22
  tools?: IAgentTool[];
23
+ /**
24
+ * Tool approval gate (§6) applied to backend *and* frontend (split-loop)
25
+ * tools. Omitted = allow everything (back-compat). Pass a
26
+ * `DefaultToolAuthorizer` to get the policy-driven review flow.
27
+ */
28
+ authorizer?: IToolAuthorizer;
23
29
  }
24
30
  export interface AgentBackend {
25
31
  service: AgentService;
@@ -1 +1 @@
1
- {"version":3,"file":"create-agent-backend.d.ts","sourceRoot":"","sources":["../src/create-agent-backend.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,MAAM,EAAE,iBAAiB,CAAC;IAC1B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,0BAA0B;IAC1B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACpC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CA8B3E"}
1
+ {"version":3,"file":"create-agent-backend.d.ts","sourceRoot":"","sources":["../src/create-agent-backend.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,MAAM,EAAE,iBAAiB,CAAC;IAC1B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC,qEAAqE;IACrE,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,0BAA0B;IAC1B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACpC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAgC3E"}
@@ -32,7 +32,9 @@ export function createAgentBackend(config) {
32
32
  specs: () => bridge.specs(),
33
33
  has: (n) => bridge.has(n),
34
34
  run: (call, sessionId) => bridge.run(call, sessionId),
35
+ category: (n) => bridge.category(n),
35
36
  },
37
+ authorizer: config.authorizer,
36
38
  });
37
39
  service.setHooks(hooks);
38
40
  return { service, hooks, memory, providers, tools, channel, bridge };
@@ -6,7 +6,7 @@
6
6
  * This is the backend analogue of the frontend's `StoreFsMemory` — same
7
7
  * `IAgentMemory` contract, different substrate (node `fs` vs the virtual store).
8
8
  */
9
- import type { AgentMessage, Conversation, ConversationSummary } from '@hamak/ai-agent';
9
+ import type { AgentMessage, Conversation, ConversationSummary, ConversationUsage } from '@hamak/ai-agent';
10
10
  import type { IAgentMemory } from '@hamak/ai-agent/spi';
11
11
  export declare class FileAgentMemory implements IAgentMemory {
12
12
  private readonly root;
@@ -19,6 +19,7 @@ export declare class FileAgentMemory implements IAgentMemory {
19
19
  append(agentId: string, sessionId: string, message: AgentMessage): Promise<void>;
20
20
  update(agentId: string, sessionId: string, messageId: string, changes: Partial<Pick<AgentMessage, 'content' | 'toolCalls'>>): Promise<void>;
21
21
  patch(agentId: string, sessionId: string, changes: Partial<Pick<Conversation, 'title' | 'pinned' | 'systemPrompt'>>): Promise<void>;
22
+ setUsage(agentId: string, sessionId: string, usage: ConversationUsage): Promise<void>;
22
23
  reset(agentId: string, sessionId: string): Promise<void>;
23
24
  list(agentId: string): Promise<ConversationSummary[]>;
24
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file-agent-memory.d.ts","sourceRoot":"","sources":["../src/file-agent-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAoBxD,qBAAa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM;IAEzC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,IAAI;IAIN,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAUrE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YAIzD,KAAK;IAKb,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhF,MAAM,CACV,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC;IAUV,KAAK,CACT,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,CAAC,CAAC,GACxE,OAAO,CAAC,IAAI,CAAC;IAMV,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;CAuB5D"}
1
+ {"version":3,"file":"file-agent-memory.d.ts","sourceRoot":"","sources":["../src/file-agent-memory.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE1G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAoBxD,qBAAa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM;IAEzC,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,IAAI;IAIN,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAUrE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YAIzD,KAAK;IAKb,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhF,MAAM,CACV,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC;IAUV,KAAK,CACT,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,CAAC,CAAC,GACxE,OAAO,CAAC,IAAI,CAAC;IAMV,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrF,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;CAuB5D"}
@@ -91,6 +91,12 @@ export class FileAgentMemory {
91
91
  return;
92
92
  await this.write(agentId, sessionId, { ...existing, ...changes, updatedAt: nowIso() });
93
93
  }
94
+ async setUsage(agentId, sessionId, usage) {
95
+ const existing = await this.get(agentId, sessionId);
96
+ if (!existing)
97
+ return;
98
+ await this.write(agentId, sessionId, { ...existing, usage, updatedAt: nowIso() });
99
+ }
94
100
  async reset(agentId, sessionId) {
95
101
  await fs.rm(this.file(agentId, sessionId), { force: true });
96
102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hamak/ai-agent-backend",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Backend for @hamak/ai-agent: hosted-model providers (Anthropic), durable memory, and an Express agent-chat route",