@halo-sdk/core 1.0.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.
Files changed (54) hide show
  1. package/README.md +8 -0
  2. package/dist/halo-agent.d.ts +73 -0
  3. package/dist/halo-agent.d.ts.map +1 -0
  4. package/dist/halo-agent.js +95 -0
  5. package/dist/halo-agent.js.map +1 -0
  6. package/dist/halo-session.d.ts +60 -0
  7. package/dist/halo-session.d.ts.map +1 -0
  8. package/dist/halo-session.js +80 -0
  9. package/dist/halo-session.js.map +1 -0
  10. package/dist/halo.d.ts +20 -0
  11. package/dist/halo.d.ts.map +1 -0
  12. package/dist/halo.js +20 -0
  13. package/dist/halo.js.map +1 -0
  14. package/dist/index.d.ts +11 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +6 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/log.d.ts +22 -0
  19. package/dist/log.d.ts.map +1 -0
  20. package/dist/log.js +41 -0
  21. package/dist/log.js.map +1 -0
  22. package/dist/model-adapter.d.ts +45 -0
  23. package/dist/model-adapter.d.ts.map +1 -0
  24. package/dist/model-adapter.js +2 -0
  25. package/dist/model-adapter.js.map +1 -0
  26. package/dist/prefix.d.ts +35 -0
  27. package/dist/prefix.d.ts.map +1 -0
  28. package/dist/prefix.js +84 -0
  29. package/dist/prefix.js.map +1 -0
  30. package/dist/session-impl.d.ts +62 -0
  31. package/dist/session-impl.d.ts.map +1 -0
  32. package/dist/session-impl.js +308 -0
  33. package/dist/session-impl.js.map +1 -0
  34. package/dist/session.d.ts +72 -0
  35. package/dist/session.d.ts.map +1 -0
  36. package/dist/session.js +2 -0
  37. package/dist/session.js.map +1 -0
  38. package/dist/strategies.d.ts +26 -0
  39. package/dist/strategies.d.ts.map +1 -0
  40. package/dist/strategies.js +2 -0
  41. package/dist/strategies.js.map +1 -0
  42. package/dist/tool-utils.d.ts +14 -0
  43. package/dist/tool-utils.d.ts.map +1 -0
  44. package/dist/tool-utils.js +36 -0
  45. package/dist/tool-utils.js.map +1 -0
  46. package/dist/tool.d.ts +22 -0
  47. package/dist/tool.d.ts.map +1 -0
  48. package/dist/tool.js +23 -0
  49. package/dist/tool.js.map +1 -0
  50. package/dist/types.d.ts +51 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +44 -0
