@centerseedwu/naru-agent 0.2.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 +392 -0
- package/dist/agent.d.ts +39 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +578 -0
- package/dist/agent.js.map +1 -0
- package/dist/compression/base.d.ts +12 -0
- package/dist/compression/base.d.ts.map +1 -0
- package/dist/compression/base.js +2 -0
- package/dist/compression/base.js.map +1 -0
- package/dist/compression/compressor.d.ts +20 -0
- package/dist/compression/compressor.d.ts.map +1 -0
- package/dist/compression/compressor.js +52 -0
- package/dist/compression/compressor.js.map +1 -0
- package/dist/compression/in-memory-store.d.ts +8 -0
- package/dist/compression/in-memory-store.d.ts.map +1 -0
- package/dist/compression/in-memory-store.js +13 -0
- package/dist/compression/in-memory-store.js.map +1 -0
- package/dist/decision/index.d.ts +7 -0
- package/dist/decision/index.d.ts.map +1 -0
- package/dist/decision/index.js +4 -0
- package/dist/decision/index.js.map +1 -0
- package/dist/decision/llm-structured-classifier.d.ts +18 -0
- package/dist/decision/llm-structured-classifier.d.ts.map +1 -0
- package/dist/decision/llm-structured-classifier.js +44 -0
- package/dist/decision/llm-structured-classifier.js.map +1 -0
- package/dist/decision/tool-planner.d.ts +14 -0
- package/dist/decision/tool-planner.d.ts.map +1 -0
- package/dist/decision/tool-planner.js +35 -0
- package/dist/decision/tool-planner.js.map +1 -0
- package/dist/decision/types.d.ts +53 -0
- package/dist/decision/types.d.ts.map +1 -0
- package/dist/decision/types.js +12 -0
- package/dist/decision/types.js.map +1 -0
- package/dist/event-bus.d.ts +10 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +34 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/guardrails/base.d.ts +10 -0
- package/dist/guardrails/base.d.ts.map +1 -0
- package/dist/guardrails/base.js +2 -0
- package/dist/guardrails/base.js.map +1 -0
- package/dist/guardrails/keyword.d.ts +15 -0
- package/dist/guardrails/keyword.d.ts.map +1 -0
- package/dist/guardrails/keyword.js +37 -0
- package/dist/guardrails/keyword.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/intent/base.d.ts +19 -0
- package/dist/intent/base.d.ts.map +1 -0
- package/dist/intent/base.js +2 -0
- package/dist/intent/base.js.map +1 -0
- package/dist/intent/llm-classifier.d.ts +22 -0
- package/dist/intent/llm-classifier.d.ts.map +1 -0
- package/dist/intent/llm-classifier.js +49 -0
- package/dist/intent/llm-classifier.js.map +1 -0
- package/dist/intent/tool-calling-classifier.d.ts +16 -0
- package/dist/intent/tool-calling-classifier.d.ts.map +1 -0
- package/dist/intent/tool-calling-classifier.js +56 -0
- package/dist/intent/tool-calling-classifier.js.map +1 -0
- package/dist/knowledge/base.d.ts +14 -0
- package/dist/knowledge/base.d.ts.map +1 -0
- package/dist/knowledge/base.js +10 -0
- package/dist/knowledge/base.js.map +1 -0
- package/dist/knowledge/chroma-store.d.ts +25 -0
- package/dist/knowledge/chroma-store.d.ts.map +1 -0
- package/dist/knowledge/chroma-store.js +70 -0
- package/dist/knowledge/chroma-store.js.map +1 -0
- package/dist/knowledge/contextualizer.d.ts +17 -0
- package/dist/knowledge/contextualizer.d.ts.map +1 -0
- package/dist/knowledge/contextualizer.js +47 -0
- package/dist/knowledge/contextualizer.js.map +1 -0
- package/dist/knowledge/graph-store.d.ts +22 -0
- package/dist/knowledge/graph-store.d.ts.map +1 -0
- package/dist/knowledge/graph-store.js +116 -0
- package/dist/knowledge/graph-store.js.map +1 -0
- package/dist/knowledge/hybrid-store.d.ts +16 -0
- package/dist/knowledge/hybrid-store.d.ts.map +1 -0
- package/dist/knowledge/hybrid-store.js +39 -0
- package/dist/knowledge/hybrid-store.js.map +1 -0
- package/dist/knowledge/in-memory-store.d.ts +27 -0
- package/dist/knowledge/in-memory-store.d.ts.map +1 -0
- package/dist/knowledge/in-memory-store.js +54 -0
- package/dist/knowledge/in-memory-store.js.map +1 -0
- package/dist/knowledge/pgvector-store.d.ts +27 -0
- package/dist/knowledge/pgvector-store.d.ts.map +1 -0
- package/dist/knowledge/pgvector-store.js +68 -0
- package/dist/knowledge/pgvector-store.js.map +1 -0
- package/dist/memory/base.d.ts +21 -0
- package/dist/memory/base.d.ts.map +1 -0
- package/dist/memory/base.js +9 -0
- package/dist/memory/base.js.map +1 -0
- package/dist/memory/in-memory-store.d.ts +10 -0
- package/dist/memory/in-memory-store.d.ts.map +1 -0
- package/dist/memory/in-memory-store.js +35 -0
- package/dist/memory/in-memory-store.js.map +1 -0
- package/dist/memory/manager.d.ts +29 -0
- package/dist/memory/manager.d.ts.map +1 -0
- package/dist/memory/manager.js +121 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/memory/mem0-manager.d.ts +32 -0
- package/dist/memory/mem0-manager.d.ts.map +1 -0
- package/dist/memory/mem0-manager.js +77 -0
- package/dist/memory/mem0-manager.js.map +1 -0
- package/dist/memory/pgvector-store.d.ts +22 -0
- package/dist/memory/pgvector-store.d.ts.map +1 -0
- package/dist/memory/pgvector-store.js +89 -0
- package/dist/memory/pgvector-store.js.map +1 -0
- package/dist/orchestration/channel.d.ts +18 -0
- package/dist/orchestration/channel.d.ts.map +1 -0
- package/dist/orchestration/channel.js +2 -0
- package/dist/orchestration/channel.js.map +1 -0
- package/dist/orchestration/executor.d.ts +19 -0
- package/dist/orchestration/executor.d.ts.map +1 -0
- package/dist/orchestration/executor.js +2 -0
- package/dist/orchestration/executor.js.map +1 -0
- package/dist/orchestration/index.d.ts +13 -0
- package/dist/orchestration/index.d.ts.map +1 -0
- package/dist/orchestration/index.js +9 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/intent.d.ts +49 -0
- package/dist/orchestration/intent.d.ts.map +1 -0
- package/dist/orchestration/intent.js +57 -0
- package/dist/orchestration/intent.js.map +1 -0
- package/dist/orchestration/orchestrator.d.ts +59 -0
- package/dist/orchestration/orchestrator.d.ts.map +1 -0
- package/dist/orchestration/orchestrator.js +216 -0
- package/dist/orchestration/orchestrator.js.map +1 -0
- package/dist/orchestration/pending.d.ts +28 -0
- package/dist/orchestration/pending.d.ts.map +1 -0
- package/dist/orchestration/pending.js +32 -0
- package/dist/orchestration/pending.js.map +1 -0
- package/dist/orchestration/result.d.ts +24 -0
- package/dist/orchestration/result.d.ts.map +1 -0
- package/dist/orchestration/result.js +2 -0
- package/dist/orchestration/result.js.map +1 -0
- package/dist/orchestration/session-state.d.ts +24 -0
- package/dist/orchestration/session-state.d.ts.map +1 -0
- package/dist/orchestration/session-state.js +19 -0
- package/dist/orchestration/session-state.js.map +1 -0
- package/dist/orchestration/trace.d.ts +20 -0
- package/dist/orchestration/trace.d.ts.map +1 -0
- package/dist/orchestration/trace.js +2 -0
- package/dist/orchestration/trace.js.map +1 -0
- package/dist/session/base.d.ts +7 -0
- package/dist/session/base.d.ts.map +1 -0
- package/dist/session/base.js +2 -0
- package/dist/session/base.js.map +1 -0
- package/dist/session/in-memory-store.d.ts +9 -0
- package/dist/session/in-memory-store.d.ts.map +1 -0
- package/dist/session/in-memory-store.js +13 -0
- package/dist/session/in-memory-store.js.map +1 -0
- package/dist/session/redis-store.d.ts +16 -0
- package/dist/session/redis-store.d.ts.map +1 -0
- package/dist/session/redis-store.js +29 -0
- package/dist/session/redis-store.js.map +1 -0
- package/dist/skills/base.d.ts +38 -0
- package/dist/skills/base.d.ts.map +1 -0
- package/dist/skills/base.js +24 -0
- package/dist/skills/base.js.map +1 -0
- package/dist/skills/registry.d.ts +11 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +37 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/selectors.d.ts +23 -0
- package/dist/skills/selectors.d.ts.map +1 -0
- package/dist/skills/selectors.js +52 -0
- package/dist/skills/selectors.js.map +1 -0
- package/dist/tools/base.d.ts +34 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +22 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/vercel-adapter.d.ts +17 -0
- package/dist/tools/vercel-adapter.d.ts.map +1 -0
- package/dist/tools/vercel-adapter.js +66 -0
- package/dist/tools/vercel-adapter.js.map +1 -0
- package/dist/tracing/collector.d.ts +16 -0
- package/dist/tracing/collector.d.ts.map +1 -0
- package/dist/tracing/collector.js +92 -0
- package/dist/tracing/collector.js.map +1 -0
- package/dist/tracing/exporters/jsonl.d.ts +13 -0
- package/dist/tracing/exporters/jsonl.d.ts.map +1 -0
- package/dist/tracing/exporters/jsonl.js +14 -0
- package/dist/tracing/exporters/jsonl.js.map +1 -0
- package/dist/tracing/trace.d.ts +34 -0
- package/dist/tracing/trace.d.ts.map +1 -0
- package/dist/tracing/trace.js +28 -0
- package/dist/tracing/trace.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/math.d.ts +3 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +14 -0
- package/dist/utils/math.js.map +1 -0
- package/dist-cjs/agent.js +581 -0
- package/dist-cjs/compression/base.js +2 -0
- package/dist-cjs/compression/compressor.js +55 -0
- package/dist-cjs/compression/in-memory-store.js +16 -0
- package/dist-cjs/decision/index.js +9 -0
- package/dist-cjs/decision/llm-structured-classifier.js +47 -0
- package/dist-cjs/decision/tool-planner.js +38 -0
- package/dist-cjs/decision/types.js +15 -0
- package/dist-cjs/event-bus.js +37 -0
- package/dist-cjs/guardrails/base.js +2 -0
- package/dist-cjs/guardrails/keyword.js +40 -0
- package/dist-cjs/index.js +84 -0
- package/dist-cjs/intent/base.js +2 -0
- package/dist-cjs/intent/llm-classifier.js +52 -0
- package/dist-cjs/intent/tool-calling-classifier.js +59 -0
- package/dist-cjs/knowledge/base.js +12 -0
- package/dist-cjs/knowledge/chroma-store.js +106 -0
- package/dist-cjs/knowledge/contextualizer.js +50 -0
- package/dist-cjs/knowledge/graph-store.js +152 -0
- package/dist-cjs/knowledge/hybrid-store.js +42 -0
- package/dist-cjs/knowledge/in-memory-store.js +57 -0
- package/dist-cjs/knowledge/pgvector-store.js +71 -0
- package/dist-cjs/memory/base.js +11 -0
- package/dist-cjs/memory/in-memory-store.js +38 -0
- package/dist-cjs/memory/manager.js +124 -0
- package/dist-cjs/memory/mem0-manager.js +113 -0
- package/dist-cjs/memory/pgvector-store.js +92 -0
- package/dist-cjs/orchestration/channel.js +2 -0
- package/dist-cjs/orchestration/executor.js +2 -0
- package/dist-cjs/orchestration/index.js +17 -0
- package/dist-cjs/orchestration/intent.js +61 -0
- package/dist-cjs/orchestration/orchestrator.js +219 -0
- package/dist-cjs/orchestration/pending.js +36 -0
- package/dist-cjs/orchestration/result.js +2 -0
- package/dist-cjs/orchestration/session-state.js +22 -0
- package/dist-cjs/orchestration/trace.js +2 -0
- package/dist-cjs/session/base.js +2 -0
- package/dist-cjs/session/in-memory-store.js +16 -0
- package/dist-cjs/session/redis-store.js +32 -0
- package/dist-cjs/skills/base.js +27 -0
- package/dist-cjs/skills/registry.js +40 -0
- package/dist-cjs/skills/selectors.js +56 -0
- package/dist-cjs/tools/base.js +24 -0
- package/dist-cjs/tools/vercel-adapter.js +69 -0
- package/dist-cjs/tracing/collector.js +95 -0
- package/dist-cjs/tracing/exporters/jsonl.js +17 -0
- package/dist-cjs/tracing/trace.js +31 -0
- package/dist-cjs/types.js +9 -0
- package/dist-cjs/utils/math.js +17 -0
- package/package.json +70 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PgVectorMemoryStore = void 0;
|
|
4
|
+
const math_js_1 = require("../utils/math.js");
|
|
5
|
+
/**
|
|
6
|
+
* PostgreSQL + pgvector backed memory store. Requires `pg` as optional dependency.
|
|
7
|
+
*/
|
|
8
|
+
class PgVectorMemoryStore {
|
|
9
|
+
pool;
|
|
10
|
+
tableName;
|
|
11
|
+
dimensions;
|
|
12
|
+
initialized = false;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.pool = config.pool;
|
|
15
|
+
this.tableName = config.tableName ?? "naru_memories";
|
|
16
|
+
this.dimensions = config.dimensions ?? 1536;
|
|
17
|
+
}
|
|
18
|
+
async ensureTable() {
|
|
19
|
+
if (this.initialized)
|
|
20
|
+
return;
|
|
21
|
+
await this.pool.query(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
user_id TEXT NOT NULL,
|
|
25
|
+
content TEXT NOT NULL,
|
|
26
|
+
metadata JSONB DEFAULT '{}',
|
|
27
|
+
embedding vector(${this.dimensions}),
|
|
28
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
29
|
+
updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
30
|
+
)
|
|
31
|
+
`);
|
|
32
|
+
await this.pool.query(`
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_${this.tableName}_user_id
|
|
34
|
+
ON ${this.tableName}(user_id)
|
|
35
|
+
`);
|
|
36
|
+
this.initialized = true;
|
|
37
|
+
}
|
|
38
|
+
async add(item, embedding) {
|
|
39
|
+
await this.ensureTable();
|
|
40
|
+
await this.pool.query(`INSERT INTO ${this.tableName} (id, user_id, content, metadata, embedding, created_at, updated_at)
|
|
41
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
42
|
+
ON CONFLICT (id) DO UPDATE SET content = $3, metadata = $4, embedding = $5, updated_at = $7`, [
|
|
43
|
+
item.id,
|
|
44
|
+
item.userId,
|
|
45
|
+
item.content,
|
|
46
|
+
JSON.stringify(item.metadata),
|
|
47
|
+
(0, math_js_1.toVectorLiteral)(embedding),
|
|
48
|
+
item.createdAt,
|
|
49
|
+
item.updatedAt,
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
async search(userId, embedding, topK = 5) {
|
|
53
|
+
await this.ensureTable();
|
|
54
|
+
const result = await this.pool.query(`SELECT id, user_id, content, metadata, created_at, updated_at,
|
|
55
|
+
1 - (embedding <=> $1::vector) AS score
|
|
56
|
+
FROM ${this.tableName}
|
|
57
|
+
WHERE user_id = $2
|
|
58
|
+
ORDER BY embedding <=> $1::vector
|
|
59
|
+
LIMIT $3`, [(0, math_js_1.toVectorLiteral)(embedding), userId, topK]);
|
|
60
|
+
return result.rows.map((r) => ({
|
|
61
|
+
id: r.id,
|
|
62
|
+
userId: r.user_id,
|
|
63
|
+
content: r.content,
|
|
64
|
+
metadata: (r.metadata ?? {}),
|
|
65
|
+
score: r.score,
|
|
66
|
+
createdAt: new Date(r.created_at),
|
|
67
|
+
updatedAt: new Date(r.updated_at),
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
async update(itemId, content, embedding) {
|
|
71
|
+
await this.ensureTable();
|
|
72
|
+
await this.pool.query(`UPDATE ${this.tableName} SET content = $1, embedding = $2, updated_at = NOW() WHERE id = $3`, [content, (0, math_js_1.toVectorLiteral)(embedding), itemId]);
|
|
73
|
+
}
|
|
74
|
+
async delete(itemId) {
|
|
75
|
+
await this.ensureTable();
|
|
76
|
+
await this.pool.query(`DELETE FROM ${this.tableName} WHERE id = $1`, [itemId]);
|
|
77
|
+
}
|
|
78
|
+
async getAll(userId) {
|
|
79
|
+
await this.ensureTable();
|
|
80
|
+
const result = await this.pool.query(`SELECT id, user_id, content, metadata, created_at, updated_at
|
|
81
|
+
FROM ${this.tableName} WHERE user_id = $1 ORDER BY created_at`, [userId]);
|
|
82
|
+
return result.rows.map((r) => ({
|
|
83
|
+
id: r.id,
|
|
84
|
+
userId: r.user_id,
|
|
85
|
+
content: r.content,
|
|
86
|
+
metadata: (r.metadata ?? {}),
|
|
87
|
+
createdAt: new Date(r.created_at),
|
|
88
|
+
updatedAt: new Date(r.updated_at),
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.PgVectorMemoryStore = PgVectorMemoryStore;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemorySessionStateStore = exports.classifyConfirmationDisposition = exports.InMemoryPendingStateManager = exports.LLMFallbackIntentResolver = exports.DeterministicIntentResolver = exports.AgentOrchestrator = void 0;
|
|
4
|
+
// Orchestrator
|
|
5
|
+
var orchestrator_js_1 = require("./orchestrator.js");
|
|
6
|
+
Object.defineProperty(exports, "AgentOrchestrator", { enumerable: true, get: function () { return orchestrator_js_1.AgentOrchestrator; } });
|
|
7
|
+
// Intent
|
|
8
|
+
var intent_js_1 = require("./intent.js");
|
|
9
|
+
Object.defineProperty(exports, "DeterministicIntentResolver", { enumerable: true, get: function () { return intent_js_1.DeterministicIntentResolver; } });
|
|
10
|
+
Object.defineProperty(exports, "LLMFallbackIntentResolver", { enumerable: true, get: function () { return intent_js_1.LLMFallbackIntentResolver; } });
|
|
11
|
+
// Pending state
|
|
12
|
+
var pending_js_1 = require("./pending.js");
|
|
13
|
+
Object.defineProperty(exports, "InMemoryPendingStateManager", { enumerable: true, get: function () { return pending_js_1.InMemoryPendingStateManager; } });
|
|
14
|
+
Object.defineProperty(exports, "classifyConfirmationDisposition", { enumerable: true, get: function () { return pending_js_1.classifyConfirmationDisposition; } });
|
|
15
|
+
// Session state
|
|
16
|
+
var session_state_js_1 = require("./session-state.js");
|
|
17
|
+
Object.defineProperty(exports, "InMemorySessionStateStore", { enumerable: true, get: function () { return session_state_js_1.InMemorySessionStateStore; } });
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Generic intent types and resolvers for the orchestration layer.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LLMFallbackIntentResolver = exports.DeterministicIntentResolver = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* DeterministicIntentResolver — fast pattern matching, no LLM calls.
|
|
9
|
+
* Returns first matching pattern or unknown with confidence 0.
|
|
10
|
+
*/
|
|
11
|
+
class DeterministicIntentResolver {
|
|
12
|
+
patterns;
|
|
13
|
+
constructor(patterns) {
|
|
14
|
+
this.patterns = patterns;
|
|
15
|
+
}
|
|
16
|
+
async resolve(input) {
|
|
17
|
+
for (const entry of this.patterns) {
|
|
18
|
+
if (entry.pattern.test(input.message)) {
|
|
19
|
+
return entry.intent;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return { object: "unknown", confidence: 0 };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.DeterministicIntentResolver = DeterministicIntentResolver;
|
|
26
|
+
/**
|
|
27
|
+
* LLMFallbackIntentResolver — tries deterministic first, falls back to LLM classifier.
|
|
28
|
+
*/
|
|
29
|
+
class LLMFallbackIntentResolver {
|
|
30
|
+
primary;
|
|
31
|
+
fallbackAgent;
|
|
32
|
+
parseResponse;
|
|
33
|
+
constructor(config) {
|
|
34
|
+
this.primary = config.primary;
|
|
35
|
+
this.fallbackAgent = config.fallbackAgent;
|
|
36
|
+
this.parseResponse = config.parseResponse;
|
|
37
|
+
}
|
|
38
|
+
async resolve(input) {
|
|
39
|
+
const primaryResult = await this.primary.resolve(input);
|
|
40
|
+
if (primaryResult.object !== "unknown") {
|
|
41
|
+
return primaryResult;
|
|
42
|
+
}
|
|
43
|
+
// Fallback to LLM
|
|
44
|
+
const llmResponse = await this.fallbackAgent.chat(`Classify the intent of this message: "${input.message}". Return a JSON object with "object" (string) and "confidence" (number 0-1).`);
|
|
45
|
+
if (this.parseResponse) {
|
|
46
|
+
return this.parseResponse(llmResponse.content);
|
|
47
|
+
}
|
|
48
|
+
// Default parsing
|
|
49
|
+
try {
|
|
50
|
+
const parsed = JSON.parse(llmResponse.content);
|
|
51
|
+
return {
|
|
52
|
+
object: (parsed.object ?? "unknown"),
|
|
53
|
+
confidence: parsed.confidence ?? 0.5,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { object: "unknown", confidence: 0 };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.LLMFallbackIntentResolver = LLMFallbackIntentResolver;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentOrchestrator = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const pending_js_1 = require("./pending.js");
|
|
6
|
+
/**
|
|
7
|
+
* AgentOrchestrator — wraps one or more AgentChatDelegate instances with:
|
|
8
|
+
* Phase 0: Pending confirmation handling
|
|
9
|
+
* Phase 1: Intent resolution
|
|
10
|
+
* Phase 2: Direct execution (bypass LLM)
|
|
11
|
+
* Phase 3: Delegate routing
|
|
12
|
+
*
|
|
13
|
+
* AgentOrchestrator itself satisfies AgentChatDelegate, enabling nesting.
|
|
14
|
+
*/
|
|
15
|
+
class AgentOrchestrator {
|
|
16
|
+
config;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
async fireHook(fn) {
|
|
21
|
+
if (fn) {
|
|
22
|
+
try {
|
|
23
|
+
await fn();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// hooks do not affect main flow
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async chat(message, options) {
|
|
31
|
+
const startTime = Date.now();
|
|
32
|
+
const traceId = (0, uuid_1.v4)();
|
|
33
|
+
const sessionId = options?.sessionId ?? null;
|
|
34
|
+
const timings = { total: 0 };
|
|
35
|
+
let phaseReached = "delegate";
|
|
36
|
+
let orchestrationIntent = null;
|
|
37
|
+
let directExecutorUsed = null;
|
|
38
|
+
let delegateUsed = null;
|
|
39
|
+
// Fire beforeMessage hook
|
|
40
|
+
await this.fireHook(this.config.lifecycleHooks?.beforeMessage
|
|
41
|
+
? () => this.config.lifecycleHooks.beforeMessage(message, options)
|
|
42
|
+
: undefined);
|
|
43
|
+
const buildDecisionTrace = (overrides) => ({
|
|
44
|
+
traceId,
|
|
45
|
+
phaseReached: overrides.phaseReached,
|
|
46
|
+
intentResolved: overrides.orchestrationIntent,
|
|
47
|
+
timings: overrides.timings,
|
|
48
|
+
directExecutorUsed: overrides.directExecutorUsed,
|
|
49
|
+
delegateUsed: overrides.delegateUsed,
|
|
50
|
+
});
|
|
51
|
+
const buildFinalResult = (baseResult, overrides) => {
|
|
52
|
+
const decisionTrace = buildDecisionTrace(overrides);
|
|
53
|
+
return {
|
|
54
|
+
...baseResult,
|
|
55
|
+
content: overrides.content ?? baseResult.content,
|
|
56
|
+
orchestrationIntent: overrides.orchestrationIntent,
|
|
57
|
+
decisionTrace,
|
|
58
|
+
pendingConfirmation: overrides.pendingConfirmation ?? null,
|
|
59
|
+
sessionId: overrides.sessionId !== undefined ? overrides.sessionId : (sessionId ?? baseResult.sessionId),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
// Cache session state to avoid triple fetch within the same chat() call
|
|
63
|
+
let cachedSessionState;
|
|
64
|
+
try {
|
|
65
|
+
// === Phase 0: Pending Confirmation ===
|
|
66
|
+
if (this.config.pendingStateManager && sessionId) {
|
|
67
|
+
const pending = await this.config.pendingStateManager.getPending(sessionId);
|
|
68
|
+
if (pending) {
|
|
69
|
+
const classifier = this.config.confirmationClassifier ?? pending_js_1.classifyConfirmationDisposition;
|
|
70
|
+
const disposition = classifier(message);
|
|
71
|
+
if (disposition === "confirm" || disposition === "reject") {
|
|
72
|
+
// Handle confirmation/rejection
|
|
73
|
+
await this.config.pendingStateManager.clearPending(sessionId);
|
|
74
|
+
phaseReached = "pending_confirmation";
|
|
75
|
+
timings.total = Date.now() - startTime;
|
|
76
|
+
const confirmContent = disposition === "confirm"
|
|
77
|
+
? `Confirmed: ${pending.type}`
|
|
78
|
+
: `Rejected: ${pending.type}`;
|
|
79
|
+
const baseResult = {
|
|
80
|
+
content: confirmContent,
|
|
81
|
+
blocked: false,
|
|
82
|
+
usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
|
|
83
|
+
intent: null,
|
|
84
|
+
toolCalls: [],
|
|
85
|
+
timings: { total: timings.total },
|
|
86
|
+
sessionId,
|
|
87
|
+
traceId,
|
|
88
|
+
trace: null,
|
|
89
|
+
};
|
|
90
|
+
const result = buildFinalResult(baseResult, {
|
|
91
|
+
phaseReached,
|
|
92
|
+
orchestrationIntent: null,
|
|
93
|
+
timings,
|
|
94
|
+
directExecutorUsed: null,
|
|
95
|
+
delegateUsed: null,
|
|
96
|
+
pendingConfirmation: null,
|
|
97
|
+
});
|
|
98
|
+
await this.fireHook(this.config.lifecycleHooks?.afterMessage
|
|
99
|
+
? () => this.config.lifecycleHooks.afterMessage(result)
|
|
100
|
+
: undefined);
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
// override — clear pending, continue normal flow
|
|
104
|
+
await this.config.pendingStateManager.clearPending(sessionId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// === Phase 1: Intent Resolution ===
|
|
108
|
+
if (this.config.intentResolver) {
|
|
109
|
+
const intentStart = Date.now();
|
|
110
|
+
if (this.config.sessionStateStore && sessionId && cachedSessionState === undefined) {
|
|
111
|
+
cachedSessionState = await this.config.sessionStateStore.get(sessionId);
|
|
112
|
+
}
|
|
113
|
+
orchestrationIntent = await this.config.intentResolver.resolve({
|
|
114
|
+
message,
|
|
115
|
+
sessionState: cachedSessionState ?? undefined,
|
|
116
|
+
});
|
|
117
|
+
timings.intentResolution = Date.now() - intentStart;
|
|
118
|
+
}
|
|
119
|
+
// === Phase 2: Direct Execution ===
|
|
120
|
+
if (this.config.directExecutors && orchestrationIntent) {
|
|
121
|
+
const execStart = Date.now();
|
|
122
|
+
for (const executor of this.config.directExecutors) {
|
|
123
|
+
if (executor.canHandle(orchestrationIntent)) {
|
|
124
|
+
const execResult = await executor.execute({
|
|
125
|
+
message,
|
|
126
|
+
intent: orchestrationIntent,
|
|
127
|
+
options: options,
|
|
128
|
+
});
|
|
129
|
+
if (execResult !== null) {
|
|
130
|
+
phaseReached = "direct_execution";
|
|
131
|
+
directExecutorUsed = executor.name;
|
|
132
|
+
timings.directExecution = Date.now() - execStart;
|
|
133
|
+
timings.total = Date.now() - startTime;
|
|
134
|
+
const result = buildFinalResult(execResult, {
|
|
135
|
+
phaseReached,
|
|
136
|
+
orchestrationIntent,
|
|
137
|
+
timings,
|
|
138
|
+
directExecutorUsed,
|
|
139
|
+
delegateUsed: null,
|
|
140
|
+
});
|
|
141
|
+
await this.fireHook(this.config.lifecycleHooks?.afterMessage
|
|
142
|
+
? () => this.config.lifecycleHooks.afterMessage(result)
|
|
143
|
+
: undefined);
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// === Phase 3: Delegate Routing ===
|
|
150
|
+
const delegateStart = Date.now();
|
|
151
|
+
let selectedDelegate = this.config.delegate;
|
|
152
|
+
let selectedDelegateName = "default";
|
|
153
|
+
if (orchestrationIntent && this.config.delegates) {
|
|
154
|
+
const mapped = this.config.delegates.get(orchestrationIntent.object);
|
|
155
|
+
if (mapped) {
|
|
156
|
+
selectedDelegate = mapped;
|
|
157
|
+
selectedDelegateName = orchestrationIntent.object;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Enrich options with session state if available (use cached fetch)
|
|
161
|
+
let enrichedOptions = options;
|
|
162
|
+
if (this.config.sessionStateStore && sessionId) {
|
|
163
|
+
if (cachedSessionState === undefined) {
|
|
164
|
+
cachedSessionState = await this.config.sessionStateStore.get(sessionId);
|
|
165
|
+
}
|
|
166
|
+
if (cachedSessionState) {
|
|
167
|
+
enrichedOptions = { ...options, sessionState: cachedSessionState };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const delegateResult = await selectedDelegate.chat(message, enrichedOptions);
|
|
171
|
+
timings.delegate = Date.now() - delegateStart;
|
|
172
|
+
timings.total = Date.now() - startTime;
|
|
173
|
+
phaseReached = "delegate";
|
|
174
|
+
delegateUsed = selectedDelegateName;
|
|
175
|
+
// Update session state if applicable (reuse cached session state)
|
|
176
|
+
if (this.config.sessionStateStore && sessionId && delegateResult.sessionId) {
|
|
177
|
+
const newState = {
|
|
178
|
+
sessionId,
|
|
179
|
+
lastPresentedEntities: cachedSessionState?.lastPresentedEntities ?? [],
|
|
180
|
+
metadata: cachedSessionState?.metadata ?? {},
|
|
181
|
+
updatedAt: Date.now(),
|
|
182
|
+
};
|
|
183
|
+
await this.config.sessionStateStore.save(sessionId, newState);
|
|
184
|
+
}
|
|
185
|
+
const result = buildFinalResult(delegateResult, {
|
|
186
|
+
phaseReached,
|
|
187
|
+
orchestrationIntent,
|
|
188
|
+
timings,
|
|
189
|
+
directExecutorUsed,
|
|
190
|
+
delegateUsed,
|
|
191
|
+
sessionId: sessionId ?? delegateResult.sessionId,
|
|
192
|
+
});
|
|
193
|
+
await this.fireHook(this.config.lifecycleHooks?.afterMessage
|
|
194
|
+
? () => this.config.lifecycleHooks.afterMessage(result)
|
|
195
|
+
: undefined);
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// Fire onError hook
|
|
200
|
+
await this.fireHook(this.config.lifecycleHooks?.onError
|
|
201
|
+
? () => this.config.lifecycleHooks.onError(error)
|
|
202
|
+
: undefined);
|
|
203
|
+
// Re-throw after hook
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Process a channel-specific raw input through the channel adapter.
|
|
209
|
+
*/
|
|
210
|
+
async processChannel(rawInput) {
|
|
211
|
+
if (!this.config.channelAdapter) {
|
|
212
|
+
throw new Error("No channelAdapter configured");
|
|
213
|
+
}
|
|
214
|
+
const channelMessage = this.config.channelAdapter.parseIncoming(rawInput);
|
|
215
|
+
const result = await this.chat(channelMessage.text, channelMessage.options);
|
|
216
|
+
return this.config.channelAdapter.formatOutgoing(result);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.AgentOrchestrator = AgentOrchestrator;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pending state management — tracks confirmations awaiting user response.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InMemoryPendingStateManager = void 0;
|
|
7
|
+
exports.classifyConfirmationDisposition = classifyConfirmationDisposition;
|
|
8
|
+
/**
|
|
9
|
+
* InMemoryPendingStateManager — simple in-memory Map implementation.
|
|
10
|
+
*/
|
|
11
|
+
class InMemoryPendingStateManager {
|
|
12
|
+
store = new Map();
|
|
13
|
+
async getPending(sessionId) {
|
|
14
|
+
return this.store.get(sessionId) ?? null;
|
|
15
|
+
}
|
|
16
|
+
async setPending(sessionId, state) {
|
|
17
|
+
this.store.set(sessionId, state);
|
|
18
|
+
}
|
|
19
|
+
async clearPending(sessionId) {
|
|
20
|
+
this.store.delete(sessionId);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.InMemoryPendingStateManager = InMemoryPendingStateManager;
|
|
24
|
+
const CONFIRM_PATTERN = /^(好|確認|對|yes|y|ok|好的|是|沒問題|sure|confirm)$/i;
|
|
25
|
+
const REJECT_PATTERN = /^(不要|取消|no|n|不|cancel|否|算了|不行|reject)$/i;
|
|
26
|
+
/**
|
|
27
|
+
* Default implementation to classify a user message's disposition toward a pending confirmation.
|
|
28
|
+
*/
|
|
29
|
+
function classifyConfirmationDisposition(message) {
|
|
30
|
+
const trimmed = message.trim();
|
|
31
|
+
if (CONFIRM_PATTERN.test(trimmed))
|
|
32
|
+
return "confirm";
|
|
33
|
+
if (REJECT_PATTERN.test(trimmed))
|
|
34
|
+
return "reject";
|
|
35
|
+
return "override";
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AgentSessionState — tracks entities presented in the last response for coreference resolution.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InMemorySessionStateStore = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* InMemorySessionStateStore — simple in-memory Map implementation.
|
|
9
|
+
*/
|
|
10
|
+
class InMemorySessionStateStore {
|
|
11
|
+
store = new Map();
|
|
12
|
+
async get(sessionId) {
|
|
13
|
+
return this.store.get(sessionId) ?? null;
|
|
14
|
+
}
|
|
15
|
+
async save(sessionId, state) {
|
|
16
|
+
this.store.set(sessionId, state);
|
|
17
|
+
}
|
|
18
|
+
async clear(sessionId) {
|
|
19
|
+
this.store.delete(sessionId);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.InMemorySessionStateStore = InMemorySessionStateStore;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemorySessionStore = void 0;
|
|
4
|
+
class InMemorySessionStore {
|
|
5
|
+
store = new Map();
|
|
6
|
+
async get(sessionId) {
|
|
7
|
+
return this.store.get(sessionId) ?? null;
|
|
8
|
+
}
|
|
9
|
+
async save(sessionId, history) {
|
|
10
|
+
this.store.set(sessionId, history);
|
|
11
|
+
}
|
|
12
|
+
async delete(sessionId) {
|
|
13
|
+
this.store.delete(sessionId);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.InMemorySessionStore = InMemorySessionStore;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisSessionStore = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Redis-backed session store. Requires `ioredis` as optional dependency.
|
|
6
|
+
*/
|
|
7
|
+
class RedisSessionStore {
|
|
8
|
+
redis;
|
|
9
|
+
prefix;
|
|
10
|
+
ttlSeconds;
|
|
11
|
+
constructor(redis, prefix = "naru:session:", ttlSeconds = 86400) {
|
|
12
|
+
this.redis = redis;
|
|
13
|
+
this.prefix = prefix;
|
|
14
|
+
this.ttlSeconds = ttlSeconds;
|
|
15
|
+
}
|
|
16
|
+
key(sessionId) {
|
|
17
|
+
return `${this.prefix}${sessionId}`;
|
|
18
|
+
}
|
|
19
|
+
async get(sessionId) {
|
|
20
|
+
const data = await this.redis.get(this.key(sessionId));
|
|
21
|
+
if (!data)
|
|
22
|
+
return null;
|
|
23
|
+
return JSON.parse(data);
|
|
24
|
+
}
|
|
25
|
+
async save(sessionId, history) {
|
|
26
|
+
await this.redis.set(this.key(sessionId), JSON.stringify(history), "EX", this.ttlSeconds);
|
|
27
|
+
}
|
|
28
|
+
async delete(sessionId) {
|
|
29
|
+
await this.redis.del(this.key(sessionId));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.RedisSessionStore = RedisSessionStore;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skill = skill;
|
|
4
|
+
exports.makeSkillResult = makeSkillResult;
|
|
5
|
+
/**
|
|
6
|
+
* Factory function to create a skill (equivalent to Python @skill decorator).
|
|
7
|
+
*/
|
|
8
|
+
function skill(config) {
|
|
9
|
+
return {
|
|
10
|
+
name: config.name,
|
|
11
|
+
description: config.description ?? "",
|
|
12
|
+
triggers: config.triggers ?? [],
|
|
13
|
+
priority: config.priority ?? 0,
|
|
14
|
+
alwaysActive: config.alwaysActive ?? false,
|
|
15
|
+
run: config.run,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function makeSkillResult(partial) {
|
|
19
|
+
return {
|
|
20
|
+
promptInjection: "",
|
|
21
|
+
extraTools: [],
|
|
22
|
+
overrideSystemPrompt: null,
|
|
23
|
+
skillName: "",
|
|
24
|
+
skipped: false,
|
|
25
|
+
...partial,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SkillRegistry = void 0;
|
|
4
|
+
const selectors_js_1 = require("./selectors.js");
|
|
5
|
+
const base_js_1 = require("./base.js");
|
|
6
|
+
class SkillRegistry {
|
|
7
|
+
skills;
|
|
8
|
+
selector;
|
|
9
|
+
maxActiveSkills;
|
|
10
|
+
constructor(skills, selector, maxActiveSkills = 3) {
|
|
11
|
+
this.skills = skills;
|
|
12
|
+
this.selector = selector ?? new selectors_js_1.KeywordSkillSelector();
|
|
13
|
+
this.maxActiveSkills = maxActiveSkills;
|
|
14
|
+
}
|
|
15
|
+
async selectSkills(message) {
|
|
16
|
+
const selected = await this.selector.select(this.skills, message);
|
|
17
|
+
return selected
|
|
18
|
+
.sort((a, b) => b.priority - a.priority)
|
|
19
|
+
.slice(0, this.maxActiveSkills);
|
|
20
|
+
}
|
|
21
|
+
async runSkills(message, context) {
|
|
22
|
+
const selected = await this.selectSkills(message);
|
|
23
|
+
if (selected.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
const results = await Promise.allSettled(selected.map(async (s) => {
|
|
26
|
+
try {
|
|
27
|
+
const result = await s.run(message, context);
|
|
28
|
+
return { ...result, skillName: s.name };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return (0, base_js_1.makeSkillResult)({ skillName: s.name, skipped: true });
|
|
32
|
+
}
|
|
33
|
+
}));
|
|
34
|
+
return results
|
|
35
|
+
.filter((r) => r.status === "fulfilled")
|
|
36
|
+
.map((r) => r.value)
|
|
37
|
+
.filter((r) => !r.skipped);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.SkillRegistry = SkillRegistry;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmbeddingSkillSelector = exports.KeywordSkillSelector = void 0;
|
|
4
|
+
const math_js_1 = require("../utils/math.js");
|
|
5
|
+
/**
|
|
6
|
+
* Case-insensitive keyword matching on skill triggers.
|
|
7
|
+
*/
|
|
8
|
+
class KeywordSkillSelector {
|
|
9
|
+
async select(skills, message) {
|
|
10
|
+
const lower = message.toLowerCase();
|
|
11
|
+
return skills.filter((s) => s.alwaysActive ||
|
|
12
|
+
s.triggers.some((t) => lower.includes(t.toLowerCase())));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.KeywordSkillSelector = KeywordSkillSelector;
|
|
16
|
+
/**
|
|
17
|
+
* Embedding-based similarity matching for skill selection.
|
|
18
|
+
*/
|
|
19
|
+
class EmbeddingSkillSelector {
|
|
20
|
+
embedFn;
|
|
21
|
+
topK;
|
|
22
|
+
similarityThreshold;
|
|
23
|
+
cachedEmbeddings = null;
|
|
24
|
+
constructor(embedFn, topK = 2, similarityThreshold = 0.45) {
|
|
25
|
+
this.embedFn = embedFn;
|
|
26
|
+
this.topK = topK;
|
|
27
|
+
this.similarityThreshold = similarityThreshold;
|
|
28
|
+
}
|
|
29
|
+
async select(skills, message) {
|
|
30
|
+
const alwaysActive = skills.filter((s) => s.alwaysActive);
|
|
31
|
+
const candidates = skills.filter((s) => !s.alwaysActive);
|
|
32
|
+
if (candidates.length === 0)
|
|
33
|
+
return alwaysActive;
|
|
34
|
+
// Build skill description embeddings (cached)
|
|
35
|
+
if (!this.cachedEmbeddings) {
|
|
36
|
+
const descriptions = candidates.map((s) => `${s.name}: ${s.description} ${s.triggers.join(" ")}`);
|
|
37
|
+
const embeddings = await this.embedFn(descriptions);
|
|
38
|
+
this.cachedEmbeddings = new Map();
|
|
39
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
40
|
+
this.cachedEmbeddings.set(candidates[i].name, embeddings[i]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const [queryEmbed] = await this.embedFn([message]);
|
|
44
|
+
const scored = candidates
|
|
45
|
+
.map((s) => ({
|
|
46
|
+
skill: s,
|
|
47
|
+
score: (0, math_js_1.cosineSimilarity)(queryEmbed, this.cachedEmbeddings.get(s.name)),
|
|
48
|
+
}))
|
|
49
|
+
.filter((x) => x.score >= this.similarityThreshold)
|
|
50
|
+
.sort((a, b) => b.score - a.score)
|
|
51
|
+
.slice(0, this.topK)
|
|
52
|
+
.map((x) => x.skill);
|
|
53
|
+
return [...alwaysActive, ...scored];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.EmbeddingSkillSelector = EmbeddingSkillSelector;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tool = tool;
|
|
4
|
+
/**
|
|
5
|
+
* Factory function to create a tool (equivalent to Python @tool decorator).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const weatherTool = tool({
|
|
9
|
+
* name: "get_weather",
|
|
10
|
+
* description: "Get weather for a city",
|
|
11
|
+
* parameters: z.object({ city: z.string() }),
|
|
12
|
+
* execute: async ({ city }) => `Weather in ${city}: sunny`,
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
function tool(config) {
|
|
16
|
+
return {
|
|
17
|
+
name: config.name,
|
|
18
|
+
description: config.description,
|
|
19
|
+
parameters: config.parameters,
|
|
20
|
+
execute: config.execute,
|
|
21
|
+
timeout: config.timeout,
|
|
22
|
+
retries: config.retries,
|
|
23
|
+
};
|
|
24
|
+
}
|