@smooai/smooth-operator-core 0.1.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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agent.d.ts +276 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +450 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/cast.d.ts +81 -0
  7. package/dist/cast.d.ts.map +1 -0
  8. package/dist/cast.js +103 -0
  9. package/dist/cast.js.map +1 -0
  10. package/dist/checkpoint.d.ts +25 -0
  11. package/dist/checkpoint.d.ts.map +1 -0
  12. package/dist/checkpoint.js +23 -0
  13. package/dist/checkpoint.js.map +1 -0
  14. package/dist/compaction.d.ts +21 -0
  15. package/dist/compaction.d.ts.map +1 -0
  16. package/dist/compaction.js +50 -0
  17. package/dist/compaction.js.map +1 -0
  18. package/dist/cost.d.ts +34 -0
  19. package/dist/cost.d.ts.map +1 -0
  20. package/dist/cost.js +42 -0
  21. package/dist/cost.js.map +1 -0
  22. package/dist/humanGate.d.ts +44 -0
  23. package/dist/humanGate.d.ts.map +1 -0
  24. package/dist/humanGate.js +30 -0
  25. package/dist/humanGate.js.map +1 -0
  26. package/dist/index.d.ts +32 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +21 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/knowledge.d.ts +30 -0
  31. package/dist/knowledge.d.ts.map +1 -0
  32. package/dist/knowledge.js +43 -0
  33. package/dist/knowledge.js.map +1 -0
  34. package/dist/llmProvider.d.ts +106 -0
  35. package/dist/llmProvider.d.ts.map +1 -0
  36. package/dist/llmProvider.js +160 -0
  37. package/dist/llmProvider.js.map +1 -0
  38. package/dist/memory.d.ts +23 -0
  39. package/dist/memory.d.ts.map +1 -0
  40. package/dist/memory.js +40 -0
  41. package/dist/memory.js.map +1 -0
  42. package/dist/rerank.d.ts +27 -0
  43. package/dist/rerank.d.ts.map +1 -0
  44. package/dist/rerank.js +45 -0
  45. package/dist/rerank.js.map +1 -0
  46. package/dist/thread.d.ts +43 -0
  47. package/dist/thread.d.ts.map +1 -0
  48. package/dist/thread.js +60 -0
  49. package/dist/thread.js.map +1 -0
  50. package/dist/toolSearch.d.ts +55 -0
  51. package/dist/toolSearch.d.ts.map +1 -0
  52. package/dist/toolSearch.js +110 -0
  53. package/dist/toolSearch.js.map +1 -0
  54. package/dist/vector.d.ts +36 -0
  55. package/dist/vector.d.ts.map +1 -0
  56. package/dist/vector.js +75 -0
  57. package/dist/vector.js.map +1 -0
  58. package/dist/workflow.d.ts +62 -0
  59. package/dist/workflow.d.ts.map +1 -0
  60. package/dist/workflow.js +109 -0
  61. package/dist/workflow.js.map +1 -0
  62. package/package.json +38 -0