package/dist/prefix.js ADDED
@@ -0,0 +1,84 @@
1
+ import { createHash } from "node:crypto";
2
+ export class StablePrefix {
3
+ _system;
4
+ _toolSpecs;
5
+ _fewShots;
6
+ _hashFn;
7
+ _fingerprintCache = null;
8
+ constructor(opts) {
9
+ this._system = opts.system;
10
+ this._toolSpecs = [...opts.tools];
11
+ this._fewShots = [...(opts.fewShots ?? [])];
12
+ this._hashFn = opts.hashFn ?? defaultHash;
13
+ }
14
+ /** Messages that form the stable prefix: [system, ...fewShots]. */
15
+ toMessages() {
16
+ return [{ role: "system", content: this._system }, ...this._fewShots.map((m) => ({ ...m }))];
17
+ }
18
+ /** Shallow copy of the tool list. */
19
+ tools() {
20
+ return this._toolSpecs.map((t) => ({ ...t, function: { ...t.function } }));
21
+ }
22
+ /** SHA-256[:16] fingerprint of the entire prefix. */
23
+ get fingerprint() {
24
+ if (this._fingerprintCache !== null)
25
+ return this._fingerprintCache;
26
+ this._fingerprintCache = this.computeFingerprint();
27
+ return this._fingerprintCache;
28
+ }
29
+ get diagnostics() {
30
+ return {
31
+ systemHash: this._hashFn(JSON.stringify(this._system)),
32
+ toolSpecsHash: this._hashFn(JSON.stringify(this._toolSpecs)),
33
+ fewShotsHash: this._hashFn(JSON.stringify(this._fewShots)),
34
+ toolCount: this._toolSpecs.length,
35
+ toolNames: this._toolSpecs.map((t) => t.function.name).filter(Boolean),
36
+ };
37
+ }
38
+ // ── Mutation ──
39
+ addTool(spec) {
40
+ const name = spec.function?.name;
41
+ if (!name)
42
+ return false;
43
+ if (this._toolSpecs.some((t) => t.function?.name === name))
44
+ return false;
45
+ this._toolSpecs.push(spec);
46
+ this.invalidate();
47
+ return true;
48
+ }
49
+ removeTool(name) {
50
+ const idx = this._toolSpecs.findIndex((t) => t.function?.name === name);
51
+ if (idx < 0)
52
+ return false;
53
+ this._toolSpecs.splice(idx, 1);
54
+ this.invalidate();
55
+ return true;
56
+ }
57
+ addFewShot(msg) {
58
+ this._fewShots.push(msg);
59
+ this.invalidate();
60
+ }
61
+ removeFewShot(index) {
62
+ if (index < 0 || index >= this._fewShots.length)
63
+ return false;
64
+ this._fewShots.splice(index, 1);
65
+ this.invalidate();
66
+ return true;
67
+ }
68
+ // ── Private ──
69
+ invalidate() {
70
+ this._fingerprintCache = null;
71
+ }
72
+ computeFingerprint() {
73
+ const blob = JSON.stringify({
74
+ system: this._system,
75
+ tools: this._toolSpecs,
76
+ shots: this._fewShots,
77
+ });
78
+ return this._hashFn(blob);
79
+ }
80
+ }
81
+ function defaultHash(input) {
82
+ return createHash("sha256").update(input).digest("hex").slice(0, 16);
83
+ }
84
+ //# sourceMappingURL=prefix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefix.js","sourceRoot":"","sources":["../src/prefix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { ChatMessage, ToolCall, ToolDefinition, ToolSpec } from "./types.js";
2
+ import type { TurnResult, TurnChunk, ToolResult, SessionStats, HaloAgentOptions } from "./session.js";
3
+ /** Internal implementation. Exported for testing only. */
4
+ export declare class HaloAgentImpl {
5
+ private _adapter;
6
+ private _prefix;
7
+ private _log;
8
+ private _context;
9
+ private _repair;
10
+ private _listeners;
11
+ private _stats;
12
+ private _keepAliveTimer;
13
+ private _toolExecutors;
14
+ constructor(opts: HaloAgentOptions);
15
+ get stats(): Readonly<SessionStats>;
16
+ run(input: string, opts?: {
17
+ maxSteps?: number;
18
+ onToolCall?: (call: ToolCall) => Promise<ToolResult>;
19
+ onStep?: (s: {
20
+ step: number;
21
+ content: string;
22
+ toolCalls: ToolCall[];
23
+ }) => void;
24
+ }): Promise<TurnResult>;
25
+ send(input: string): Promise<TurnResult>;
26
+ stream(input: string): AsyncGenerator<TurnChunk>;
27
+ submitToolResult(result: ToolResult): Promise<TurnResult>;
28
+ /**
29
+ * Stream-compatible entry for AI SDK (useChat) integration.
30
+ *
31
+ * Accepts UIMessages from `useChat()`, converts them to ChatMessages,
32
+ * hydrates prior history, then streams the last user message.
33
+ *
34
+ * When tools with `execute` are present, uses `run()` for auto-execution.
35
+ * Otherwise uses `stream()` for plain text streaming.
36
+ *
37
+ * Cache-first: only `_log` is modified via hydrate(), `_prefix` is untouched.
38
+ */
39
+ sdkStream(messages: {
40
+ role: string;
41
+ content: string;
42
+ }[]): AsyncGenerator<TurnChunk>;
43
+ addTool(spec: ToolSpec): void;
44
+ addTool(name: string, def: ToolDefinition): void;
45
+ removeTool(name: string): void;
46
+ addFewShot(msg: ChatMessage): void;
47
+ removeFewShot(index: number): boolean;
48
+ keepAlive(intervalMs?: number): {
49
+ stop: () => void;
50
+ };
51
+ /** Restore conversation state from external history. */
52
+ hydrate(messages: ChatMessage[]): void;
53
+ clearLog(): void;
54
+ setSystem(system: string): void;
55
+ /** Resolve history, applying ContextStrategy (prefix is read-only). */
56
+ private _resolveHistory;
57
+ private _callModel;
58
+ private _emit;
59
+ private _stopKeepAlive;
60
+ private _computeSavings;
61
+ }
62
+ //# sourceMappingURL=session-impl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-impl.d.ts","sourceRoot":"","sources":["../src/session-impl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EAEV,YAAY,EACZ,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAItB,0DAA0D;AAC1D,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,UAAU,CAAsE;IACxF,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,cAAc,CAA2E;gBAErF,IAAI,EAAE,gBAAgB;IAiDlC,IAAI,KAAK,IAAI,QAAQ,CAAC,YAAY,CAAC,CAElC;IAEK,GAAG,CACP,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;SAAE,KAAK,IAAI,CAAC;KAChF,GACA,OAAO,CAAC,UAAU,CAAC;IA+ChB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAKvC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC;IAOjD,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAS/D;;;;;;;;;;OAUG;IACI,SAAS,CACd,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,GAC5C,cAAc,CAAC,SAAS,CAAC;IAmC5B,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;IAC7B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI;IAgBhD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAGlC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAMrC,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,IAAI,CAAA;KAAE;IAyBpD,wDAAwD;IACxD,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI;IAMtC,QAAQ,IAAI,IAAI;IAIhB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS/B,uEAAuE;IACvE,OAAO,CAAC,eAAe;YAmBT,UAAU;IAyDxB,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,eAAe;CAOxB"}
@@ -0,0 +1,308 @@
1
+ import { StablePrefix } from "./prefix.js";
2
+ import { MessageLog } from "./log.js";
3
+ import { normalizeTools, definitionToSpec } from "./tool-utils.js";
4
+ /** Internal implementation. Exported for testing only. */
5
+ export class HaloAgentImpl {
6
+ _adapter;
7
+ _prefix;
8
+ _log;
9
+ _context;
10
+ _repair;
11
+ _listeners;
12
+ _stats;
13
+ _keepAliveTimer = null;
14
+ _toolExecutors;
15
+ constructor(opts) {
16
+ this._adapter = opts.adapter;
17
+ // Normalize tools: accept both ToolSpec[] and Record<string, ToolDefinition>.
18
+ const { toolSpecs, executors } = normalizeTools(opts.tools);
19
+ this._toolExecutors = executors;
20
+ this._prefix = new StablePrefix({
21
+ system: opts.system,
22
+ tools: toolSpecs,
23
+ fewShots: opts.fewShots,
24
+ });
25
+ this._log = new MessageLog();
26
+ this._context = opts.context;
27
+ this._repair = opts.repair;
28
+ this._listeners = new Map();
29
+ // Register external listener if provided.
30
+ if (opts.on) {
31
+ for (const ev of ["cache:miss", "context:truncated", "repair:applied"]) {
32
+ this._listeners.set(ev, new Set());
33
+ this._listeners.get(ev).add(opts.on);
34
+ }
35
+ }
36
+ this._stats = {
37
+ turns: 0,
38
+ totalPromptTokens: 0,
39
+ totalCompletionTokens: 0,
40
+ pricingSnapshot: {
41
+ recordedAt: Date.now(),
42
+ inputPricePer1k: this._adapter.pricing?.inputPricePer1k ?? 0,
43
+ cachedInputPricePer1k: this._adapter.pricing?.cachedInputPricePer1k ?? 0,
44
+ },
45
+ recentDiagnostics: [],
46
+ };
47
+ if (this._adapter.pricing) {
48
+ this._stats.caching = {
49
+ totalCacheHitTokens: 0,
50
+ totalCacheMissTokens: 0,
51
+ cacheHitRate: 0,
52
+ estimatedSavingsUsd: null,
53
+ };
54
+ }
55
+ }
56
+ // ── Core ──
57
+ get stats() {
58
+ return this._stats;
59
+ }
60
+ async run(input, opts) {
61
+ const maxSteps = opts?.maxSteps ?? 10;
62
+ const onToolCall = opts?.onToolCall;
63
+ const onStep = opts?.onStep;
64
+ let step = 0;
65
+ let result = await this.send(input);
66
+ while (result.toolCalls.length > 0 && step < maxSteps) {
67
+ step++;
68
+ for (const call of result.toolCalls) {
69
+ const executor = this._toolExecutors.get(call.function.name);
70
+ if (executor) {
71
+ // Auto-execute when tool definition includes execute().
72
+ let parsed;
73
+ try {
74
+ parsed = JSON.parse(call.function.arguments);
75
+ }
76
+ catch {
77
+ parsed = {};
78
+ }
79
+ const output = await executor(parsed);
80
+ this._log.append({
81
+ role: "tool",
82
+ tool_call_id: call.id,
83
+ content: output,
84
+ });
85
+ }
86
+ else if (onToolCall) {
87
+ const r = await onToolCall(call);
88
+ this._log.append({
89
+ role: "tool",
90
+ tool_call_id: call.id,
91
+ content: r.isError ? `ERROR: ${r.output}` : r.output,
92
+ });
93
+ }
94
+ else {
95
+ // No executor and no onToolCall — stop loop, return current result.
96
+ return result;
97
+ }
98
+ }
99
+ onStep?.({ step, content: result.content, toolCalls: result.toolCalls });
100
+ result = await this._callModel();
101
+ }
102
+ return result;
103
+ }
104
+ async send(input) {
105
+ this._log.append({ role: "user", content: input });
106
+ return this._callModel();
107
+ }
108
+ async *stream(input) {
109
+ this._log.append({ role: "user", content: input });
110
+ const prefix = this._prefix.toMessages();
111
+ const history = this._log.toFullHistory();
112
+ yield* this._adapter.stream(prefix, history, this._prefix.tools());
113
+ }
114
+ async submitToolResult(result) {
115
+ this._log.append({
116
+ role: "tool",
117
+ tool_call_id: result.toolCallId,
118
+ content: result.isError ? `ERROR: ${result.output}` : result.output,
119
+ });
120
+ return this._callModel();
121
+ }
122
+ /**
123
+ * Stream-compatible entry for AI SDK (useChat) integration.
124
+ *
125
+ * Accepts UIMessages from `useChat()`, converts them to ChatMessages,
126
+ * hydrates prior history, then streams the last user message.
127
+ *
128
+ * When tools with `execute` are present, uses `run()` for auto-execution.
129
+ * Otherwise uses `stream()` for plain text streaming.
130
+ *
131
+ * Cache-first: only `_log` is modified via hydrate(), `_prefix` is untouched.
132
+ */
133
+ async *sdkStream(messages) {
134
+ // Convert UIMessages → ChatMessages (system role is already in prefix).
135
+ const chatMessages = messages
136
+ .filter((m) => m.role !== "system")
137
+ .map((m) => ({
138
+ role: m.role,
139
+ content: m.content,
140
+ }));
141
+ if (chatMessages.length === 0) {
142
+ yield { type: "text-delta", delta: "" };
143
+ yield { type: "done", usage: { promptTokens: 0, completionTokens: 0 } };
144
+ return;
145
+ }
146
+ // Last message is the current user input; everything before it is history.
147
+ const lastMsg = chatMessages.pop();
148
+ if (chatMessages.length > 0) {
149
+ this.hydrate(chatMessages);
150
+ }
151
+ // If the agent has tools with auto-execute, use run() for full tool loop.
152
+ if (this._toolExecutors.size > 0) {
153
+ const result = await this.run(lastMsg.content);
154
+ yield { type: "text-delta", delta: result.content };
155
+ yield { type: "done", usage: result.usage };
156
+ return;
157
+ }
158
+ // Plain text: stream normally.
159
+ yield* this.stream(lastMsg.content);
160
+ }
161
+ addTool(specOrName, def) {
162
+ if (typeof specOrName === "string") {
163
+ // addTool(name, def)
164
+ const name = specOrName;
165
+ const d = def;
166
+ const spec = definitionToSpec(name, d);
167
+ this._prefix.addTool(spec);
168
+ if (d.execute) {
169
+ this._toolExecutors.set(name, d.execute);
170
+ }
171
+ }
172
+ else {
173
+ // addTool(spec)
174
+ this._prefix.addTool(specOrName);
175
+ }
176
+ }
177
+ removeTool(name) {
178
+ this._prefix.removeTool(name);
179
+ this._toolExecutors.delete(name);
180
+ }
181
+ addFewShot(msg) {
182
+ this._prefix.addFewShot(msg);
183
+ }
184
+ removeFewShot(index) {
185
+ return this._prefix.removeFewShot(index);
186
+ }
187
+ // ── Keep-alive ──
188
+ keepAlive(intervalMs) {
189
+ // Delegate to adapter if it provides a custom keep-alive (e.g. Gemini).
190
+ if (this._adapter.keepAlive) {
191
+ return this._adapter.keepAlive(this._prefix.toMessages());
192
+ }
193
+ // Default: periodic ping to maintain server-side KV cache.
194
+ const ms = intervalMs ?? 120_000;
195
+ if (this._keepAliveTimer)
196
+ clearInterval(this._keepAliveTimer);
197
+ this._keepAliveTimer = setInterval(() => {
198
+ this._adapter
199
+ .chat(this._prefix.toMessages(), [{ role: "user", content: "ping" }], undefined)
200
+ .catch(() => {
201
+ /* keep-alive failure is silent */
202
+ });
203
+ }, ms);
204
+ return { stop: () => this._stopKeepAlive() };
205
+ }
206
+ // ── Hydrate ──
207
+ /** Restore conversation state from external history. */
208
+ hydrate(messages) {
209
+ this._log.hydrate(messages);
210
+ }
211
+ // ── Lifecycle ──
212
+ clearLog() {
213
+ this._log = new MessageLog();
214
+ }
215
+ setSystem(system) {
216
+ this._prefix = new StablePrefix({
217
+ system,
218
+ tools: this._prefix.tools(),
219
+ });
220
+ }
221
+ // ── Private ──
222
+ /** Resolve history, applying ContextStrategy (prefix is read-only). */
223
+ _resolveHistory() {
224
+ const prefix = this._prefix.toMessages();
225
+ let history = this._log.toFullHistory();
226
+ if (this._context) {
227
+ const ctxMax = this._adapter.contextWindow;
228
+ const prepared = this._context.prepare(prefix, history, ctxMax);
229
+ if (prepared.modified) {
230
+ this._emit("context:truncated", {
231
+ droppedCount: prepared.droppedCount,
232
+ summary: prepared.summary,
233
+ });
234
+ }
235
+ return prepared.history;
236
+ }
237
+ return history;
238
+ }
239
+ async _callModel() {
240
+ const prefix = this._prefix.toMessages();
241
+ const history = this._resolveHistory();
242
+ const tools = this._prefix.tools();
243
+ const { content, toolCalls, usage } = await this._adapter.chat(prefix, history, tools.length > 0 ? tools : undefined);
244
+ // Apply repair.
245
+ let repairedCalls = toolCalls;
246
+ if (this._repair && toolCalls.length > 0) {
247
+ const rr = this._repair.repair(toolCalls, content);
248
+ repairedCalls = rr.toolCalls;
249
+ if (rr.fixed > 0 || rr.suppressed > 0) {
250
+ this._emit("repair:applied", {
251
+ fixed: rr.fixed,
252
+ suppressed: rr.suppressed,
253
+ notes: rr.notes,
254
+ });
255
+ }
256
+ }
257
+ // Append assistant message.
258
+ const assistantMsg = { role: "assistant", content };
259
+ if (repairedCalls.length > 0)
260
+ assistantMsg.tool_calls = repairedCalls;
261
+ this._log.append(assistantMsg);
262
+ // Update stats.
263
+ this._stats.turns++;
264
+ this._stats.totalPromptTokens += usage.promptTokens;
265
+ this._stats.totalCompletionTokens += usage.completionTokens;
266
+ if (this._stats.caching && usage.caching) {
267
+ this._stats.caching.totalCacheHitTokens += usage.caching.hitTokens;
268
+ this._stats.caching.totalCacheMissTokens += usage.caching.missTokens;
269
+ const total = this._stats.caching.totalCacheHitTokens + this._stats.caching.totalCacheMissTokens;
270
+ this._stats.caching.cacheHitRate =
271
+ total > 0 ? this._stats.caching.totalCacheHitTokens / total : 0;
272
+ this._stats.caching.estimatedSavingsUsd = this._computeSavings(this._stats.caching.totalCacheHitTokens);
273
+ if (usage.caching.missTokens > 0 && this._stats.turns > 1) {
274
+ this._emit("cache:miss", {
275
+ type: "unknown",
276
+ detail: `missTokens: ${usage.caching.missTokens}`,
277
+ });
278
+ }
279
+ }
280
+ return { content, toolCalls: repairedCalls, usage };
281
+ }
282
+ _emit(event, payload) {
283
+ const handlers = this._listeners.get(event);
284
+ if (!handlers)
285
+ return;
286
+ for (const fn of handlers) {
287
+ try {
288
+ fn(event, payload);
289
+ }
290
+ catch {
291
+ /* silent */
292
+ }
293
+ }
294
+ }
295
+ _stopKeepAlive() {
296
+ if (this._keepAliveTimer) {
297
+ clearInterval(this._keepAliveTimer);
298
+ this._keepAliveTimer = null;
299
+ }
300
+ }
301
+ _computeSavings(cacheHitTokens) {
302
+ if (!this._adapter.pricing)
303
+ return null;
304
+ return ((cacheHitTokens / 1000) *
305
+ (this._adapter.pricing.inputPricePer1k - this._adapter.pricing.cachedInputPricePer1k));
306
+ }
307
+ }
308
+ //# sourceMappingURL=session-impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-impl.js","sourceRoot":"","sources":["../src/session-impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import type { ChatMessage, ToolCall, ToolDefinition, ToolSpec, Usage } from "./types.js";
2
+ import type { ContextStrategy, RepairStrategy } from "./strategies.js";
3
+ import type { ModelAdapter } from "./model-adapter.js";
4
+ export interface TurnResult {
5
+ content: string;
6
+ toolCalls: ToolCall[];
7
+ usage: Usage;
8
+ }
9
+ export interface ToolResult {
10
+ toolCallId: string;
11
+ output: string;
12
+ isError?: boolean;
13
+ }
14
+ export type TurnChunk = {
15
+ type: "text-delta";
16
+ delta: string;
17
+ } | {
18
+ type: "tool-call-delta";
19
+ index: number;
20
+ name?: string;
21
+ argumentsDelta?: string;
22
+ } | {
23
+ type: "tool-call-ready";
24
+ index: number;
25
+ call: ToolCall;
26
+ } | {
27
+ type: "done";
28
+ usage: Usage;
29
+ };
30
+ export type AgentEvent = "cache:miss" | "context:truncated" | "repair:applied";
31
+ export interface CacheMissReason {
32
+ type: "cold-start" | "system-changed" | "tools-changed" | "fewshots-changed" | "unknown";
33
+ detail: string;
34
+ added?: string[];
35
+ removed?: string[];
36
+ }
37
+ export interface PricingSnapshot {
38
+ recordedAt: number;
39
+ inputPricePer1k: number;
40
+ cachedInputPricePer1k: number;
41
+ }
42
+ export interface SessionStats {
43
+ turns: number;
44
+ totalPromptTokens: number;
45
+ totalCompletionTokens: number;
46
+ caching?: {
47
+ totalCacheHitTokens: number;
48
+ totalCacheMissTokens: number;
49
+ cacheHitRate: number;
50
+ estimatedSavingsUsd: number | null;
51
+ };
52
+ pricingSnapshot: PricingSnapshot;
53
+ recentDiagnostics: CacheMissReason[];
54
+ }
55
+ export interface HaloAgentOptions {
56
+ adapter: ModelAdapter;
57
+ system: string;
58
+ /**
59
+ * Tools available to the model.
60
+ *
61
+ * Accepts either a flat array of `ToolSpec` objects (backward-compatible),
62
+ * or a named record of `ToolDefinition` objects. When `ToolDefinition`
63
+ * includes `execute`, the `run()` method calls it automatically —
64
+ * no `onToolCall` callback needed.
65
+ */
66
+ tools?: ToolSpec[] | Record<string, ToolDefinition<any>>;
67
+ fewShots?: ChatMessage[];
68
+ context?: ContextStrategy;
69
+ repair?: RepairStrategy;
70
+ on?: (event: AgentEvent, payload: unknown) => void;
71
+ }
72
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;CACd;AAID,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAID,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAInC,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,gBAAgB,CAAC;AAI/E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC;IACzF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IAEd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAE9B,OAAO,CAAC,EAAE;QACR,mBAAmB,EAAE,MAAM,CAAC;QAC5B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;KACpC,CAAC;IAEF,eAAe,EAAE,eAAe,CAAC;IAEjC,iBAAiB,EAAE,eAAe,EAAE,CAAC;CACtC;AAID,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;OAOG;IAEH,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IAEzB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import type { ChatMessage, ToolCall } from "./types.js";
2
+ export interface ContextStrategy {
3
+ /**
4
+ * Prepare history for a context-limited send.
5
+ *
6
+ * `prefix` is READ-ONLY — strategies MUST NOT modify it.
7
+ * Only `history` may be truncated / summarized.
8
+ * This preserves the stable prefix for cache-hit guarantees.
9
+ */
10
+ prepare(prefix: ChatMessage[], history: ChatMessage[], ctxMax: number): {
11
+ history: ChatMessage[];
12
+ modified: boolean;
13
+ summary?: string;
14
+ droppedCount: number;
15
+ };
16
+ }
17
+ export interface RepairResult {
18
+ toolCalls: ToolCall[];
19
+ fixed: number;
20
+ suppressed: number;
21
+ notes: string[];
22
+ }
23
+ export interface RepairStrategy {
24
+ repair(toolCalls: ToolCall[], rawContent: string): RepairResult;
25
+ }
26
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../src/strategies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,OAAO,CACL,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,EAAE,WAAW,EAAE,EACtB,MAAM,EAAE,MAAM,GACb;QACD,OAAO,EAAE,WAAW,EAAE,CAAC;QACvB,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAID,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY,CAAC;CACjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=strategies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../src/strategies.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import type { ToolSpec, ToolDefinition } from "./types.js";
2
+ /** Convert a named ToolDefinition to a ToolSpec. */
3
+ export declare function definitionToSpec(name: string, def: ToolDefinition): ToolSpec;
4
+ /** Result of normalizing tool inputs: flat specs + executor map. */
5
+ export interface NormalizedTools {
6
+ toolSpecs: ToolSpec[];
7
+ executors: Map<string, (args: Record<string, unknown>) => string | Promise<string>>;
8
+ }
9
+ /**
10
+ * Normalize tools from either a flat array of ToolSpec objects or a
11
+ * named record of ToolDefinition objects into a unified representation.
12
+ */
13
+ export declare function normalizeTools(tools: ToolSpec[] | Record<string, ToolDefinition<any>> | undefined): NormalizedTools;
14
+ //# sourceMappingURL=tool-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-utils.d.ts","sourceRoot":"","sources":["../src/tool-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3D,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,QAAQ,CAS5E;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;CACrF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAE5B,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,GAClE,eAAe,CAsBjB"}
@@ -0,0 +1,36 @@
1
+ /** Convert a named ToolDefinition to a ToolSpec. */
2
+ export function definitionToSpec(name, def) {
3
+ return {
4
+ type: "function",
5
+ function: {
6
+ name,
7
+ description: def.description,
8
+ parameters: def.parameters,
9
+ },
10
+ };
11
+ }
12
+ /**
13
+ * Normalize tools from either a flat array of ToolSpec objects or a
14
+ * named record of ToolDefinition objects into a unified representation.
15
+ */
16
+ export function normalizeTools(
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ tools) {
19
+ const executors = new Map();
20
+ if (!tools)
21
+ return { toolSpecs: [], executors };
22
+ if (Array.isArray(tools)) {
23
+ return { toolSpecs: tools, executors };
24
+ }
25
+ const specs = [];
26
+ for (const [name, def] of Object.entries(tools)) {
27
+ specs.push(definitionToSpec(name, def));
28
+ if (def.execute) {
29
+ executors.set(name,
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ def.execute);
32
+ }
33
+ }
34
+ return { toolSpecs: specs, executors };
35
+ }
36
+ //# sourceMappingURL=tool-utils.js.map