package/dist/cast.js ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Multi-agent cast: roles and per-role tool-access policy.
3
+ *
4
+ * Phase-2 sibling of the C# reference (`dotnet/core/src/Cast.cs`) and the Rust
5
+ * engine. A *cast* is the set of named roles a lead can dispatch to; each role has
6
+ * a {@link RoleKind} (Lead / Sidekick / Shadow) and a {@link Clearance} that gates
7
+ * which tools it may call.
8
+ *
9
+ * {@link Clearance} semantics (mirrors the reference engines):
10
+ * - a **deny always wins** — a denied tool is never permitted;
11
+ * - a **non-empty allow-list is a whitelist** — only listed tools are permitted;
12
+ * - **empty allow + empty deny means "all tools"**.
13
+ *
14
+ * Clearance is wired into the agent loop: if `AgentOptions.clearance` forbids a
15
+ * tool the model asked for, that tool is *not* executed — a clear "not permitted"
16
+ * result is returned to the model instead, mirroring how the engine surfaces other
17
+ * tool errors.
18
+ */
19
+ /** A role's place in a multi-agent cast. Mirrors the reference engines' `RoleKind`. */
20
+ export var RoleKind;
21
+ (function (RoleKind) {
22
+ /** The orchestrator that delegates to sidekicks. */
23
+ RoleKind["Lead"] = "lead";
24
+ /** A focused specialist a lead can dispatch a sub-task to. */
25
+ RoleKind["Sidekick"] = "sidekick";
26
+ /** A passive observer (e.g. for logging/critique); not directly dispatchable. */
27
+ RoleKind["Shadow"] = "shadow";
28
+ })(RoleKind || (RoleKind = {}));
29
+ /**
30
+ * Tool-access policy for a role. A deny always wins; a non-empty `allowTools` is a
31
+ * whitelist; empty allow + empty deny means "all tools". `denyEverything` blocks
32
+ * every tool regardless of the lists.
33
+ */
34
+ export class Clearance {
35
+ allowTools;
36
+ denyTools;
37
+ denyEverything;
38
+ constructor(options = {}) {
39
+ this.allowTools = new Set(options.allowTools ?? []);
40
+ this.denyTools = new Set(options.denyTools ?? []);
41
+ this.denyEverything = options.denyEverything ?? false;
42
+ }
43
+ static allowAll() {
44
+ return new Clearance();
45
+ }
46
+ static denyAll() {
47
+ return new Clearance({ denyEverything: true });
48
+ }
49
+ static allow(...tools) {
50
+ return new Clearance({ allowTools: tools });
51
+ }
52
+ static deny(...tools) {
53
+ return new Clearance({ denyTools: tools });
54
+ }
55
+ /** Whether `tool` is permitted under this clearance. */
56
+ isAllowed(tool) {
57
+ if (this.denyEverything)
58
+ return false;
59
+ if (this.denyTools.has(tool))
60
+ return false;
61
+ if (this.allowTools.size > 0)
62
+ return this.allowTools.has(tool);
63
+ return true;
64
+ }
65
+ }
66
+ /** Build an {@link OperatorRole} with the reference-engine defaults applied. */
67
+ export function makeRole(name, kind, overrides = {}) {
68
+ return {
69
+ name,
70
+ kind,
71
+ instructions: overrides.instructions ?? '',
72
+ permissions: overrides.permissions ?? Clearance.allowAll(),
73
+ maxIterations: overrides.maxIterations ?? 8,
74
+ hidden: overrides.hidden ?? false,
75
+ };
76
+ }
77
+ /** The registered set of roles a lead can dispatch to. Mirrors the reference engines' `Cast`. */
78
+ export class Cast {
79
+ roles = new Map();
80
+ register(role) {
81
+ this.roles.set(role.name, role);
82
+ return this;
83
+ }
84
+ get(name) {
85
+ return this.roles.get(name);
86
+ }
87
+ list() {
88
+ return [...this.roles.values()];
89
+ }
90
+ listVisible() {
91
+ return this.list().filter((r) => !r.hidden);
92
+ }
93
+ sidekicks() {
94
+ return this.list().filter((r) => r.kind === RoleKind.Sidekick);
95
+ }
96
+ get count() {
97
+ return this.roles.size;
98
+ }
99
+ get isEmpty() {
100
+ return this.roles.size === 0;
101
+ }
102
+ }
103
+ //# sourceMappingURL=cast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cast.js","sourceRoot":"","sources":["../src/cast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Conversation checkpointing — persist a turn's state so it can resume.
3
+ *
4
+ * Phase-1 sibling of the reference engines' checkpointing. A `CheckpointStore`
5
+ * saves and loads the conversation (the non-system messages) keyed by a
6
+ * conversation id, so a later turn — even in a new process — can pick up where
7
+ * the last left off. `InMemoryCheckpointStore` is the zero-dependency default.
8
+ */
9
+ type Message = Record<string, unknown>;
10
+ export interface Checkpoint {
11
+ conversationId: string;
12
+ messages: Message[];
13
+ }
14
+ export interface CheckpointStore {
15
+ save(checkpoint: Checkpoint): void;
16
+ load(conversationId: string): Checkpoint | undefined;
17
+ }
18
+ /** A process-local checkpoint store backed by a Map. */
19
+ export declare class InMemoryCheckpointStore implements CheckpointStore {
20
+ private readonly store;
21
+ save(checkpoint: Checkpoint): void;
22
+ load(conversationId: string): Checkpoint | undefined;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../src/checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvC,MAAM,WAAW,UAAU;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC5B,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;CACxD;AAED,wDAAwD;AACxD,qBAAa,uBAAwB,YAAW,eAAe;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IAEvD,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAQlC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;CAGvD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Conversation checkpointing — persist a turn's state so it can resume.
3
+ *
4
+ * Phase-1 sibling of the reference engines' checkpointing. A `CheckpointStore`
5
+ * saves and loads the conversation (the non-system messages) keyed by a
6
+ * conversation id, so a later turn — even in a new process — can pick up where
7
+ * the last left off. `InMemoryCheckpointStore` is the zero-dependency default.
8
+ */
9
+ /** A process-local checkpoint store backed by a Map. */
10
+ export class InMemoryCheckpointStore {
11
+ store = new Map();
12
+ save(checkpoint) {
13
+ // Copy the messages so later mutation of the live list doesn't bleed in.
14
+ this.store.set(checkpoint.conversationId, {
15
+ conversationId: checkpoint.conversationId,
16
+ messages: checkpoint.messages.map((m) => ({ ...m })),
17
+ });
18
+ }
19
+ load(conversationId) {
20
+ return this.store.get(conversationId);
21
+ }
22
+ }
23
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../src/checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,wDAAwD;AACxD,MAAM,OAAO,uBAAuB;IACf,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEvD,IAAI,CAAC,UAAsB;QACvB,yEAAyE;QACzE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE;YACtC,cAAc,EAAE,UAAU,CAAC,cAAc;YACzC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;SACvD,CAAC,CAAC;IACP,CAAC;IAED,IAAI,CAAC,cAAsB;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;CACJ"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Token-aware conversation compaction (sliding window).
3
+ *
4
+ * Phase-1 sibling of the reference engines' compaction. When a conversation's
5
+ * estimated token count exceeds a budget, drop the oldest non-system messages
6
+ * (keeping the system prompt and most recent turns) so the next model call stays
7
+ * within context. A coarse char/4 token estimate is used.
8
+ *
9
+ * Safety: the kept window never *starts* on a `tool` message (which would orphan
10
+ * a tool result whose preceding `assistant` tool_call was trimmed).
11
+ */
12
+ type Message = Record<string, unknown>;
13
+ export declare function estimateTokens(message: Message): number;
14
+ /**
15
+ * Return `messages` trimmed to roughly `maxTokens`, preserving system messages
16
+ * and the most recent turns. Returns the input unchanged when already within
17
+ * budget or when `maxTokens` is non-positive (disabled).
18
+ */
19
+ export declare function compact(messages: Message[], maxTokens: number): Message[];
20
+ export {};
21
+ //# sourceMappingURL=compaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAOvD;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAwBzE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Token-aware conversation compaction (sliding window).
3
+ *
4
+ * Phase-1 sibling of the reference engines' compaction. When a conversation's
5
+ * estimated token count exceeds a budget, drop the oldest non-system messages
6
+ * (keeping the system prompt and most recent turns) so the next model call stays
7
+ * within context. A coarse char/4 token estimate is used.
8
+ *
9
+ * Safety: the kept window never *starts* on a `tool` message (which would orphan
10
+ * a tool result whose preceding `assistant` tool_call was trimmed).
11
+ */
12
+ const CHARS_PER_TOKEN = 4;
13
+ export function estimateTokens(message) {
14
+ let text = typeof message.content === 'string' ? message.content : '';
15
+ const toolCalls = message.tool_calls ?? [];
16
+ for (const tc of toolCalls) {
17
+ text += String(tc.function?.name ?? '') + String(tc.function?.arguments ?? '');
18
+ }
19
+ return Math.max(1, Math.ceil(text.length / CHARS_PER_TOKEN));
20
+ }
21
+ /**
22
+ * Return `messages` trimmed to roughly `maxTokens`, preserving system messages
23
+ * and the most recent turns. Returns the input unchanged when already within
24
+ * budget or when `maxTokens` is non-positive (disabled).
25
+ */
26
+ export function compact(messages, maxTokens) {
27
+ if (maxTokens <= 0)
28
+ return messages;
29
+ const system = messages.filter((m) => m.role === 'system');
30
+ const rest = messages.filter((m) => m.role !== 'system');
31
+ const systemTokens = system.reduce((sum, m) => sum + estimateTokens(m), 0);
32
+ const total = systemTokens + rest.reduce((sum, m) => sum + estimateTokens(m), 0);
33
+ if (total <= maxTokens)
34
+ return messages;
35
+ const budget = maxTokens - systemTokens;
36
+ const kept = [];
37
+ let running = 0;
38
+ for (let i = rest.length - 1; i >= 0; i--) {
39
+ const t = estimateTokens(rest[i]);
40
+ if (running + t > budget && kept.length > 0)
41
+ break;
42
+ kept.unshift(rest[i]);
43
+ running += t;
44
+ }
45
+ // Never start the kept window on an orphaned tool result.
46
+ while (kept.length > 0 && kept[0].role === 'tool')
47
+ kept.shift();
48
+ return [...system, ...kept];
49
+ }
50
+ //# sourceMappingURL=compaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC;AAI1B,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC3C,IAAI,IAAI,GAAG,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,SAAS,GAAI,OAAO,CAAC,UAAsF,IAAI,EAAE,CAAC;IACxH,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QACzB,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,QAAmB,EAAE,SAAiB;IAC1D,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAEzD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjF,IAAI,KAAK,IAAI,SAAS;QAAE,OAAO,QAAQ,CAAC;IAExC,MAAM,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;IACxC,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,OAAO,GAAG,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM;QACnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC,CAAC;IACjB,CAAC;IAED,0DAA0D;IAC1D,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAEhE,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAChC,CAAC"}
package/dist/cost.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Token-usage accounting and budget enforcement.
3
+ *
4
+ * Phase-1 sibling of the reference engines' cost tracking. Accumulates token
5
+ * usage across a turn's model calls, optionally converts it to a USD cost via a
6
+ * per-model pricing table, and lets a turn stop early once a token or cost budget
7
+ * is hit. Usage is exact; cost depends on the (approximate, overridable) pricing.
8
+ */
9
+ export interface Usage {
10
+ promptTokens: number;
11
+ completionTokens: number;
12
+ }
13
+ export declare function totalTokens(u: Usage): number;
14
+ /** USD per 1,000,000 tokens, input and output. */
15
+ export interface ModelPricing {
16
+ inputPerMTok: number;
17
+ outputPerMTok: number;
18
+ }
19
+ export declare function pricingCost(p: ModelPricing, u: Usage): number;
20
+ /** Approximate default pricing (USD / 1M tokens). Override via AgentOptions.pricing. */
21
+ export declare const DEFAULT_PRICING: Record<string, ModelPricing>;
22
+ /** A ceiling for a turn. Either limit may be set; the first hit stops the turn. */
23
+ export interface CostBudget {
24
+ maxUsd?: number;
25
+ maxTokens?: number;
26
+ }
27
+ /** Accumulates usage + cost across a turn's model calls. */
28
+ export declare class CostTracker {
29
+ usage: Usage;
30
+ costUsd: number;
31
+ record(model: string, usage: Usage, pricing?: Record<string, ModelPricing>): void;
32
+ exceeds(budget?: CostBudget): boolean;
33
+ }
34
+ //# sourceMappingURL=cost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,KAAK;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAE5C;AAED,kDAAkD;AAClD,MAAM,WAAW,YAAY;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,CAE7D;AAED,wFAAwF;AACxF,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAGxD,CAAC;AAEF,mFAAmF;AACnF,MAAM,WAAW,UAAU;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,4DAA4D;AAC5D,qBAAa,WAAW;IACpB,KAAK,EAAE,KAAK,CAA4C;IACxD,OAAO,SAAK;IAEZ,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,IAAI;IAQjF,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO;CAMxC"}
package/dist/cost.js ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Token-usage accounting and budget enforcement.
3
+ *
4
+ * Phase-1 sibling of the reference engines' cost tracking. Accumulates token
5
+ * usage across a turn's model calls, optionally converts it to a USD cost via a
6
+ * per-model pricing table, and lets a turn stop early once a token or cost budget
7
+ * is hit. Usage is exact; cost depends on the (approximate, overridable) pricing.
8
+ */
9
+ export function totalTokens(u) {
10
+ return u.promptTokens + u.completionTokens;
11
+ }
12
+ export function pricingCost(p, u) {
13
+ return (u.promptTokens * p.inputPerMTok + u.completionTokens * p.outputPerMTok) / 1_000_000;
14
+ }
15
+ /** Approximate default pricing (USD / 1M tokens). Override via AgentOptions.pricing. */
16
+ export const DEFAULT_PRICING = {
17
+ 'claude-haiku-4-5': { inputPerMTok: 1.0, outputPerMTok: 5.0 },
18
+ 'claude-sonnet-4-5': { inputPerMTok: 3.0, outputPerMTok: 15.0 },
19
+ };
20
+ /** Accumulates usage + cost across a turn's model calls. */
21
+ export class CostTracker {
22
+ usage = { promptTokens: 0, completionTokens: 0 };
23
+ costUsd = 0;
24
+ record(model, usage, pricing) {
25
+ this.usage.promptTokens += usage.promptTokens;
26
+ this.usage.completionTokens += usage.completionTokens;
27
+ const table = pricing ?? DEFAULT_PRICING;
28
+ const mp = table[model];
29
+ if (mp)
30
+ this.costUsd += pricingCost(mp, usage);
31
+ }
32
+ exceeds(budget) {
33
+ if (!budget)
34
+ return false;
35
+ if (budget.maxTokens !== undefined && totalTokens(this.usage) >= budget.maxTokens)
36
+ return true;
37
+ if (budget.maxUsd !== undefined && this.costUsd >= budget.maxUsd)
38
+ return true;
39
+ return false;
40
+ }
41
+ }
42
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,UAAU,WAAW,CAAC,CAAQ;IAChC,OAAO,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC;AAC/C,CAAC;AAQD,MAAM,UAAU,WAAW,CAAC,CAAe,EAAE,CAAQ;IACjD,OAAO,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;AAChG,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,MAAM,eAAe,GAAiC;IACzD,kBAAkB,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE;IAC7D,mBAAmB,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE;CAClE,CAAC;AAQF,4DAA4D;AAC5D,MAAM,OAAO,WAAW;IACpB,KAAK,GAAU,EAAE,YAAY,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IACxD,OAAO,GAAG,CAAC,CAAC;IAEZ,MAAM,CAAC,KAAa,EAAE,KAAY,EAAE,OAAsC;QACtE,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,IAAI,eAAe,CAAC;QACzC,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,EAAE;YAAE,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,MAAmB;QACvB,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC/F,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Human-in-the-loop approval — pause before a sensitive/write tool runs.
3
+ *
4
+ * Phase-2 sibling of the C# `HumanGate` (`dotnet/core`) and the Rust engine's
5
+ * confirmation hook. When a turn is about to run a tool the caller flagged as
6
+ * needing approval, the agent consults a {@link HumanGate} first. The gate IS the
7
+ * pause point — a UI gate awaits a real person (e.g. resolving a promise when a
8
+ * button is clicked); a programmatic gate decides immediately. A denial is never
9
+ * executed; the denial reason is fed back to the model as the tool result so the
10
+ * model can adapt. With no gate configured, behavior is unchanged.
11
+ */
12
+ /** The human's verdict on a tool call that required approval. */
13
+ export declare enum HumanDecision {
14
+ Approved = "approved",
15
+ Denied = "denied"
16
+ }
17
+ /**
18
+ * A request for human approval before the agent executes a sensitive/write tool.
19
+ * Mirrors the C# `HumanApprovalRequest` / the Rust engine's `HumanRequest::Confirm`.
20
+ */
21
+ export interface HumanApprovalRequest {
22
+ toolName: string;
23
+ arguments: Record<string, unknown>;
24
+ prompt: string;
25
+ }
26
+ /** The response to a {@link HumanApprovalRequest}. Mirrors the C# `HumanApprovalResponse`. */
27
+ export interface HumanApprovalResponse {
28
+ decision: HumanDecision;
29
+ reason?: string;
30
+ }
31
+ /** True when the decision is {@link HumanDecision.Approved}. */
32
+ export declare function isApproved(response: HumanApprovalResponse): boolean;
33
+ /** Build an approval. */
34
+ export declare function approve(): HumanApprovalResponse;
35
+ /** Build a denial carrying a reason the model will see. */
36
+ export declare function deny(reason: string): HumanApprovalResponse;
37
+ /**
38
+ * The human-in-the-loop seam: the agent consults it before running any tool that
39
+ * {@link AgentOptions.requiresApproval} flags. The implementation IS the pause
40
+ * point — wire it to a UI awaiting a real person, or decide programmatically.
41
+ * Mirrors the C# `IHumanGate` (here just an async function, the idiomatic TS seam).
42
+ */
43
+ export type HumanGate = (request: HumanApprovalRequest) => Promise<HumanApprovalResponse>;
44
+ //# sourceMappingURL=humanGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanGate.d.ts","sourceRoot":"","sources":["../src/humanGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,iEAAiE;AACjE,oBAAY,aAAa;IACrB,QAAQ,aAAa;IACrB,MAAM,WAAW;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,8FAA8F;AAC9F,MAAM,WAAW,qBAAqB;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAEnE;AAED,yBAAyB;AACzB,wBAAgB,OAAO,IAAI,qBAAqB,CAE/C;AAED,2DAA2D;AAC3D,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,qBAAqB,CAE1D;AAED;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Human-in-the-loop approval — pause before a sensitive/write tool runs.
3
+ *
4
+ * Phase-2 sibling of the C# `HumanGate` (`dotnet/core`) and the Rust engine's
5
+ * confirmation hook. When a turn is about to run a tool the caller flagged as
6
+ * needing approval, the agent consults a {@link HumanGate} first. The gate IS the
7
+ * pause point — a UI gate awaits a real person (e.g. resolving a promise when a
8
+ * button is clicked); a programmatic gate decides immediately. A denial is never
9
+ * executed; the denial reason is fed back to the model as the tool result so the
10
+ * model can adapt. With no gate configured, behavior is unchanged.
11
+ */
12
+ /** The human's verdict on a tool call that required approval. */
13
+ export var HumanDecision;
14
+ (function (HumanDecision) {
15
+ HumanDecision["Approved"] = "approved";
16
+ HumanDecision["Denied"] = "denied";
17
+ })(HumanDecision || (HumanDecision = {}));
18
+ /** True when the decision is {@link HumanDecision.Approved}. */
19
+ export function isApproved(response) {
20
+ return response.decision === HumanDecision.Approved;
21
+ }
22
+ /** Build an approval. */
23
+ export function approve() {
24
+ return { decision: HumanDecision.Approved };
25
+ }
26
+ /** Build a denial carrying a reason the model will see. */
27
+ export function deny(reason) {
28
+ return { decision: HumanDecision.Denied, reason };
29
+ }
30
+ //# sourceMappingURL=humanGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanGate.js","sourceRoot":"","sources":["../src/humanGate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,iEAAiE;AACjE,MAAM,CAAN,IAAY,aAGX;AAHD,WAAY,aAAa;IACrB,sCAAqB,CAAA;IACrB,kCAAiB,CAAA;AACrB,CAAC,EAHW,aAAa,KAAb,aAAa,QAGxB;AAkBD,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,QAA+B;IACtD,OAAO,QAAQ,CAAC,QAAQ,KAAK,aAAa,CAAC,QAAQ,CAAC;AACxD,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,OAAO;IACnB,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC;AAChD,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,IAAI,CAAC,MAAc;IAC/B,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @smooai/smooth-operator-core — a native, in-process agent engine for TypeScript.
3
+ *
4
+ * The Phase-0 TypeScript sibling of the Rust reference engine, the C# core, and
5
+ * the Python core: an agentic tool-calling loop over any OpenAI-compatible chat
6
+ * client, with in-memory knowledge grounding. See `docs/Architecture/TypeScript Core.md`.
7
+ */
8
+ export { delegateTool, SmoothAgent } from './agent.js';
9
+ export type { AgentOptions, AgentRunResponse, ChatChunk, ChatClientLike, StreamEvent, Tool } from './agent.js';
10
+ export { Cast, Clearance, makeRole, RoleKind } from './cast.js';
11
+ export type { OperatorRole } from './cast.js';
12
+ export { InMemoryCheckpointStore } from './checkpoint.js';
13
+ export type { Checkpoint, CheckpointStore } from './checkpoint.js';
14
+ export { CostTracker, DEFAULT_PRICING } from './cost.js';
15
+ export type { CostBudget, ModelPricing, Usage } from './cost.js';
16
+ export { approve, deny, HumanDecision, isApproved } from './humanGate.js';
17
+ export type { HumanApprovalRequest, HumanApprovalResponse, HumanGate } from './humanGate.js';
18
+ export { InMemoryKnowledge } from './knowledge.js';
19
+ export type { Knowledge, KnowledgeHit } from './knowledge.js';
20
+ export { MockLlmProvider, textResponse, toolCallResponse } from './llmProvider.js';
21
+ export type { LlmProvider, RecordedCall, ScriptedMessage, ScriptedUsage } from './llmProvider.js';
22
+ export { InMemoryMemory } from './memory.js';
23
+ export type { Memory, MemoryEntry } from './memory.js';
24
+ export { LexicalReranker, NoopReranker } from './rerank.js';
25
+ export type { Reranker } from './rerank.js';
26
+ export { SmoothAgentThread } from './thread.js';
27
+ export { MAX_MATCHES, TOOL_SEARCH_NAME, ToolSearch } from './toolSearch.js';
28
+ export { HashEmbedder, hashToken, VectorKnowledge } from './vector.js';
29
+ export type { Embedder } from './vector.js';
30
+ export { END, Workflow, WorkflowError } from './workflow.js';
31
+ export type { NodeFn, Router } from './workflow.js';
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC/G,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1E,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnF,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @smooai/smooth-operator-core — a native, in-process agent engine for TypeScript.
3
+ *
4
+ * The Phase-0 TypeScript sibling of the Rust reference engine, the C# core, and
5
+ * the Python core: an agentic tool-calling loop over any OpenAI-compatible chat
6
+ * client, with in-memory knowledge grounding. See `docs/Architecture/TypeScript Core.md`.
7
+ */
8
+ export { delegateTool, SmoothAgent } from './agent.js';
9
+ export { Cast, Clearance, makeRole, RoleKind } from './cast.js';
10
+ export { InMemoryCheckpointStore } from './checkpoint.js';
11
+ export { CostTracker, DEFAULT_PRICING } from './cost.js';
12
+ export { approve, deny, HumanDecision, isApproved } from './humanGate.js';
13
+ export { InMemoryKnowledge } from './knowledge.js';
14
+ export { MockLlmProvider, textResponse, toolCallResponse } from './llmProvider.js';
15
+ export { InMemoryMemory } from './memory.js';
16
+ export { LexicalReranker, NoopReranker } from './rerank.js';
17
+ export { SmoothAgentThread } from './thread.js';
18
+ export { MAX_MATCHES, TOOL_SEARCH_NAME, ToolSearch } from './toolSearch.js';
19
+ export { HashEmbedder, hashToken, VectorKnowledge } from './vector.js';
20
+ export { END, Workflow, WorkflowError } from './workflow.js';
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEhE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * In-memory knowledge base for the TypeScript smooth-operator core.
3
+ *
4
+ * A minimal lexical-overlap retriever — the Phase-0 sibling of the Rust engine's
5
+ * in-memory lexical store and the Python core's `InMemoryKnowledge`. Documents
6
+ * are scored by token overlap with the query; the top-k are returned. When
7
+ * nothing overlaps, the first k documents are returned anyway so the agent still
8
+ * has context to ground (or honestly decline) against.
9
+ */
10
+ export interface KnowledgeHit {
11
+ content: string;
12
+ source: string;
13
+ score: number;
14
+ }
15
+ /**
16
+ * A retriever: returns the most relevant documents for a query. Both the lexical
17
+ * {@link InMemoryKnowledge} and the embedding-backed `VectorKnowledge` satisfy
18
+ * this, so the agent accepts either.
19
+ */
20
+ export interface Knowledge {
21
+ query(query: string, topK?: number): KnowledgeHit[];
22
+ }
23
+ export declare class InMemoryKnowledge {
24
+ private readonly docs;
25
+ /** Add a document to the knowledge base. */
26
+ ingest(content: string, source: string): void;
27
+ /** Return up to `topK` documents, ranked by token overlap with `query`. */
28
+ query(query: string, topK?: number): KnowledgeHit[];
29
+ }
30
+ //# sourceMappingURL=knowledge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,YAAY;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACtB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CACvD;AAWD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAElC,4CAA4C;IAC5C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI7C,2EAA2E;IAC3E,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,YAAY,EAAE;CAsBjD"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * In-memory knowledge base for the TypeScript smooth-operator core.
3
+ *
4
+ * A minimal lexical-overlap retriever — the Phase-0 sibling of the Rust engine's
5
+ * in-memory lexical store and the Python core's `InMemoryKnowledge`. Documents
6
+ * are scored by token overlap with the query; the top-k are returned. When
7
+ * nothing overlaps, the first k documents are returned anyway so the agent still
8
+ * has context to ground (or honestly decline) against.
9
+ */
10
+ function tokenize(text) {
11
+ return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
12
+ }
13
+ export class InMemoryKnowledge {
14
+ docs = [];
15
+ /** Add a document to the knowledge base. */
16
+ ingest(content, source) {
17
+ this.docs.push({ content, source });
18
+ }
19
+ /** Return up to `topK` documents, ranked by token overlap with `query`. */
20
+ query(query, topK = 4) {
21
+ const qTokens = new Set(tokenize(query));
22
+ const scored = this.docs.map((doc) => {
23
+ const docTokens = new Set(tokenize(doc.content));
24
+ let overlap = 0;
25
+ for (const t of docTokens)
26
+ if (qTokens.has(t))
27
+ overlap++;
28
+ return { overlap, doc };
29
+ });
30
+ scored.sort((a, b) => b.overlap - a.overlap);
31
+ const hits = scored
32
+ .slice(0, topK)
33
+ .filter((s) => s.overlap > 0)
34
+ .map((s) => ({ content: s.doc.content, source: s.doc.source, score: s.overlap }));
35
+ if (hits.length === 0) {
36
+ // No lexical overlap — still hand the model the first k docs so it can
37
+ // ground or honestly decline, rather than retrieving nothing.
38
+ return this.docs.slice(0, topK).map((doc) => ({ content: doc.content, source: doc.source, score: 0 }));
39
+ }
40
+ return hits;
41
+ }
42
+ }
43
+ //# sourceMappingURL=knowledge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsBH,SAAS,QAAQ,CAAC,IAAY;IAC1B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,OAAO,iBAAiB;IACT,IAAI,GAAU,EAAE,CAAC;IAElC,4CAA4C;IAC5C,MAAM,CAAC,OAAe,EAAE,MAAc;QAClC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,KAAa,EAAE,IAAI,GAAG,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACjD,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,MAAM,CAAC,IAAI,SAAS;gBAAE,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,OAAO,EAAE,CAAC;YACzD,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QAE7C,MAAM,IAAI,GAAG,MAAM;aACd,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;aAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,uEAAuE;YACvE,8DAA8D;YAC9D,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3G,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}