@yugenlab/vaayu 0.1.11 → 0.1.12
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/chunks/{agentic-tool-loop-O3NUV7KG.js → agentic-tool-loop-NQESOBLC.js} +2 -2
- package/chunks/akasha-5C5Q6NMP.js +12 -0
- package/chunks/{chunk-7XV5ISV7.js → chunk-26K6DS6N.js} +2 -2
- package/chunks/chunk-5E3ZS5SW.js +529 -0
- package/chunks/{chunk-D46QTN3G.js → chunk-ARZCIITZ.js} +47 -18
- package/chunks/{chunk-ZYY6N3SP.js → chunk-FEDPZOZ5.js} +548 -389
- package/chunks/{chunk-3AYSJ7WB.js → chunk-GWYC7R2L.js} +13 -7
- package/chunks/chunk-H46F2Y6R.js +134 -0
- package/chunks/{chunk-QV4GPIPT.js → chunk-HXHDP2PZ.js} +8 -4
- package/chunks/chunk-KVQH4LE7.js +396 -0
- package/chunks/{chunk-Z576WVLG.js → chunk-LJCT7UYP.js} +17 -7
- package/chunks/{chunk-LJUEMPLG.js → chunk-M2RLX5LU.js} +32 -14
- package/chunks/{chunk-IGKYKEKT.js → chunk-NAQKA54E.js} +8 -2
- package/chunks/{chunk-F6RNEGFX.js → chunk-PZ4AQ22L.js} +78 -13
- package/chunks/{chunk-G2QREGXK.js → chunk-R273KC7J.js} +275 -2
- package/chunks/{chunk-A3HOZBC5.js → chunk-RVKTGKFD.js} +2 -2
- package/chunks/{chunk-VCUJES75.js → chunk-TSOQ2CT3.js} +763 -620
- package/chunks/{chunk-V2ZIKDN4.js → chunk-VEZ2DI2M.js} +16 -5
- package/chunks/{chunk-W4PVGBUH.js → chunk-XP3NIH5F.js} +7 -3
- package/chunks/{chunk-7AYYXHYZ.js → chunk-Y6IZH6FT.js} +19 -4
- package/chunks/{chunk-JZTFJE7M.js → chunk-YRTGGYJU.js} +14 -10
- package/chunks/{consolidation-indexer-VIWOP6VO.js → consolidation-indexer-KPXORCJ4.js} +9 -9
- package/chunks/database-BX3LVYXS.js +11 -0
- package/chunks/{day-consolidation-HMHSXIOM.js → day-consolidation-CR3TJFAL.js} +5 -5
- package/chunks/{dist-CY5NX2IK.js → dist-ESCM3CP5.js} +31 -21
- package/chunks/graphrag-73XA7LBX.js +14 -0
- package/chunks/hierarchical-temporal-search-GHKVKNZ6.js +8 -0
- package/chunks/hybrid-search-OD756RDV.js +20 -0
- package/chunks/{memory-store-LEERUQGL.js → memory-store-4GCBR2DZ.js} +4 -4
- package/chunks/periodic-consolidation-IINCHP6L.js +11 -0
- package/chunks/{postgres-7GZDDX77.js → postgres-YLCUNVPQ.js} +2 -2
- package/chunks/recall-64RROTUC.js +21 -0
- package/chunks/search-JVCDNTAJ.js +19 -0
- package/chunks/{session-store-O3TS7DUY.js → session-store-3EDQZEDS.js} +12 -6
- package/chunks/{sqlite-7BC4DJTN.js → sqlite-4N7YH2KK.js} +2 -2
- package/chunks/{src-6GVZTUH6.js → src-OPSDZEFI.js} +2 -2
- package/chunks/{suncalc-NOHGYHDU.js → suncalc-RM7URNUR.js} +2 -2
- package/chunks/{tree-RSHKDTCR.js → tree-FIUVGJ5J.js} +2 -2
- package/chunks/{vasana-engine-BJFHJVGM.js → vasana-engine-W4PYWT5H.js} +5 -5
- package/gateway.js +2358 -768
- package/package.json +1 -1
- package/pair-cli.js +2 -2
- package/chunks/chunk-2OBLQJYJ.js +0 -198
- package/chunks/chunk-67DXWEKG.js +0 -123
- package/chunks/graphrag-T2QWNX57.js +0 -14
- package/chunks/hierarchical-temporal-search-U6DG74IR.js +0 -8
- package/chunks/hybrid-search-BYTXCOXP.js +0 -20
- package/chunks/periodic-consolidation-D6SSKZ7H.js +0 -11
- package/chunks/recall-LNRQVATQ.js +0 -21
- package/chunks/search-BIODUW2P.js +0 -19
package/gateway.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import "./chunks/chunk-IEKAYVA3.js";
|
|
2
3
|
import {
|
|
3
4
|
SqliteStorage
|
|
4
5
|
} from "./chunks/chunk-EG37M4QL.js";
|
|
@@ -7,28 +8,30 @@ import {
|
|
|
7
8
|
buildAgentTree,
|
|
8
9
|
buildKaalaHealthNode
|
|
9
10
|
} from "./chunks/chunk-G5VYCA6O.js";
|
|
10
|
-
import "./chunks/chunk-
|
|
11
|
-
import "./chunks/chunk-
|
|
12
|
-
import "./chunks/chunk-
|
|
13
|
-
import "./chunks/chunk-
|
|
14
|
-
import "./chunks/chunk-
|
|
15
|
-
import "./chunks/chunk-
|
|
16
|
-
import "./chunks/chunk-
|
|
11
|
+
import "./chunks/chunk-TSOQ2CT3.js";
|
|
12
|
+
import "./chunks/chunk-LJCT7UYP.js";
|
|
13
|
+
import "./chunks/chunk-YRTGGYJU.js";
|
|
14
|
+
import "./chunks/chunk-PZ4AQ22L.js";
|
|
15
|
+
import "./chunks/chunk-HXHDP2PZ.js";
|
|
16
|
+
import "./chunks/chunk-XP3NIH5F.js";
|
|
17
|
+
import "./chunks/chunk-5E3ZS5SW.js";
|
|
18
|
+
import "./chunks/chunk-26K6DS6N.js";
|
|
17
19
|
import {
|
|
18
20
|
IMessageAdapter,
|
|
19
21
|
TelegramAdapter,
|
|
22
|
+
TringAdapter,
|
|
20
23
|
TwitterAdapter,
|
|
21
24
|
WhatsAppAdapter,
|
|
22
25
|
generateMantra,
|
|
23
26
|
require_lib,
|
|
24
27
|
validateMantra
|
|
25
|
-
} from "./chunks/chunk-
|
|
28
|
+
} from "./chunks/chunk-R273KC7J.js";
|
|
26
29
|
import {
|
|
27
30
|
searchSessions
|
|
28
|
-
} from "./chunks/chunk-
|
|
29
|
-
import "./chunks/chunk-
|
|
30
|
-
import "./chunks/chunk-
|
|
31
|
-
import "./chunks/chunk-
|
|
31
|
+
} from "./chunks/chunk-GWYC7R2L.js";
|
|
32
|
+
import "./chunks/chunk-Y6IZH6FT.js";
|
|
33
|
+
import "./chunks/chunk-M2RLX5LU.js";
|
|
34
|
+
import "./chunks/chunk-ARZCIITZ.js";
|
|
32
35
|
import {
|
|
33
36
|
addTurn,
|
|
34
37
|
createSession,
|
|
@@ -38,18 +41,17 @@ import {
|
|
|
38
41
|
listTurnsWithTimestamps,
|
|
39
42
|
loadSession,
|
|
40
43
|
updateSessionMeta
|
|
41
|
-
} from "./chunks/chunk-
|
|
42
|
-
import "./chunks/chunk-
|
|
43
|
-
import "./chunks/chunk-
|
|
44
|
-
import "./chunks/chunk-
|
|
45
|
-
import "./chunks/chunk-
|
|
46
|
-
import "./chunks/chunk-2OBLQJYJ.js";
|
|
44
|
+
} from "./chunks/chunk-FEDPZOZ5.js";
|
|
45
|
+
import "./chunks/chunk-RVKTGKFD.js";
|
|
46
|
+
import "./chunks/chunk-VEZ2DI2M.js";
|
|
47
|
+
import "./chunks/chunk-H46F2Y6R.js";
|
|
48
|
+
import "./chunks/chunk-KVQH4LE7.js";
|
|
47
49
|
import {
|
|
48
50
|
__commonJS,
|
|
49
51
|
__export,
|
|
50
52
|
__require,
|
|
51
53
|
__toESM
|
|
52
|
-
} from "./chunks/chunk-
|
|
54
|
+
} from "./chunks/chunk-NAQKA54E.js";
|
|
53
55
|
|
|
54
56
|
// ../node_modules/.pnpm/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js
|
|
55
57
|
var require_identity = __commonJS({
|
|
@@ -13080,8 +13082,8 @@ function createSessionLock() {
|
|
|
13080
13082
|
const run = async (sessionId, fn, options) => {
|
|
13081
13083
|
const previous = sessionLocks.get(sessionId)?.tail ?? Promise.resolve();
|
|
13082
13084
|
let release;
|
|
13083
|
-
const gate = new Promise((
|
|
13084
|
-
release =
|
|
13085
|
+
const gate = new Promise((resolve3) => {
|
|
13086
|
+
release = resolve3;
|
|
13085
13087
|
});
|
|
13086
13088
|
sessionLocks.set(sessionId, { tail: gate });
|
|
13087
13089
|
const controller = new AbortController();
|
|
@@ -16353,7 +16355,7 @@ async function runCodex(config, prompt, signal, dynamicSystemPrompt) {
|
|
|
16353
16355
|
child.stdin.write(prompt);
|
|
16354
16356
|
child.stdin.end();
|
|
16355
16357
|
}
|
|
16356
|
-
const code = await new Promise((
|
|
16358
|
+
const code = await new Promise((resolve3, reject) => {
|
|
16357
16359
|
child.on("error", (err) => {
|
|
16358
16360
|
clearTimeout(timer);
|
|
16359
16361
|
if (err.code === "ENOENT") {
|
|
@@ -16366,7 +16368,7 @@ async function runCodex(config, prompt, signal, dynamicSystemPrompt) {
|
|
|
16366
16368
|
reject(err);
|
|
16367
16369
|
}
|
|
16368
16370
|
});
|
|
16369
|
-
child.on("close", (exitCode) =>
|
|
16371
|
+
child.on("close", (exitCode) => resolve3(exitCode));
|
|
16370
16372
|
});
|
|
16371
16373
|
clearTimeout(timer);
|
|
16372
16374
|
let output = null;
|
|
@@ -16517,7 +16519,7 @@ async function runClaudeCode(config, prompt, signal, dynamicSystemPrompt) {
|
|
|
16517
16519
|
}
|
|
16518
16520
|
signal.addEventListener("abort", () => child.kill("SIGKILL"), { once: true });
|
|
16519
16521
|
}
|
|
16520
|
-
const code = await new Promise((
|
|
16522
|
+
const code = await new Promise((resolve3, reject) => {
|
|
16521
16523
|
child.on("error", (err) => {
|
|
16522
16524
|
clearTimeout(timer);
|
|
16523
16525
|
if (err.code === "ENOENT") {
|
|
@@ -16530,7 +16532,7 @@ async function runClaudeCode(config, prompt, signal, dynamicSystemPrompt) {
|
|
|
16530
16532
|
reject(err);
|
|
16531
16533
|
}
|
|
16532
16534
|
});
|
|
16533
|
-
child.on("close", (exitCode) =>
|
|
16535
|
+
child.on("close", (exitCode) => resolve3(exitCode));
|
|
16534
16536
|
});
|
|
16535
16537
|
clearTimeout(timer);
|
|
16536
16538
|
try {
|
|
@@ -17606,7 +17608,7 @@ var resolveOllamaBinary = (entry) => {
|
|
|
17606
17608
|
return "ollama";
|
|
17607
17609
|
};
|
|
17608
17610
|
var fetchOllamaModelsFromCli = async (binPath, host) => {
|
|
17609
|
-
return new Promise((
|
|
17611
|
+
return new Promise((resolve3) => {
|
|
17610
17612
|
execFile(
|
|
17611
17613
|
binPath,
|
|
17612
17614
|
["list"],
|
|
@@ -17621,16 +17623,16 @@ var fetchOllamaModelsFromCli = async (binPath, host) => {
|
|
|
17621
17623
|
if (error) {
|
|
17622
17624
|
const message = error instanceof Error ? error.message : String(error);
|
|
17623
17625
|
const details = stderr?.toString().trim();
|
|
17624
|
-
|
|
17626
|
+
resolve3({ error: details ? `${message} (${details})` : message });
|
|
17625
17627
|
return;
|
|
17626
17628
|
}
|
|
17627
17629
|
const lines = stdout.trim().split(/\r?\n/).filter(Boolean);
|
|
17628
17630
|
if (lines.length <= 1) {
|
|
17629
|
-
|
|
17631
|
+
resolve3({ models: [] });
|
|
17630
17632
|
return;
|
|
17631
17633
|
}
|
|
17632
17634
|
const models = lines.slice(1).map((line) => line.trim()).filter(Boolean).map((line) => line.split(/\s+/)[0]).filter((model) => Boolean(model));
|
|
17633
|
-
|
|
17635
|
+
resolve3({ models });
|
|
17634
17636
|
}
|
|
17635
17637
|
);
|
|
17636
17638
|
});
|
|
@@ -17672,8 +17674,8 @@ async function fetchModelList(providerId, entry, logger) {
|
|
|
17672
17674
|
try {
|
|
17673
17675
|
if (entry.type === "ollama") {
|
|
17674
17676
|
const requestTimeoutMs2 = 8e3;
|
|
17675
|
-
const sleep = (ms) => new Promise((
|
|
17676
|
-
setTimeout(
|
|
17677
|
+
const sleep = (ms) => new Promise((resolve3) => {
|
|
17678
|
+
setTimeout(resolve3, ms);
|
|
17677
17679
|
});
|
|
17678
17680
|
let lastError;
|
|
17679
17681
|
let lastApiError;
|
|
@@ -19582,9 +19584,182 @@ function isToolAllowed(policy, toolName) {
|
|
|
19582
19584
|
// packages/tools/src/mcp-manager.ts
|
|
19583
19585
|
import fs7 from "node:fs";
|
|
19584
19586
|
import path7 from "node:path";
|
|
19587
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
19588
|
+
|
|
19589
|
+
// packages/tools/src/mcp-stdio-client.ts
|
|
19585
19590
|
import { spawn as spawn3 } from "node:child_process";
|
|
19591
|
+
import { createInterface } from "node:readline";
|
|
19592
|
+
var McpStdioClient = class {
|
|
19593
|
+
process = null;
|
|
19594
|
+
reader = null;
|
|
19595
|
+
nextId = 1;
|
|
19596
|
+
pending = /* @__PURE__ */ new Map();
|
|
19597
|
+
timeoutMs;
|
|
19598
|
+
/* ── Reconnect state ─────────────────────────────────────────── */
|
|
19599
|
+
maxReconnectAttempts;
|
|
19600
|
+
reconnectAttempts = 0;
|
|
19601
|
+
lastCommand = "";
|
|
19602
|
+
lastArgs = [];
|
|
19603
|
+
lastEnv;
|
|
19604
|
+
constructor(options) {
|
|
19605
|
+
this.timeoutMs = options?.timeoutMs ?? 15e3;
|
|
19606
|
+
this.maxReconnectAttempts = options?.maxReconnectAttempts ?? 3;
|
|
19607
|
+
}
|
|
19608
|
+
/** Spawn the MCP server process and initialize JSON-RPC communication. */
|
|
19609
|
+
async connect(command, args = [], env) {
|
|
19610
|
+
this.lastCommand = command;
|
|
19611
|
+
this.lastArgs = args;
|
|
19612
|
+
this.lastEnv = env;
|
|
19613
|
+
this.reconnectAttempts = 0;
|
|
19614
|
+
const child = spawn3(command, args, {
|
|
19615
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
19616
|
+
env: { ...process.env, ...env ?? {} }
|
|
19617
|
+
});
|
|
19618
|
+
this.process = child;
|
|
19619
|
+
this.reader = createInterface({ input: child.stdout });
|
|
19620
|
+
this.reader.on("line", (line) => this.handleLine(line));
|
|
19621
|
+
child.on("exit", () => {
|
|
19622
|
+
for (const [id, pending] of this.pending) {
|
|
19623
|
+
clearTimeout(pending.timer);
|
|
19624
|
+
pending.reject(new Error("MCP server process exited"));
|
|
19625
|
+
this.pending.delete(id);
|
|
19626
|
+
}
|
|
19627
|
+
this.process = null;
|
|
19628
|
+
});
|
|
19629
|
+
child.on("error", (err) => {
|
|
19630
|
+
for (const [id, pending] of this.pending) {
|
|
19631
|
+
clearTimeout(pending.timer);
|
|
19632
|
+
pending.reject(err);
|
|
19633
|
+
this.pending.delete(id);
|
|
19634
|
+
}
|
|
19635
|
+
this.process = null;
|
|
19636
|
+
});
|
|
19637
|
+
await this.call("initialize", {
|
|
19638
|
+
protocolVersion: "2024-11-05",
|
|
19639
|
+
capabilities: {},
|
|
19640
|
+
clientInfo: { name: "vaayu-gateway", version: "0.1.0" }
|
|
19641
|
+
});
|
|
19642
|
+
this.writeLine(
|
|
19643
|
+
JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" })
|
|
19644
|
+
);
|
|
19645
|
+
}
|
|
19646
|
+
/** Send a JSON-RPC request and wait for the response. Auto-reconnects on dead process. */
|
|
19647
|
+
async call(method, params) {
|
|
19648
|
+
if (!this.connected && this.lastCommand) {
|
|
19649
|
+
await this.reconnect();
|
|
19650
|
+
}
|
|
19651
|
+
if (!this.connected) {
|
|
19652
|
+
throw new Error("McpStdioClient is not connected");
|
|
19653
|
+
}
|
|
19654
|
+
const id = this.nextId++;
|
|
19655
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
19656
|
+
this.writeLine(JSON.stringify(request));
|
|
19657
|
+
return new Promise((resolve3, reject) => {
|
|
19658
|
+
const timer = setTimeout(() => {
|
|
19659
|
+
this.pending.delete(id);
|
|
19660
|
+
reject(new Error(`MCP request timed out after ${this.timeoutMs}ms: ${method}`));
|
|
19661
|
+
}, this.timeoutMs);
|
|
19662
|
+
this.pending.set(id, { resolve: resolve3, reject, timer });
|
|
19663
|
+
});
|
|
19664
|
+
}
|
|
19665
|
+
/**
|
|
19666
|
+
* Re-connect to the MCP server after a crash.
|
|
19667
|
+
* Uses exponential backoff (100ms * 2^attempt). Throws after max attempts.
|
|
19668
|
+
*/
|
|
19669
|
+
async reconnect() {
|
|
19670
|
+
if (this.connected) return;
|
|
19671
|
+
if (!this.lastCommand) {
|
|
19672
|
+
throw new Error("Cannot reconnect: no previous connection params");
|
|
19673
|
+
}
|
|
19674
|
+
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
19675
|
+
throw new Error(
|
|
19676
|
+
`McpStdioClient reconnect failed after ${this.maxReconnectAttempts} attempts`
|
|
19677
|
+
);
|
|
19678
|
+
}
|
|
19679
|
+
this.disconnect();
|
|
19680
|
+
const backoffMs = 100 * Math.pow(2, this.reconnectAttempts);
|
|
19681
|
+
this.reconnectAttempts++;
|
|
19682
|
+
await new Promise((r) => setTimeout(r, backoffMs));
|
|
19683
|
+
await this.connect(this.lastCommand, this.lastArgs, this.lastEnv);
|
|
19684
|
+
}
|
|
19685
|
+
/**
|
|
19686
|
+
* Check if the MCP server process is alive and responsive.
|
|
19687
|
+
* Sends a lightweight tools/list ping. Returns false on any failure.
|
|
19688
|
+
*/
|
|
19689
|
+
async isHealthy() {
|
|
19690
|
+
if (!this.connected) return false;
|
|
19691
|
+
try {
|
|
19692
|
+
await this.listTools();
|
|
19693
|
+
return true;
|
|
19694
|
+
} catch {
|
|
19695
|
+
return false;
|
|
19696
|
+
}
|
|
19697
|
+
}
|
|
19698
|
+
/** List available tools from the MCP server. */
|
|
19699
|
+
async listTools() {
|
|
19700
|
+
const result = await this.call("tools/list");
|
|
19701
|
+
return result.tools;
|
|
19702
|
+
}
|
|
19703
|
+
/** Call a tool by name with arguments. */
|
|
19704
|
+
async callTool(name, args) {
|
|
19705
|
+
return await this.call("tools/call", {
|
|
19706
|
+
name,
|
|
19707
|
+
arguments: args
|
|
19708
|
+
});
|
|
19709
|
+
}
|
|
19710
|
+
/** Kill the child process and clean up. */
|
|
19711
|
+
disconnect() {
|
|
19712
|
+
for (const [id, pending] of this.pending) {
|
|
19713
|
+
clearTimeout(pending.timer);
|
|
19714
|
+
pending.reject(new Error("McpStdioClient disconnected"));
|
|
19715
|
+
this.pending.delete(id);
|
|
19716
|
+
}
|
|
19717
|
+
if (this.process && !this.process.killed) {
|
|
19718
|
+
this.process.kill("SIGTERM");
|
|
19719
|
+
}
|
|
19720
|
+
this.process = null;
|
|
19721
|
+
if (this.reader) {
|
|
19722
|
+
this.reader.close();
|
|
19723
|
+
this.reader = null;
|
|
19724
|
+
}
|
|
19725
|
+
}
|
|
19726
|
+
/** Whether the client is currently connected. */
|
|
19727
|
+
get connected() {
|
|
19728
|
+
return this.process !== null && !this.process.killed;
|
|
19729
|
+
}
|
|
19730
|
+
/** Handle an incoming NDJSON line from the MCP server stdout. */
|
|
19731
|
+
handleLine(line) {
|
|
19732
|
+
const trimmed = line.trim();
|
|
19733
|
+
if (!trimmed) return;
|
|
19734
|
+
let parsed;
|
|
19735
|
+
try {
|
|
19736
|
+
parsed = JSON.parse(trimmed);
|
|
19737
|
+
} catch {
|
|
19738
|
+
return;
|
|
19739
|
+
}
|
|
19740
|
+
if (typeof parsed.id !== "number") return;
|
|
19741
|
+
const pending = this.pending.get(parsed.id);
|
|
19742
|
+
if (!pending) return;
|
|
19743
|
+
this.pending.delete(parsed.id);
|
|
19744
|
+
clearTimeout(pending.timer);
|
|
19745
|
+
if (parsed.error) {
|
|
19746
|
+
pending.reject(
|
|
19747
|
+
new Error(`MCP error ${parsed.error.code}: ${parsed.error.message}`)
|
|
19748
|
+
);
|
|
19749
|
+
} else {
|
|
19750
|
+
pending.resolve(parsed.result);
|
|
19751
|
+
}
|
|
19752
|
+
}
|
|
19753
|
+
/** Write a single NDJSON line to the child process stdin. */
|
|
19754
|
+
writeLine(data2) {
|
|
19755
|
+
this.process?.stdin?.write(data2 + "\n");
|
|
19756
|
+
}
|
|
19757
|
+
};
|
|
19758
|
+
|
|
19759
|
+
// packages/tools/src/mcp-manager.ts
|
|
19586
19760
|
var McpServerManager = class {
|
|
19587
19761
|
servers = /* @__PURE__ */ new Map();
|
|
19762
|
+
stdioClients = /* @__PURE__ */ new Map();
|
|
19588
19763
|
logger;
|
|
19589
19764
|
constructor(configs = [], options = {}) {
|
|
19590
19765
|
this.logger = options.logger;
|
|
@@ -19628,19 +19803,42 @@ var McpServerManager = class {
|
|
|
19628
19803
|
this.startServer(state);
|
|
19629
19804
|
}
|
|
19630
19805
|
}
|
|
19806
|
+
/** Check health of all stdio clients. Returns map of serverId to healthy status. */
|
|
19807
|
+
async healthCheck() {
|
|
19808
|
+
const results = /* @__PURE__ */ new Map();
|
|
19809
|
+
for (const [id, client] of this.stdioClients) {
|
|
19810
|
+
try {
|
|
19811
|
+
if (!client.connected) {
|
|
19812
|
+
results.set(id, false);
|
|
19813
|
+
continue;
|
|
19814
|
+
}
|
|
19815
|
+
await client.listTools();
|
|
19816
|
+
results.set(id, true);
|
|
19817
|
+
} catch {
|
|
19818
|
+
results.set(id, false);
|
|
19819
|
+
this.stdioClients.delete(id);
|
|
19820
|
+
}
|
|
19821
|
+
}
|
|
19822
|
+
return results;
|
|
19823
|
+
}
|
|
19824
|
+
/** Stop all managed MCP server processes and disconnect stdio clients. */
|
|
19631
19825
|
stopAll() {
|
|
19632
19826
|
for (const state of this.servers.values()) {
|
|
19633
19827
|
if (state.process && !state.process.killed) {
|
|
19634
19828
|
state.process.kill("SIGTERM");
|
|
19635
19829
|
}
|
|
19636
19830
|
}
|
|
19831
|
+
for (const [id, client] of this.stdioClients) {
|
|
19832
|
+
client.disconnect();
|
|
19833
|
+
this.stdioClients.delete(id);
|
|
19834
|
+
}
|
|
19637
19835
|
}
|
|
19638
19836
|
startServer(state) {
|
|
19639
19837
|
if (state.process && !state.process.killed) {
|
|
19640
19838
|
return;
|
|
19641
19839
|
}
|
|
19642
19840
|
const { command, args, env, cwd } = state.config;
|
|
19643
|
-
const child =
|
|
19841
|
+
const child = spawn4(command, args ?? [], {
|
|
19644
19842
|
cwd: cwd ?? process.cwd(),
|
|
19645
19843
|
env: {
|
|
19646
19844
|
...process.env,
|
|
@@ -19718,6 +19916,7 @@ var McpServerManager = class {
|
|
|
19718
19916
|
{
|
|
19719
19917
|
method: "POST",
|
|
19720
19918
|
headers: {
|
|
19919
|
+
accept: "application/json",
|
|
19721
19920
|
"content-type": "application/json",
|
|
19722
19921
|
...authToken ? { authorization: `Bearer ${authToken}` } : {}
|
|
19723
19922
|
},
|
|
@@ -19729,6 +19928,16 @@ var McpServerManager = class {
|
|
|
19729
19928
|
signal: ctx.signal
|
|
19730
19929
|
}
|
|
19731
19930
|
);
|
|
19931
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
19932
|
+
if (!contentType.toLowerCase().includes("application/json")) {
|
|
19933
|
+
return {
|
|
19934
|
+
ok: false,
|
|
19935
|
+
error: {
|
|
19936
|
+
code: "mcp_protocol_error",
|
|
19937
|
+
message: `MCP HTTP response content-type mismatch: expected application/json, got ${contentType || "unknown"}`
|
|
19938
|
+
}
|
|
19939
|
+
};
|
|
19940
|
+
}
|
|
19732
19941
|
const data2 = await response.json().catch(() => null);
|
|
19733
19942
|
if (!response.ok || !data2) {
|
|
19734
19943
|
return {
|
|
@@ -19753,13 +19962,45 @@ var McpServerManager = class {
|
|
|
19753
19962
|
};
|
|
19754
19963
|
}
|
|
19755
19964
|
}
|
|
19756
|
-
return
|
|
19757
|
-
|
|
19758
|
-
|
|
19759
|
-
|
|
19760
|
-
|
|
19965
|
+
return this.invokeViaStdio(state, toolName, input);
|
|
19966
|
+
}
|
|
19967
|
+
/** Invoke an MCP tool via stdio JSON-RPC. Lazily connects on first call. */
|
|
19968
|
+
async invokeViaStdio(state, toolName, input) {
|
|
19969
|
+
const serverId = state.config.id;
|
|
19970
|
+
try {
|
|
19971
|
+
let client = this.stdioClients.get(serverId);
|
|
19972
|
+
if (!client || !client.connected) {
|
|
19973
|
+
client = new McpStdioClient({ timeoutMs: 3e4 });
|
|
19974
|
+
await client.connect(
|
|
19975
|
+
state.config.command,
|
|
19976
|
+
state.config.args ?? [],
|
|
19977
|
+
state.config.env
|
|
19978
|
+
);
|
|
19979
|
+
this.stdioClients.set(serverId, client);
|
|
19980
|
+
this.logger?.info("mcp_stdio_connected", { serverId });
|
|
19761
19981
|
}
|
|
19762
|
-
|
|
19982
|
+
const result = await client.callTool(
|
|
19983
|
+
toolName,
|
|
19984
|
+
input ?? {}
|
|
19985
|
+
);
|
|
19986
|
+
const textContent = result.content?.filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
19987
|
+
if (result.isError) {
|
|
19988
|
+
return {
|
|
19989
|
+
ok: false,
|
|
19990
|
+
error: { code: "mcp_tool_error", message: textContent || "Tool execution failed" }
|
|
19991
|
+
};
|
|
19992
|
+
}
|
|
19993
|
+
return { ok: true, output: textContent || result };
|
|
19994
|
+
} catch (error) {
|
|
19995
|
+
this.stdioClients.delete(serverId);
|
|
19996
|
+
return {
|
|
19997
|
+
ok: false,
|
|
19998
|
+
error: {
|
|
19999
|
+
code: "mcp_stdio_error",
|
|
20000
|
+
message: error instanceof Error ? error.message : "MCP stdio invocation failed"
|
|
20001
|
+
}
|
|
20002
|
+
};
|
|
20003
|
+
}
|
|
19763
20004
|
}
|
|
19764
20005
|
};
|
|
19765
20006
|
|
|
@@ -19993,7 +20234,7 @@ async function loadSunCalc() {
|
|
|
19993
20234
|
sunCalcCache = void 0;
|
|
19994
20235
|
}
|
|
19995
20236
|
try {
|
|
19996
|
-
const mod = await import("./chunks/suncalc-
|
|
20237
|
+
const mod = await import("./chunks/suncalc-RM7URNUR.js");
|
|
19997
20238
|
const candidates = [
|
|
19998
20239
|
mod.default,
|
|
19999
20240
|
mod["module.exports"],
|
|
@@ -23917,7 +24158,7 @@ function buildSkillTools(dataDir) {
|
|
|
23917
24158
|
};
|
|
23918
24159
|
}
|
|
23919
24160
|
const driver = payload.driver ?? process.env.VAAYU_SANDBOX_DRIVER ?? "docker";
|
|
23920
|
-
const { createSandboxRunner: createSandboxRunner2 } = await import("./chunks/src-
|
|
24161
|
+
const { createSandboxRunner: createSandboxRunner2 } = await import("./chunks/src-OPSDZEFI.js");
|
|
23921
24162
|
const runner = createSandboxRunner2(driver);
|
|
23922
24163
|
const result = await runner.run({
|
|
23923
24164
|
command: "bash",
|
|
@@ -24591,6 +24832,330 @@ function registerBuiltinTools(registry, options = {}) {
|
|
|
24591
24832
|
}
|
|
24592
24833
|
}
|
|
24593
24834
|
|
|
24835
|
+
// packages/tools/src/skill-resolver.ts
|
|
24836
|
+
import { execSync } from "node:child_process";
|
|
24837
|
+
import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
|
|
24838
|
+
import { join, resolve } from "node:path";
|
|
24839
|
+
import { homedir } from "node:os";
|
|
24840
|
+
var EXEC_OPTS = {
|
|
24841
|
+
encoding: "utf8",
|
|
24842
|
+
timeout: 1e4,
|
|
24843
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
24844
|
+
};
|
|
24845
|
+
var HIGH_RISK_PATTERNS2 = ["sudo ", "rm -rf", "eval(", "exec(", "child_process"];
|
|
24846
|
+
var MEDIUM_RISK_PATTERNS2 = ["chmod 777", "npm install"];
|
|
24847
|
+
var SkillResolver = class {
|
|
24848
|
+
localRoot;
|
|
24849
|
+
installDir;
|
|
24850
|
+
logger;
|
|
24851
|
+
constructor(options) {
|
|
24852
|
+
this.localRoot = options?.localSkillsRoot ?? "ecosystem/skills";
|
|
24853
|
+
this.installDir = options?.installDir ?? join(homedir(), ".chitragupta", "skills");
|
|
24854
|
+
this.logger = options?.logger;
|
|
24855
|
+
}
|
|
24856
|
+
/**
|
|
24857
|
+
* Search for skills matching an intent across all sources.
|
|
24858
|
+
* Sources are checked in order: local registry, npm, GitHub.
|
|
24859
|
+
*/
|
|
24860
|
+
async search(intent) {
|
|
24861
|
+
const keywords = intent.toLowerCase().split(/\s+/).filter(Boolean);
|
|
24862
|
+
if (keywords.length === 0) return [];
|
|
24863
|
+
const results = [];
|
|
24864
|
+
results.push(...this.searchLocal(keywords));
|
|
24865
|
+
results.push(...this.searchNpm(keywords));
|
|
24866
|
+
results.push(...this.searchGitHub(keywords));
|
|
24867
|
+
return results;
|
|
24868
|
+
}
|
|
24869
|
+
/**
|
|
24870
|
+
* Guard: validate skill safety before execution.
|
|
24871
|
+
* Checks for dangerous code patterns and manifest validity.
|
|
24872
|
+
*/
|
|
24873
|
+
guard(candidate) {
|
|
24874
|
+
const warnings = [];
|
|
24875
|
+
const blockedReasons = [];
|
|
24876
|
+
if (candidate.manifestValid === false) {
|
|
24877
|
+
blockedReasons.push("invalid_manifest: missing name or tools array");
|
|
24878
|
+
}
|
|
24879
|
+
if (candidate.source === "local") {
|
|
24880
|
+
const skillPath = join(this.localRoot, candidate.name);
|
|
24881
|
+
const patterns = this.scanFilePatterns(skillPath);
|
|
24882
|
+
blockedReasons.push(...patterns.blocked);
|
|
24883
|
+
warnings.push(...patterns.warnings);
|
|
24884
|
+
}
|
|
24885
|
+
return { safe: blockedReasons.length === 0, warnings, blockedReasons };
|
|
24886
|
+
}
|
|
24887
|
+
/**
|
|
24888
|
+
* Install a skill candidate and return the installed skill info.
|
|
24889
|
+
* Returns null on any failure.
|
|
24890
|
+
*/
|
|
24891
|
+
async install(candidate) {
|
|
24892
|
+
try {
|
|
24893
|
+
const targetDir = join(this.installDir, candidate.name);
|
|
24894
|
+
if (candidate.source === "npm") {
|
|
24895
|
+
execSync(`npm install --prefix ${this.installDir} ${candidate.name}`, EXEC_OPTS);
|
|
24896
|
+
} else if (candidate.source === "github" && candidate.url) {
|
|
24897
|
+
execSync(`gh repo clone ${candidate.url} ${targetDir}`, EXEC_OPTS);
|
|
24898
|
+
} else if (candidate.source === "local") {
|
|
24899
|
+
return this.readInstalledSkill(join(this.localRoot, candidate.name), candidate);
|
|
24900
|
+
} else {
|
|
24901
|
+
this.logger?.warn("skill_install_unsupported_source", { source: candidate.source });
|
|
24902
|
+
return null;
|
|
24903
|
+
}
|
|
24904
|
+
return this.readInstalledSkill(targetDir, candidate);
|
|
24905
|
+
} catch (err) {
|
|
24906
|
+
this.logger?.warn("skill_install_failed", {
|
|
24907
|
+
name: candidate.name,
|
|
24908
|
+
error: err instanceof Error ? err.message : String(err)
|
|
24909
|
+
});
|
|
24910
|
+
return null;
|
|
24911
|
+
}
|
|
24912
|
+
}
|
|
24913
|
+
/* ── Private: search sources ──────────────────────────────────── */
|
|
24914
|
+
/** Scan local skills root for directories with SKILL.md or manifest.json. */
|
|
24915
|
+
searchLocal(keywords) {
|
|
24916
|
+
try {
|
|
24917
|
+
if (!existsSync2(this.localRoot)) return [];
|
|
24918
|
+
const entries2 = readdirSync(this.localRoot, { withFileTypes: true });
|
|
24919
|
+
const candidates = [];
|
|
24920
|
+
for (const entry of entries2) {
|
|
24921
|
+
if (!entry.isDirectory()) continue;
|
|
24922
|
+
const dirPath = join(this.localRoot, entry.name);
|
|
24923
|
+
const hasSkillMd = existsSync2(join(dirPath, "SKILL.md"));
|
|
24924
|
+
const hasManifest = existsSync2(join(dirPath, "manifest.json"));
|
|
24925
|
+
if (!hasSkillMd && !hasManifest) continue;
|
|
24926
|
+
const manifest = this.readManifest(dirPath);
|
|
24927
|
+
const searchText = `${entry.name} ${manifest?.description ?? ""}`.toLowerCase();
|
|
24928
|
+
const matches = keywords.some((kw) => searchText.includes(kw));
|
|
24929
|
+
if (!matches) continue;
|
|
24930
|
+
candidates.push({
|
|
24931
|
+
name: entry.name,
|
|
24932
|
+
source: "local",
|
|
24933
|
+
description: typeof manifest?.description === "string" ? manifest.description : "",
|
|
24934
|
+
version: typeof manifest?.version === "string" ? manifest.version : void 0,
|
|
24935
|
+
manifestValid: this.isManifestValid(manifest)
|
|
24936
|
+
});
|
|
24937
|
+
}
|
|
24938
|
+
return candidates;
|
|
24939
|
+
} catch (err) {
|
|
24940
|
+
this.logger?.warn("skill_search_local_failed", { error: err instanceof Error ? err.message : String(err) });
|
|
24941
|
+
return [];
|
|
24942
|
+
}
|
|
24943
|
+
}
|
|
24944
|
+
/** Search npm for chitragupta-skill packages matching keywords. */
|
|
24945
|
+
searchNpm(keywords) {
|
|
24946
|
+
try {
|
|
24947
|
+
const keyword = keywords[0] ?? "";
|
|
24948
|
+
const raw = execSync(`npm search chitragupta-skill-${keyword} --json 2>/dev/null`, EXEC_OPTS);
|
|
24949
|
+
const parsed = JSON.parse(typeof raw === "string" ? raw : "[]");
|
|
24950
|
+
if (!Array.isArray(parsed)) return [];
|
|
24951
|
+
return parsed.slice(0, 10).map((pkg) => ({
|
|
24952
|
+
name: pkg.name ?? "unknown",
|
|
24953
|
+
source: "npm",
|
|
24954
|
+
description: pkg.description ?? "",
|
|
24955
|
+
version: pkg.version
|
|
24956
|
+
}));
|
|
24957
|
+
} catch (err) {
|
|
24958
|
+
this.logger?.warn("skill_search_npm_failed", { error: err instanceof Error ? err.message : String(err) });
|
|
24959
|
+
return [];
|
|
24960
|
+
}
|
|
24961
|
+
}
|
|
24962
|
+
/** Search GitHub for repos with the chitragupta-skill topic. */
|
|
24963
|
+
searchGitHub(keywords) {
|
|
24964
|
+
try {
|
|
24965
|
+
const raw = execSync(
|
|
24966
|
+
`gh search repos --topic chitragupta-skill --json name,description,url --limit 5 2>/dev/null`,
|
|
24967
|
+
EXEC_OPTS
|
|
24968
|
+
);
|
|
24969
|
+
const parsed = JSON.parse(typeof raw === "string" ? raw : "[]");
|
|
24970
|
+
if (!Array.isArray(parsed)) return [];
|
|
24971
|
+
const kw = keywords.join(" ").toLowerCase();
|
|
24972
|
+
return parsed.filter((r) => `${r.name ?? ""} ${r.description ?? ""}`.toLowerCase().includes(kw)).map((r) => ({
|
|
24973
|
+
name: r.name ?? "unknown",
|
|
24974
|
+
source: "github",
|
|
24975
|
+
description: r.description ?? "",
|
|
24976
|
+
url: r.url
|
|
24977
|
+
}));
|
|
24978
|
+
} catch (err) {
|
|
24979
|
+
this.logger?.warn("skill_search_github_failed", { error: err instanceof Error ? err.message : String(err) });
|
|
24980
|
+
return [];
|
|
24981
|
+
}
|
|
24982
|
+
}
|
|
24983
|
+
/* ── Private: helpers ─────────────────────────────────────────── */
|
|
24984
|
+
/** Read and parse manifest.json from a skill directory. */
|
|
24985
|
+
readManifest(dirPath) {
|
|
24986
|
+
try {
|
|
24987
|
+
const content = readFileSync(join(dirPath, "manifest.json"), "utf8");
|
|
24988
|
+
return JSON.parse(content);
|
|
24989
|
+
} catch {
|
|
24990
|
+
return null;
|
|
24991
|
+
}
|
|
24992
|
+
}
|
|
24993
|
+
/** Check whether a manifest has the required fields (name + tools array). */
|
|
24994
|
+
isManifestValid(manifest) {
|
|
24995
|
+
if (!manifest) return false;
|
|
24996
|
+
return typeof manifest.name === "string" && Array.isArray(manifest.tools);
|
|
24997
|
+
}
|
|
24998
|
+
/** Scan files in a directory for dangerous patterns. */
|
|
24999
|
+
scanFilePatterns(dirPath) {
|
|
25000
|
+
const blocked = [];
|
|
25001
|
+
const warnings = [];
|
|
25002
|
+
try {
|
|
25003
|
+
if (!existsSync2(dirPath)) return { blocked, warnings };
|
|
25004
|
+
const files = readdirSync(dirPath).filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
|
|
25005
|
+
for (const file of files) {
|
|
25006
|
+
const content = readFileSync(join(dirPath, file), "utf8");
|
|
25007
|
+
for (const pattern of HIGH_RISK_PATTERNS2) {
|
|
25008
|
+
if (content.includes(pattern)) blocked.push(`${file}: contains '${pattern}'`);
|
|
25009
|
+
}
|
|
25010
|
+
for (const pattern of MEDIUM_RISK_PATTERNS2) {
|
|
25011
|
+
if (content.includes(pattern)) warnings.push(`${file}: contains '${pattern}'`);
|
|
25012
|
+
}
|
|
25013
|
+
}
|
|
25014
|
+
} catch (err) {
|
|
25015
|
+
this.logger?.warn("skill_scan_patterns_failed", { dirPath, error: err instanceof Error ? err.message : String(err) });
|
|
25016
|
+
}
|
|
25017
|
+
return { blocked, warnings };
|
|
25018
|
+
}
|
|
25019
|
+
/** Read tool definitions from an installed skill's manifest. */
|
|
25020
|
+
readInstalledSkill(skillPath, candidate) {
|
|
25021
|
+
const manifest = this.readManifest(skillPath);
|
|
25022
|
+
if (!manifest || !Array.isArray(manifest.tools)) return null;
|
|
25023
|
+
const toolDefs = manifest.tools.map((t2) => ({
|
|
25024
|
+
name: typeof t2.name === "string" ? t2.name : "unknown",
|
|
25025
|
+
description: typeof t2.description === "string" ? t2.description : ""
|
|
25026
|
+
}));
|
|
25027
|
+
return { name: candidate.name, path: resolve(skillPath), source: candidate.source, toolDefinitions: toolDefs };
|
|
25028
|
+
}
|
|
25029
|
+
};
|
|
25030
|
+
|
|
25031
|
+
// packages/tools/src/skill-learner.ts
|
|
25032
|
+
var SkillLearner = class _SkillLearner {
|
|
25033
|
+
/** In-memory feedback store (flushes to persistent storage when wired). */
|
|
25034
|
+
feedback = [];
|
|
25035
|
+
gaps = /* @__PURE__ */ new Map();
|
|
25036
|
+
successCounts = /* @__PURE__ */ new Map();
|
|
25037
|
+
failureCounts = /* @__PURE__ */ new Map();
|
|
25038
|
+
gapThreshold;
|
|
25039
|
+
promotionThreshold;
|
|
25040
|
+
demotionThreshold;
|
|
25041
|
+
logger;
|
|
25042
|
+
constructor(options) {
|
|
25043
|
+
this.gapThreshold = options?.gapThreshold ?? 3;
|
|
25044
|
+
this.promotionThreshold = options?.promotionThreshold ?? 5;
|
|
25045
|
+
this.demotionThreshold = options?.demotionThreshold ?? 3;
|
|
25046
|
+
this.logger = options?.logger;
|
|
25047
|
+
}
|
|
25048
|
+
/** Record successful skill execution. */
|
|
25049
|
+
recordSuccess(skillName, intent, sessionId, feedback) {
|
|
25050
|
+
this.feedback.push({
|
|
25051
|
+
skillName,
|
|
25052
|
+
intent,
|
|
25053
|
+
outcome: "success",
|
|
25054
|
+
feedback,
|
|
25055
|
+
sessionId,
|
|
25056
|
+
timestamp: Date.now()
|
|
25057
|
+
});
|
|
25058
|
+
this.successCounts.set(skillName, (this.successCounts.get(skillName) ?? 0) + 1);
|
|
25059
|
+
this.logger?.info("skill_success_recorded", { skillName, total: this.successCounts.get(skillName) });
|
|
25060
|
+
}
|
|
25061
|
+
/** Record skill failure or user rejection. */
|
|
25062
|
+
recordFailure(skillName, intent, sessionId, reason) {
|
|
25063
|
+
this.feedback.push({
|
|
25064
|
+
skillName,
|
|
25065
|
+
intent,
|
|
25066
|
+
outcome: "failure",
|
|
25067
|
+
feedback: reason,
|
|
25068
|
+
sessionId,
|
|
25069
|
+
timestamp: Date.now()
|
|
25070
|
+
});
|
|
25071
|
+
this.failureCounts.set(skillName, (this.failureCounts.get(skillName) ?? 0) + 1);
|
|
25072
|
+
this.logger?.info("skill_failure_recorded", { skillName, reason, total: this.failureCounts.get(skillName) });
|
|
25073
|
+
}
|
|
25074
|
+
/** Record skill gap (no skill matched user intent). */
|
|
25075
|
+
recordGap(intent, sessionId) {
|
|
25076
|
+
const existing = this.gaps.get(intent);
|
|
25077
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
25078
|
+
if (existing) {
|
|
25079
|
+
existing.occurrences += 1;
|
|
25080
|
+
existing.lastSeen = now;
|
|
25081
|
+
if (!existing.sessionIds.includes(sessionId)) existing.sessionIds.push(sessionId);
|
|
25082
|
+
} else {
|
|
25083
|
+
this.gaps.set(intent, { intent, occurrences: 1, firstSeen: now, lastSeen: now, sessionIds: [sessionId] });
|
|
25084
|
+
}
|
|
25085
|
+
this.feedback.push({
|
|
25086
|
+
skillName: "",
|
|
25087
|
+
intent,
|
|
25088
|
+
outcome: "gap",
|
|
25089
|
+
sessionId,
|
|
25090
|
+
timestamp: Date.now()
|
|
25091
|
+
});
|
|
25092
|
+
this.logger?.info("skill_gap_recorded", { intent, occurrences: this.gaps.get(intent)?.occurrences });
|
|
25093
|
+
}
|
|
25094
|
+
/** Get skill gaps that have exceeded the occurrence threshold. */
|
|
25095
|
+
getActionableGaps() {
|
|
25096
|
+
const actionable = [];
|
|
25097
|
+
for (const gap of this.gaps.values()) {
|
|
25098
|
+
if (gap.occurrences >= this.gapThreshold) actionable.push(gap);
|
|
25099
|
+
}
|
|
25100
|
+
return actionable;
|
|
25101
|
+
}
|
|
25102
|
+
/** Evaluate whether a skill should be promoted (lab -> production). */
|
|
25103
|
+
evaluatePromotion(skillName) {
|
|
25104
|
+
return (this.successCounts.get(skillName) ?? 0) >= this.promotionThreshold;
|
|
25105
|
+
}
|
|
25106
|
+
/** Evaluate whether a skill should be demoted/disabled. */
|
|
25107
|
+
evaluateDemotion(skillName) {
|
|
25108
|
+
return (this.failureCounts.get(skillName) ?? 0) >= this.demotionThreshold;
|
|
25109
|
+
}
|
|
25110
|
+
/** Get raw feedback records for analysis. */
|
|
25111
|
+
getFeedback() {
|
|
25112
|
+
return this.feedback;
|
|
25113
|
+
}
|
|
25114
|
+
/** Reset counters (for testing or periodic cleanup). */
|
|
25115
|
+
reset() {
|
|
25116
|
+
this.feedback.length = 0;
|
|
25117
|
+
this.gaps.clear();
|
|
25118
|
+
this.successCounts.clear();
|
|
25119
|
+
this.failureCounts.clear();
|
|
25120
|
+
}
|
|
25121
|
+
/** Wire 4: Serialize learner state for persistence. */
|
|
25122
|
+
serialize() {
|
|
25123
|
+
return {
|
|
25124
|
+
feedback: [...this.feedback],
|
|
25125
|
+
gaps: Object.fromEntries(this.gaps),
|
|
25126
|
+
successCounts: Object.fromEntries(this.successCounts),
|
|
25127
|
+
failureCounts: Object.fromEntries(this.failureCounts)
|
|
25128
|
+
};
|
|
25129
|
+
}
|
|
25130
|
+
/** Wire 4: Restore from persisted snapshot. */
|
|
25131
|
+
static restore(snapshot, options) {
|
|
25132
|
+
const learner = new _SkillLearner(options);
|
|
25133
|
+
for (const fb of snapshot.feedback) learner.feedback.push(fb);
|
|
25134
|
+
for (const [intent, gap] of Object.entries(snapshot.gaps)) learner.gaps.set(intent, gap);
|
|
25135
|
+
for (const [k, v] of Object.entries(snapshot.successCounts)) learner.successCounts.set(k, v);
|
|
25136
|
+
for (const [k, v] of Object.entries(snapshot.failureCounts)) learner.failureCounts.set(k, v);
|
|
25137
|
+
return learner;
|
|
25138
|
+
}
|
|
25139
|
+
/** Wire 4: Flush state to a JSON file for cross-restart persistence. */
|
|
25140
|
+
async flush(filePath) {
|
|
25141
|
+
const { writeFile, mkdir } = await import("node:fs/promises");
|
|
25142
|
+
const { dirname: dirname4 } = await import("node:path");
|
|
25143
|
+
await mkdir(dirname4(filePath), { recursive: true });
|
|
25144
|
+
await writeFile(filePath, JSON.stringify(this.serialize(), null, 2), "utf-8");
|
|
25145
|
+
}
|
|
25146
|
+
/** Wire 4: Load state from a JSON file (best-effort). */
|
|
25147
|
+
static async load(filePath, options) {
|
|
25148
|
+
try {
|
|
25149
|
+
const { readFile } = await import("node:fs/promises");
|
|
25150
|
+
const raw = await readFile(filePath, "utf-8");
|
|
25151
|
+
const snapshot = JSON.parse(raw);
|
|
25152
|
+
return _SkillLearner.restore(snapshot, options);
|
|
25153
|
+
} catch {
|
|
25154
|
+
return null;
|
|
25155
|
+
}
|
|
25156
|
+
}
|
|
25157
|
+
};
|
|
25158
|
+
|
|
24594
25159
|
// apps/gateway/dist/agent/commands/skill-lifecycle.js
|
|
24595
25160
|
async function handleSkillLifecycleCommand(params) {
|
|
24596
25161
|
const { action, fromPath, deleteSource, ackRisk, notes, locale, session, message, storage, toolRegistry, toolPolicy, routingDecision, routingResult } = params;
|
|
@@ -26152,6 +26717,45 @@ function buildGreetingContinuationReply(params) {
|
|
|
26152
26717
|
}
|
|
26153
26718
|
return topic ? `${userPrefix}I'm still with you. We were on "${topic}". Want to continue from there?` : `${userPrefix}I'm still with you. Want to continue where we left off?`;
|
|
26154
26719
|
}
|
|
26720
|
+
function buildRecentGreetingReply(params) {
|
|
26721
|
+
const { userName, locale } = params;
|
|
26722
|
+
const style = normalizeStyle(params.style);
|
|
26723
|
+
const userPrefix = buildUserPrefix2(userName);
|
|
26724
|
+
if (locale === "te") {
|
|
26725
|
+
return `${userPrefix}\u0C07\u0C2A\u0C4D\u0C2A\u0C41\u0C21\u0C47 \u0C2E\u0C28\u0C02 hi \u0C1A\u0C46\u0C2A\u0C4D\u0C2A\u0C41\u0C15\u0C41\u0C28\u0C4D\u0C28\u0C3E\u0C02. \u0C28\u0C47\u0C28\u0C41 \u0C07\u0C15\u0C4D\u0C15\u0C21\u0C47 \u0C09\u0C28\u0C4D\u0C28\u0C3E\u0C28\u0C41 - \u0C07\u0C15 \u0C0F\u0C2E\u0C3F \u0C1A\u0C47\u0C26\u0C4D\u0C26\u0C3E\u0C02?`;
|
|
26726
|
+
}
|
|
26727
|
+
if (locale === "es") {
|
|
26728
|
+
return `${userPrefix}Hace un momento ya nos saludamos. Sigo aqui contigo. Que hacemos ahora?`;
|
|
26729
|
+
}
|
|
26730
|
+
if (locale === "de") {
|
|
26731
|
+
return `${userPrefix}Wir haben uns gerade eben schon begrusst. Ich bin da. Was machen wir als nachstes?`;
|
|
26732
|
+
}
|
|
26733
|
+
if (locale === "pl") {
|
|
26734
|
+
return `${userPrefix}Przed chwila juz sie przywitalismy. Jestem tutaj. Co robimy dalej?`;
|
|
26735
|
+
}
|
|
26736
|
+
if (locale === "hi") {
|
|
26737
|
+
return `${userPrefix}\u0905\u092D\u0940 \u0915\u0941\u091B \u092E\u093F\u0928\u091F \u092A\u0939\u0932\u0947 \u0939\u0940 \u0939\u092E\u0928\u0947 hi \u0915\u0939\u093E \u0925\u093E\u0964 \u092E\u0948\u0902 \u092F\u0939\u0940\u0902 \u0939\u0942\u0901, \u0905\u092C \u0915\u094D\u092F\u093E \u0915\u0930\u0947\u0902?`;
|
|
26738
|
+
}
|
|
26739
|
+
if (locale === "ja") {
|
|
26740
|
+
return `${userPrefix}\u3055\u3063\u304D\u3082\u3046\u6328\u62F6\u3057\u305F\u3088\u3002\u79C1\u306F\u3053\u3053\u306B\u3044\u308B\u3002\u6B21\u306F\u4F55\u3059\u308B?`;
|
|
26741
|
+
}
|
|
26742
|
+
if (style === "professional") {
|
|
26743
|
+
return `${userPrefix}We just greeted a moment ago. I'm here. How may I help now?`;
|
|
26744
|
+
}
|
|
26745
|
+
if (style === "direct") {
|
|
26746
|
+
return `${userPrefix}We just said hi. I'm here. What's next?`;
|
|
26747
|
+
}
|
|
26748
|
+
if (style === "chatty") {
|
|
26749
|
+
return `${userPrefix}Yep, we just said hi a moment ago. I'm right here with you. What are we doing next?`;
|
|
26750
|
+
}
|
|
26751
|
+
if (style === "sarcastic") {
|
|
26752
|
+
return `${userPrefix}Yep, hi already happened a minute ago. Still here. What's the next move?`;
|
|
26753
|
+
}
|
|
26754
|
+
if (style === "flirty") {
|
|
26755
|
+
return `${userPrefix}We just said hi a moment ago. I'm still with you. What shall we do next?`;
|
|
26756
|
+
}
|
|
26757
|
+
return `${userPrefix}We just said hi a moment ago. I'm here with you. What should we do next?`;
|
|
26758
|
+
}
|
|
26155
26759
|
function buildAffectionReply(params) {
|
|
26156
26760
|
const { userName, locale } = params;
|
|
26157
26761
|
const style = normalizeStyle(params.style);
|
|
@@ -26531,20 +27135,24 @@ function buildConversationStyleSystem(params) {
|
|
|
26531
27135
|
// apps/gateway/dist/agent/quick-response-smalltalk.js
|
|
26532
27136
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
26533
27137
|
var RESUME_TOPIC_CUE_RE = /\b(continue|resume|pick\s+up|pick-up|where\s+we\s+left|left\s+off|carry\s+on|again|back\s+to|from\s+before|as\s+we\s+were|malli|phir)\b/i;
|
|
26534
|
-
var
|
|
26535
|
-
function isSmalltalkResponseModel(model) {
|
|
26536
|
-
if (typeof model !== "string")
|
|
26537
|
-
return false;
|
|
26538
|
-
return model.startsWith(SMALLTALK_MODEL_PREFIX);
|
|
26539
|
-
}
|
|
27138
|
+
var SAME_TURN_ECHO_MS = 2e4;
|
|
26540
27139
|
function wantsTopicContinuationCue(text) {
|
|
26541
27140
|
const trimmed = text.trim();
|
|
26542
27141
|
if (!trimmed)
|
|
26543
27142
|
return false;
|
|
26544
27143
|
return RESUME_TOPIC_CUE_RE.test(trimmed);
|
|
26545
27144
|
}
|
|
27145
|
+
function shouldSkipCurrentTurnEcho(params) {
|
|
27146
|
+
const { content, trimmed, createdAt, now } = params;
|
|
27147
|
+
if (content !== trimmed)
|
|
27148
|
+
return false;
|
|
27149
|
+
const createdAtMs = createdAt ? Date.parse(createdAt) : Number.NaN;
|
|
27150
|
+
if (!Number.isFinite(createdAtMs))
|
|
27151
|
+
return false;
|
|
27152
|
+
return now - createdAtMs <= SAME_TURN_ECHO_MS;
|
|
27153
|
+
}
|
|
26546
27154
|
async function resolveRecentTopicHint(params) {
|
|
26547
|
-
const { isEstablishedSession, storage, session, trimmed, assistantName, isPureGreeting: isPureGreeting2, isPureAck: isPureAck2 } = params;
|
|
27155
|
+
const { isEstablishedSession, storage, session, trimmed, assistantName, isPureGreeting: isPureGreeting2, isPureAck: isPureAck2, maxTopicAgeMs } = params;
|
|
26548
27156
|
if (!isEstablishedSession)
|
|
26549
27157
|
return void 0;
|
|
26550
27158
|
try {
|
|
@@ -26559,6 +27167,7 @@ async function resolveRecentTopicHint(params) {
|
|
|
26559
27167
|
if (event.role === "assistant" && pendingUserEvent) {
|
|
26560
27168
|
candidates.push({
|
|
26561
27169
|
content: pendingUserEvent.content.trim(),
|
|
27170
|
+
createdAt: pendingUserEvent.createdAt,
|
|
26562
27171
|
assistantModel: typeof event.metadata?.model === "string" ? event.metadata.model : void 0
|
|
26563
27172
|
});
|
|
26564
27173
|
pendingUserEvent = void 0;
|
|
@@ -26567,22 +27176,30 @@ async function resolveRecentTopicHint(params) {
|
|
|
26567
27176
|
if (pendingUserEvent) {
|
|
26568
27177
|
candidates.push({
|
|
26569
27178
|
content: pendingUserEvent.content.trim(),
|
|
27179
|
+
createdAt: pendingUserEvent.createdAt,
|
|
26570
27180
|
assistantModel: void 0
|
|
26571
27181
|
});
|
|
26572
27182
|
}
|
|
26573
|
-
|
|
27183
|
+
const now = Date.now();
|
|
26574
27184
|
for (const candidate of [...candidates].reverse()) {
|
|
26575
27185
|
const content = candidate.content;
|
|
26576
27186
|
if (!content)
|
|
26577
27187
|
continue;
|
|
26578
|
-
if (
|
|
26579
|
-
|
|
27188
|
+
if (shouldSkipCurrentTurnEcho({
|
|
27189
|
+
content,
|
|
27190
|
+
trimmed,
|
|
27191
|
+
createdAt: candidate.createdAt,
|
|
27192
|
+
now
|
|
27193
|
+
})) {
|
|
26580
27194
|
continue;
|
|
26581
27195
|
}
|
|
26582
|
-
if (
|
|
26583
|
-
|
|
27196
|
+
if (typeof maxTopicAgeMs === "number" && Number.isFinite(maxTopicAgeMs) && maxTopicAgeMs > 0) {
|
|
27197
|
+
const candidateTime = candidate.createdAt ? Date.parse(candidate.createdAt) : Number.NaN;
|
|
27198
|
+
if (Number.isFinite(candidateTime) && now - candidateTime > maxTopicAgeMs) {
|
|
27199
|
+
continue;
|
|
27200
|
+
}
|
|
26584
27201
|
}
|
|
26585
|
-
if (
|
|
27202
|
+
if (isPureGreeting2(content, assistantName) || isPureAck2(content, assistantName)) {
|
|
26586
27203
|
continue;
|
|
26587
27204
|
}
|
|
26588
27205
|
const topic = content.replace(/\s+/g, " ").replace(/[!?.,;:]+$/g, "");
|
|
@@ -26594,6 +27211,43 @@ async function resolveRecentTopicHint(params) {
|
|
|
26594
27211
|
}
|
|
26595
27212
|
return void 0;
|
|
26596
27213
|
}
|
|
27214
|
+
function resolveContinuityWindowMs(windowMinutes) {
|
|
27215
|
+
const minutes = Number.isFinite(windowMinutes) ? Math.max(1, Math.min(180, Number(windowMinutes))) : 8;
|
|
27216
|
+
return minutes * 6e4;
|
|
27217
|
+
}
|
|
27218
|
+
async function resolveGreetingContinuityDecision(params) {
|
|
27219
|
+
const { continuityEnabled, continuityWindowMinutes, isEstablishedSession, storage, session, trimmed, assistantName, isPureGreeting: isPureGreeting2, isPureAck: isPureAck2 } = params;
|
|
27220
|
+
const hasResumeCue = wantsTopicContinuationCue(trimmed);
|
|
27221
|
+
if (!isEstablishedSession)
|
|
27222
|
+
return { continuation: hasResumeCue, repeatedGreeting: false };
|
|
27223
|
+
if (!continuityEnabled && !hasResumeCue)
|
|
27224
|
+
return { continuation: false, repeatedGreeting: false };
|
|
27225
|
+
const windowMs = resolveContinuityWindowMs(continuityWindowMinutes);
|
|
27226
|
+
const updatedAtMs = session.updatedAt ? Date.parse(session.updatedAt) : Number.NaN;
|
|
27227
|
+
const now = Date.now();
|
|
27228
|
+
const recentSessionActivity = Number.isFinite(updatedAtMs) && now - updatedAtMs <= windowMs;
|
|
27229
|
+
if (!hasResumeCue) {
|
|
27230
|
+
if (!continuityEnabled || !recentSessionActivity) {
|
|
27231
|
+
return { continuation: false, repeatedGreeting: false };
|
|
27232
|
+
}
|
|
27233
|
+
const repeatedWindowMs = Math.min(windowMs, 2e4);
|
|
27234
|
+
if (Number.isFinite(updatedAtMs) && now - updatedAtMs <= repeatedWindowMs) {
|
|
27235
|
+
return { continuation: false, repeatedGreeting: true };
|
|
27236
|
+
}
|
|
27237
|
+
return { continuation: true, repeatedGreeting: false };
|
|
27238
|
+
}
|
|
27239
|
+
const topic = await resolveRecentTopicHint({
|
|
27240
|
+
isEstablishedSession,
|
|
27241
|
+
storage,
|
|
27242
|
+
session,
|
|
27243
|
+
trimmed,
|
|
27244
|
+
assistantName,
|
|
27245
|
+
isPureGreeting: isPureGreeting2,
|
|
27246
|
+
isPureAck: isPureAck2,
|
|
27247
|
+
maxTopicAgeMs: hasResumeCue ? void 0 : windowMs
|
|
27248
|
+
});
|
|
27249
|
+
return { continuation: true, repeatedGreeting: false, topic };
|
|
27250
|
+
}
|
|
26597
27251
|
async function recordSmalltalkFastLane(params) {
|
|
26598
27252
|
const { routingResult, storage, sessionId, locale, matched, mode, intent, confidence, threshold } = params;
|
|
26599
27253
|
routingResult.smalltalkFastLane = {
|
|
@@ -26643,8 +27297,8 @@ async function maybeHandleSemanticSmalltalk(params) {
|
|
|
26643
27297
|
preferEmbeddings: true
|
|
26644
27298
|
}).catch(() => null);
|
|
26645
27299
|
let timeoutHandle;
|
|
26646
|
-
const timeoutPromise = new Promise((
|
|
26647
|
-
timeoutHandle = setTimeout(() =>
|
|
27300
|
+
const timeoutPromise = new Promise((resolve3) => {
|
|
27301
|
+
timeoutHandle = setTimeout(() => resolve3(SEMANTIC_TIMEOUT_SENTINEL), SEMANTIC_NLU_BUDGET_MS);
|
|
26648
27302
|
});
|
|
26649
27303
|
const interpretedOrTimeout = await Promise.race([
|
|
26650
27304
|
interpretedPromise,
|
|
@@ -26778,7 +27432,6 @@ async function handleQuickResponses(params) {
|
|
|
26778
27432
|
const mode = params.mode ?? "full";
|
|
26779
27433
|
const locationAssignments = mode === "full" ? extractLocationAssignments2(message.text) : null;
|
|
26780
27434
|
const isEstablishedSession = session.updatedAt !== session.createdAt;
|
|
26781
|
-
const isMatureSession = isEstablishedSession && Date.now() - new Date(session.createdAt).getTime() > 3 * 6e4;
|
|
26782
27435
|
const conversationStyle = resolveConversationStyle({
|
|
26783
27436
|
sessionId: session.id,
|
|
26784
27437
|
text: trimmed,
|
|
@@ -26791,6 +27444,12 @@ async function handleQuickResponses(params) {
|
|
|
26791
27444
|
existing: profile.toneTags
|
|
26792
27445
|
})
|
|
26793
27446
|
};
|
|
27447
|
+
if (conversationStyle.source === "explicit" && conversationStyle.changed && conversationStyle.style !== "default") {
|
|
27448
|
+
const updated = updateProfile({ toneTags: profileForStyledReplies.toneTags ?? profile.toneTags });
|
|
27449
|
+
broadcastEvent("profile.updated", updated);
|
|
27450
|
+
void appendPreferenceMemory(`Tone: ${conversationStyle.style}`, ["preference", "style", "tone"]).catch(() => {
|
|
27451
|
+
});
|
|
27452
|
+
}
|
|
26794
27453
|
const emitLocal = async (model, replyText) => {
|
|
26795
27454
|
const reply = normalizeAgentReply(replyText);
|
|
26796
27455
|
await appendAssistantEvent(storage, session.id, reply, {
|
|
@@ -26815,9 +27474,10 @@ async function handleQuickResponses(params) {
|
|
|
26815
27474
|
const emitFastLaneHit = (mode2, intent) => emitSmalltalkFastLane({ matched: true, mode: mode2, intent, confidence: 1, threshold: 1 });
|
|
26816
27475
|
const emitSmalltalk = async (kind) => {
|
|
26817
27476
|
await emitFastLaneHit(kind === "greeting" ? "greeting_rule" : "ack_rule", kind === "greeting" ? "smalltalk.greeting" : "smalltalk.ack");
|
|
26818
|
-
if (kind === "greeting"
|
|
26819
|
-
const
|
|
26820
|
-
|
|
27477
|
+
if (kind === "greeting") {
|
|
27478
|
+
const greetingContinuity = await resolveGreetingContinuityDecision({
|
|
27479
|
+
continuityEnabled: params.continuity?.enabled ?? true,
|
|
27480
|
+
continuityWindowMinutes: params.continuity?.windowMinutes,
|
|
26821
27481
|
isEstablishedSession,
|
|
26822
27482
|
storage,
|
|
26823
27483
|
session,
|
|
@@ -26825,13 +27485,22 @@ async function handleQuickResponses(params) {
|
|
|
26825
27485
|
assistantName: profile.assistantName,
|
|
26826
27486
|
isPureGreeting: isPureGreeting2,
|
|
26827
27487
|
isPureAck: isPureAck2
|
|
26828
|
-
})
|
|
26829
|
-
|
|
26830
|
-
|
|
26831
|
-
|
|
26832
|
-
|
|
26833
|
-
|
|
26834
|
-
|
|
27488
|
+
});
|
|
27489
|
+
if (greetingContinuity.repeatedGreeting) {
|
|
27490
|
+
return emitLocal("smalltalk.greeting", buildRecentGreetingReply({
|
|
27491
|
+
userName: profile.userName?.trim(),
|
|
27492
|
+
locale,
|
|
27493
|
+
style: conversationStyle.style
|
|
27494
|
+
}));
|
|
27495
|
+
}
|
|
27496
|
+
if (greetingContinuity.continuation) {
|
|
27497
|
+
return emitLocal("smalltalk.greeting", buildGreetingContinuationReply({
|
|
27498
|
+
userName: profile.userName?.trim(),
|
|
27499
|
+
locale,
|
|
27500
|
+
topic: greetingContinuity.topic,
|
|
27501
|
+
style: conversationStyle.style
|
|
27502
|
+
}));
|
|
27503
|
+
}
|
|
26835
27504
|
}
|
|
26836
27505
|
return emitLocal(kind === "greeting" ? "smalltalk.greeting" : "smalltalk.ack", buildSmalltalkReply2(profileForStyledReplies, kind, message.channel, locale));
|
|
26837
27506
|
};
|
|
@@ -30226,21 +30895,30 @@ function isAbortLikeError(error) {
|
|
|
30226
30895
|
if (!error)
|
|
30227
30896
|
return false;
|
|
30228
30897
|
const textFrom = (value) => typeof value === "string" ? value : String(value ?? "");
|
|
30898
|
+
const hasAbortMarker = (value) => /abort|aborted|aborterror|abortederror/i.test(value);
|
|
30229
30899
|
if (error instanceof Error) {
|
|
30230
30900
|
const name = textFrom(error.name);
|
|
30231
30901
|
const message = textFrom(error.message);
|
|
30232
|
-
if (
|
|
30902
|
+
if (hasAbortMarker(name) || hasAbortMarker(message))
|
|
30903
|
+
return true;
|
|
30904
|
+
const cause = error.cause;
|
|
30905
|
+
if (cause && isAbortLikeError(cause))
|
|
30233
30906
|
return true;
|
|
30234
30907
|
return false;
|
|
30235
30908
|
}
|
|
30236
30909
|
if (typeof error === "string") {
|
|
30237
|
-
return
|
|
30910
|
+
return hasAbortMarker(error);
|
|
30238
30911
|
}
|
|
30239
30912
|
if (typeof error === "object" && error !== null) {
|
|
30240
30913
|
const entry = error;
|
|
30241
30914
|
const name = textFrom(entry.name);
|
|
30242
30915
|
const message = textFrom(entry.message);
|
|
30243
|
-
|
|
30916
|
+
const code = textFrom(entry.code);
|
|
30917
|
+
if (hasAbortMarker(name) || hasAbortMarker(message) || hasAbortMarker(code))
|
|
30918
|
+
return true;
|
|
30919
|
+
if (entry.cause && isAbortLikeError(entry.cause))
|
|
30920
|
+
return true;
|
|
30921
|
+
return false;
|
|
30244
30922
|
}
|
|
30245
30923
|
return false;
|
|
30246
30924
|
}
|
|
@@ -30931,8 +31609,21 @@ async function handleToolPlanning(params) {
|
|
|
30931
31609
|
await appendAssistantEvent(storage, session.id, locationPrompt, { providerId: "tool", model: promptModel }, message);
|
|
30932
31610
|
return buildEarlyResult(session, promptModel, locationPrompt, routingDecision, routingResult);
|
|
30933
31611
|
}
|
|
31612
|
+
let recommendedToolsForDecision = [];
|
|
31613
|
+
if (chitraguptaBridge) {
|
|
31614
|
+
try {
|
|
31615
|
+
recommendedToolsForDecision = chitraguptaBridge.recommend(normalized.norm);
|
|
31616
|
+
} catch {
|
|
31617
|
+
recommendedToolsForDecision = [];
|
|
31618
|
+
}
|
|
31619
|
+
}
|
|
30934
31620
|
const tool = toolRegistry.get(toolName);
|
|
30935
31621
|
if (tool) {
|
|
31622
|
+
const hasChosenRecommendation = recommendedToolsForDecision.includes(toolName);
|
|
31623
|
+
const preferredTool = recommendedToolsForDecision.find((name) => name && name !== toolName);
|
|
31624
|
+
if (!hasChosenRecommendation && preferredTool) {
|
|
31625
|
+
chitraguptaBridge?.onSkillRejected(preferredTool, toolName);
|
|
31626
|
+
}
|
|
30936
31627
|
if (signal?.aborted) {
|
|
30937
31628
|
return buildEarlyResult(session, "agent.aborted", t(locale, "system.request_cancelled"), routingDecision, routingResult);
|
|
30938
31629
|
}
|
|
@@ -31879,12 +32570,24 @@ function resolveInitialProviderAndModel(params) {
|
|
|
31879
32570
|
tier: terminalChain.tier
|
|
31880
32571
|
});
|
|
31881
32572
|
} else {
|
|
31882
|
-
|
|
31883
|
-
|
|
31884
|
-
|
|
31885
|
-
|
|
31886
|
-
|
|
31887
|
-
|
|
32573
|
+
const finalFallbackProviders = ["google", "openai"];
|
|
32574
|
+
const configuredFallback = providers.list().find((provider) => finalFallbackProviders.includes(provider.id));
|
|
32575
|
+
if (configuredFallback) {
|
|
32576
|
+
resolvedProviderId = configuredFallback.id;
|
|
32577
|
+
resolvedModel = void 0;
|
|
32578
|
+
logger.warn("provider_resolved_via_final_template_fallback", {
|
|
32579
|
+
sessionId,
|
|
32580
|
+
fallbackProviderId: configuredFallback.id,
|
|
32581
|
+
tier: terminalChain.tier
|
|
32582
|
+
});
|
|
32583
|
+
} else {
|
|
32584
|
+
resolvedProviderId = "__template__";
|
|
32585
|
+
capturedTemplateResponse = terminalChain.templateResponse;
|
|
32586
|
+
logger.warn("provider_all_exhausted_template_fallback", {
|
|
32587
|
+
sessionId,
|
|
32588
|
+
templateResponse: terminalChain.templateResponse?.slice(0, 80)
|
|
32589
|
+
});
|
|
32590
|
+
}
|
|
31888
32591
|
}
|
|
31889
32592
|
}
|
|
31890
32593
|
return {
|
|
@@ -36737,6 +37440,19 @@ function mapMargaComplexityToTier(complexity) {
|
|
|
36737
37440
|
return "fast";
|
|
36738
37441
|
return complexity === "complex" || complexity === "expert" ? "deep" : "fast";
|
|
36739
37442
|
}
|
|
37443
|
+
async function resolveMargaDecisionLocalFirst(input) {
|
|
37444
|
+
if (!input.autoRouting)
|
|
37445
|
+
return null;
|
|
37446
|
+
const localClassifier = input.localClassifier ?? ((text, hasTools) => classifyMessage(text, hasTools));
|
|
37447
|
+
const localDecision = localClassifier(input.routingText, input.hasTools);
|
|
37448
|
+
if (localDecision)
|
|
37449
|
+
return localDecision;
|
|
37450
|
+
return await input.runtime.chitraguptaBridge?.decideRoute({
|
|
37451
|
+
message: input.routingText,
|
|
37452
|
+
hasTools: input.hasTools,
|
|
37453
|
+
bindingStrategy: "hybrid"
|
|
37454
|
+
}) ?? null;
|
|
37455
|
+
}
|
|
36740
37456
|
var MANAS_TYPE_THRESHOLDS = {
|
|
36741
37457
|
system_command: 0.5,
|
|
36742
37458
|
conversation: 0.5,
|
|
@@ -36749,6 +37465,31 @@ var MANAS_TYPE_THRESHOLDS = {
|
|
|
36749
37465
|
agentic_task: 0.65
|
|
36750
37466
|
};
|
|
36751
37467
|
var MANAS_SHORTCIRCUIT_FALLBACK = 0.55;
|
|
37468
|
+
var DEFAULT_POLICY_SIDECAR_CONFIDENCE = {
|
|
37469
|
+
minConfidenceForCautious: 0.7,
|
|
37470
|
+
minConfidenceForDeny: 0.82,
|
|
37471
|
+
minConfidenceForSafeFastLane: 0.55,
|
|
37472
|
+
downgradePolicy: "standard"
|
|
37473
|
+
};
|
|
37474
|
+
function applyPolicySidecarConfidenceOverride(policyClassifier, config) {
|
|
37475
|
+
if (policyClassifier.source !== "sidecar")
|
|
37476
|
+
return policyClassifier;
|
|
37477
|
+
if (policyClassifier.policy === "standard")
|
|
37478
|
+
return policyClassifier;
|
|
37479
|
+
const thresholds = { ...DEFAULT_POLICY_SIDECAR_CONFIDENCE, ...config ?? {} };
|
|
37480
|
+
const minConfidence = policyClassifier.policy === "deny" ? thresholds.minConfidenceForDeny : policyClassifier.policy === "cautious" ? thresholds.minConfidenceForCautious : thresholds.minConfidenceForSafeFastLane;
|
|
37481
|
+
if (policyClassifier.confidence >= minConfidence)
|
|
37482
|
+
return policyClassifier;
|
|
37483
|
+
const downgraded = thresholds.downgradePolicy;
|
|
37484
|
+
return {
|
|
37485
|
+
...policyClassifier,
|
|
37486
|
+
policy: downgraded,
|
|
37487
|
+
reasons: [
|
|
37488
|
+
...policyClassifier.reasons ?? [],
|
|
37489
|
+
`policy_confidence_override:${policyClassifier.policy}->${downgraded}:${policyClassifier.confidence.toFixed(2)}<${minConfidence.toFixed(2)}`
|
|
37490
|
+
]
|
|
37491
|
+
};
|
|
37492
|
+
}
|
|
36752
37493
|
async function resolveRoutingDecision(input) {
|
|
36753
37494
|
const { routingText, locale, languageSource, autoRouting, sessionId, payload, prefs, profile, providers, config, runtime, deps, sessionRoute, hasPayloadOverride, sessionPinExpired, budgetPressure, latencyPreference, conversationStyleHint } = input;
|
|
36754
37495
|
const activeSessionPin = !hasPayloadOverride && !sessionPinExpired && sessionRoute.pinProviderId ? {
|
|
@@ -36798,6 +37539,7 @@ async function resolveRoutingDecision(input) {
|
|
|
36798
37539
|
};
|
|
36799
37540
|
}
|
|
36800
37541
|
}
|
|
37542
|
+
policyClassifier = applyPolicySidecarConfidenceOverride(policyClassifier, config.routing.policySidecarConfidence);
|
|
36801
37543
|
const naturalCommand = detectNaturalLanguageCommand(routingText, locale);
|
|
36802
37544
|
const commandText = naturalCommand ?? payload.message.text;
|
|
36803
37545
|
const command = parseCommand(commandText);
|
|
@@ -36812,11 +37554,12 @@ async function resolveRoutingDecision(input) {
|
|
|
36812
37554
|
looksLikeRecentRecap: deps.looksLikeRecentRecap
|
|
36813
37555
|
});
|
|
36814
37556
|
const hasTools = runtime.toolRegistry.list().length > 0;
|
|
36815
|
-
const margaDecision =
|
|
36816
|
-
|
|
37557
|
+
const margaDecision = await resolveMargaDecisionLocalFirst({
|
|
37558
|
+
autoRouting,
|
|
37559
|
+
routingText,
|
|
36817
37560
|
hasTools,
|
|
36818
|
-
|
|
36819
|
-
})
|
|
37561
|
+
runtime
|
|
37562
|
+
});
|
|
36820
37563
|
const margaRoutingDecision = autoRouting && margaDecision?.providerId && providers.get(margaDecision.providerId) ? {
|
|
36821
37564
|
target: {
|
|
36822
37565
|
providerId: margaDecision.providerId,
|
|
@@ -37357,8 +38100,8 @@ function buildObservationMask(toolName, lineCount, charCount, turnsAgo) {
|
|
|
37357
38100
|
var DEFAULT_CHAT_ATTEMPT_TIMEOUT_MS = 15e3;
|
|
37358
38101
|
var MIN_CHAT_ATTEMPT_TIMEOUT_MS = 1e3;
|
|
37359
38102
|
var MAX_CHAT_ATTEMPT_TIMEOUT_MS = 12e4;
|
|
37360
|
-
var GENERAL_LOCAL_TIMEOUT_CAP_MS =
|
|
37361
|
-
var SMALLTALK_LOCAL_TIMEOUT_CAP_MS =
|
|
38103
|
+
var GENERAL_LOCAL_TIMEOUT_CAP_MS = 6e3;
|
|
38104
|
+
var SMALLTALK_LOCAL_TIMEOUT_CAP_MS = 2500;
|
|
37362
38105
|
var DEFAULT_CHAT_MAX_ATTEMPTS = 3;
|
|
37363
38106
|
var MIN_CHAT_MAX_ATTEMPTS = 1;
|
|
37364
38107
|
var MAX_CHAT_MAX_ATTEMPTS = 10;
|
|
@@ -37521,7 +38264,8 @@ async function runChatWithFallback(params) {
|
|
|
37521
38264
|
listProviders: listProviders2,
|
|
37522
38265
|
preferCliForConversation
|
|
37523
38266
|
});
|
|
37524
|
-
const
|
|
38267
|
+
const configuredMaxAttempts = resolveChatMaxAttempts(config);
|
|
38268
|
+
const maxAttempts = params.actionabilityKind === "smalltalk" || params.actionabilityKind === "general" ? Math.min(configuredMaxAttempts, 2) : configuredMaxAttempts;
|
|
37525
38269
|
const attempts = builtAttempts;
|
|
37526
38270
|
if (attempts.length > maxAttempts) {
|
|
37527
38271
|
logger.info("provider_attempts_limited", {
|
|
@@ -38284,9 +39028,32 @@ function resolveSmalltalkProviderFallback(params) {
|
|
|
38284
39028
|
|
|
38285
39029
|
// apps/gateway/dist/agent/loop-chat-result.js
|
|
38286
39030
|
async function handleChatPhase(input) {
|
|
38287
|
-
const { deps, session, payload, runSignal, runId, routingDecision, routingResult, actionability, margaDecision, resolvedProviderId, resolvedModel, semanticCacheCategory, semanticCacheRule, routingText, context, retrievalHits, retrievalDecision, normalizedOutboundMeta, combinedSystem, resolveModelAlias: resolveModelAlias2, normalizeModelId: normalizeModelId2, listProviderModels, profile, locale, toolPolicy, budgetFallbackTarget, maybeAppendSmritiMemorySafe, enqueueSmritiMemoryAppendSafe, allowMemory, memoryAllowed, memoryManager, stripModelThinking: stripModelThinking2, manasRouteHint } = input;
|
|
39031
|
+
const { deps, session, payload, runSignal, runId, routingDecision, routingResult, actionability, margaDecision, resolvedProviderId, resolvedModel, semanticCacheCategory, semanticCacheRule, routingText, context, retrievalHits, retrievalDecision, normalizedOutboundMeta, combinedSystem, resolveModelAlias: resolveModelAlias2, normalizeModelId: normalizeModelId2, listProviderModels, profile, locale, conversationStyleHint, turiyaSignal, toolPolicy, budgetFallbackTarget, maybeAppendSmritiMemorySafe, enqueueSmritiMemoryAppendSafe = maybeAppendSmritiMemorySafe, allowMemory, memoryAllowed, memoryManager, stripModelThinking: stripModelThinking2, manasRouteHint } = input;
|
|
38288
39032
|
const { runtime, formatProviderError: formatProviderError2, lastAnthropicCallAt } = deps;
|
|
38289
39033
|
const { config, logger, storage, providers, getProvider } = runtime;
|
|
39034
|
+
const profileForConversationalFallback = conversationStyleHint && conversationStyleHint !== "default" ? {
|
|
39035
|
+
...profile,
|
|
39036
|
+
toneTags: styleToToneTags({
|
|
39037
|
+
style: conversationStyleHint,
|
|
39038
|
+
existing: profile.toneTags
|
|
39039
|
+
})
|
|
39040
|
+
} : profile;
|
|
39041
|
+
const emitTuriyaOutcome = (reward, context2) => {
|
|
39042
|
+
if (!runtime.chitraguptaBridge || !turiyaSignal?.tier)
|
|
39043
|
+
return;
|
|
39044
|
+
const boundedReward = Number(Math.max(-1, Math.min(1, reward)).toFixed(4));
|
|
39045
|
+
const outcomeContext = {
|
|
39046
|
+
confidence: Number(turiyaSignal.confidence.toFixed(4)),
|
|
39047
|
+
costEstimate: Number(turiyaSignal.costEstimate.toFixed(4)),
|
|
39048
|
+
...context2 ?? {}
|
|
39049
|
+
};
|
|
39050
|
+
void runtime.chitraguptaBridge.recordTuriyaOutcome({
|
|
39051
|
+
tier: turiyaSignal.tier,
|
|
39052
|
+
reward: boundedReward,
|
|
39053
|
+
context: outcomeContext
|
|
39054
|
+
}).catch(() => {
|
|
39055
|
+
});
|
|
39056
|
+
};
|
|
38290
39057
|
if (margaDecision?.skipLLM) {
|
|
38291
39058
|
logger.info("marga_skip_llm", {
|
|
38292
39059
|
sessionId: session.id,
|
|
@@ -38294,7 +39061,7 @@ async function handleChatPhase(input) {
|
|
|
38294
39061
|
complexity: margaDecision.complexity
|
|
38295
39062
|
});
|
|
38296
39063
|
const skipKind = margaDecision.taskType === "heartbeat" ? "ack" : "greeting";
|
|
38297
|
-
const skipContent = deps.buildSmalltalkReply(
|
|
39064
|
+
const skipContent = deps.buildSmalltalkReply(profileForConversationalFallback, skipKind, payload.message.channel, locale);
|
|
38298
39065
|
const skipModel = `marga:${margaDecision.taskType}`;
|
|
38299
39066
|
await appendAssistantEvent(storage, session.id, skipContent, {
|
|
38300
39067
|
providerId: "marga",
|
|
@@ -38312,6 +39079,7 @@ async function handleChatPhase(input) {
|
|
|
38312
39079
|
});
|
|
38313
39080
|
routingResult.selected = { providerId: "marga", model: skipModel };
|
|
38314
39081
|
routingResult.fallbackUsed = false;
|
|
39082
|
+
emitTuriyaOutcome(0.95, { margaSkip: 1, providerFailure: 0, fallbackUsed: 0 });
|
|
38315
39083
|
return buildEarlyResult(session, skipModel, skipContent, routingDecision, routingResult);
|
|
38316
39084
|
}
|
|
38317
39085
|
if (!margaDecision?.skipLLM && manasRouteHint?.action === "skip_llm") {
|
|
@@ -38377,6 +39145,7 @@ async function handleChatPhase(input) {
|
|
|
38377
39145
|
}, payload.message);
|
|
38378
39146
|
routingResult.selected = cached2.selected;
|
|
38379
39147
|
routingResult.fallbackUsed = false;
|
|
39148
|
+
emitTuriyaOutcome(0.8, { semanticCacheHit: 1, providerFailure: 0, fallbackUsed: 0 });
|
|
38380
39149
|
return buildEarlyResult(session, cacheModel, cached2.responseContent, routingDecision, routingResult);
|
|
38381
39150
|
}
|
|
38382
39151
|
const agenticTools = runtime.toolRegistry.list().filter((t2) => deps.isToolAllowed(toolPolicy, t2.name)).filter((t2) => !t2.name.startsWith("memory.")).map((t2) => ({
|
|
@@ -38443,7 +39212,8 @@ async function handleChatPhase(input) {
|
|
|
38443
39212
|
routingResult.fallbackUsed = false;
|
|
38444
39213
|
return buildEarlyResult(session, recoveryModel, recoveryContent, routingDecision, routingResult);
|
|
38445
39214
|
}
|
|
38446
|
-
const
|
|
39215
|
+
const inferredActionability = inferSmalltalkActionability(actionability, payload.message.text, profile, { isPureGreeting: deps.isPureGreeting, isPureAck: deps.isPureAck }, margaDecision);
|
|
39216
|
+
const effectiveActionability = inferredActionability.kind === "smalltalk" || margaDecision?.taskType !== "smalltalk" ? inferredActionability : { kind: "smalltalk", reason: "smalltalk_greeting" };
|
|
38447
39217
|
if (escalation.reason !== "request_aborted" && effectiveActionability.kind !== "smalltalk") {
|
|
38448
39218
|
const degradedToolResult = await handleToolPlanning({
|
|
38449
39219
|
session,
|
|
@@ -38493,14 +39263,38 @@ async function handleChatPhase(input) {
|
|
|
38493
39263
|
});
|
|
38494
39264
|
if (degradedToolResult) {
|
|
38495
39265
|
routingResult.escalation = escalation;
|
|
39266
|
+
emitTuriyaOutcome(0.3, { degradedToolRecovery: 1, providerFailure: 1, fallbackUsed: 1 });
|
|
38496
39267
|
return degradedToolResult;
|
|
38497
39268
|
}
|
|
39269
|
+
if (actionability.kind === "tool" || routingResult.actionability?.kind === "tool") {
|
|
39270
|
+
const recoveryContent = "I'm in recovery mode right now and can still run deterministic tools. Try a direct ask like weather, forecast, notes, reminders, or time.";
|
|
39271
|
+
const recoveryModel = "tool.recovery";
|
|
39272
|
+
routingResult.escalation = escalation;
|
|
39273
|
+
await appendAssistantEvent(storage, session.id, recoveryContent, {
|
|
39274
|
+
providerId: "tool",
|
|
39275
|
+
model: recoveryModel
|
|
39276
|
+
}, payload.message);
|
|
39277
|
+
await maybeAppendSmritiMemorySafe({
|
|
39278
|
+
userText: payload.message.text,
|
|
39279
|
+
assistantText: recoveryContent,
|
|
39280
|
+
sessionId: session.id,
|
|
39281
|
+
channel: payload.message.channel,
|
|
39282
|
+
chatId: payload.message.chatId,
|
|
39283
|
+
userId: payload.message.userId,
|
|
39284
|
+
providerId: "tool",
|
|
39285
|
+
model: recoveryModel
|
|
39286
|
+
});
|
|
39287
|
+
routingResult.selected = { providerId: "tool", model: recoveryModel };
|
|
39288
|
+
routingResult.fallbackUsed = false;
|
|
39289
|
+
emitTuriyaOutcome(0.15, { toolRecoveryPrompt: 1, providerFailure: 1, fallbackUsed: 1 });
|
|
39290
|
+
return buildEarlyResult(session, recoveryModel, recoveryContent, routingDecision, routingResult);
|
|
39291
|
+
}
|
|
38498
39292
|
}
|
|
38499
39293
|
const smalltalkFallback = resolveSmalltalkProviderFallback({
|
|
38500
39294
|
actionability: effectiveActionability,
|
|
38501
39295
|
escalation,
|
|
38502
39296
|
buildSmalltalkReply: deps.buildSmalltalkReply,
|
|
38503
|
-
profile,
|
|
39297
|
+
profile: profileForConversationalFallback,
|
|
38504
39298
|
channel: payload.message.channel,
|
|
38505
39299
|
locale
|
|
38506
39300
|
});
|
|
@@ -38522,6 +39316,7 @@ async function handleChatPhase(input) {
|
|
|
38522
39316
|
});
|
|
38523
39317
|
routingResult.selected = { providerId: "local", model: smalltalkFallback.model };
|
|
38524
39318
|
routingResult.fallbackUsed = false;
|
|
39319
|
+
emitTuriyaOutcome(0.25, { smalltalkFallback: 1, providerFailure: 1, fallbackUsed: 1 });
|
|
38525
39320
|
return buildEarlyResult(session, smalltalkFallback.model, smalltalkFallback.content, routingDecision, routingResult);
|
|
38526
39321
|
}
|
|
38527
39322
|
const content = chatResult.friendlyMessage ? chatResult.friendlyMessage : formatProviderError2(chatResult.error ?? new Error("Provider failed"));
|
|
@@ -38543,12 +39338,13 @@ async function handleChatPhase(input) {
|
|
|
38543
39338
|
});
|
|
38544
39339
|
routingResult.selected = { providerId: "error", model: errorModel };
|
|
38545
39340
|
routingResult.fallbackUsed = false;
|
|
39341
|
+
emitTuriyaOutcome(-1, { errorEscalation: 1, providerFailure: 1, fallbackUsed: 1 });
|
|
38546
39342
|
return buildEarlyResult(session, errorModel, content, routingDecision, routingResult);
|
|
38547
39343
|
}
|
|
38548
39344
|
const { response, provider, model, fallbackUsed } = chatResult;
|
|
38549
39345
|
let finalResponse = response;
|
|
38550
39346
|
if (response.toolCalls?.length && agenticTools.length > 0) {
|
|
38551
|
-
const { runAgenticToolLoop } = await import("./chunks/agentic-tool-loop-
|
|
39347
|
+
const { runAgenticToolLoop } = await import("./chunks/agentic-tool-loop-NQESOBLC.js");
|
|
38552
39348
|
const agenticResult = await runAgenticToolLoop({
|
|
38553
39349
|
toolCalls: response.toolCalls,
|
|
38554
39350
|
initialContent: response.content,
|
|
@@ -38616,6 +39412,11 @@ async function handleChatPhase(input) {
|
|
|
38616
39412
|
}
|
|
38617
39413
|
});
|
|
38618
39414
|
}
|
|
39415
|
+
emitTuriyaOutcome(fallbackUsed ? 0.55 : 1, {
|
|
39416
|
+
providerFailure: 0,
|
|
39417
|
+
fallbackUsed: fallbackUsed ? 1 : 0,
|
|
39418
|
+
semanticCacheWrite: cacheStored ? 1 : 0
|
|
39419
|
+
});
|
|
38619
39420
|
return finalizeChatRun({
|
|
38620
39421
|
storage,
|
|
38621
39422
|
session,
|
|
@@ -38664,11 +39465,11 @@ async function executeAgentRun(params) {
|
|
|
38664
39465
|
const { deps, session, payload, runId, sessionRoute, runSignal } = params;
|
|
38665
39466
|
const { runtime, stripModelThinking: stripModelThinking2, formatProviderError: formatProviderError2, buildProfileSystemPrompt: buildProfileSystemPrompt2, smritiAutoMemoryReady, smritiAutoMemorySessions, runSmritiAutoMemoryScript, smritiClient, smritiRetrieveEnabled, smritiRetrieveLimit, listProviderModels, resolveModelAlias: resolveModelAlias2, normalizeModelId: normalizeModelId2, inferProviderFromModel: inferProviderFromModel2, lastAnthropicCallAt, memoryManager } = deps;
|
|
38666
39467
|
const { config, logger, storage, providers, soulPrompt, getProvider, memoryAllowed, maybeAppendSmritiMemory, enqueueSmritiMemoryAppend } = runtime;
|
|
38667
|
-
const
|
|
38668
|
-
const
|
|
38669
|
-
const
|
|
38670
|
-
const normalizedAuditContext =
|
|
38671
|
-
const normalizedOutboundMeta =
|
|
39468
|
+
const normFrom = payload.message.normalization;
|
|
39469
|
+
const normInc = normalizeIncomingText(payload.message.text ?? "");
|
|
39470
|
+
const normMatch = normFrom?.audit?.raw === normInc.raw && normFrom?.audit?.norm === normInc.norm;
|
|
39471
|
+
const normalizedAuditContext = normMatch && normFrom?.audit ? normFrom.audit : buildNormalizationAuditContext(normInc);
|
|
39472
|
+
const normalizedOutboundMeta = normMatch && normFrom?.outbound ? normFrom.outbound : buildNormalizationOutboundMeta(normInc);
|
|
38672
39473
|
const routingText = normalizedAuditContext.norm || payload.message.text;
|
|
38673
39474
|
const retrievalText = normalizedAuditContext.search || normalizedAuditContext.norm || payload.message.text;
|
|
38674
39475
|
const message = {
|
|
@@ -38768,16 +39569,8 @@ async function executeAgentRun(params) {
|
|
|
38768
39569
|
const pinUntilMs = sessionRoute.pinUntil ? Date.parse(sessionRoute.pinUntil) : Number.NaN;
|
|
38769
39570
|
const sessionPinExpired = Boolean(sessionRoute.pinProviderId) && Number.isFinite(pinUntilMs) && pinUntilMs <= Date.now();
|
|
38770
39571
|
if (sessionPinExpired && storage.setSessionRoute) {
|
|
38771
|
-
void storage.setSessionRoute(session.id, {
|
|
38772
|
-
|
|
38773
|
-
laneId: sessionRoute.laneId,
|
|
38774
|
-
queueMode: sessionRoute.queueMode,
|
|
38775
|
-
announceMode: sessionRoute.announceMode
|
|
38776
|
-
}).catch((error) => {
|
|
38777
|
-
logger.warn("session_route_pin_clear_failed", {
|
|
38778
|
-
sessionId: session.id,
|
|
38779
|
-
error: error instanceof Error ? error.message : String(error)
|
|
38780
|
-
});
|
|
39572
|
+
void storage.setSessionRoute(session.id, { agentId: sessionRoute.agentId, laneId: sessionRoute.laneId, queueMode: sessionRoute.queueMode, announceMode: sessionRoute.announceMode }).catch((e) => {
|
|
39573
|
+
logger.warn("session_route_pin_clear_failed", { sessionId: session.id, error: e instanceof Error ? e.message : String(e) });
|
|
38781
39574
|
});
|
|
38782
39575
|
}
|
|
38783
39576
|
const earlyBudgetState = await evaluateBudgetState({ storage, config, logger });
|
|
@@ -38816,7 +39609,7 @@ async function executeAgentRun(params) {
|
|
|
38816
39609
|
latencyPreference,
|
|
38817
39610
|
conversationStyleHint: earlyStyleHint !== "default" ? earlyStyleHint : void 0
|
|
38818
39611
|
});
|
|
38819
|
-
const { command, actionability, policyClassifier, margaDecision, routingDecision, complexitySignal, scoringResult, earlyRoutingResult, activeSessionPin, manasRouteHint, manasClassification, complexityProfile34 } = routing;
|
|
39612
|
+
const { command, actionability, policyClassifier, margaDecision, routingDecision, complexitySignal, scoringResult, earlyRoutingResult, activeSessionPin, turiyaSignal, manasRouteHint, manasClassification, complexityProfile34 } = routing;
|
|
38820
39613
|
if (!command) {
|
|
38821
39614
|
const allowMemoryEarly = memoryAllowed() && payload.memoryMode !== "disabled";
|
|
38822
39615
|
const maybeAppendSmritiMemorySafeEarly = allowMemoryEarly ? maybeAppendSmritiMemory : async () => {
|
|
@@ -39090,9 +39883,10 @@ async function executeAgentRun(params) {
|
|
|
39090
39883
|
});
|
|
39091
39884
|
if (runSignal.aborted)
|
|
39092
39885
|
throw new Error("Request aborted");
|
|
39886
|
+
let chitraguptaRecs = [];
|
|
39093
39887
|
try {
|
|
39094
|
-
|
|
39095
|
-
if (chitraguptaRecs
|
|
39888
|
+
chitraguptaRecs = runtime.chitraguptaBridge?.recommend(payload.message.text) ?? [];
|
|
39889
|
+
if (chitraguptaRecs.length > 0) {
|
|
39096
39890
|
logger.debug("chitragupta_recommendations", {
|
|
39097
39891
|
sessionId: session.id,
|
|
39098
39892
|
query: payload.message.text.slice(0, 100),
|
|
@@ -39123,7 +39917,7 @@ async function executeAgentRun(params) {
|
|
|
39123
39917
|
});
|
|
39124
39918
|
if (preChatResult)
|
|
39125
39919
|
return preChatResult;
|
|
39126
|
-
|
|
39920
|
+
const chatPhaseResult = await handleChatPhase({
|
|
39127
39921
|
margaDecision,
|
|
39128
39922
|
deps,
|
|
39129
39923
|
session,
|
|
@@ -39150,6 +39944,8 @@ async function executeAgentRun(params) {
|
|
|
39150
39944
|
locale,
|
|
39151
39945
|
toolPolicy,
|
|
39152
39946
|
budgetFallbackTarget,
|
|
39947
|
+
conversationStyleHint: conversationStyle.style,
|
|
39948
|
+
turiyaSignal,
|
|
39153
39949
|
maybeAppendSmritiMemorySafe,
|
|
39154
39950
|
enqueueSmritiMemoryAppendSafe,
|
|
39155
39951
|
allowMemory,
|
|
@@ -39158,6 +39954,22 @@ async function executeAgentRun(params) {
|
|
|
39158
39954
|
stripModelThinking: stripModelThinking2,
|
|
39159
39955
|
manasRouteHint
|
|
39160
39956
|
});
|
|
39957
|
+
try {
|
|
39958
|
+
const bridge = runtime.chitraguptaBridge;
|
|
39959
|
+
if (bridge && chitraguptaRecs.length > 0) {
|
|
39960
|
+
const toolCallNames = (chatPhaseResult.response.toolCalls ?? []).map((toolCall) => toolCall?.name?.trim()).filter((name) => Boolean(name));
|
|
39961
|
+
if (toolCallNames.length > 0) {
|
|
39962
|
+
const chosenTool = toolCallNames[0] ?? "llm";
|
|
39963
|
+
for (const rec of chitraguptaRecs) {
|
|
39964
|
+
if (rec && !toolCallNames.includes(rec)) {
|
|
39965
|
+
bridge.onSkillRejected(rec, chosenTool);
|
|
39966
|
+
}
|
|
39967
|
+
}
|
|
39968
|
+
}
|
|
39969
|
+
}
|
|
39970
|
+
} catch {
|
|
39971
|
+
}
|
|
39972
|
+
return chatPhaseResult;
|
|
39161
39973
|
}
|
|
39162
39974
|
|
|
39163
39975
|
// apps/gateway/dist/routing-trace.js
|
|
@@ -39631,6 +40443,16 @@ function createAgentLoop(deps) {
|
|
|
39631
40443
|
error: error instanceof Error ? error.message : String(error)
|
|
39632
40444
|
});
|
|
39633
40445
|
}
|
|
40446
|
+
try {
|
|
40447
|
+
const bridge = runtime.chitraguptaBridge;
|
|
40448
|
+
const noToolUsed = !result.response.toolCalls?.length;
|
|
40449
|
+
const isSubstantive = payload.message.text.trim().length > 10;
|
|
40450
|
+
const isNonTemplate = result.response.model !== "template:deterministic" && result.response.model !== "system.queued" && result.response.model !== "system.continuity";
|
|
40451
|
+
if (bridge && noToolUsed && isSubstantive && isNonTemplate) {
|
|
40452
|
+
bridge.recordSkillGap(payload.message.text, result.session.id);
|
|
40453
|
+
}
|
|
40454
|
+
} catch {
|
|
40455
|
+
}
|
|
39634
40456
|
return result;
|
|
39635
40457
|
}
|
|
39636
40458
|
return runAgent;
|
|
@@ -44142,7 +44964,7 @@ async function forwardToBridge(runtime, connectionId, request) {
|
|
|
44142
44964
|
if (!bridgeConnection) {
|
|
44143
44965
|
throw new Error("Bridge connection not found or disconnected");
|
|
44144
44966
|
}
|
|
44145
|
-
return new Promise((
|
|
44967
|
+
return new Promise((resolve3, reject) => {
|
|
44146
44968
|
const requestId = `fwd-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
44147
44969
|
const timer = setTimeout(() => {
|
|
44148
44970
|
pendingBridgeRequests.delete(requestId);
|
|
@@ -44152,7 +44974,7 @@ async function forwardToBridge(runtime, connectionId, request) {
|
|
|
44152
44974
|
resolve: (result) => {
|
|
44153
44975
|
clearTimeout(timer);
|
|
44154
44976
|
pendingBridgeRequests.delete(requestId);
|
|
44155
|
-
|
|
44977
|
+
resolve3(result);
|
|
44156
44978
|
}
|
|
44157
44979
|
});
|
|
44158
44980
|
bridgeConnection.sendEvent("bridge.request", {
|
|
@@ -44211,10 +45033,10 @@ function createBridgeExecutor(bridgeRegistry, connections) {
|
|
|
44211
45033
|
}
|
|
44212
45034
|
const timeoutMs = ctx?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
44213
45035
|
const requestId = `anriva-tool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
44214
|
-
return new Promise((
|
|
45036
|
+
return new Promise((resolve3) => {
|
|
44215
45037
|
const timer = setTimeout(() => {
|
|
44216
45038
|
pendingBridgeRequests.delete(requestId);
|
|
44217
|
-
|
|
45039
|
+
resolve3({
|
|
44218
45040
|
ok: false,
|
|
44219
45041
|
error: { code: "bridge_timeout", message: `Bridge request timed out after ${timeoutMs}ms` }
|
|
44220
45042
|
});
|
|
@@ -44223,7 +45045,7 @@ function createBridgeExecutor(bridgeRegistry, connections) {
|
|
|
44223
45045
|
ctx.signal.addEventListener("abort", () => {
|
|
44224
45046
|
clearTimeout(timer);
|
|
44225
45047
|
pendingBridgeRequests.delete(requestId);
|
|
44226
|
-
|
|
45048
|
+
resolve3({
|
|
44227
45049
|
ok: false,
|
|
44228
45050
|
error: { code: "aborted", message: "Request aborted" }
|
|
44229
45051
|
});
|
|
@@ -44233,7 +45055,7 @@ function createBridgeExecutor(bridgeRegistry, connections) {
|
|
|
44233
45055
|
resolve: (result) => {
|
|
44234
45056
|
clearTimeout(timer);
|
|
44235
45057
|
pendingBridgeRequests.delete(requestId);
|
|
44236
|
-
|
|
45058
|
+
resolve3({
|
|
44237
45059
|
ok: result.ok,
|
|
44238
45060
|
output: result.payload,
|
|
44239
45061
|
error: result.error
|
|
@@ -45984,7 +46806,7 @@ function createKaalaBroker(deps, options) {
|
|
|
45984
46806
|
dispatch(lane);
|
|
45985
46807
|
}
|
|
45986
46808
|
};
|
|
45987
|
-
const
|
|
46809
|
+
const spawn8 = (input) => {
|
|
45988
46810
|
if (!options.enabled) {
|
|
45989
46811
|
throw new Error("Kaala broker is disabled.");
|
|
45990
46812
|
}
|
|
@@ -46036,13 +46858,13 @@ function createKaalaBroker(deps, options) {
|
|
|
46036
46858
|
parentRunId: input.parentRunId,
|
|
46037
46859
|
metadata: input.metadata
|
|
46038
46860
|
};
|
|
46039
|
-
let
|
|
46861
|
+
let resolve3;
|
|
46040
46862
|
const promise = new Promise((res) => {
|
|
46041
|
-
|
|
46863
|
+
resolve3 = res;
|
|
46042
46864
|
});
|
|
46043
46865
|
const entry = {
|
|
46044
46866
|
record,
|
|
46045
|
-
resolve,
|
|
46867
|
+
resolve: resolve3,
|
|
46046
46868
|
promise,
|
|
46047
46869
|
cancelled: false,
|
|
46048
46870
|
controller: new AbortController()
|
|
@@ -46090,8 +46912,8 @@ function createKaalaBroker(deps, options) {
|
|
|
46090
46912
|
if (entry.record.endedAt) return entry.record;
|
|
46091
46913
|
if (!timeoutMs) return entry.promise;
|
|
46092
46914
|
let timeoutId;
|
|
46093
|
-
const timeoutPromise = new Promise((
|
|
46094
|
-
timeoutId = setTimeout(() =>
|
|
46915
|
+
const timeoutPromise = new Promise((resolve3) => {
|
|
46916
|
+
timeoutId = setTimeout(() => resolve3(void 0), timeoutMs);
|
|
46095
46917
|
});
|
|
46096
46918
|
const result = await Promise.race([entry.promise, timeoutPromise]);
|
|
46097
46919
|
if (timeoutId) clearTimeout(timeoutId);
|
|
@@ -46163,7 +46985,7 @@ function createKaalaBroker(deps, options) {
|
|
|
46163
46985
|
};
|
|
46164
46986
|
};
|
|
46165
46987
|
return {
|
|
46166
|
-
spawn:
|
|
46988
|
+
spawn: spawn8,
|
|
46167
46989
|
list,
|
|
46168
46990
|
get,
|
|
46169
46991
|
wait: wait2,
|
|
@@ -46190,8 +47012,8 @@ function buildMetrics(entry, result) {
|
|
|
46190
47012
|
}
|
|
46191
47013
|
async function runWithTimeout(action, timeoutMs) {
|
|
46192
47014
|
let timeoutId;
|
|
46193
|
-
const timeoutPromise = new Promise((
|
|
46194
|
-
timeoutId = setTimeout(() =>
|
|
47015
|
+
const timeoutPromise = new Promise((resolve3) => {
|
|
47016
|
+
timeoutId = setTimeout(() => resolve3({ timedOut: true }), timeoutMs);
|
|
46195
47017
|
});
|
|
46196
47018
|
try {
|
|
46197
47019
|
const result = await Promise.race([
|
|
@@ -46746,8 +47568,15 @@ var CHANNEL_IDS = [
|
|
|
46746
47568
|
"imessage",
|
|
46747
47569
|
"web"
|
|
46748
47570
|
];
|
|
46749
|
-
var
|
|
46750
|
-
|
|
47571
|
+
var CHANNEL_ALIASES = {
|
|
47572
|
+
whispr: "signal"
|
|
47573
|
+
};
|
|
47574
|
+
var isChannelId = (value) => Boolean(value) && (CHANNEL_IDS.includes(normalizeChannelId(value)) || CHANNEL_IDS.includes(value));
|
|
47575
|
+
var toChannelId = (value) => isChannelId(value) ? normalizeChannelId(value) : void 0;
|
|
47576
|
+
function normalizeChannelId(value) {
|
|
47577
|
+
const normalized = CHANNEL_ALIASES[value.trim().toLowerCase()];
|
|
47578
|
+
return normalized ?? value.toLowerCase();
|
|
47579
|
+
}
|
|
46751
47580
|
|
|
46752
47581
|
// apps/gateway/dist/kaala/audit.js
|
|
46753
47582
|
import { randomUUID as randomUUID25 } from "node:crypto";
|
|
@@ -50007,20 +50836,20 @@ function hasRegexSupport(lang) {
|
|
|
50007
50836
|
|
|
50008
50837
|
// packages/nlu/src/prototypes.ts
|
|
50009
50838
|
var import_yaml = __toESM(require_dist(), 1);
|
|
50010
|
-
import { readFileSync } from "node:fs";
|
|
50011
|
-
import { join, dirname } from "node:path";
|
|
50839
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
50840
|
+
import { join as join2, dirname } from "node:path";
|
|
50012
50841
|
import { fileURLToPath } from "node:url";
|
|
50013
50842
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
50014
|
-
var YAML_PATH =
|
|
50843
|
+
var YAML_PATH = join2(__dirname, "intent-prototypes.yaml");
|
|
50015
50844
|
var cached = null;
|
|
50016
50845
|
function loadIntentPrototypes() {
|
|
50017
50846
|
if (cached) return cached;
|
|
50018
50847
|
let raw;
|
|
50019
50848
|
try {
|
|
50020
|
-
raw =
|
|
50849
|
+
raw = readFileSync2(YAML_PATH, "utf-8");
|
|
50021
50850
|
} catch {
|
|
50022
|
-
const fallbackPath =
|
|
50023
|
-
raw =
|
|
50851
|
+
const fallbackPath = join2(__dirname, "..", "src", "intent-prototypes.yaml");
|
|
50852
|
+
raw = readFileSync2(fallbackPath, "utf-8");
|
|
50024
50853
|
}
|
|
50025
50854
|
const parsed = (0, import_yaml.parse)(raw);
|
|
50026
50855
|
cached = parsed;
|
|
@@ -50369,6 +51198,9 @@ var DEFAULT_HYBRID_THRESHOLD = 0.6;
|
|
|
50369
51198
|
var DEFAULT_EMBEDDING_THRESHOLD = 0.62;
|
|
50370
51199
|
var PREFER_EMBEDDING_TIMEOUT_MS = 350;
|
|
50371
51200
|
var DEFAULT_SMALLTALK_CLOUD_TIMEOUT_MS = 900;
|
|
51201
|
+
var DEFAULT_OLLAMA_CHAT_MODEL = "qwen3:8b";
|
|
51202
|
+
var SHORT_CHECKIN_PACK_LOCALE_SEPARATOR = /[-_]/;
|
|
51203
|
+
var WHITESPACE_RE = /\s+/g;
|
|
50372
51204
|
var SOCIAL_CHECKIN_RE = /\b(h(?:ow|w)\s*(?:are|r)\s*(?:you|u)|how(?:'s|\s+is)\s+it\s+going|what(?:'s|\s+is)\s+up|you\s+there|all\s+good|namaste|namaskar(?:am|a)?|namaskaram|vanakkam|bagunava|bagunnava|bagnava|ela\s+undh?i|em[i]?\s+chest(?:h|)un(?:n|)av(?:u|a)?|em[i]?\s+chest(?:h|)un(?:n|)ar(?:u|a)?|como\s+estas|como\s+esta|que\s+tal|wie\s+geht(?:\s+es|s)(?:\s+(?:dir|ihnen))?|alles\s+gut|comment\s+(?:ca|ça)\s+va|ca\s+va|ça\s+va|kaise\s+(?:ho|hai|hain)|aap\s+kaise\s+(?:ho|hain)|kya\s+haal(?:\s+hai)?|kya\s+chal\s+raha\s+hai|कैसे\s+(?:हो|हैं)|क्या\s+हाल(?:\s+है)?|क्या\s+चल\s+रहा\s+है|お元気|元気(?:ですか)?|調子どう|調子はどう|genki(?:\s+desu\s+ka)?|konnichiwa|ohayo(?:u)?|nasilsin|nasilsiniz|как\s+дела|كيف\s+حالك)\b/i;
|
|
50373
51205
|
var SOCIAL_ACTION_GUARD_RE = /\b(weather|forecast|clima|tiempo|wetter|pogoda|meteo|rain|snow|temperature|temp|router|network|wifi|device|client|connected|lan|scan|time|clock|remind|note|notes|search|find|nearest|hospital|train|rail|journey|memory|session|provider|model|language|lang|tone|style|emoji|persona|set|delete|forget|clear|music|play|transcrib|calendar|event|todo|joke|funny|meme|story|poem|quote|news|latest|top|tell\s+me|who\s+(?:are|r)\s+(?:you|u)|what\s+are\s+you|what\s+can\s+(?:you|u)\s+do)\b/i;
|
|
50374
51206
|
var SHORT_SOCIAL_TOKEN_RE = /[^\p{L}\p{N}']+/gu;
|
|
@@ -50460,7 +51292,36 @@ function normalizeBaseUrl4(value) {
|
|
|
50460
51292
|
return void 0;
|
|
50461
51293
|
return trimmed.replace(/\/$/, "");
|
|
50462
51294
|
}
|
|
50463
|
-
function
|
|
51295
|
+
function normalizeCheckinPhrase(input) {
|
|
51296
|
+
return input.toLowerCase().replace(SHORT_SOCIAL_TOKEN_RE, " ").trim().replace(WHITESPACE_RE, " ");
|
|
51297
|
+
}
|
|
51298
|
+
function resolveLocalePhrasePack(packs, language) {
|
|
51299
|
+
if (!packs)
|
|
51300
|
+
return /* @__PURE__ */ new Set();
|
|
51301
|
+
const locale = (language ?? "").trim().toLowerCase();
|
|
51302
|
+
const baseLocale = locale.split(SHORT_CHECKIN_PACK_LOCALE_SEPARATOR)[0] ?? "";
|
|
51303
|
+
const candidates = [
|
|
51304
|
+
packs[locale],
|
|
51305
|
+
packs[baseLocale],
|
|
51306
|
+
packs.default,
|
|
51307
|
+
packs["*"]
|
|
51308
|
+
].filter((value) => Array.isArray(value));
|
|
51309
|
+
const terms = /* @__PURE__ */ new Set();
|
|
51310
|
+
for (const pack of candidates) {
|
|
51311
|
+
for (const phrase of pack) {
|
|
51312
|
+
const normalized = normalizeCheckinPhrase(phrase);
|
|
51313
|
+
if (!normalized)
|
|
51314
|
+
continue;
|
|
51315
|
+
terms.add(normalized);
|
|
51316
|
+
for (const token of normalized.split(" ")) {
|
|
51317
|
+
if (token)
|
|
51318
|
+
terms.add(token);
|
|
51319
|
+
}
|
|
51320
|
+
}
|
|
51321
|
+
}
|
|
51322
|
+
return terms;
|
|
51323
|
+
}
|
|
51324
|
+
function looksLikeGenericSocialCheckin(text, options) {
|
|
50464
51325
|
const trimmed = text.trim();
|
|
50465
51326
|
if (!trimmed || trimmed.startsWith("/"))
|
|
50466
51327
|
return false;
|
|
@@ -50481,12 +51342,16 @@ function looksLikeGenericSocialCheckin(text) {
|
|
|
50481
51342
|
return false;
|
|
50482
51343
|
if (SOCIAL_CHECKIN_RE.test(trimmed))
|
|
50483
51344
|
return true;
|
|
51345
|
+
const localeTerms = resolveLocalePhrasePack(options?.phrasePacks, options?.language);
|
|
51346
|
+
const normalizedText = normalizeCheckinPhrase(trimmed);
|
|
51347
|
+
if (localeTerms.size > 0 && localeTerms.has(normalizedText))
|
|
51348
|
+
return true;
|
|
50484
51349
|
if (words.length > 3)
|
|
50485
51350
|
return false;
|
|
50486
51351
|
const normalizedWords = words.map((word) => word.toLowerCase().replace(SHORT_SOCIAL_TOKEN_RE, "")).filter(Boolean);
|
|
50487
51352
|
if (!normalizedWords.length || normalizedWords.length > 3)
|
|
50488
51353
|
return false;
|
|
50489
|
-
return normalizedWords.every((word) => SHORT_SOCIAL_TOKENS.has(word));
|
|
51354
|
+
return normalizedWords.every((word) => SHORT_SOCIAL_TOKENS.has(word) || localeTerms.has(word));
|
|
50490
51355
|
}
|
|
50491
51356
|
async function detectRequestLanguage(text, config, logger) {
|
|
50492
51357
|
const provider = config.nlu?.langDetectProvider ?? "auto";
|
|
@@ -50507,7 +51372,7 @@ function resolveDefaultModel(providerId, entry) {
|
|
|
50507
51372
|
return entry.models[0];
|
|
50508
51373
|
if (entry.type === "ollama") {
|
|
50509
51374
|
const required = entry.requiredModels?.find((model) => !/embed|bge/i.test(model));
|
|
50510
|
-
return required ??
|
|
51375
|
+
return required ?? DEFAULT_OLLAMA_CHAT_MODEL;
|
|
50511
51376
|
}
|
|
50512
51377
|
if (entry.type === "minimax")
|
|
50513
51378
|
return "MiniMax-M2.5-Lightning";
|
|
@@ -51300,7 +52165,15 @@ function createHybridNluInterpreter(params) {
|
|
|
51300
52165
|
if (langDetectEnabled) {
|
|
51301
52166
|
detectedLang = await detectRequestLanguage(request.text, config, logger);
|
|
51302
52167
|
}
|
|
51303
|
-
|
|
52168
|
+
const fastEmbeddingCandidates = request.preferEmbeddings ? embeddingCandidates.map((candidate) => ({
|
|
52169
|
+
...candidate,
|
|
52170
|
+
models: candidate.models.slice(0, 1),
|
|
52171
|
+
timeoutMs: Math.min(candidate.timeoutMs, PREFER_EMBEDDING_TIMEOUT_MS)
|
|
52172
|
+
})) : embeddingCandidates;
|
|
52173
|
+
if (request.preferEmbeddings && looksLikeGenericSocialCheckin(request.text, {
|
|
52174
|
+
language: detectedLang,
|
|
52175
|
+
phrasePacks: config.nlu?.shortCheckinPacks
|
|
52176
|
+
})) {
|
|
51304
52177
|
if (smalltalkCloudFallbackEnabled && candidates.length > 0) {
|
|
51305
52178
|
const smalltalkCandidates = prioritizeSmalltalkFallbackCandidates(candidates, {
|
|
51306
52179
|
preferredProviderId: llmConfig?.smalltalkCloudProviderId,
|
|
@@ -51326,7 +52199,7 @@ function createHybridNluInterpreter(params) {
|
|
|
51326
52199
|
return mergeNluResults(rulesResult, deterministicSmalltalk, hybridThreshold);
|
|
51327
52200
|
}
|
|
51328
52201
|
if (embeddingFirst) {
|
|
51329
|
-
const embeddingResult2 = await classifyWithEmbeddings(request,
|
|
52202
|
+
const embeddingResult2 = await classifyWithEmbeddings(request, fastEmbeddingCandidates, logger, embeddingThreshold, detectedLang);
|
|
51330
52203
|
if (embeddingResult2) {
|
|
51331
52204
|
if (hasRegexSupport(detectedLang) && rulesResult && rulesResult.intent !== "unknown") {
|
|
51332
52205
|
if (rulesResult.intent === embeddingResult2.intent) {
|
|
@@ -51350,16 +52223,16 @@ function createHybridNluInterpreter(params) {
|
|
|
51350
52223
|
return { ...rulesResult, language: detectedLang };
|
|
51351
52224
|
}
|
|
51352
52225
|
if (request.preferEmbeddings) {
|
|
51353
|
-
|
|
51354
|
-
|
|
51355
|
-
|
|
51356
|
-
|
|
51357
|
-
|
|
51358
|
-
const embeddingOnlyResult = await classifyWithEmbeddings(request, fastEmbeddingCandidates, logger, embeddingThreshold, detectedLang);
|
|
51359
|
-
if (embeddingOnlyResult) {
|
|
51360
|
-
return mergeNluResults(rulesResult, embeddingOnlyResult, hybridThreshold);
|
|
52226
|
+
if (!embeddingFirst) {
|
|
52227
|
+
const embeddingOnlyResult = await classifyWithEmbeddings(request, fastEmbeddingCandidates, logger, embeddingThreshold, detectedLang);
|
|
52228
|
+
if (embeddingOnlyResult) {
|
|
52229
|
+
return mergeNluResults(rulesResult, embeddingOnlyResult, hybridThreshold);
|
|
52230
|
+
}
|
|
51361
52231
|
}
|
|
51362
|
-
if (looksLikeGenericSocialCheckin(request.text
|
|
52232
|
+
if (looksLikeGenericSocialCheckin(request.text, {
|
|
52233
|
+
language: detectedLang,
|
|
52234
|
+
phrasePacks: config.nlu?.shortCheckinPacks
|
|
52235
|
+
})) {
|
|
51363
52236
|
return {
|
|
51364
52237
|
intent: "smalltalk.greeting",
|
|
51365
52238
|
confidence: 0.61,
|
|
@@ -51779,8 +52652,73 @@ function isLoopbackHost(host) {
|
|
|
51779
52652
|
import fs39 from "node:fs";
|
|
51780
52653
|
import os10 from "node:os";
|
|
51781
52654
|
import path37 from "node:path";
|
|
52655
|
+
import { pathToFileURL } from "node:url";
|
|
51782
52656
|
|
|
51783
52657
|
// packages/config/src/schema-nlu.ts
|
|
52658
|
+
var DEFAULT_SHORT_CHECKIN_PACKS = {
|
|
52659
|
+
en: [
|
|
52660
|
+
"hi",
|
|
52661
|
+
"hello",
|
|
52662
|
+
"hey",
|
|
52663
|
+
"how are you",
|
|
52664
|
+
"whats up",
|
|
52665
|
+
"just checking"
|
|
52666
|
+
],
|
|
52667
|
+
es: [
|
|
52668
|
+
"hola",
|
|
52669
|
+
"como estas",
|
|
52670
|
+
"que tal",
|
|
52671
|
+
"todo bien"
|
|
52672
|
+
],
|
|
52673
|
+
fr: [
|
|
52674
|
+
"bonjour",
|
|
52675
|
+
"salut",
|
|
52676
|
+
"ca va",
|
|
52677
|
+
"comment ca va"
|
|
52678
|
+
],
|
|
52679
|
+
de: [
|
|
52680
|
+
"hallo",
|
|
52681
|
+
"wie gehts",
|
|
52682
|
+
"alles gut",
|
|
52683
|
+
"guten morgen"
|
|
52684
|
+
],
|
|
52685
|
+
hi: [
|
|
52686
|
+
"namaste",
|
|
52687
|
+
"kaise ho",
|
|
52688
|
+
"aap kaise hain",
|
|
52689
|
+
"kya haal hai"
|
|
52690
|
+
],
|
|
52691
|
+
te: [
|
|
52692
|
+
"namaskaram",
|
|
52693
|
+
"bagunnava",
|
|
52694
|
+
"em chesthunavu",
|
|
52695
|
+
"ela unnava"
|
|
52696
|
+
],
|
|
52697
|
+
ja: [
|
|
52698
|
+
"konnichiwa",
|
|
52699
|
+
"genki desu ka",
|
|
52700
|
+
"ohayo",
|
|
52701
|
+
"konbanwa"
|
|
52702
|
+
],
|
|
52703
|
+
ar: [
|
|
52704
|
+
"marhaba",
|
|
52705
|
+
"ahlan",
|
|
52706
|
+
"kayfa haluk",
|
|
52707
|
+
"kayf halak"
|
|
52708
|
+
],
|
|
52709
|
+
tr: [
|
|
52710
|
+
"merhaba",
|
|
52711
|
+
"nasilsin",
|
|
52712
|
+
"nasilsiniz",
|
|
52713
|
+
"iyi misin"
|
|
52714
|
+
],
|
|
52715
|
+
ru: [
|
|
52716
|
+
"privet",
|
|
52717
|
+
"kak dela",
|
|
52718
|
+
"zdravstvuy",
|
|
52719
|
+
"dobryy den"
|
|
52720
|
+
]
|
|
52721
|
+
};
|
|
51784
52722
|
var nluSchema = external_exports.object({
|
|
51785
52723
|
enabled: external_exports.boolean().default(false),
|
|
51786
52724
|
// Remote NLU service is optional; Vaayu always has in-process rule NLU.
|
|
@@ -51800,6 +52738,9 @@ var nluSchema = external_exports.object({
|
|
|
51800
52738
|
langDetectMinConfidence: external_exports.number().min(0).max(1).default(0.55),
|
|
51801
52739
|
// Minimum cosine similarity for embedding-based intent classification.
|
|
51802
52740
|
embeddingThreshold: external_exports.number().min(0).max(1).default(0.62),
|
|
52741
|
+
// Locale-indexed short-checkin phrase packs for greeting/check-in fast lane.
|
|
52742
|
+
// Top-10 locales ship by default (en, es, fr, de, hi, te, ja, ar, tr, ru).
|
|
52743
|
+
shortCheckinPacks: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).default(DEFAULT_SHORT_CHECKIN_PACKS),
|
|
51803
52744
|
// GLiNER v2.1 endpoint for language-agnostic NER slot filling.
|
|
51804
52745
|
glinerEndpoint: external_exports.string().default("http://localhost:8501"),
|
|
51805
52746
|
// GLiNER API path (supports FastAPI adapters like /gliner-2).
|
|
@@ -51856,6 +52797,12 @@ var nluSchema = external_exports.object({
|
|
|
51856
52797
|
}).default({});
|
|
51857
52798
|
|
|
51858
52799
|
// packages/config/src/schema-channels.ts
|
|
52800
|
+
var normalizeTringPlatform = (value) => {
|
|
52801
|
+
const normalized = value.trim().toLowerCase();
|
|
52802
|
+
if (normalized === "whispr") return "signal";
|
|
52803
|
+
return normalized;
|
|
52804
|
+
};
|
|
52805
|
+
var tringPlatformSchema = external_exports.string().transform((value) => normalizeTringPlatform(value)).pipe(external_exports.enum(["whatsapp", "telegram", "signal"]));
|
|
51859
52806
|
var telegramSchema = external_exports.object({
|
|
51860
52807
|
enabled: external_exports.boolean().default(false),
|
|
51861
52808
|
botToken: external_exports.string().optional(),
|
|
@@ -51955,11 +52902,24 @@ var imessageSchema = external_exports.object({
|
|
|
51955
52902
|
});
|
|
51956
52903
|
}
|
|
51957
52904
|
}).default({});
|
|
52905
|
+
var tringSchema = external_exports.object({
|
|
52906
|
+
enabled: external_exports.boolean().default(false),
|
|
52907
|
+
daemonUrl: external_exports.string().default("http://localhost:8787"),
|
|
52908
|
+
tringBin: external_exports.string().optional(),
|
|
52909
|
+
platforms: external_exports.array(tringPlatformSchema).default(["whatsapp", "telegram", "signal"]),
|
|
52910
|
+
pollIntervalMs: external_exports.number().int().min(500).max(6e4).default(2e3),
|
|
52911
|
+
autoStartDaemon: external_exports.boolean().default(true),
|
|
52912
|
+
allowedChats: external_exports.array(external_exports.string()).optional(),
|
|
52913
|
+
providerId: external_exports.string().optional(),
|
|
52914
|
+
model: external_exports.string().default("mock-1"),
|
|
52915
|
+
system: external_exports.string().optional()
|
|
52916
|
+
}).default({});
|
|
51958
52917
|
var channelsSchema = external_exports.object({
|
|
51959
52918
|
telegram: telegramSchema,
|
|
51960
52919
|
twitter: twitterSchema,
|
|
51961
52920
|
whatsapp: whatsappSchema,
|
|
51962
|
-
imessage: imessageSchema
|
|
52921
|
+
imessage: imessageSchema,
|
|
52922
|
+
tring: tringSchema
|
|
51963
52923
|
}).default({});
|
|
51964
52924
|
|
|
51965
52925
|
// packages/config/src/schema.ts
|
|
@@ -52152,6 +53112,15 @@ var routingSchema = external_exports.object({
|
|
|
52152
53112
|
reasoning: external_exports.object({
|
|
52153
53113
|
mode: external_exports.enum(["off", "auto", "on"]).default("off"),
|
|
52154
53114
|
modelOverrides: external_exports.record(external_exports.string(), external_exports.string()).default({})
|
|
53115
|
+
}).default({}),
|
|
53116
|
+
policySidecarConfidence: external_exports.object({
|
|
53117
|
+
// Avoid low-confidence deep routing signals from sidecar.
|
|
53118
|
+
minConfidenceForCautious: external_exports.number().min(0).max(1).default(0.7),
|
|
53119
|
+
minConfidenceForDeny: external_exports.number().min(0).max(1).default(0.82),
|
|
53120
|
+
// Keep safe-fast-lane reasonably confident too.
|
|
53121
|
+
minConfidenceForSafeFastLane: external_exports.number().min(0).max(1).default(0.55),
|
|
53122
|
+
// Policy to apply when sidecar confidence is below threshold.
|
|
53123
|
+
downgradePolicy: external_exports.enum(["standard", "safe_fast_lane"]).default("standard")
|
|
52155
53124
|
}).default({})
|
|
52156
53125
|
}).default({});
|
|
52157
53126
|
var mcpServerSchema = external_exports.object({
|
|
@@ -54515,7 +55484,7 @@ var FileStorage = class {
|
|
|
54515
55484
|
import path25 from "node:path";
|
|
54516
55485
|
async function createStorage(options) {
|
|
54517
55486
|
if (options.driver === "sqlite") {
|
|
54518
|
-
const module = await import("./chunks/sqlite-
|
|
55487
|
+
const module = await import("./chunks/sqlite-4N7YH2KK.js");
|
|
54519
55488
|
const sqlitePath = options.sqlitePath ?? path25.join(options.dataDir, "vaayu.db");
|
|
54520
55489
|
return new module.SqliteStorage({ sqlitePath });
|
|
54521
55490
|
}
|
|
@@ -54523,7 +55492,7 @@ async function createStorage(options) {
|
|
|
54523
55492
|
if (!options.postgresUrl) {
|
|
54524
55493
|
throw new Error("Postgres driver requires postgresUrl");
|
|
54525
55494
|
}
|
|
54526
|
-
const module = await import("./chunks/postgres-
|
|
55495
|
+
const module = await import("./chunks/postgres-YLCUNVPQ.js");
|
|
54527
55496
|
return module.PostgresStorage.create({ url: options.postgresUrl });
|
|
54528
55497
|
}
|
|
54529
55498
|
return new FileStorage({ dataDir: options.dataDir });
|
|
@@ -55311,131 +56280,15 @@ var IdempotencyStore = class {
|
|
|
55311
56280
|
}
|
|
55312
56281
|
};
|
|
55313
56282
|
|
|
55314
|
-
// apps/gateway/dist/
|
|
56283
|
+
// apps/gateway/dist/memory/smriti.js
|
|
55315
56284
|
import fs30 from "node:fs";
|
|
55316
56285
|
import path28 from "node:path";
|
|
55317
|
-
function readCacheFile(cachePath, logger) {
|
|
55318
|
-
if (!fs30.existsSync(cachePath))
|
|
55319
|
-
return null;
|
|
55320
|
-
try {
|
|
55321
|
-
const raw = fs30.readFileSync(cachePath, "utf8");
|
|
55322
|
-
if (!raw.trim())
|
|
55323
|
-
return null;
|
|
55324
|
-
const parsed = JSON.parse(raw);
|
|
55325
|
-
if (!parsed || parsed.version !== 1)
|
|
55326
|
-
return null;
|
|
55327
|
-
return parsed;
|
|
55328
|
-
} catch (error) {
|
|
55329
|
-
logger?.warn("provider_model_cache_read_failed", {
|
|
55330
|
-
error: error instanceof Error ? error.message : String(error)
|
|
55331
|
-
});
|
|
55332
|
-
return null;
|
|
55333
|
-
}
|
|
55334
|
-
}
|
|
55335
|
-
function writeCacheFile(cachePath, cache, logger) {
|
|
55336
|
-
try {
|
|
55337
|
-
fs30.mkdirSync(path28.dirname(cachePath), { recursive: true });
|
|
55338
|
-
const providers = {};
|
|
55339
|
-
for (const [providerId, entry] of cache.entries()) {
|
|
55340
|
-
providers[providerId] = entry;
|
|
55341
|
-
}
|
|
55342
|
-
const payload = {
|
|
55343
|
-
version: 1,
|
|
55344
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
55345
|
-
providers
|
|
55346
|
-
};
|
|
55347
|
-
fs30.writeFileSync(cachePath, JSON.stringify(payload, null, 2));
|
|
55348
|
-
} catch (error) {
|
|
55349
|
-
logger?.warn("provider_model_cache_write_failed", {
|
|
55350
|
-
error: error instanceof Error ? error.message : String(error)
|
|
55351
|
-
});
|
|
55352
|
-
}
|
|
55353
|
-
}
|
|
55354
|
-
function createProviderModelCacheStore(params) {
|
|
55355
|
-
const { cachePath, logger } = params;
|
|
55356
|
-
const cache = /* @__PURE__ */ new Map();
|
|
55357
|
-
const existing = readCacheFile(cachePath, logger);
|
|
55358
|
-
if (existing?.providers) {
|
|
55359
|
-
for (const [providerId, entry] of Object.entries(existing.providers)) {
|
|
55360
|
-
cache.set(providerId, entry);
|
|
55361
|
-
}
|
|
55362
|
-
}
|
|
55363
|
-
let pending = null;
|
|
55364
|
-
const flush = () => writeCacheFile(cachePath, cache, logger);
|
|
55365
|
-
const scheduleFlush = () => {
|
|
55366
|
-
if (pending)
|
|
55367
|
-
return;
|
|
55368
|
-
pending = setTimeout(() => {
|
|
55369
|
-
pending = null;
|
|
55370
|
-
flush();
|
|
55371
|
-
}, 500);
|
|
55372
|
-
};
|
|
55373
|
-
return {
|
|
55374
|
-
cache,
|
|
55375
|
-
get: (providerId) => cache.get(providerId),
|
|
55376
|
-
set: (providerId, entry) => {
|
|
55377
|
-
cache.set(providerId, entry);
|
|
55378
|
-
scheduleFlush();
|
|
55379
|
-
},
|
|
55380
|
-
update: (providerId, update) => {
|
|
55381
|
-
const existingEntry = cache.get(providerId);
|
|
55382
|
-
if (!existingEntry)
|
|
55383
|
-
return;
|
|
55384
|
-
cache.set(providerId, { ...existingEntry, ...update });
|
|
55385
|
-
scheduleFlush();
|
|
55386
|
-
},
|
|
55387
|
-
flush
|
|
55388
|
-
};
|
|
55389
|
-
}
|
|
55390
|
-
|
|
55391
|
-
// apps/gateway/dist/models-refresh.js
|
|
55392
|
-
function startModelRefreshLoop(params) {
|
|
55393
|
-
const { enabled, intervalMs, jitterMs, initialDelayMs, providerIds, refreshProvider, logger } = params;
|
|
55394
|
-
if (!enabled || providerIds.length === 0) {
|
|
55395
|
-
return null;
|
|
55396
|
-
}
|
|
55397
|
-
let stopped = false;
|
|
55398
|
-
let timer = null;
|
|
55399
|
-
const nextDelay = () => {
|
|
55400
|
-
const jitter = jitterMs > 0 ? Math.floor(Math.random() * jitterMs) : 0;
|
|
55401
|
-
return intervalMs + jitter;
|
|
55402
|
-
};
|
|
55403
|
-
const runCycle = async () => {
|
|
55404
|
-
if (stopped)
|
|
55405
|
-
return;
|
|
55406
|
-
for (const providerId of providerIds) {
|
|
55407
|
-
if (stopped)
|
|
55408
|
-
return;
|
|
55409
|
-
try {
|
|
55410
|
-
await refreshProvider(providerId);
|
|
55411
|
-
} catch (error) {
|
|
55412
|
-
logger.warn("provider_models_refresh_failed", {
|
|
55413
|
-
providerId,
|
|
55414
|
-
error: error instanceof Error ? error.message : String(error)
|
|
55415
|
-
});
|
|
55416
|
-
}
|
|
55417
|
-
}
|
|
55418
|
-
timer = setTimeout(runCycle, nextDelay());
|
|
55419
|
-
};
|
|
55420
|
-
timer = setTimeout(runCycle, Math.max(0, initialDelayMs ?? intervalMs));
|
|
55421
|
-
return {
|
|
55422
|
-
stop: () => {
|
|
55423
|
-
stopped = true;
|
|
55424
|
-
if (timer)
|
|
55425
|
-
clearTimeout(timer);
|
|
55426
|
-
}
|
|
55427
|
-
};
|
|
55428
|
-
}
|
|
55429
|
-
|
|
55430
|
-
// apps/gateway/dist/memory/smriti.js
|
|
55431
|
-
import fs31 from "node:fs";
|
|
55432
|
-
import path29 from "node:path";
|
|
55433
56286
|
import { randomUUID as randomUUID34 } from "node:crypto";
|
|
55434
|
-
import { spawn as
|
|
56287
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
55435
56288
|
var _chitraguptaMemory = null;
|
|
55436
56289
|
async function getChitraguptaMemory() {
|
|
55437
56290
|
if (!_chitraguptaMemory) {
|
|
55438
|
-
_chitraguptaMemory = await import("./chunks/dist-
|
|
56291
|
+
_chitraguptaMemory = await import("./chunks/dist-ESCM3CP5.js");
|
|
55439
56292
|
}
|
|
55440
56293
|
return _chitraguptaMemory;
|
|
55441
56294
|
}
|
|
@@ -55473,7 +56326,7 @@ function computeRetryDelayMs(retries) {
|
|
|
55473
56326
|
function createSmritiHelpers(deps) {
|
|
55474
56327
|
const { logger, getProfile, memoryAllowed, markdownMemory, smritiClient, smritiSource, smritiAutoCapture, smritiAutoCaptureMode, smritiDefaultTags, smritiBaseUrl, smritiApiKey, smritiPrefix, smritiOwner, smritiTimeoutMs, smritiAutoMemoryReady, smritiAutoMemoryPython, smritiAutoMemorySessionScript, smritiAutoMemoryPromptScript, storageRoot, repoRoot } = deps;
|
|
55475
56328
|
const smritiState = {};
|
|
55476
|
-
const outboxPath2 =
|
|
56329
|
+
const outboxPath2 = path28.join(storageRoot ?? repoRoot, OUTBOX_FILE);
|
|
55477
56330
|
let outboxLoaded = false;
|
|
55478
56331
|
let outboxEntries2 = [];
|
|
55479
56332
|
let outboxOps = Promise.resolve();
|
|
@@ -55488,7 +56341,7 @@ function createSmritiHelpers(deps) {
|
|
|
55488
56341
|
if (outboxLoaded)
|
|
55489
56342
|
return;
|
|
55490
56343
|
try {
|
|
55491
|
-
const raw = await
|
|
56344
|
+
const raw = await fs30.promises.readFile(outboxPath2, "utf8");
|
|
55492
56345
|
const parsed = JSON.parse(raw);
|
|
55493
56346
|
outboxEntries2 = Array.isArray(parsed) ? parsed.filter(isSmritiOutboxEntry) : [];
|
|
55494
56347
|
} catch {
|
|
@@ -55497,12 +56350,12 @@ function createSmritiHelpers(deps) {
|
|
|
55497
56350
|
outboxLoaded = true;
|
|
55498
56351
|
}
|
|
55499
56352
|
async function persistOutboxUnsafe() {
|
|
55500
|
-
const dir =
|
|
55501
|
-
await
|
|
56353
|
+
const dir = path28.dirname(outboxPath2);
|
|
56354
|
+
await fs30.promises.mkdir(dir, { recursive: true });
|
|
55502
56355
|
const tempPath = `${outboxPath2}.tmp`;
|
|
55503
|
-
await
|
|
56356
|
+
await fs30.promises.writeFile(tempPath, `${JSON.stringify(outboxEntries2, null, 2)}
|
|
55504
56357
|
`, "utf8");
|
|
55505
|
-
await
|
|
56358
|
+
await fs30.promises.rename(tempPath, outboxPath2);
|
|
55506
56359
|
}
|
|
55507
56360
|
function shouldSkipDailyTranscriptWrite() {
|
|
55508
56361
|
return isSmritiMemoryEnabled() && isSmritiWriteThroughEnabled();
|
|
@@ -55767,11 +56620,11 @@ function createSmritiHelpers(deps) {
|
|
|
55767
56620
|
if (!smritiAutoMemoryReady)
|
|
55768
56621
|
return null;
|
|
55769
56622
|
const scriptPath = params.kind === "session" ? smritiAutoMemorySessionScript : smritiAutoMemoryPromptScript;
|
|
55770
|
-
if (!
|
|
56623
|
+
if (!fs30.existsSync(scriptPath))
|
|
55771
56624
|
return null;
|
|
55772
56625
|
const env = buildSmritiAutoMemoryEnv({ userId: params.userId });
|
|
55773
|
-
return await new Promise((
|
|
55774
|
-
const child =
|
|
56626
|
+
return await new Promise((resolve3) => {
|
|
56627
|
+
const child = spawn5(smritiAutoMemoryPython, [scriptPath], {
|
|
55775
56628
|
env,
|
|
55776
56629
|
stdio: ["pipe", "pipe", "pipe"]
|
|
55777
56630
|
});
|
|
@@ -55779,7 +56632,7 @@ function createSmritiHelpers(deps) {
|
|
|
55779
56632
|
let stderr = "";
|
|
55780
56633
|
const timeout = setTimeout(() => {
|
|
55781
56634
|
child.kill("SIGKILL");
|
|
55782
|
-
|
|
56635
|
+
resolve3(null);
|
|
55783
56636
|
}, 15e3);
|
|
55784
56637
|
child.stdout.on("data", (chunk) => {
|
|
55785
56638
|
stdout += chunk.toString();
|
|
@@ -55793,7 +56646,7 @@ function createSmritiHelpers(deps) {
|
|
|
55793
56646
|
kind: params.kind,
|
|
55794
56647
|
error: error.message
|
|
55795
56648
|
});
|
|
55796
|
-
|
|
56649
|
+
resolve3(null);
|
|
55797
56650
|
});
|
|
55798
56651
|
child.on("close", () => {
|
|
55799
56652
|
clearTimeout(timeout);
|
|
@@ -55805,17 +56658,17 @@ function createSmritiHelpers(deps) {
|
|
|
55805
56658
|
}
|
|
55806
56659
|
const trimmed = stdout.trim();
|
|
55807
56660
|
if (!trimmed)
|
|
55808
|
-
return
|
|
56661
|
+
return resolve3(null);
|
|
55809
56662
|
try {
|
|
55810
56663
|
const parsed = JSON.parse(trimmed);
|
|
55811
56664
|
const message = typeof parsed.systemMessage === "string" ? parsed.systemMessage.trim() : "";
|
|
55812
|
-
|
|
56665
|
+
resolve3(message || null);
|
|
55813
56666
|
} catch (error) {
|
|
55814
56667
|
logger.warn("smriti_auto_memory_parse_failed", {
|
|
55815
56668
|
kind: params.kind,
|
|
55816
56669
|
error: error instanceof Error ? error.message : String(error)
|
|
55817
56670
|
});
|
|
55818
|
-
|
|
56671
|
+
resolve3(null);
|
|
55819
56672
|
}
|
|
55820
56673
|
});
|
|
55821
56674
|
if (params.input)
|
|
@@ -55866,6 +56719,122 @@ function createSmritiHelpers(deps) {
|
|
|
55866
56719
|
};
|
|
55867
56720
|
}
|
|
55868
56721
|
|
|
56722
|
+
// apps/gateway/dist/models-cache.js
|
|
56723
|
+
import fs31 from "node:fs";
|
|
56724
|
+
import path29 from "node:path";
|
|
56725
|
+
function readCacheFile(cachePath, logger) {
|
|
56726
|
+
if (!fs31.existsSync(cachePath))
|
|
56727
|
+
return null;
|
|
56728
|
+
try {
|
|
56729
|
+
const raw = fs31.readFileSync(cachePath, "utf8");
|
|
56730
|
+
if (!raw.trim())
|
|
56731
|
+
return null;
|
|
56732
|
+
const parsed = JSON.parse(raw);
|
|
56733
|
+
if (!parsed || parsed.version !== 1)
|
|
56734
|
+
return null;
|
|
56735
|
+
return parsed;
|
|
56736
|
+
} catch (error) {
|
|
56737
|
+
logger?.warn("provider_model_cache_read_failed", {
|
|
56738
|
+
error: error instanceof Error ? error.message : String(error)
|
|
56739
|
+
});
|
|
56740
|
+
return null;
|
|
56741
|
+
}
|
|
56742
|
+
}
|
|
56743
|
+
function writeCacheFile(cachePath, cache, logger) {
|
|
56744
|
+
try {
|
|
56745
|
+
fs31.mkdirSync(path29.dirname(cachePath), { recursive: true });
|
|
56746
|
+
const providers = {};
|
|
56747
|
+
for (const [providerId, entry] of cache.entries()) {
|
|
56748
|
+
providers[providerId] = entry;
|
|
56749
|
+
}
|
|
56750
|
+
const payload = {
|
|
56751
|
+
version: 1,
|
|
56752
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
56753
|
+
providers
|
|
56754
|
+
};
|
|
56755
|
+
fs31.writeFileSync(cachePath, JSON.stringify(payload, null, 2));
|
|
56756
|
+
} catch (error) {
|
|
56757
|
+
logger?.warn("provider_model_cache_write_failed", {
|
|
56758
|
+
error: error instanceof Error ? error.message : String(error)
|
|
56759
|
+
});
|
|
56760
|
+
}
|
|
56761
|
+
}
|
|
56762
|
+
function createProviderModelCacheStore(params) {
|
|
56763
|
+
const { cachePath, logger } = params;
|
|
56764
|
+
const cache = /* @__PURE__ */ new Map();
|
|
56765
|
+
const existing = readCacheFile(cachePath, logger);
|
|
56766
|
+
if (existing?.providers) {
|
|
56767
|
+
for (const [providerId, entry] of Object.entries(existing.providers)) {
|
|
56768
|
+
cache.set(providerId, entry);
|
|
56769
|
+
}
|
|
56770
|
+
}
|
|
56771
|
+
let pending = null;
|
|
56772
|
+
const flush = () => writeCacheFile(cachePath, cache, logger);
|
|
56773
|
+
const scheduleFlush = () => {
|
|
56774
|
+
if (pending)
|
|
56775
|
+
return;
|
|
56776
|
+
pending = setTimeout(() => {
|
|
56777
|
+
pending = null;
|
|
56778
|
+
flush();
|
|
56779
|
+
}, 500);
|
|
56780
|
+
};
|
|
56781
|
+
return {
|
|
56782
|
+
cache,
|
|
56783
|
+
get: (providerId) => cache.get(providerId),
|
|
56784
|
+
set: (providerId, entry) => {
|
|
56785
|
+
cache.set(providerId, entry);
|
|
56786
|
+
scheduleFlush();
|
|
56787
|
+
},
|
|
56788
|
+
update: (providerId, update) => {
|
|
56789
|
+
const existingEntry = cache.get(providerId);
|
|
56790
|
+
if (!existingEntry)
|
|
56791
|
+
return;
|
|
56792
|
+
cache.set(providerId, { ...existingEntry, ...update });
|
|
56793
|
+
scheduleFlush();
|
|
56794
|
+
},
|
|
56795
|
+
flush
|
|
56796
|
+
};
|
|
56797
|
+
}
|
|
56798
|
+
|
|
56799
|
+
// apps/gateway/dist/models-refresh.js
|
|
56800
|
+
function startModelRefreshLoop(params) {
|
|
56801
|
+
const { enabled, intervalMs, jitterMs, initialDelayMs, providerIds, refreshProvider, logger } = params;
|
|
56802
|
+
if (!enabled || providerIds.length === 0) {
|
|
56803
|
+
return null;
|
|
56804
|
+
}
|
|
56805
|
+
let stopped = false;
|
|
56806
|
+
let timer = null;
|
|
56807
|
+
const nextDelay = () => {
|
|
56808
|
+
const jitter = jitterMs > 0 ? Math.floor(Math.random() * jitterMs) : 0;
|
|
56809
|
+
return intervalMs + jitter;
|
|
56810
|
+
};
|
|
56811
|
+
const runCycle = async () => {
|
|
56812
|
+
if (stopped)
|
|
56813
|
+
return;
|
|
56814
|
+
for (const providerId of providerIds) {
|
|
56815
|
+
if (stopped)
|
|
56816
|
+
return;
|
|
56817
|
+
try {
|
|
56818
|
+
await refreshProvider(providerId);
|
|
56819
|
+
} catch (error) {
|
|
56820
|
+
logger.warn("provider_models_refresh_failed", {
|
|
56821
|
+
providerId,
|
|
56822
|
+
error: error instanceof Error ? error.message : String(error)
|
|
56823
|
+
});
|
|
56824
|
+
}
|
|
56825
|
+
}
|
|
56826
|
+
timer = setTimeout(runCycle, nextDelay());
|
|
56827
|
+
};
|
|
56828
|
+
timer = setTimeout(runCycle, Math.max(0, initialDelayMs ?? intervalMs));
|
|
56829
|
+
return {
|
|
56830
|
+
stop: () => {
|
|
56831
|
+
stopped = true;
|
|
56832
|
+
if (timer)
|
|
56833
|
+
clearTimeout(timer);
|
|
56834
|
+
}
|
|
56835
|
+
};
|
|
56836
|
+
}
|
|
56837
|
+
|
|
55869
56838
|
// apps/gateway/dist/runtime/memory-markdown.js
|
|
55870
56839
|
import fs32 from "node:fs";
|
|
55871
56840
|
import path30 from "node:path";
|
|
@@ -55910,65 +56879,259 @@ function createMarkdownMemoryWriter(params) {
|
|
|
55910
56879
|
return { enabled, dailyDir, longTermPath, appendDaily, appendLongTerm };
|
|
55911
56880
|
}
|
|
55912
56881
|
|
|
55913
|
-
// apps/gateway/dist/gateway/
|
|
55914
|
-
|
|
55915
|
-
|
|
55916
|
-
}
|
|
55917
|
-
|
|
55918
|
-
|
|
55919
|
-
|
|
55920
|
-
|
|
55921
|
-
|
|
55922
|
-
|
|
55923
|
-
|
|
56882
|
+
// apps/gateway/dist/gateway/config-path.js
|
|
56883
|
+
import fs33 from "node:fs";
|
|
56884
|
+
import path31 from "node:path";
|
|
56885
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
56886
|
+
var GATEWAY_CONFIG_FILENAMES = [
|
|
56887
|
+
"vaayu.config.json",
|
|
56888
|
+
"vaayu.config.yaml",
|
|
56889
|
+
"vaayu.config.yml"
|
|
56890
|
+
];
|
|
56891
|
+
function resolvePreferredGatewayConfigPath(params) {
|
|
56892
|
+
const envConfigPath = params?.envConfigPath ?? process.env.VAAYU_CONFIG;
|
|
56893
|
+
if (envConfigPath?.trim()) {
|
|
56894
|
+
return void 0;
|
|
56895
|
+
}
|
|
56896
|
+
const existsSync5 = params?.existsSync ?? fs33.existsSync;
|
|
56897
|
+
const moduleFilePath = params?.moduleFilePath ?? fileURLToPath2(import.meta.url);
|
|
56898
|
+
let currentDir = path31.dirname(moduleFilePath);
|
|
56899
|
+
for (let depth = 0; depth < 10; depth += 1) {
|
|
56900
|
+
for (const filename of GATEWAY_CONFIG_FILENAMES) {
|
|
56901
|
+
const candidate = path31.join(currentDir, filename);
|
|
56902
|
+
if (existsSync5(candidate)) {
|
|
56903
|
+
return candidate;
|
|
55924
56904
|
}
|
|
55925
|
-
|
|
56905
|
+
}
|
|
56906
|
+
const parent = path31.dirname(currentDir);
|
|
56907
|
+
if (parent === currentDir)
|
|
56908
|
+
break;
|
|
56909
|
+
currentDir = parent;
|
|
56910
|
+
}
|
|
56911
|
+
return void 0;
|
|
56912
|
+
}
|
|
56913
|
+
|
|
56914
|
+
// apps/gateway/dist/gateway/identity-loader.js
|
|
56915
|
+
import fs34 from "node:fs";
|
|
56916
|
+
import path32 from "node:path";
|
|
56917
|
+
var MAX_PROMPT_CHARS_DEFAULT = 12e3;
|
|
56918
|
+
function uniqueStrings(values) {
|
|
56919
|
+
const seen = /* @__PURE__ */ new Set();
|
|
56920
|
+
const out = [];
|
|
56921
|
+
for (const value of values) {
|
|
56922
|
+
if (!value)
|
|
56923
|
+
continue;
|
|
56924
|
+
if (seen.has(value))
|
|
56925
|
+
continue;
|
|
56926
|
+
seen.add(value);
|
|
56927
|
+
out.push(value);
|
|
56928
|
+
}
|
|
56929
|
+
return out;
|
|
56930
|
+
}
|
|
56931
|
+
function buildCandidateRoots(repoRoot) {
|
|
56932
|
+
const roots = [repoRoot];
|
|
56933
|
+
let current = repoRoot;
|
|
56934
|
+
for (let i = 0; i < 3; i += 1) {
|
|
56935
|
+
const parent = path32.dirname(current);
|
|
56936
|
+
if (!parent || parent === current)
|
|
56937
|
+
break;
|
|
56938
|
+
roots.push(parent);
|
|
56939
|
+
current = parent;
|
|
56940
|
+
}
|
|
56941
|
+
return uniqueStrings(roots);
|
|
56942
|
+
}
|
|
56943
|
+
function readFirstExisting(roots, filenames) {
|
|
56944
|
+
for (const root of roots) {
|
|
56945
|
+
for (const name of filenames) {
|
|
56946
|
+
const candidate = path32.join(root, name);
|
|
55926
56947
|
try {
|
|
55927
|
-
|
|
55928
|
-
|
|
55929
|
-
|
|
55930
|
-
|
|
55931
|
-
|
|
55932
|
-
|
|
55933
|
-
|
|
55934
|
-
|
|
56948
|
+
if (!fs34.existsSync(candidate))
|
|
56949
|
+
continue;
|
|
56950
|
+
const text = fs34.readFileSync(candidate, "utf8").trim();
|
|
56951
|
+
if (!text)
|
|
56952
|
+
continue;
|
|
56953
|
+
return { file: candidate, text };
|
|
56954
|
+
} catch {
|
|
56955
|
+
}
|
|
56956
|
+
}
|
|
56957
|
+
}
|
|
56958
|
+
return null;
|
|
56959
|
+
}
|
|
56960
|
+
function extractIdentityFields(identity, user) {
|
|
56961
|
+
const fields = {};
|
|
56962
|
+
if (identity) {
|
|
56963
|
+
const nameMatch = identity.match(/(?:^|\n)\s*(?:-\s*)?(?:\*\*)?Name(?:\*\*)?:\s*(?:\*\*)?(.+?)(?:\*\*)?$/im);
|
|
56964
|
+
if (nameMatch?.[1]) {
|
|
56965
|
+
const raw = nameMatch[1].trim().replace(/^_\(?|_?\)?$/g, "");
|
|
56966
|
+
if (raw && !raw.startsWith("(") && raw.length < 64) {
|
|
56967
|
+
fields.assistantName = raw;
|
|
56968
|
+
}
|
|
56969
|
+
}
|
|
56970
|
+
const emojiMatch = identity.match(/(?:^|\n)\s*(?:-\s*)?(?:\*\*)?Emoji(?:\*\*)?:\s*(?:\*\*)?(.+?)(?:\*\*)?$/im);
|
|
56971
|
+
if (emojiMatch?.[1]) {
|
|
56972
|
+
const raw = emojiMatch[1].trim().replace(/^_\(?|_?\)?$/g, "");
|
|
56973
|
+
if (raw && !raw.startsWith("(") && raw.length < 8) {
|
|
56974
|
+
fields.emoji = raw;
|
|
56975
|
+
}
|
|
56976
|
+
}
|
|
56977
|
+
}
|
|
56978
|
+
if (user) {
|
|
56979
|
+
if (!fields.userName) {
|
|
56980
|
+
const callMatch = user.match(/(?:^|\n)\s*(?:What to call them|Call them|User name|userName):\s*(.+?)$/im);
|
|
56981
|
+
if (callMatch?.[1]) {
|
|
56982
|
+
const raw = callMatch[1].trim().split(/\s*[/,]\s*/)[0];
|
|
56983
|
+
if (raw && raw.length < 64) {
|
|
56984
|
+
fields.userName = raw;
|
|
56985
|
+
}
|
|
56986
|
+
}
|
|
56987
|
+
}
|
|
56988
|
+
if (!fields.assistantName) {
|
|
56989
|
+
const assistantCallMatch = user.match(/(?:^|\n)\s*(?:What to call assistant|Assistant name|assistantName):\s*(.+?)$/im);
|
|
56990
|
+
if (assistantCallMatch?.[1]) {
|
|
56991
|
+
const raw = assistantCallMatch[1].trim();
|
|
56992
|
+
if (raw && raw.length < 64) {
|
|
56993
|
+
fields.assistantName = raw;
|
|
56994
|
+
}
|
|
56995
|
+
}
|
|
56996
|
+
}
|
|
56997
|
+
}
|
|
56998
|
+
return fields;
|
|
56999
|
+
}
|
|
57000
|
+
function truncatePrompt(text, maxChars) {
|
|
57001
|
+
if (text.length <= maxChars)
|
|
57002
|
+
return text;
|
|
57003
|
+
return `${text.slice(0, maxChars)}
|
|
57004
|
+
|
|
57005
|
+
[...identity truncated]`;
|
|
57006
|
+
}
|
|
57007
|
+
function loadWorkspaceIdentityPrompt(params) {
|
|
57008
|
+
const roots = buildCandidateRoots(params.repoRoot);
|
|
57009
|
+
const maxChars = params.maxPromptChars ?? MAX_PROMPT_CHARS_DEFAULT;
|
|
57010
|
+
const filesLoaded = [];
|
|
57011
|
+
const parts = [];
|
|
57012
|
+
const soul = readFirstExisting(roots, ["SOUL.md", "soul.md"]);
|
|
57013
|
+
if (soul) {
|
|
57014
|
+
filesLoaded.push(soul.file);
|
|
57015
|
+
parts.push(soul.text);
|
|
57016
|
+
}
|
|
57017
|
+
const identity = readFirstExisting(roots, ["IDENTITY.md", "identity.md"]);
|
|
57018
|
+
if (identity) {
|
|
57019
|
+
filesLoaded.push(identity.file);
|
|
57020
|
+
parts.push(identity.text);
|
|
57021
|
+
}
|
|
57022
|
+
const personality = readFirstExisting(roots, ["PERSONALITY.md", "personality.md"]);
|
|
57023
|
+
if (personality) {
|
|
57024
|
+
filesLoaded.push(personality.file);
|
|
57025
|
+
parts.push(personality.text);
|
|
57026
|
+
}
|
|
57027
|
+
const user = readFirstExisting(roots, ["USER.md", "user.md"]);
|
|
57028
|
+
if (user) {
|
|
57029
|
+
filesLoaded.push(user.file);
|
|
57030
|
+
parts.push(user.text);
|
|
57031
|
+
}
|
|
57032
|
+
const fields = extractIdentityFields(identity?.text, user?.text);
|
|
57033
|
+
const prompt = truncatePrompt(parts.filter(Boolean).join("\n\n"), maxChars).trim();
|
|
57034
|
+
return { prompt, rootsChecked: roots, filesLoaded, fields };
|
|
57035
|
+
}
|
|
57036
|
+
function reloadIdentity(params) {
|
|
57037
|
+
return loadWorkspaceIdentityPrompt(params);
|
|
57038
|
+
}
|
|
57039
|
+
|
|
57040
|
+
// apps/gateway/dist/gateway/setup-smriti.js
|
|
57041
|
+
import fs35 from "node:fs";
|
|
57042
|
+
import path33 from "node:path";
|
|
57043
|
+
function resolveSmritiRuntimeConfig(params) {
|
|
57044
|
+
const { config, repoRoot, logger } = params;
|
|
57045
|
+
const smritiConfig = config.smriti ?? {};
|
|
57046
|
+
const smritiEnabled = smritiConfig.enabled ?? false;
|
|
57047
|
+
const smritiBaseUrl = smritiConfig.baseUrl ?? "http://127.0.0.1:7788";
|
|
57048
|
+
const smritiConfigPath = process.env.SMRITI_CONFIG_PATH ?? path33.resolve(repoRoot, "smriti", "smriti.config.json");
|
|
57049
|
+
let smritiLocalConfig = null;
|
|
57050
|
+
if (smritiEnabled && smritiBaseUrl && fs35.existsSync(smritiConfigPath)) {
|
|
57051
|
+
try {
|
|
57052
|
+
const raw = fs35.readFileSync(smritiConfigPath, "utf8");
|
|
57053
|
+
smritiLocalConfig = JSON.parse(raw);
|
|
57054
|
+
} catch (error) {
|
|
57055
|
+
logger.warn("smriti_config_load_failed", {
|
|
57056
|
+
error: error instanceof Error ? error.message : String(error)
|
|
57057
|
+
});
|
|
57058
|
+
}
|
|
57059
|
+
}
|
|
57060
|
+
let smritiApiKey = smritiConfig.apiKey;
|
|
57061
|
+
if (!smritiApiKey && smritiEnabled && smritiBaseUrl) {
|
|
57062
|
+
try {
|
|
57063
|
+
const parsed = new URL(smritiBaseUrl);
|
|
57064
|
+
if (isLoopbackHost(parsed.hostname)) {
|
|
57065
|
+
const storageRoot = smritiLocalConfig?.storage?.root;
|
|
57066
|
+
if (storageRoot) {
|
|
57067
|
+
const baseDir = path33.dirname(smritiConfigPath);
|
|
57068
|
+
const resolvedStorage = path33.isAbsolute(storageRoot) ? storageRoot : path33.resolve(baseDir, storageRoot);
|
|
57069
|
+
const keyPath = path33.join(resolvedStorage, "keys", "master.key");
|
|
57070
|
+
if (fs35.existsSync(keyPath)) {
|
|
57071
|
+
const key = fs35.readFileSync(keyPath, "utf8").trim();
|
|
57072
|
+
if (key) {
|
|
57073
|
+
smritiApiKey = key;
|
|
57074
|
+
logger.info("smriti_master_key_loaded", { path: keyPath });
|
|
57075
|
+
}
|
|
55935
57076
|
}
|
|
55936
|
-
|
|
55937
|
-
const requestMeta = buildChatMeta({
|
|
55938
|
-
purpose: "summary",
|
|
55939
|
-
providerId: provider.id,
|
|
55940
|
-
model,
|
|
55941
|
-
normalization: buildNormalizationOutboundMeta(normalizeIncomingText(buildOutboundPromptText4(messages)))
|
|
55942
|
-
});
|
|
55943
|
-
const response = await chatWithPolicy({
|
|
55944
|
-
provider,
|
|
55945
|
-
request: buildChatRequest({
|
|
55946
|
-
model,
|
|
55947
|
-
messages,
|
|
55948
|
-
temperature: 0.3,
|
|
55949
|
-
maxTokens: 1024,
|
|
55950
|
-
metadata: requestMeta
|
|
55951
|
-
}),
|
|
55952
|
-
logger,
|
|
55953
|
-
meta: requestMeta
|
|
55954
|
-
});
|
|
55955
|
-
logger?.info("summary_llm_generated", {
|
|
55956
|
-
provider: provider.id,
|
|
55957
|
-
model,
|
|
55958
|
-
inputLength: prompt.length,
|
|
55959
|
-
outputLength: response.content.length
|
|
55960
|
-
});
|
|
55961
|
-
return response.content;
|
|
55962
|
-
} catch (error) {
|
|
55963
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
55964
|
-
logger?.error("summary_llm_error", {
|
|
55965
|
-
error: message,
|
|
55966
|
-
provider: provider.id,
|
|
55967
|
-
model
|
|
55968
|
-
});
|
|
55969
|
-
throw error;
|
|
57077
|
+
}
|
|
55970
57078
|
}
|
|
57079
|
+
} catch (error) {
|
|
57080
|
+
logger.warn("smriti_master_key_load_failed", {
|
|
57081
|
+
error: error instanceof Error ? error.message : String(error)
|
|
57082
|
+
});
|
|
55971
57083
|
}
|
|
57084
|
+
}
|
|
57085
|
+
const smritiPrefix = smritiConfig.prefix;
|
|
57086
|
+
const smritiOwner = smritiConfig.owner;
|
|
57087
|
+
const smritiAutoCapture = smritiConfig.autoCapture ?? false;
|
|
57088
|
+
const smritiAutoCaptureMode = smritiConfig.autoCaptureMode ?? "exchange";
|
|
57089
|
+
const smritiRetrieveEnabled = smritiConfig.retrieveEnabled ?? false;
|
|
57090
|
+
const smritiRetrieveLimit = smritiConfig.retrieveLimit ?? 5;
|
|
57091
|
+
const smritiDefaultTags = smritiConfig.defaultTags ?? void 0;
|
|
57092
|
+
const smritiSource = smritiConfig.source;
|
|
57093
|
+
const smritiAutoMemoryEnabled = smritiConfig.autoMemoryEnabled ?? false;
|
|
57094
|
+
const smritiAutoMemoryPython = smritiConfig.autoMemoryPython ?? "python3";
|
|
57095
|
+
const smritiAutoMemoryFallbackRoot = path33.resolve(repoRoot, "skills-core", "smriti-auto-memory", "hooks", "scripts");
|
|
57096
|
+
const smritiAutoMemoryRootCandidates = [
|
|
57097
|
+
smritiAutoMemoryFallbackRoot,
|
|
57098
|
+
path33.resolve(repoRoot, "..", "ecosystem", "skills", "smriti-auto-memory", "hooks", "scripts"),
|
|
57099
|
+
path33.resolve(repoRoot, "skills", "smriti-auto-memory", "hooks", "scripts")
|
|
57100
|
+
];
|
|
57101
|
+
const smritiAutoMemoryDefaultRoot = smritiAutoMemoryRootCandidates.find((candidate) => fs35.existsSync(candidate)) ?? smritiAutoMemoryFallbackRoot;
|
|
57102
|
+
const smritiAutoMemoryRoot = smritiConfig.autoMemoryPath ?? smritiAutoMemoryDefaultRoot;
|
|
57103
|
+
const smritiAutoMemorySessionScript = path33.join(smritiAutoMemoryRoot, "session-start.py");
|
|
57104
|
+
const smritiAutoMemoryPromptScript = path33.join(smritiAutoMemoryRoot, "user-prompt.py");
|
|
57105
|
+
const smritiAutoMemoryReady = smritiEnabled && smritiAutoMemoryEnabled && Boolean(smritiApiKey) && fs35.existsSync(smritiAutoMemorySessionScript) && fs35.existsSync(smritiAutoMemoryPromptScript);
|
|
57106
|
+
const smritiClientOptions = smritiEnabled && smritiBaseUrl ? {
|
|
57107
|
+
baseUrl: smritiBaseUrl,
|
|
57108
|
+
apiKey: smritiApiKey,
|
|
57109
|
+
timeoutMs: smritiConfig.timeoutMs,
|
|
57110
|
+
prefix: smritiPrefix ? smritiPrefix.replace(/\/$/, "") : smritiOwner ? `user/${normalizeSmritiOwner(smritiOwner)}` : void 0
|
|
57111
|
+
} : void 0;
|
|
57112
|
+
return {
|
|
57113
|
+
smritiConfig,
|
|
57114
|
+
smritiEnabled,
|
|
57115
|
+
smritiBaseUrl,
|
|
57116
|
+
smritiApiKey,
|
|
57117
|
+
smritiPrefix,
|
|
57118
|
+
smritiOwner,
|
|
57119
|
+
smritiAutoCapture,
|
|
57120
|
+
smritiAutoCaptureMode,
|
|
57121
|
+
smritiRetrieveEnabled,
|
|
57122
|
+
smritiRetrieveLimit,
|
|
57123
|
+
smritiDefaultTags,
|
|
57124
|
+
smritiSource,
|
|
57125
|
+
smritiAutoMemoryEnabled,
|
|
57126
|
+
smritiAutoMemoryPython,
|
|
57127
|
+
smritiAutoMemoryRoot,
|
|
57128
|
+
smritiAutoMemorySessionScript,
|
|
57129
|
+
smritiAutoMemoryPromptScript,
|
|
57130
|
+
smritiAutoMemoryReady,
|
|
57131
|
+
smritiClientOptions,
|
|
57132
|
+
smritiVectorProvider: smritiLocalConfig?.vector?.provider,
|
|
57133
|
+
smritiVectorFallbacks: smritiLocalConfig?.vector?.fallbackProviders,
|
|
57134
|
+
smritiEmbeddingProviders: smritiLocalConfig?.embeddings?.providerPriority
|
|
55972
57135
|
};
|
|
55973
57136
|
}
|
|
55974
57137
|
|
|
@@ -56028,8 +57191,8 @@ function cleanupPairings(pairingStore, channelPairingStore) {
|
|
|
56028
57191
|
}
|
|
56029
57192
|
|
|
56030
57193
|
// apps/gateway/dist/gateway/tool-registry.js
|
|
56031
|
-
import
|
|
56032
|
-
import
|
|
57194
|
+
import path34 from "node:path";
|
|
57195
|
+
import fs36 from "node:fs";
|
|
56033
57196
|
|
|
56034
57197
|
// apps/gateway/dist/gateway/smriti-status.js
|
|
56035
57198
|
async function buildSmritiStatus(params) {
|
|
@@ -56269,13 +57432,13 @@ async function setupToolRegistry(params) {
|
|
|
56269
57432
|
});
|
|
56270
57433
|
const autoMcpServers = [];
|
|
56271
57434
|
if (gwEnv.holoCube.enabled && gwEnv.holoCube.bridgeUrl) {
|
|
56272
|
-
const defaultHoloManifestPath =
|
|
57435
|
+
const defaultHoloManifestPath = path34.resolve(repoRoot, "..", "ecosystem", "skills", "holo-cube", "server", "mcp.manifest.json");
|
|
56273
57436
|
const holoManifestCandidates = [
|
|
56274
57437
|
defaultHoloManifestPath,
|
|
56275
|
-
|
|
56276
|
-
|
|
57438
|
+
path34.resolve(repoRoot, "skills-core", "holo-cube", "server", "mcp.manifest.json"),
|
|
57439
|
+
path34.resolve(repoRoot, "skills", "holo-cube", "server", "mcp.manifest.json")
|
|
56277
57440
|
];
|
|
56278
|
-
const holoManifestPath = holoManifestCandidates.find((candidate) =>
|
|
57441
|
+
const holoManifestPath = holoManifestCandidates.find((candidate) => fs36.existsSync(candidate)) ?? defaultHoloManifestPath;
|
|
56279
57442
|
autoMcpServers.push({
|
|
56280
57443
|
id: "holocube",
|
|
56281
57444
|
command: "node",
|
|
@@ -56302,23 +57465,23 @@ async function setupToolRegistry(params) {
|
|
|
56302
57465
|
}
|
|
56303
57466
|
|
|
56304
57467
|
// apps/gateway/dist/gateway/tool-policy.js
|
|
56305
|
-
import
|
|
56306
|
-
import
|
|
57468
|
+
import fs37 from "node:fs";
|
|
57469
|
+
import path35 from "node:path";
|
|
56307
57470
|
function createToolPolicyLoader(logger) {
|
|
56308
57471
|
return (customPath, baseDir) => {
|
|
56309
57472
|
const cwd = baseDir ?? process.cwd();
|
|
56310
|
-
const fallbackPolicyPath =
|
|
57473
|
+
const fallbackPolicyPath = path35.resolve(cwd, "skills-core", "skills.config.json");
|
|
56311
57474
|
const defaultCandidates = [
|
|
56312
57475
|
fallbackPolicyPath,
|
|
56313
|
-
|
|
57476
|
+
path35.resolve(cwd, "skills", "skills.config.json")
|
|
56314
57477
|
];
|
|
56315
57478
|
const configuredBase = customPath ?? process.env.VAAYU_SKILLS_CONFIG;
|
|
56316
|
-
const firstExisting = defaultCandidates.find((candidate) =>
|
|
56317
|
-
const policyPath = configuredBase ?
|
|
56318
|
-
if (!
|
|
57479
|
+
const firstExisting = defaultCandidates.find((candidate) => fs37.existsSync(candidate));
|
|
57480
|
+
const policyPath = configuredBase ? path35.isAbsolute(configuredBase) ? configuredBase : path35.resolve(cwd, configuredBase) : firstExisting ?? fallbackPolicyPath;
|
|
57481
|
+
if (!fs37.existsSync(policyPath))
|
|
56319
57482
|
return void 0;
|
|
56320
57483
|
try {
|
|
56321
|
-
const raw =
|
|
57484
|
+
const raw = fs37.readFileSync(policyPath, "utf8");
|
|
56322
57485
|
const parsed = JSON.parse(raw);
|
|
56323
57486
|
return {
|
|
56324
57487
|
allow: Array.isArray(parsed.allow) ? parsed.allow : [],
|
|
@@ -57150,8 +58313,8 @@ function createWeatherDefaultsUpdater(params) {
|
|
|
57150
58313
|
}
|
|
57151
58314
|
|
|
57152
58315
|
// apps/gateway/dist/skills.js
|
|
57153
|
-
import
|
|
57154
|
-
import
|
|
58316
|
+
import fs38 from "node:fs";
|
|
58317
|
+
import path36 from "node:path";
|
|
57155
58318
|
var SKILL_PACK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
57156
58319
|
"assets",
|
|
57157
58320
|
"resources",
|
|
@@ -57165,17 +58328,17 @@ var SKILL_PACK_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
57165
58328
|
".tmp"
|
|
57166
58329
|
]);
|
|
57167
58330
|
function isSkillPackDir(dir) {
|
|
57168
|
-
return
|
|
58331
|
+
return fs38.existsSync(path36.join(dir, "manifest.json")) && fs38.existsSync(path36.join(dir, "SKILL.md"));
|
|
57169
58332
|
}
|
|
57170
58333
|
function collectSkillPackDirs(root) {
|
|
57171
|
-
if (!
|
|
58334
|
+
if (!fs38.existsSync(root)) {
|
|
57172
58335
|
return [];
|
|
57173
58336
|
}
|
|
57174
58337
|
const out = [];
|
|
57175
58338
|
const stack = [];
|
|
57176
|
-
const entries2 =
|
|
58339
|
+
const entries2 = fs38.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !SKILL_PACK_SKIP_DIRS.has(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
|
|
57177
58340
|
for (const entry of entries2.reverse()) {
|
|
57178
|
-
stack.push(
|
|
58341
|
+
stack.push(path36.join(root, entry.name));
|
|
57179
58342
|
}
|
|
57180
58343
|
while (stack.length) {
|
|
57181
58344
|
const dir = stack.pop();
|
|
@@ -57187,21 +58350,21 @@ function collectSkillPackDirs(root) {
|
|
|
57187
58350
|
}
|
|
57188
58351
|
let children;
|
|
57189
58352
|
try {
|
|
57190
|
-
children =
|
|
58353
|
+
children = fs38.readdirSync(dir, { withFileTypes: true });
|
|
57191
58354
|
} catch {
|
|
57192
58355
|
continue;
|
|
57193
58356
|
}
|
|
57194
58357
|
const ordered = children.filter((child) => child.isDirectory()).filter((child) => !SKILL_PACK_SKIP_DIRS.has(child.name)).filter((child) => !child.name.startsWith(".")).sort((a, b) => a.name.localeCompare(b.name));
|
|
57195
58358
|
for (const child of ordered.reverse()) {
|
|
57196
|
-
stack.push(
|
|
58359
|
+
stack.push(path36.join(dir, child.name));
|
|
57197
58360
|
}
|
|
57198
58361
|
}
|
|
57199
58362
|
return out;
|
|
57200
58363
|
}
|
|
57201
58364
|
function resolveSkillAssetPath(options) {
|
|
57202
|
-
const baseRoot =
|
|
57203
|
-
const direct =
|
|
57204
|
-
if (
|
|
58365
|
+
const baseRoot = path36.resolve(options.repoRoot, options.root);
|
|
58366
|
+
const direct = path36.join(baseRoot, options.skillId, ...options.relativePath);
|
|
58367
|
+
if (fs38.existsSync(direct)) {
|
|
57205
58368
|
return direct;
|
|
57206
58369
|
}
|
|
57207
58370
|
const maxDepth = 5;
|
|
@@ -57216,7 +58379,7 @@ function resolveSkillAssetPath(options) {
|
|
|
57216
58379
|
continue;
|
|
57217
58380
|
let children;
|
|
57218
58381
|
try {
|
|
57219
|
-
children =
|
|
58382
|
+
children = fs38.readdirSync(next.dir, { withFileTypes: true });
|
|
57220
58383
|
} catch {
|
|
57221
58384
|
continue;
|
|
57222
58385
|
}
|
|
@@ -57227,10 +58390,10 @@ function resolveSkillAssetPath(options) {
|
|
|
57227
58390
|
continue;
|
|
57228
58391
|
if (child.name.startsWith("."))
|
|
57229
58392
|
continue;
|
|
57230
|
-
const childDir =
|
|
58393
|
+
const childDir = path36.join(next.dir, child.name);
|
|
57231
58394
|
if (child.name === options.skillId) {
|
|
57232
|
-
const candidate =
|
|
57233
|
-
if (
|
|
58395
|
+
const candidate = path36.join(childDir, ...options.relativePath);
|
|
58396
|
+
if (fs38.existsSync(candidate)) {
|
|
57234
58397
|
return candidate;
|
|
57235
58398
|
}
|
|
57236
58399
|
}
|
|
@@ -57244,30 +58407,30 @@ function resolveSkillAssetPath(options) {
|
|
|
57244
58407
|
}
|
|
57245
58408
|
function loadSkillManifests(includeLab, baseDir) {
|
|
57246
58409
|
const rootDir = baseDir ?? process.cwd();
|
|
57247
|
-
const ecosystemDir =
|
|
58410
|
+
const ecosystemDir = path36.resolve(rootDir, "..", "ecosystem");
|
|
57248
58411
|
const coreStableRoots = [
|
|
57249
|
-
|
|
58412
|
+
path36.resolve(rootDir, "skills-core"),
|
|
57250
58413
|
// Legacy fallback during migration.
|
|
57251
|
-
|
|
58414
|
+
path36.resolve(rootDir, "skills")
|
|
57252
58415
|
];
|
|
57253
58416
|
const roots = [
|
|
57254
58417
|
...coreStableRoots.map((dir) => ({ dir, status: "stable" })),
|
|
57255
58418
|
// Approved third-party skills
|
|
57256
|
-
{ dir:
|
|
58419
|
+
{ dir: path36.resolve(ecosystemDir, "skills"), status: "stable" },
|
|
57257
58420
|
// Community submissions (discoverable, not tool-executable by default)
|
|
57258
|
-
{ dir:
|
|
58421
|
+
{ dir: path36.resolve(ecosystemDir, "skill-community"), status: "community" }
|
|
57259
58422
|
];
|
|
57260
58423
|
if (includeLab) {
|
|
57261
|
-
roots.push({ dir:
|
|
58424
|
+
roots.push({ dir: path36.resolve(ecosystemDir, "skill-lab"), status: "lab" });
|
|
57262
58425
|
}
|
|
57263
58426
|
const manifests = [];
|
|
57264
58427
|
const seen = /* @__PURE__ */ new Set();
|
|
57265
58428
|
for (const root of roots) {
|
|
57266
58429
|
const packDirs = collectSkillPackDirs(root.dir);
|
|
57267
58430
|
for (const packDir of packDirs) {
|
|
57268
|
-
const manifestPath =
|
|
58431
|
+
const manifestPath = path36.join(packDir, "manifest.json");
|
|
57269
58432
|
try {
|
|
57270
|
-
const raw =
|
|
58433
|
+
const raw = fs38.readFileSync(manifestPath, "utf8");
|
|
57271
58434
|
const data2 = JSON.parse(raw);
|
|
57272
58435
|
if (!data2.id) {
|
|
57273
58436
|
continue;
|
|
@@ -58074,6 +59237,7 @@ function setupGatewayStores(params) {
|
|
|
58074
59237
|
let twitterAdapter;
|
|
58075
59238
|
let whatsappAdapter;
|
|
58076
59239
|
let imessageAdapter;
|
|
59240
|
+
let tringAdapter;
|
|
58077
59241
|
let skillManifests = loadSkillManifests(gwEnv.skillsLabEnabled, repoRoot);
|
|
58078
59242
|
const telegramAdapterRef = {
|
|
58079
59243
|
get: () => telegramAdapter,
|
|
@@ -58099,6 +59263,12 @@ function setupGatewayStores(params) {
|
|
|
58099
59263
|
imessageAdapter = adapter;
|
|
58100
59264
|
}
|
|
58101
59265
|
};
|
|
59266
|
+
const tringAdapterRef = {
|
|
59267
|
+
get: () => tringAdapter,
|
|
59268
|
+
set: (adapter) => {
|
|
59269
|
+
tringAdapter = adapter;
|
|
59270
|
+
}
|
|
59271
|
+
};
|
|
58102
59272
|
const skillManifestsRef = {
|
|
58103
59273
|
get: () => skillManifests,
|
|
58104
59274
|
set: (skills) => {
|
|
@@ -58198,6 +59368,11 @@ function setupGatewayStores(params) {
|
|
|
58198
59368
|
});
|
|
58199
59369
|
return;
|
|
58200
59370
|
}
|
|
59371
|
+
const tringChannel = normalizeTringChannel(channel);
|
|
59372
|
+
if (tringAdapter && tringChannel) {
|
|
59373
|
+
await sendTringMessage(tringAdapter, tringChannel, chatId, content);
|
|
59374
|
+
return;
|
|
59375
|
+
}
|
|
58201
59376
|
if (channel === "hub") {
|
|
58202
59377
|
const profile = getProfile?.();
|
|
58203
59378
|
await sendHubReply({
|
|
@@ -58213,7 +59388,15 @@ function setupGatewayStores(params) {
|
|
|
58213
59388
|
}
|
|
58214
59389
|
}
|
|
58215
59390
|
async function isChannelAllowed(channel, chatId, userId) {
|
|
59391
|
+
const tringPlatforms = (config.channels.tring.platforms ?? []).map((platform) => normalizeTringPlatform2(platform)).filter((platform) => Boolean(platform));
|
|
59392
|
+
const tringEnabledFor = (platform) => Boolean(config.channels.tring.enabled && tringPlatforms.includes(platform));
|
|
59393
|
+
const tringAllowedChats = config.channels.tring.allowedChats ?? [];
|
|
58216
59394
|
if (channel === "telegram") {
|
|
59395
|
+
if (!config.channels.telegram.enabled && tringEnabledFor("telegram")) {
|
|
59396
|
+
if (tringAllowedChats.length === 0)
|
|
59397
|
+
return true;
|
|
59398
|
+
return tringAllowedChats.includes(chatId);
|
|
59399
|
+
}
|
|
58217
59400
|
const configured = config.channels.telegram.allowedChats ?? [];
|
|
58218
59401
|
const requirePairing = config.channels.telegram.requirePairing ?? configured.length === 0;
|
|
58219
59402
|
if (!requirePairing && configured.includes(chatId))
|
|
@@ -58227,12 +59410,23 @@ function setupGatewayStores(params) {
|
|
|
58227
59410
|
return true;
|
|
58228
59411
|
}
|
|
58229
59412
|
if (channel === "whatsapp") {
|
|
59413
|
+
if (!config.channels.whatsapp.enabled && tringEnabledFor("whatsapp")) {
|
|
59414
|
+
if (tringAllowedChats.length === 0)
|
|
59415
|
+
return true;
|
|
59416
|
+
return tringAllowedChats.includes(chatId);
|
|
59417
|
+
}
|
|
58230
59418
|
const allowedNumbers = config.channels.whatsapp.allowedNumbers ?? [];
|
|
58231
59419
|
if (allowedNumbers.length === 0)
|
|
58232
59420
|
return true;
|
|
58233
59421
|
if (chatId && allowedNumbers.includes(chatId))
|
|
58234
59422
|
return true;
|
|
58235
59423
|
}
|
|
59424
|
+
if ((channel === "signal" || channel === "whispr") && tringEnabledFor("signal")) {
|
|
59425
|
+
if (tringAllowedChats.length === 0)
|
|
59426
|
+
return true;
|
|
59427
|
+
if (chatId && tringAllowedChats.includes(chatId))
|
|
59428
|
+
return true;
|
|
59429
|
+
}
|
|
58236
59430
|
if (channel === "imessage") {
|
|
58237
59431
|
const allowedChats = config.channels.imessage.allowedChats ?? [];
|
|
58238
59432
|
if (allowedChats.length === 0)
|
|
@@ -58257,6 +59451,7 @@ function setupGatewayStores(params) {
|
|
|
58257
59451
|
twitterAdapterRef,
|
|
58258
59452
|
whatsappAdapterRef,
|
|
58259
59453
|
imessageAdapterRef,
|
|
59454
|
+
tringAdapterRef,
|
|
58260
59455
|
skillManifestsRef,
|
|
58261
59456
|
broadcastEvent,
|
|
58262
59457
|
getProvider,
|
|
@@ -58264,6 +59459,26 @@ function setupGatewayStores(params) {
|
|
|
58264
59459
|
isChannelAllowed
|
|
58265
59460
|
};
|
|
58266
59461
|
}
|
|
59462
|
+
async function sendTringMessage(adapter, platform, chatId, content) {
|
|
59463
|
+
await adapter.sendMessage(platform, chatId, content);
|
|
59464
|
+
}
|
|
59465
|
+
function normalizeTringPlatform2(platform) {
|
|
59466
|
+
const normalized = platform.trim().toLowerCase();
|
|
59467
|
+
if (normalized === "whispr")
|
|
59468
|
+
return "signal";
|
|
59469
|
+
if (normalized === "telegram" || normalized === "whatsapp" || normalized === "signal")
|
|
59470
|
+
return normalized;
|
|
59471
|
+
return void 0;
|
|
59472
|
+
}
|
|
59473
|
+
function normalizeTringChannel(channel) {
|
|
59474
|
+
if (channel === "telegram")
|
|
59475
|
+
return "telegram";
|
|
59476
|
+
if (channel === "whatsapp")
|
|
59477
|
+
return "whatsapp";
|
|
59478
|
+
if (channel === "signal" || channel === "whispr")
|
|
59479
|
+
return "signal";
|
|
59480
|
+
return void 0;
|
|
59481
|
+
}
|
|
58267
59482
|
|
|
58268
59483
|
// apps/gateway/dist/gateway/setup-tools.js
|
|
58269
59484
|
async function setupGatewayTools(ctx) {
|
|
@@ -58340,271 +59555,244 @@ async function setupGatewayTools(ctx) {
|
|
|
58340
59555
|
};
|
|
58341
59556
|
}
|
|
58342
59557
|
|
|
58343
|
-
// apps/gateway/dist/gateway/
|
|
58344
|
-
|
|
58345
|
-
|
|
58346
|
-
|
|
58347
|
-
|
|
58348
|
-
|
|
58349
|
-
|
|
58350
|
-
|
|
58351
|
-
|
|
58352
|
-
|
|
58353
|
-
|
|
58354
|
-
|
|
58355
|
-
const
|
|
58356
|
-
|
|
58357
|
-
|
|
58358
|
-
|
|
58359
|
-
|
|
58360
|
-
|
|
58361
|
-
|
|
58362
|
-
|
|
58363
|
-
|
|
58364
|
-
|
|
58365
|
-
try {
|
|
58366
|
-
const parsed = new URL(smritiBaseUrl);
|
|
58367
|
-
if (isLoopbackHost(parsed.hostname)) {
|
|
58368
|
-
const storageRoot = smritiLocalConfig?.storage?.root;
|
|
58369
|
-
if (storageRoot) {
|
|
58370
|
-
const baseDir = path34.dirname(smritiConfigPath);
|
|
58371
|
-
const resolvedStorage = path34.isAbsolute(storageRoot) ? storageRoot : path34.resolve(baseDir, storageRoot);
|
|
58372
|
-
const keyPath = path34.join(resolvedStorage, "keys", "master.key");
|
|
58373
|
-
if (fs36.existsSync(keyPath)) {
|
|
58374
|
-
const key = fs36.readFileSync(keyPath, "utf8").trim();
|
|
58375
|
-
if (key) {
|
|
58376
|
-
smritiApiKey = key;
|
|
58377
|
-
logger.info("smriti_master_key_loaded", { path: keyPath });
|
|
58378
|
-
}
|
|
59558
|
+
// apps/gateway/dist/gateway/summary-llm.js
|
|
59559
|
+
function buildOutboundPromptText4(messages) {
|
|
59560
|
+
return messages.map((message) => `${message.role}: ${message.content}`).join("\n");
|
|
59561
|
+
}
|
|
59562
|
+
function createSummaryLLM(getProvider, getModel, logger) {
|
|
59563
|
+
return {
|
|
59564
|
+
async generate(prompt) {
|
|
59565
|
+
const provider = getProvider();
|
|
59566
|
+
if (!provider) {
|
|
59567
|
+
logger?.warn("summary_llm_no_provider");
|
|
59568
|
+
throw new Error("No provider available for summarization");
|
|
59569
|
+
}
|
|
59570
|
+
const model = getModel() ?? "gpt-4o-mini";
|
|
59571
|
+
try {
|
|
59572
|
+
const messages = [
|
|
59573
|
+
{
|
|
59574
|
+
role: "system",
|
|
59575
|
+
content: "You are a concise summarizer. Generate clear, factual summaries that preserve important details."
|
|
59576
|
+
},
|
|
59577
|
+
{
|
|
59578
|
+
role: "user",
|
|
59579
|
+
content: prompt
|
|
58379
59580
|
}
|
|
58380
|
-
|
|
59581
|
+
];
|
|
59582
|
+
const requestMeta = buildChatMeta({
|
|
59583
|
+
purpose: "summary",
|
|
59584
|
+
providerId: provider.id,
|
|
59585
|
+
model,
|
|
59586
|
+
normalization: buildNormalizationOutboundMeta(normalizeIncomingText(buildOutboundPromptText4(messages)))
|
|
59587
|
+
});
|
|
59588
|
+
const response = await chatWithPolicy({
|
|
59589
|
+
provider,
|
|
59590
|
+
request: buildChatRequest({
|
|
59591
|
+
model,
|
|
59592
|
+
messages,
|
|
59593
|
+
temperature: 0.3,
|
|
59594
|
+
maxTokens: 1024,
|
|
59595
|
+
metadata: requestMeta
|
|
59596
|
+
}),
|
|
59597
|
+
logger,
|
|
59598
|
+
meta: requestMeta
|
|
59599
|
+
});
|
|
59600
|
+
logger?.info("summary_llm_generated", {
|
|
59601
|
+
provider: provider.id,
|
|
59602
|
+
model,
|
|
59603
|
+
inputLength: prompt.length,
|
|
59604
|
+
outputLength: response.content.length
|
|
59605
|
+
});
|
|
59606
|
+
return response.content;
|
|
59607
|
+
} catch (error) {
|
|
59608
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
59609
|
+
logger?.error("summary_llm_error", {
|
|
59610
|
+
error: message,
|
|
59611
|
+
provider: provider.id,
|
|
59612
|
+
model
|
|
59613
|
+
});
|
|
59614
|
+
throw error;
|
|
58381
59615
|
}
|
|
58382
|
-
} catch (error) {
|
|
58383
|
-
logger.warn("smriti_master_key_load_failed", {
|
|
58384
|
-
error: error instanceof Error ? error.message : String(error)
|
|
58385
|
-
});
|
|
58386
59616
|
}
|
|
58387
|
-
}
|
|
58388
|
-
const smritiPrefix = smritiConfig.prefix;
|
|
58389
|
-
const smritiOwner = smritiConfig.owner;
|
|
58390
|
-
const smritiAutoCapture = smritiConfig.autoCapture ?? false;
|
|
58391
|
-
const smritiAutoCaptureMode = smritiConfig.autoCaptureMode ?? "exchange";
|
|
58392
|
-
const smritiRetrieveEnabled = smritiConfig.retrieveEnabled ?? false;
|
|
58393
|
-
const smritiRetrieveLimit = smritiConfig.retrieveLimit ?? 5;
|
|
58394
|
-
const smritiDefaultTags = smritiConfig.defaultTags ?? void 0;
|
|
58395
|
-
const smritiSource = smritiConfig.source;
|
|
58396
|
-
const smritiAutoMemoryEnabled = smritiConfig.autoMemoryEnabled ?? false;
|
|
58397
|
-
const smritiAutoMemoryPython = smritiConfig.autoMemoryPython ?? "python3";
|
|
58398
|
-
const smritiAutoMemoryFallbackRoot = path34.resolve(repoRoot, "skills-core", "smriti-auto-memory", "hooks", "scripts");
|
|
58399
|
-
const smritiAutoMemoryRootCandidates = [
|
|
58400
|
-
smritiAutoMemoryFallbackRoot,
|
|
58401
|
-
path34.resolve(repoRoot, "..", "ecosystem", "skills", "smriti-auto-memory", "hooks", "scripts"),
|
|
58402
|
-
path34.resolve(repoRoot, "skills", "smriti-auto-memory", "hooks", "scripts")
|
|
58403
|
-
];
|
|
58404
|
-
const smritiAutoMemoryDefaultRoot = smritiAutoMemoryRootCandidates.find((candidate) => fs36.existsSync(candidate)) ?? smritiAutoMemoryFallbackRoot;
|
|
58405
|
-
const smritiAutoMemoryRoot = smritiConfig.autoMemoryPath ?? smritiAutoMemoryDefaultRoot;
|
|
58406
|
-
const smritiAutoMemorySessionScript = path34.join(smritiAutoMemoryRoot, "session-start.py");
|
|
58407
|
-
const smritiAutoMemoryPromptScript = path34.join(smritiAutoMemoryRoot, "user-prompt.py");
|
|
58408
|
-
const smritiAutoMemoryReady = smritiEnabled && smritiAutoMemoryEnabled && Boolean(smritiApiKey) && fs36.existsSync(smritiAutoMemorySessionScript) && fs36.existsSync(smritiAutoMemoryPromptScript);
|
|
58409
|
-
const smritiClientOptions = smritiEnabled && smritiBaseUrl ? {
|
|
58410
|
-
baseUrl: smritiBaseUrl,
|
|
58411
|
-
apiKey: smritiApiKey,
|
|
58412
|
-
timeoutMs: smritiConfig.timeoutMs,
|
|
58413
|
-
prefix: smritiPrefix ? smritiPrefix.replace(/\/$/, "") : smritiOwner ? `user/${normalizeSmritiOwner(smritiOwner)}` : void 0
|
|
58414
|
-
} : void 0;
|
|
58415
|
-
return {
|
|
58416
|
-
smritiConfig,
|
|
58417
|
-
smritiEnabled,
|
|
58418
|
-
smritiBaseUrl,
|
|
58419
|
-
smritiApiKey,
|
|
58420
|
-
smritiPrefix,
|
|
58421
|
-
smritiOwner,
|
|
58422
|
-
smritiAutoCapture,
|
|
58423
|
-
smritiAutoCaptureMode,
|
|
58424
|
-
smritiRetrieveEnabled,
|
|
58425
|
-
smritiRetrieveLimit,
|
|
58426
|
-
smritiDefaultTags,
|
|
58427
|
-
smritiSource,
|
|
58428
|
-
smritiAutoMemoryEnabled,
|
|
58429
|
-
smritiAutoMemoryPython,
|
|
58430
|
-
smritiAutoMemoryRoot,
|
|
58431
|
-
smritiAutoMemorySessionScript,
|
|
58432
|
-
smritiAutoMemoryPromptScript,
|
|
58433
|
-
smritiAutoMemoryReady,
|
|
58434
|
-
smritiClientOptions,
|
|
58435
|
-
smritiVectorProvider: smritiLocalConfig?.vector?.provider,
|
|
58436
|
-
smritiVectorFallbacks: smritiLocalConfig?.vector?.fallbackProviders,
|
|
58437
|
-
smritiEmbeddingProviders: smritiLocalConfig?.embeddings?.providerPriority
|
|
58438
59617
|
};
|
|
58439
59618
|
}
|
|
58440
59619
|
|
|
58441
|
-
// apps/gateway/dist/gateway/
|
|
58442
|
-
|
|
58443
|
-
|
|
58444
|
-
|
|
58445
|
-
|
|
58446
|
-
|
|
58447
|
-
|
|
58448
|
-
|
|
58449
|
-
|
|
58450
|
-
|
|
58451
|
-
|
|
58452
|
-
|
|
58453
|
-
|
|
58454
|
-
|
|
59620
|
+
// apps/gateway/dist/gateway/setup-core.js
|
|
59621
|
+
var HARD_DEPRECATED_MODELS = {
|
|
59622
|
+
anthropic: /* @__PURE__ */ new Set([
|
|
59623
|
+
"claude-sonnet-4-20250514",
|
|
59624
|
+
"claude-opus-4-5",
|
|
59625
|
+
"claude-opus-4-5-20251101",
|
|
59626
|
+
"claude-3-5-haiku-20241022"
|
|
59627
|
+
])
|
|
59628
|
+
};
|
|
59629
|
+
var KOSHA_DISCOVERY_REFRESH_MS = 5 * 60 * 1e3;
|
|
59630
|
+
var KOSHA_PATH_ENV = "KOSHA_DISCOVERY_PATH";
|
|
59631
|
+
var koshaState = {};
|
|
59632
|
+
async function resolveKoshaRegistry(refresh) {
|
|
59633
|
+
const now = Date.now();
|
|
59634
|
+
if (!refresh && koshaState.registry && koshaState.resolvedAt) {
|
|
59635
|
+
if (now - koshaState.resolvedAt < KOSHA_DISCOVERY_REFRESH_MS) {
|
|
59636
|
+
return {
|
|
59637
|
+
registry: koshaState.registry,
|
|
59638
|
+
source: "cached"
|
|
59639
|
+
};
|
|
59640
|
+
}
|
|
58455
59641
|
}
|
|
58456
|
-
|
|
58457
|
-
|
|
58458
|
-
function buildCandidateRoots(repoRoot) {
|
|
58459
|
-
const roots = [repoRoot];
|
|
58460
|
-
let current = repoRoot;
|
|
58461
|
-
for (let i = 0; i < 3; i += 1) {
|
|
58462
|
-
const parent = path35.dirname(current);
|
|
58463
|
-
if (!parent || parent === current)
|
|
58464
|
-
break;
|
|
58465
|
-
roots.push(parent);
|
|
58466
|
-
current = parent;
|
|
59642
|
+
if (koshaState.loadingPromise) {
|
|
59643
|
+
return koshaState.loadingPromise;
|
|
58467
59644
|
}
|
|
58468
|
-
|
|
58469
|
-
|
|
58470
|
-
|
|
58471
|
-
|
|
58472
|
-
|
|
58473
|
-
|
|
59645
|
+
const loadRegistry = async () => {
|
|
59646
|
+
const importTargets = [];
|
|
59647
|
+
const envPath = process.env[KOSHA_PATH_ENV];
|
|
59648
|
+
if (envPath) {
|
|
59649
|
+
importTargets.push(envPath);
|
|
59650
|
+
if (envPath.endsWith("dist/index.js") === false) {
|
|
59651
|
+
importTargets.push(path37.join(envPath, "dist", "index.js"));
|
|
59652
|
+
}
|
|
59653
|
+
}
|
|
59654
|
+
const localCandidate = path37.resolve(process.cwd(), "..", "kosha-discovery", "dist", "index.js");
|
|
59655
|
+
importTargets.push(localCandidate);
|
|
59656
|
+
importTargets.push("kosha-discovery");
|
|
59657
|
+
let lastFailure;
|
|
59658
|
+
let lastFailureTarget;
|
|
59659
|
+
for (const rawTarget of importTargets) {
|
|
59660
|
+
const target = fs39.existsSync(rawTarget) ? pathToFileURL(path37.resolve(rawTarget)).href : rawTarget;
|
|
59661
|
+
const source = rawTarget;
|
|
58474
59662
|
try {
|
|
58475
|
-
|
|
59663
|
+
const mod = await import(target);
|
|
59664
|
+
if (!mod?.createKosha) {
|
|
59665
|
+
lastFailure = `Kosha module missing createKosha export: ${source}`;
|
|
59666
|
+
lastFailureTarget = source;
|
|
58476
59667
|
continue;
|
|
58477
|
-
|
|
58478
|
-
|
|
59668
|
+
}
|
|
59669
|
+
const registry = await mod.createKosha();
|
|
59670
|
+
if (!registry?.models || typeof registry.models !== "function") {
|
|
59671
|
+
lastFailure = `Invalid Kosha registry shape from ${source}`;
|
|
59672
|
+
lastFailureTarget = source;
|
|
58479
59673
|
continue;
|
|
58480
|
-
|
|
58481
|
-
|
|
59674
|
+
}
|
|
59675
|
+
return { registry, source };
|
|
59676
|
+
} catch (error) {
|
|
59677
|
+
lastFailure = error instanceof Error ? error.message : String(error);
|
|
59678
|
+
lastFailureTarget = source;
|
|
58482
59679
|
}
|
|
58483
59680
|
}
|
|
59681
|
+
return {
|
|
59682
|
+
error: lastFailure ?? "kosha discovery unavailable",
|
|
59683
|
+
source: lastFailureTarget
|
|
59684
|
+
};
|
|
59685
|
+
};
|
|
59686
|
+
const start = Date.now();
|
|
59687
|
+
const inFlight = loadRegistry().finally(() => {
|
|
59688
|
+
koshaState.loadingPromise = void 0;
|
|
59689
|
+
});
|
|
59690
|
+
koshaState.loadingPromise = inFlight;
|
|
59691
|
+
const resolution = await inFlight;
|
|
59692
|
+
if (!resolution.registry) {
|
|
59693
|
+
const elapsedMs = Date.now() - start;
|
|
59694
|
+
return {
|
|
59695
|
+
...resolution,
|
|
59696
|
+
error: `${resolution.error} (refresh_ms=${elapsedMs})`
|
|
59697
|
+
};
|
|
58484
59698
|
}
|
|
58485
|
-
|
|
59699
|
+
if (resolution.source === void 0) {
|
|
59700
|
+
resolution.source = "resolved";
|
|
59701
|
+
}
|
|
59702
|
+
koshaState.registry = resolution.registry;
|
|
59703
|
+
koshaState.resolvedAt = Date.now();
|
|
59704
|
+
return {
|
|
59705
|
+
...resolution,
|
|
59706
|
+
source: resolution.source
|
|
59707
|
+
};
|
|
58486
59708
|
}
|
|
58487
|
-
function
|
|
58488
|
-
const
|
|
58489
|
-
|
|
58490
|
-
|
|
58491
|
-
|
|
58492
|
-
const raw = nameMatch[1].trim().replace(/^_\(?|_?\)?$/g, "");
|
|
58493
|
-
if (raw && !raw.startsWith("(") && raw.length < 64) {
|
|
58494
|
-
fields.assistantName = raw;
|
|
58495
|
-
}
|
|
58496
|
-
}
|
|
58497
|
-
const emojiMatch = identity.match(/(?:^|\n)\s*(?:-\s*)?(?:\*\*)?Emoji(?:\*\*)?:\s*(?:\*\*)?(.+?)(?:\*\*)?$/im);
|
|
58498
|
-
if (emojiMatch?.[1]) {
|
|
58499
|
-
const raw = emojiMatch[1].trim().replace(/^_\(?|_?\)?$/g, "");
|
|
58500
|
-
if (raw && !raw.startsWith("(") && raw.length < 8) {
|
|
58501
|
-
fields.emoji = raw;
|
|
58502
|
-
}
|
|
59709
|
+
function resolveProviderEnvApiKey(envKeys) {
|
|
59710
|
+
for (const key of envKeys) {
|
|
59711
|
+
const value = process.env[key];
|
|
59712
|
+
if (value?.trim()) {
|
|
59713
|
+
return value.trim();
|
|
58503
59714
|
}
|
|
58504
59715
|
}
|
|
58505
|
-
|
|
58506
|
-
|
|
58507
|
-
|
|
58508
|
-
|
|
58509
|
-
|
|
58510
|
-
|
|
58511
|
-
|
|
58512
|
-
|
|
58513
|
-
|
|
59716
|
+
return void 0;
|
|
59717
|
+
}
|
|
59718
|
+
function enrichProvidersWithEnvDefaults(baseEntries) {
|
|
59719
|
+
const resolvedEntries = { ...baseEntries };
|
|
59720
|
+
const fallbackSpecs = [
|
|
59721
|
+
{
|
|
59722
|
+
providerId: "google",
|
|
59723
|
+
type: "google",
|
|
59724
|
+
defaultBaseUrl: "https://generativelanguage.googleapis.com/v1beta",
|
|
59725
|
+
envKeys: ["GOOGLE_API_KEY", "GEMINI_API_KEY", "VAAYU_GOOGLE_API_KEY", "VAAYU_PROVIDER_GOOGLE_API_KEY"]
|
|
59726
|
+
},
|
|
59727
|
+
{
|
|
59728
|
+
providerId: "openai",
|
|
59729
|
+
type: "openai-compatible",
|
|
59730
|
+
defaultBaseUrl: "https://api.openai.com/v1",
|
|
59731
|
+
envKeys: ["OPENAI_API_KEY", "VAAYU_OPENAI_API_KEY", "VAAYU_PROVIDER_OPENAI_API_KEY", "VAAYU_EMBEDDING_API_KEY"]
|
|
58514
59732
|
}
|
|
58515
|
-
|
|
58516
|
-
|
|
58517
|
-
|
|
58518
|
-
|
|
58519
|
-
|
|
58520
|
-
|
|
58521
|
-
|
|
58522
|
-
|
|
59733
|
+
];
|
|
59734
|
+
for (const spec of fallbackSpecs) {
|
|
59735
|
+
const existing = resolvedEntries[spec.providerId];
|
|
59736
|
+
const apiKey = resolveProviderEnvApiKey(spec.envKeys);
|
|
59737
|
+
const baseUrl = (() => {
|
|
59738
|
+
const explicit = process.env[`VAAYU_PROVIDER_${spec.providerId.toUpperCase()}_BASE_URL`];
|
|
59739
|
+
return existing?.baseUrl || explicit || spec.defaultBaseUrl;
|
|
59740
|
+
})();
|
|
59741
|
+
if (!existing && !apiKey) {
|
|
59742
|
+
continue;
|
|
58523
59743
|
}
|
|
59744
|
+
resolvedEntries[spec.providerId] = {
|
|
59745
|
+
...existing,
|
|
59746
|
+
type: existing?.type || spec.type,
|
|
59747
|
+
baseUrl: existing?.baseUrl || baseUrl,
|
|
59748
|
+
apiKey: existing?.apiKey || apiKey
|
|
59749
|
+
};
|
|
58524
59750
|
}
|
|
58525
|
-
return
|
|
59751
|
+
return resolvedEntries;
|
|
58526
59752
|
}
|
|
58527
|
-
function
|
|
58528
|
-
|
|
58529
|
-
|
|
58530
|
-
|
|
58531
|
-
|
|
58532
|
-
|
|
58533
|
-
|
|
58534
|
-
|
|
58535
|
-
const roots = buildCandidateRoots(params.repoRoot);
|
|
58536
|
-
const maxChars = params.maxPromptChars ?? MAX_PROMPT_CHARS_DEFAULT;
|
|
58537
|
-
const filesLoaded = [];
|
|
58538
|
-
const parts = [];
|
|
58539
|
-
const soul = readFirstExisting(roots, ["SOUL.md", "soul.md"]);
|
|
58540
|
-
if (soul) {
|
|
58541
|
-
filesLoaded.push(soul.file);
|
|
58542
|
-
parts.push(soul.text);
|
|
58543
|
-
}
|
|
58544
|
-
const identity = readFirstExisting(roots, ["IDENTITY.md", "identity.md"]);
|
|
58545
|
-
if (identity) {
|
|
58546
|
-
filesLoaded.push(identity.file);
|
|
58547
|
-
parts.push(identity.text);
|
|
58548
|
-
}
|
|
58549
|
-
const personality = readFirstExisting(roots, ["PERSONALITY.md", "personality.md"]);
|
|
58550
|
-
if (personality) {
|
|
58551
|
-
filesLoaded.push(personality.file);
|
|
58552
|
-
parts.push(personality.text);
|
|
58553
|
-
}
|
|
58554
|
-
const user = readFirstExisting(roots, ["USER.md", "user.md"]);
|
|
58555
|
-
if (user) {
|
|
58556
|
-
filesLoaded.push(user.file);
|
|
58557
|
-
parts.push(user.text);
|
|
59753
|
+
async function listProviderModelsFromKosha(providerId, refresh, overrideLayers) {
|
|
59754
|
+
const resolution = await resolveKoshaRegistry(refresh);
|
|
59755
|
+
if (!resolution.registry) {
|
|
59756
|
+
return {
|
|
59757
|
+
models: [],
|
|
59758
|
+
source: resolution.source === "cached" ? "cached" : "fallback",
|
|
59759
|
+
error: resolution.error ?? "kosha_discovery_unavailable"
|
|
59760
|
+
};
|
|
58558
59761
|
}
|
|
58559
|
-
const
|
|
58560
|
-
const
|
|
58561
|
-
|
|
58562
|
-
|
|
58563
|
-
|
|
58564
|
-
|
|
58565
|
-
|
|
58566
|
-
|
|
58567
|
-
|
|
58568
|
-
import fs38 from "node:fs";
|
|
58569
|
-
import path36 from "node:path";
|
|
58570
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58571
|
-
var GATEWAY_CONFIG_FILENAMES = [
|
|
58572
|
-
"vaayu.config.json",
|
|
58573
|
-
"vaayu.config.yaml",
|
|
58574
|
-
"vaayu.config.yml"
|
|
58575
|
-
];
|
|
58576
|
-
function resolvePreferredGatewayConfigPath(params) {
|
|
58577
|
-
const envConfigPath = params?.envConfigPath ?? process.env.VAAYU_CONFIG;
|
|
58578
|
-
if (envConfigPath?.trim()) {
|
|
58579
|
-
return void 0;
|
|
59762
|
+
const registry = resolution.registry;
|
|
59763
|
+
const cards = /* @__PURE__ */ new Map();
|
|
59764
|
+
const direct = registry.models({
|
|
59765
|
+
provider: providerId,
|
|
59766
|
+
mode: "chat"
|
|
59767
|
+
});
|
|
59768
|
+
for (const card of direct) {
|
|
59769
|
+
const key = `${card.provider ?? providerId}:${card.id}`;
|
|
59770
|
+
cards.set(key, card);
|
|
58580
59771
|
}
|
|
58581
|
-
|
|
58582
|
-
|
|
58583
|
-
|
|
58584
|
-
|
|
58585
|
-
|
|
58586
|
-
const
|
|
58587
|
-
if (
|
|
58588
|
-
|
|
59772
|
+
if (!cards.size) {
|
|
59773
|
+
for (const card of registry.models({
|
|
59774
|
+
originProvider: providerId,
|
|
59775
|
+
mode: "chat"
|
|
59776
|
+
})) {
|
|
59777
|
+
const key = `${card.provider ?? providerId}:${card.id}`;
|
|
59778
|
+
if (!cards.has(key)) {
|
|
59779
|
+
cards.set(key, card);
|
|
58589
59780
|
}
|
|
58590
59781
|
}
|
|
58591
|
-
const parent = path36.dirname(currentDir);
|
|
58592
|
-
if (parent === currentDir)
|
|
58593
|
-
break;
|
|
58594
|
-
currentDir = parent;
|
|
58595
59782
|
}
|
|
58596
|
-
|
|
59783
|
+
if (!cards.size) {
|
|
59784
|
+
return {
|
|
59785
|
+
models: [],
|
|
59786
|
+
source: resolution.source === "cached" ? "cached" : "fallback",
|
|
59787
|
+
error: `No chat models found in kosha for provider "${providerId}"`
|
|
59788
|
+
};
|
|
59789
|
+
}
|
|
59790
|
+
const rawModels = Array.from(cards.values()).map((card) => card.id);
|
|
59791
|
+
return {
|
|
59792
|
+
models: applyModelOverrides(Array.from(new Set(rawModels)), overrideLayers),
|
|
59793
|
+
source: "kosha"
|
|
59794
|
+
};
|
|
58597
59795
|
}
|
|
58598
|
-
|
|
58599
|
-
// apps/gateway/dist/gateway/setup-core.js
|
|
58600
|
-
var HARD_DEPRECATED_MODELS = {
|
|
58601
|
-
anthropic: /* @__PURE__ */ new Set([
|
|
58602
|
-
"claude-sonnet-4-20250514",
|
|
58603
|
-
"claude-opus-4-5",
|
|
58604
|
-
"claude-opus-4-5-20251101",
|
|
58605
|
-
"claude-3-5-haiku-20241022"
|
|
58606
|
-
])
|
|
58607
|
-
};
|
|
58608
59796
|
function stripHardDeprecatedModels(providerId, models) {
|
|
58609
59797
|
const blocked = HARD_DEPRECATED_MODELS[providerId];
|
|
58610
59798
|
if (!blocked || blocked.size === 0)
|
|
@@ -58659,6 +59847,7 @@ async function setupGatewayCore() {
|
|
|
58659
59847
|
}
|
|
58660
59848
|
const state = { startedAt: Date.now(), httpRequestCount: 0 };
|
|
58661
59849
|
const idempotency = new IdempotencyStore(12e4);
|
|
59850
|
+
config.providers.entries = enrichProvidersWithEnvDefaults(config.providers.entries);
|
|
58662
59851
|
const providers = createRegistry(config.providers);
|
|
58663
59852
|
if (providers.list().length === 0) {
|
|
58664
59853
|
providers.register(new MockProvider({ id: "mock" }));
|
|
@@ -58766,6 +59955,21 @@ async function setupGatewayCore() {
|
|
|
58766
59955
|
error = remote.error;
|
|
58767
59956
|
}
|
|
58768
59957
|
}
|
|
59958
|
+
if (!models.length) {
|
|
59959
|
+
const kosha = await listProviderModelsFromKosha(providerId, refresh, overrideLayers);
|
|
59960
|
+
if (kosha.models.length) {
|
|
59961
|
+
models = stripHardDeprecatedModels(providerId, applyModelOverrides(kosha.models, overrideLayers));
|
|
59962
|
+
modelSource = kosha.source;
|
|
59963
|
+
error ??= kosha.error;
|
|
59964
|
+
} else if (kosha.error) {
|
|
59965
|
+
error = error ? `${error}; ${kosha.error}` : kosha.error;
|
|
59966
|
+
logger.warn("model_list_kosha_unavailable", {
|
|
59967
|
+
providerId,
|
|
59968
|
+
reason: kosha.error,
|
|
59969
|
+
refresh
|
|
59970
|
+
});
|
|
59971
|
+
}
|
|
59972
|
+
}
|
|
58769
59973
|
if (!models.length && cached2?.models?.length) {
|
|
58770
59974
|
const cachedModels = stripHardDeprecatedModels(providerId, applyModelOverrides(cached2.models, overrideLayers));
|
|
58771
59975
|
if (cachedModels.length) {
|
|
@@ -58893,7 +60097,7 @@ async function setupGatewayCore() {
|
|
|
58893
60097
|
"proactiveAllowed",
|
|
58894
60098
|
"proactiveAllowedChannels"
|
|
58895
60099
|
]) {
|
|
58896
|
-
if (Object.
|
|
60100
|
+
if (Object.hasOwn(raw, key) && raw[key] === null) {
|
|
58897
60101
|
cleared[key] = void 0;
|
|
58898
60102
|
}
|
|
58899
60103
|
}
|
|
@@ -60344,14 +61548,14 @@ async function bootstrapCliProviders(logger, providers) {
|
|
|
60344
61548
|
}
|
|
60345
61549
|
}
|
|
60346
61550
|
|
|
60347
|
-
// packages/backup/src/manager.
|
|
61551
|
+
// packages/backup/src/manager.ts
|
|
60348
61552
|
import path42 from "node:path";
|
|
60349
61553
|
|
|
60350
|
-
// packages/backup/src/storage.
|
|
61554
|
+
// packages/backup/src/storage.ts
|
|
60351
61555
|
import path39 from "node:path";
|
|
60352
61556
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
60353
61557
|
|
|
60354
|
-
// packages/backup/src/utils.
|
|
61558
|
+
// packages/backup/src/utils.ts
|
|
60355
61559
|
import fs40 from "node:fs";
|
|
60356
61560
|
import path38 from "node:path";
|
|
60357
61561
|
import os11 from "node:os";
|
|
@@ -60382,8 +61586,7 @@ function createSnapshotId(date = /* @__PURE__ */ new Date()) {
|
|
|
60382
61586
|
function readJson3(filePath, fallback) {
|
|
60383
61587
|
try {
|
|
60384
61588
|
const raw = fs40.readFileSync(filePath, "utf8");
|
|
60385
|
-
if (!raw)
|
|
60386
|
-
return fallback;
|
|
61589
|
+
if (!raw) return fallback;
|
|
60387
61590
|
return JSON.parse(raw);
|
|
60388
61591
|
} catch {
|
|
60389
61592
|
return fallback;
|
|
@@ -60403,12 +61606,11 @@ function copyDirSafe(src, dest) {
|
|
|
60403
61606
|
fs40.cpSync(src, dest, { recursive: true });
|
|
60404
61607
|
}
|
|
60405
61608
|
function deleteDirSafe(dir) {
|
|
60406
|
-
if (!fs40.existsSync(dir))
|
|
60407
|
-
return;
|
|
61609
|
+
if (!fs40.existsSync(dir)) return;
|
|
60408
61610
|
fs40.rmSync(dir, { recursive: true, force: true });
|
|
60409
61611
|
}
|
|
60410
61612
|
|
|
60411
|
-
// packages/backup/src/storage.
|
|
61613
|
+
// packages/backup/src/storage.ts
|
|
60412
61614
|
async function backupStorage(params) {
|
|
60413
61615
|
const { storage, snapshotDir, logger } = params;
|
|
60414
61616
|
const driver = storage.driver;
|
|
@@ -60436,7 +61638,11 @@ async function backupStorage(params) {
|
|
|
60436
61638
|
}
|
|
60437
61639
|
if (driver === "postgres") {
|
|
60438
61640
|
const dest = path39.join(storageDir, "postgres.dump");
|
|
60439
|
-
const result = spawnSync2(
|
|
61641
|
+
const result = spawnSync2(
|
|
61642
|
+
"pg_dump",
|
|
61643
|
+
["--format=c", "--file", dest, storage.postgresUrl ?? ""],
|
|
61644
|
+
{ stdio: "pipe" }
|
|
61645
|
+
);
|
|
60440
61646
|
if (result.status !== 0) {
|
|
60441
61647
|
const error = result.stderr?.toString() || "pg_dump failed";
|
|
60442
61648
|
logger.warn("backup_pg_dump_failed", { error });
|
|
@@ -60472,7 +61678,11 @@ async function restoreStorage(params) {
|
|
|
60472
61678
|
}
|
|
60473
61679
|
if (storage.driver === "postgres") {
|
|
60474
61680
|
const dumpPath = path39.join(storageDir, "postgres.dump");
|
|
60475
|
-
const result = spawnSync2(
|
|
61681
|
+
const result = spawnSync2(
|
|
61682
|
+
"pg_restore",
|
|
61683
|
+
["--clean", "--if-exists", "--dbname", storage.postgresUrl ?? "", dumpPath],
|
|
61684
|
+
{ stdio: "pipe" }
|
|
61685
|
+
);
|
|
60476
61686
|
if (result.status !== 0) {
|
|
60477
61687
|
const error = result.stderr?.toString() || "pg_restore failed";
|
|
60478
61688
|
logger.warn("backup_pg_restore_failed", { error });
|
|
@@ -60486,15 +61696,14 @@ async function restoreStorage(params) {
|
|
|
60486
61696
|
}
|
|
60487
61697
|
}
|
|
60488
61698
|
|
|
60489
|
-
// packages/backup/src/qdrant.
|
|
61699
|
+
// packages/backup/src/qdrant.ts
|
|
60490
61700
|
import fs41 from "node:fs";
|
|
60491
61701
|
import path40 from "node:path";
|
|
60492
61702
|
var DEFAULT_COLLECTION2 = "vaayu-smriti";
|
|
60493
61703
|
var DEFAULT_TIMEOUT_MS3 = 8e3;
|
|
60494
61704
|
function buildHeaders(apiKey) {
|
|
60495
61705
|
const headers = { "content-type": "application/json" };
|
|
60496
|
-
if (apiKey)
|
|
60497
|
-
headers["api-key"] = apiKey;
|
|
61706
|
+
if (apiKey) headers["api-key"] = apiKey;
|
|
60498
61707
|
return headers;
|
|
60499
61708
|
}
|
|
60500
61709
|
async function fetchJson3(url, init, timeoutMs) {
|
|
@@ -60520,7 +61729,11 @@ async function backupQdrant(params) {
|
|
|
60520
61729
|
const collection = config.collection ?? DEFAULT_COLLECTION2;
|
|
60521
61730
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
60522
61731
|
try {
|
|
60523
|
-
const createResp = await fetchJson3(
|
|
61732
|
+
const createResp = await fetchJson3(
|
|
61733
|
+
`${url}/collections/${collection}/snapshots`,
|
|
61734
|
+
{ method: "POST", headers: buildHeaders(config.apiKey), body: "{}" },
|
|
61735
|
+
timeoutMs
|
|
61736
|
+
);
|
|
60524
61737
|
const snapshotName = createResp?.result?.name ?? createResp?.name;
|
|
60525
61738
|
if (!snapshotName) {
|
|
60526
61739
|
return { ok: false, error: "Missing snapshot name" };
|
|
@@ -60544,7 +61757,7 @@ async function backupQdrant(params) {
|
|
|
60544
61757
|
}
|
|
60545
61758
|
}
|
|
60546
61759
|
|
|
60547
|
-
// packages/backup/src/manifest.
|
|
61760
|
+
// packages/backup/src/manifest.ts
|
|
60548
61761
|
import path41 from "node:path";
|
|
60549
61762
|
var INDEX_NAME = "index.json";
|
|
60550
61763
|
var MANIFEST_NAME = "manifest.json";
|
|
@@ -60572,10 +61785,9 @@ function saveBackupManifest(snapshotDir, manifest) {
|
|
|
60572
61785
|
writeJson2(getManifestPath(snapshotDir), manifest);
|
|
60573
61786
|
}
|
|
60574
61787
|
|
|
60575
|
-
// packages/backup/src/manager.
|
|
61788
|
+
// packages/backup/src/manager.ts
|
|
60576
61789
|
var shouldRun = (lastAt, intervalMinutes) => {
|
|
60577
|
-
if (!lastAt)
|
|
60578
|
-
return true;
|
|
61790
|
+
if (!lastAt) return true;
|
|
60579
61791
|
const elapsed = Date.now() - Date.parse(lastAt);
|
|
60580
61792
|
return elapsed >= intervalMinutes * 6e4;
|
|
60581
61793
|
};
|
|
@@ -60656,11 +61868,9 @@ function createBackupManager(params) {
|
|
|
60656
61868
|
return restoreStorage({ storage, snapshotDir, logger });
|
|
60657
61869
|
};
|
|
60658
61870
|
const start = () => {
|
|
60659
|
-
if (!config.enabled || timer)
|
|
60660
|
-
return;
|
|
61871
|
+
if (!config.enabled || timer) return;
|
|
60661
61872
|
timer = setInterval(() => {
|
|
60662
|
-
if (!config.enabled)
|
|
60663
|
-
return;
|
|
61873
|
+
if (!config.enabled) return;
|
|
60664
61874
|
if (shouldRun(lastStorageRunAt, config.intervalMinutes)) {
|
|
60665
61875
|
void run("scheduled").catch((error) => {
|
|
60666
61876
|
logger.warn("backup_scheduled_run_failed", {
|
|
@@ -60678,8 +61888,7 @@ function createBackupManager(params) {
|
|
|
60678
61888
|
}
|
|
60679
61889
|
};
|
|
60680
61890
|
const stop = () => {
|
|
60681
|
-
if (!timer)
|
|
60682
|
-
return;
|
|
61891
|
+
if (!timer) return;
|
|
60683
61892
|
clearInterval(timer);
|
|
60684
61893
|
timer = void 0;
|
|
60685
61894
|
};
|
|
@@ -60704,8 +61913,7 @@ function updateIndex(localDir, manifest, keepLast, keepDays) {
|
|
|
60704
61913
|
const next = [manifest, ...index.backups.filter((item) => item.id !== manifest.id)];
|
|
60705
61914
|
const now = Date.now();
|
|
60706
61915
|
const filtered = next.filter((item, idx) => {
|
|
60707
|
-
if (keepLast && idx < keepLast)
|
|
60708
|
-
return true;
|
|
61916
|
+
if (keepLast && idx < keepLast) return true;
|
|
60709
61917
|
if (keepDays) {
|
|
60710
61918
|
const created = Date.parse(item.startedAt);
|
|
60711
61919
|
return now - created <= keepDays * 24 * 60 * 60 * 1e3;
|
|
@@ -60720,8 +61928,8 @@ function updateIndex(localDir, manifest, keepLast, keepDays) {
|
|
|
60720
61928
|
}
|
|
60721
61929
|
|
|
60722
61930
|
// apps/gateway/dist/providers/health.js
|
|
60723
|
-
import { spawn as
|
|
60724
|
-
import { existsSync as
|
|
61931
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
61932
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
60725
61933
|
import net from "node:net";
|
|
60726
61934
|
var DEFAULT_OLLAMA_URL = "http://127.0.0.1:11434";
|
|
60727
61935
|
var parseModel = (model) => {
|
|
@@ -60741,8 +61949,8 @@ var matchesRequired = (required, installed) => {
|
|
|
60741
61949
|
}
|
|
60742
61950
|
return required.base === installed.base;
|
|
60743
61951
|
};
|
|
60744
|
-
var wait = (ms) => new Promise((
|
|
60745
|
-
setTimeout(
|
|
61952
|
+
var wait = (ms) => new Promise((resolve3) => {
|
|
61953
|
+
setTimeout(resolve3, ms);
|
|
60746
61954
|
});
|
|
60747
61955
|
var normalizeBaseUrl5 = (value) => {
|
|
60748
61956
|
if (!value)
|
|
@@ -60835,7 +62043,7 @@ var resolveOllamaBinary2 = () => {
|
|
|
60835
62043
|
return process.env.OLLAMA_PATH;
|
|
60836
62044
|
const candidates = ["/opt/homebrew/bin/ollama", "/usr/local/bin/ollama", "/usr/bin/ollama"];
|
|
60837
62045
|
for (const candidate of candidates) {
|
|
60838
|
-
if (
|
|
62046
|
+
if (existsSync3(candidate))
|
|
60839
62047
|
return candidate;
|
|
60840
62048
|
}
|
|
60841
62049
|
return "ollama";
|
|
@@ -60864,24 +62072,24 @@ var isTcpListening = async (baseUrl) => {
|
|
|
60864
62072
|
}
|
|
60865
62073
|
if (!host || !Number.isFinite(port) || port <= 0)
|
|
60866
62074
|
return false;
|
|
60867
|
-
return await new Promise((
|
|
62075
|
+
return await new Promise((resolve3) => {
|
|
60868
62076
|
const socket = net.connect({ host, port });
|
|
60869
62077
|
const timeout = setTimeout(() => {
|
|
60870
62078
|
socket.destroy();
|
|
60871
|
-
|
|
62079
|
+
resolve3(false);
|
|
60872
62080
|
}, 350);
|
|
60873
62081
|
socket.once("connect", () => {
|
|
60874
62082
|
clearTimeout(timeout);
|
|
60875
62083
|
socket.destroy();
|
|
60876
|
-
|
|
62084
|
+
resolve3(true);
|
|
60877
62085
|
});
|
|
60878
62086
|
socket.once("error", () => {
|
|
60879
62087
|
clearTimeout(timeout);
|
|
60880
|
-
|
|
62088
|
+
resolve3(false);
|
|
60881
62089
|
});
|
|
60882
62090
|
});
|
|
60883
62091
|
};
|
|
60884
|
-
var tryStartOllama = async (logger, params) => new Promise((
|
|
62092
|
+
var tryStartOllama = async (logger, params) => new Promise((resolve3) => {
|
|
60885
62093
|
try {
|
|
60886
62094
|
const bin = resolveOllamaBinary2();
|
|
60887
62095
|
const env = { ...process.env };
|
|
@@ -60892,7 +62100,7 @@ var tryStartOllama = async (logger, params) => new Promise((resolve) => {
|
|
|
60892
62100
|
if (params?.keepAlive) {
|
|
60893
62101
|
env.OLLAMA_KEEP_ALIVE = params.keepAlive;
|
|
60894
62102
|
}
|
|
60895
|
-
const proc =
|
|
62103
|
+
const proc = spawn6(bin, ["serve"], {
|
|
60896
62104
|
detached: true,
|
|
60897
62105
|
stdio: "ignore",
|
|
60898
62106
|
env
|
|
@@ -60908,7 +62116,7 @@ var tryStartOllama = async (logger, params) => new Promise((resolve) => {
|
|
|
60908
62116
|
host,
|
|
60909
62117
|
keepAlive: params?.keepAlive
|
|
60910
62118
|
});
|
|
60911
|
-
|
|
62119
|
+
resolve3(false);
|
|
60912
62120
|
});
|
|
60913
62121
|
proc.once("exit", (code, signal) => {
|
|
60914
62122
|
if (settled)
|
|
@@ -60921,7 +62129,7 @@ var tryStartOllama = async (logger, params) => new Promise((resolve) => {
|
|
|
60921
62129
|
host,
|
|
60922
62130
|
keepAlive: params?.keepAlive
|
|
60923
62131
|
});
|
|
60924
|
-
|
|
62132
|
+
resolve3(false);
|
|
60925
62133
|
});
|
|
60926
62134
|
setTimeout(() => {
|
|
60927
62135
|
if (settled)
|
|
@@ -60932,7 +62140,7 @@ var tryStartOllama = async (logger, params) => new Promise((resolve) => {
|
|
|
60932
62140
|
host,
|
|
60933
62141
|
keepAlive: params?.keepAlive
|
|
60934
62142
|
});
|
|
60935
|
-
|
|
62143
|
+
resolve3(true);
|
|
60936
62144
|
}, 300);
|
|
60937
62145
|
} catch (error) {
|
|
60938
62146
|
logger.warn("ollama_autostart_failed", {
|
|
@@ -60941,7 +62149,7 @@ var tryStartOllama = async (logger, params) => new Promise((resolve) => {
|
|
|
60941
62149
|
host: resolveOllamaHost(params?.baseUrl),
|
|
60942
62150
|
keepAlive: params?.keepAlive
|
|
60943
62151
|
});
|
|
60944
|
-
|
|
62152
|
+
resolve3(false);
|
|
60945
62153
|
}
|
|
60946
62154
|
});
|
|
60947
62155
|
async function fetchOllamaModels(entry, providerId, logger) {
|
|
@@ -61667,25 +62875,108 @@ function acquireGatewayInstanceLock(params) {
|
|
|
61667
62875
|
throw new Error(`Gateway instance lock unavailable: ${lockPath}`);
|
|
61668
62876
|
}
|
|
61669
62877
|
|
|
62878
|
+
// apps/gateway/dist/chitragupta-bridge/bridge.js
|
|
62879
|
+
import { dirname as dirname2, extname, resolve as resolve2 } from "node:path";
|
|
62880
|
+
|
|
62881
|
+
// apps/gateway/dist/chitragupta-bridge/turiya-helpers.js
|
|
62882
|
+
async function classifyTuriya(baseUrls, timeoutMs, params) {
|
|
62883
|
+
const text = params.text?.trim();
|
|
62884
|
+
if (!text)
|
|
62885
|
+
return null;
|
|
62886
|
+
for (const baseUrl of baseUrls) {
|
|
62887
|
+
const controller = new AbortController();
|
|
62888
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
62889
|
+
try {
|
|
62890
|
+
const response = await fetch(`${baseUrl}/api/turiya/classify`, {
|
|
62891
|
+
method: "POST",
|
|
62892
|
+
headers: { "content-type": "application/json" },
|
|
62893
|
+
body: JSON.stringify({ text, messageCount: params.messageCount, hasTools: params.hasTools, memoryHits: params.memoryHits }),
|
|
62894
|
+
signal: controller.signal
|
|
62895
|
+
});
|
|
62896
|
+
if (!response.ok)
|
|
62897
|
+
continue;
|
|
62898
|
+
const payload = await response.json();
|
|
62899
|
+
if (typeof payload.tier !== "string")
|
|
62900
|
+
continue;
|
|
62901
|
+
return {
|
|
62902
|
+
tier: payload.tier,
|
|
62903
|
+
confidence: typeof payload.confidence === "number" ? payload.confidence : 0.5,
|
|
62904
|
+
costEstimate: typeof payload.costEstimate === "number" ? payload.costEstimate : 0
|
|
62905
|
+
};
|
|
62906
|
+
} catch {
|
|
62907
|
+
} finally {
|
|
62908
|
+
clearTimeout(timeout);
|
|
62909
|
+
}
|
|
62910
|
+
}
|
|
62911
|
+
return null;
|
|
62912
|
+
}
|
|
62913
|
+
async function recordTuriyaOutcome(baseUrls, timeoutMs, params) {
|
|
62914
|
+
for (const baseUrl of baseUrls) {
|
|
62915
|
+
const controller = new AbortController();
|
|
62916
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
62917
|
+
try {
|
|
62918
|
+
await fetch(`${baseUrl}/api/turiya/outcome`, {
|
|
62919
|
+
method: "POST",
|
|
62920
|
+
headers: { "content-type": "application/json" },
|
|
62921
|
+
body: JSON.stringify(params),
|
|
62922
|
+
signal: controller.signal
|
|
62923
|
+
});
|
|
62924
|
+
return;
|
|
62925
|
+
} catch {
|
|
62926
|
+
} finally {
|
|
62927
|
+
clearTimeout(timeout);
|
|
62928
|
+
}
|
|
62929
|
+
}
|
|
62930
|
+
}
|
|
62931
|
+
|
|
61670
62932
|
// apps/gateway/dist/chitragupta-bridge/bridge.js
|
|
61671
62933
|
var CACHE_TTL_MS = 500;
|
|
62934
|
+
var DEFAULT_SKILL_LEARNER_STATE_FILE = "skill-learner-state.json";
|
|
61672
62935
|
var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
61673
62936
|
orchestrator;
|
|
62937
|
+
vidyaBridge;
|
|
61674
62938
|
logger;
|
|
61675
62939
|
margaBaseUrl;
|
|
61676
62940
|
margaTimeoutMs;
|
|
61677
62941
|
skillsUsedPerSession = /* @__PURE__ */ new Map();
|
|
61678
62942
|
shiksha;
|
|
61679
62943
|
crystallizer;
|
|
62944
|
+
skillResolver;
|
|
62945
|
+
skillLearner;
|
|
62946
|
+
skillLearnerStatePath;
|
|
62947
|
+
loggedShikshaUnavailable = false;
|
|
62948
|
+
loggedCrystallizerUnavailable = false;
|
|
61680
62949
|
recCache = null;
|
|
61681
62950
|
recCacheQuery = "";
|
|
61682
|
-
constructor(orchestrator, logger, margaBaseUrl, margaTimeoutMs, shiksha = null, crystallizer = null) {
|
|
62951
|
+
constructor(orchestrator, vidyaBridge, logger, margaBaseUrl, margaTimeoutMs, shiksha = null, crystallizer = null, skillResolver, skillLearner, skillLearnerStatePath) {
|
|
61683
62952
|
this.orchestrator = orchestrator;
|
|
62953
|
+
this.vidyaBridge = vidyaBridge;
|
|
61684
62954
|
this.logger = logger;
|
|
61685
62955
|
this.margaBaseUrl = margaBaseUrl.replace(/\/+$/, "");
|
|
61686
62956
|
this.margaTimeoutMs = margaTimeoutMs;
|
|
61687
62957
|
this.shiksha = shiksha;
|
|
61688
62958
|
this.crystallizer = crystallizer;
|
|
62959
|
+
this.skillResolver = skillResolver ?? new SkillResolver({
|
|
62960
|
+
logger: { info: (m, d) => logger.info(m, d), warn: (m, d) => logger.warn(m, d) }
|
|
62961
|
+
});
|
|
62962
|
+
this.skillLearner = skillLearner ?? new SkillLearner({
|
|
62963
|
+
logger: { info: (m, d) => logger.info(m, d), warn: (m, d) => logger.warn(m, d) }
|
|
62964
|
+
});
|
|
62965
|
+
this.skillLearnerStatePath = skillLearnerStatePath ?? _ChitraguptaBridge.resolveSkillLearnerStatePath();
|
|
62966
|
+
}
|
|
62967
|
+
static resolveSkillLearnerStatePath(configPersistPath) {
|
|
62968
|
+
const explicitPath = process.env.VAAYU_SKILL_LEARNER_STATE_PATH?.trim();
|
|
62969
|
+
if (explicitPath)
|
|
62970
|
+
return resolve2(explicitPath);
|
|
62971
|
+
const configuredBase = configPersistPath?.trim();
|
|
62972
|
+
if (configuredBase) {
|
|
62973
|
+
const baseDir = extname(configuredBase) ? dirname2(configuredBase) : configuredBase;
|
|
62974
|
+
return resolve2(baseDir, DEFAULT_SKILL_LEARNER_STATE_FILE);
|
|
62975
|
+
}
|
|
62976
|
+
const home = process.env.CHITRAGUPTA_HOME?.trim();
|
|
62977
|
+
if (home)
|
|
62978
|
+
return resolve2(home, DEFAULT_SKILL_LEARNER_STATE_FILE);
|
|
62979
|
+
return resolve2(process.cwd(), ".chitragupta", DEFAULT_SKILL_LEARNER_STATE_FILE);
|
|
61689
62980
|
}
|
|
61690
62981
|
/* ── Factory ───────────────────────────────────────────────────── */
|
|
61691
62982
|
/** Create a bridge instance. Returns null if Chitragupta is unavailable. */
|
|
@@ -61705,24 +62996,29 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61705
62996
|
}
|
|
61706
62997
|
if (!vidya)
|
|
61707
62998
|
throw lastError ?? new Error("Chitragupta skill runtime not found");
|
|
61708
|
-
const
|
|
61709
|
-
const
|
|
62999
|
+
const Ctor = vidya;
|
|
63000
|
+
const registry = new Ctor.SkillRegistry();
|
|
63001
|
+
const bridge = new Ctor.VidyaBridge(registry);
|
|
61710
63002
|
const autoLearn = config.enableAutoLearn ?? false;
|
|
61711
63003
|
let shiksha = null;
|
|
61712
|
-
if (autoLearn &&
|
|
63004
|
+
if (autoLearn && Ctor.ShikshaController) {
|
|
61713
63005
|
try {
|
|
61714
|
-
shiksha = new
|
|
63006
|
+
shiksha = new Ctor.ShikshaController({ registry });
|
|
61715
63007
|
} catch {
|
|
61716
63008
|
}
|
|
61717
63009
|
}
|
|
63010
|
+
if (autoLearn && !shiksha)
|
|
63011
|
+
logger.warn("chitragupta_shiksha_unavailable", { autoLearn });
|
|
61718
63012
|
let crystallizer = null;
|
|
61719
|
-
if (
|
|
63013
|
+
if (Ctor.SkillCrystallizer) {
|
|
61720
63014
|
try {
|
|
61721
|
-
crystallizer = new
|
|
63015
|
+
crystallizer = new Ctor.SkillCrystallizer();
|
|
61722
63016
|
} catch {
|
|
61723
63017
|
}
|
|
61724
63018
|
}
|
|
61725
|
-
|
|
63019
|
+
if (!crystallizer)
|
|
63020
|
+
logger.warn("chitragupta_crystallizer_unavailable");
|
|
63021
|
+
const orchestrator = new Ctor.VidyaOrchestrator({ registry, bridge }, { persistPath: config.persistPath, enableAutoLearn: autoLearn, enableAutoComposition: true });
|
|
61726
63022
|
await orchestrator.initialize();
|
|
61727
63023
|
logger.info("chitragupta_bridge_initialized", {
|
|
61728
63024
|
initialized: orchestrator.isInitialized,
|
|
@@ -61733,14 +63029,17 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61733
63029
|
const margaBaseUrl = process.env.VAAYU_CHITRAGUPTA_BASE_URL?.trim() || "http://localhost:3141";
|
|
61734
63030
|
const timeoutFromEnv = Number.parseInt(process.env.VAAYU_CHITRAGUPTA_MARGA_TIMEOUT_MS ?? "", 10);
|
|
61735
63031
|
const margaTimeoutMs = Number.isFinite(timeoutFromEnv) && timeoutFromEnv > 0 ? timeoutFromEnv : 150;
|
|
61736
|
-
|
|
63032
|
+
const logAdapter = { info: (m, d) => logger.info(m, d), warn: (m, d) => logger.warn(m, d) };
|
|
63033
|
+
const skillResolver = new SkillResolver({ logger: logAdapter });
|
|
63034
|
+
const skillLearnerStatePath = _ChitraguptaBridge.resolveSkillLearnerStatePath(config.persistPath);
|
|
63035
|
+
const skillLearner = await SkillLearner.load(skillLearnerStatePath, { logger: logAdapter }) ?? new SkillLearner({ logger: logAdapter });
|
|
63036
|
+
return new _ChitraguptaBridge(orchestrator, bridge, logger, margaBaseUrl, margaTimeoutMs, shiksha, crystallizer, skillResolver, skillLearner, skillLearnerStatePath);
|
|
61737
63037
|
} catch (err) {
|
|
61738
|
-
logger.debug("chitragupta_bridge_unavailable", {
|
|
61739
|
-
reason: err instanceof Error ? err.message : String(err)
|
|
61740
|
-
});
|
|
63038
|
+
logger.debug("chitragupta_bridge_unavailable", { reason: err instanceof Error ? err.message : String(err) });
|
|
61741
63039
|
return null;
|
|
61742
63040
|
}
|
|
61743
63041
|
}
|
|
63042
|
+
/** Get Marga base URL candidates for HTTP calls. */
|
|
61744
63043
|
getMargaBaseUrlCandidates() {
|
|
61745
63044
|
const c = this.margaBaseUrl.replace(/\/+$/, "");
|
|
61746
63045
|
const r = [c];
|
|
@@ -61750,6 +63049,7 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61750
63049
|
r.push("http://127.0.0.1:3141");
|
|
61751
63050
|
return r;
|
|
61752
63051
|
}
|
|
63052
|
+
/* ── Marga Routing ────────────────────────────────────────────── */
|
|
61753
63053
|
/** Query Chitragupta's stateless routing endpoint. Returns null when unavailable. */
|
|
61754
63054
|
async decideRoute(params) {
|
|
61755
63055
|
const message = params.message?.trim();
|
|
@@ -61774,10 +63074,6 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61774
63074
|
});
|
|
61775
63075
|
if (!response.ok) {
|
|
61776
63076
|
lastError = `HTTP ${response.status}`;
|
|
61777
|
-
this.logger.debug("chitragupta_marga_http_error", {
|
|
61778
|
-
status: response.status,
|
|
61779
|
-
baseUrl
|
|
61780
|
-
});
|
|
61781
63077
|
continue;
|
|
61782
63078
|
}
|
|
61783
63079
|
const payload = await response.json();
|
|
@@ -61785,17 +63081,8 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61785
63081
|
const modelId = typeof payload.modelId === "string" ? payload.modelId.trim() : "";
|
|
61786
63082
|
if (!providerId || !modelId) {
|
|
61787
63083
|
lastError = "invalid_payload";
|
|
61788
|
-
this.logger.debug("chitragupta_marga_invalid_payload", {
|
|
61789
|
-
baseUrl
|
|
61790
|
-
});
|
|
61791
63084
|
continue;
|
|
61792
63085
|
}
|
|
61793
|
-
if (baseUrl !== this.margaBaseUrl) {
|
|
61794
|
-
this.logger.debug("chitragupta_marga_baseurl_fallback_used", {
|
|
61795
|
-
configuredBaseUrl: this.margaBaseUrl,
|
|
61796
|
-
resolvedBaseUrl: baseUrl
|
|
61797
|
-
});
|
|
61798
|
-
}
|
|
61799
63086
|
return {
|
|
61800
63087
|
providerId,
|
|
61801
63088
|
modelId,
|
|
@@ -61811,12 +63098,28 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61811
63098
|
clearTimeout(timeout);
|
|
61812
63099
|
}
|
|
61813
63100
|
}
|
|
61814
|
-
this.logger.debug("chitragupta_marga_unavailable", {
|
|
61815
|
-
reason: lastError,
|
|
61816
|
-
baseUrl: this.margaBaseUrl
|
|
61817
|
-
});
|
|
63101
|
+
this.logger.debug("chitragupta_marga_unavailable", { reason: lastError, baseUrl: this.margaBaseUrl });
|
|
61818
63102
|
return null;
|
|
61819
63103
|
}
|
|
63104
|
+
/* ── Tool Registration ────────────────────────────────────────── */
|
|
63105
|
+
/** Register gateway tools with Vidya. Safe no-op when unavailable. */
|
|
63106
|
+
registerTools(tools) {
|
|
63107
|
+
if (!tools.length)
|
|
63108
|
+
return 0;
|
|
63109
|
+
const fn = this.vidyaBridge?.registerToolsAsSkills;
|
|
63110
|
+
if (typeof fn !== "function")
|
|
63111
|
+
return 0;
|
|
63112
|
+
try {
|
|
63113
|
+
const normalized = tools.map((t2) => ({ name: t2.name, description: t2.description ?? "", inputSchema: t2.inputSchema, tags: t2.tags, aliases: t2.aliases })).filter((t2) => t2.name.trim().length > 0);
|
|
63114
|
+
if (!normalized.length)
|
|
63115
|
+
return 0;
|
|
63116
|
+
fn.call(this.vidyaBridge, normalized);
|
|
63117
|
+
return normalized.length;
|
|
63118
|
+
} catch (error) {
|
|
63119
|
+
this.logger.debug("chitragupta_bridge_tool_registration_failed", { error: error instanceof Error ? error.message : String(error) });
|
|
63120
|
+
return 0;
|
|
63121
|
+
}
|
|
63122
|
+
}
|
|
61820
63123
|
/* ── Recommend ─────────────────────────────────────────────────── */
|
|
61821
63124
|
/** Return recommended skill/tool names for a query (cached per-turn). */
|
|
61822
63125
|
recommend(query) {
|
|
@@ -61824,8 +63127,7 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61824
63127
|
if (this.recCache && this.recCacheQuery === query && Date.now() - this.recCache.ts < CACHE_TTL_MS) {
|
|
61825
63128
|
return this.recCache.names;
|
|
61826
63129
|
}
|
|
61827
|
-
const
|
|
61828
|
-
const names = matches.map((m) => m.manifest.name);
|
|
63130
|
+
const names = this.orchestrator.recommend(query).map((m) => m.manifest.name);
|
|
61829
63131
|
this.recCache = { names, ts: Date.now() };
|
|
61830
63132
|
this.recCacheQuery = query;
|
|
61831
63133
|
return names;
|
|
@@ -61840,17 +63142,14 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61840
63142
|
this.orchestrator.onSkillExecuted(toolName, success, latencyMs, sessionId);
|
|
61841
63143
|
if (sessionId) {
|
|
61842
63144
|
const list = this.skillsUsedPerSession.get(sessionId) ?? [];
|
|
61843
|
-
if (!list.includes(toolName))
|
|
63145
|
+
if (!list.includes(toolName))
|
|
61844
63146
|
list.push(toolName);
|
|
61845
|
-
}
|
|
61846
63147
|
this.skillsUsedPerSession.set(sessionId, list);
|
|
61847
63148
|
}
|
|
61848
63149
|
} catch {
|
|
61849
63150
|
}
|
|
61850
63151
|
}
|
|
61851
|
-
/**
|
|
61852
|
-
* Report when the LLM picks a different tool than Chitragupta recommended.
|
|
61853
|
-
*/
|
|
63152
|
+
/** Report when the LLM picks a different tool than Chitragupta recommended. */
|
|
61854
63153
|
onSkillRejected(rejectedTool, chosenTool) {
|
|
61855
63154
|
try {
|
|
61856
63155
|
this.orchestrator.onSkillRejected(rejectedTool, chosenTool);
|
|
@@ -61858,113 +63157,138 @@ var ChitraguptaBridge = class _ChitraguptaBridge {
|
|
|
61858
63157
|
}
|
|
61859
63158
|
}
|
|
61860
63159
|
/* ── Session lifecycle ─────────────────────────────────────────── */
|
|
61861
|
-
/**
|
|
61862
|
-
* Flush skill tracking data for a completed session.
|
|
61863
|
-
*/
|
|
63160
|
+
/** Flush skill tracking data for a completed session. */
|
|
61864
63161
|
onSessionEnd(sessionId) {
|
|
61865
63162
|
try {
|
|
61866
63163
|
const skillsUsed = this.skillsUsedPerSession.get(sessionId) ?? [];
|
|
61867
63164
|
this.orchestrator.onSessionEnd(sessionId, skillsUsed);
|
|
61868
63165
|
this.skillsUsedPerSession.delete(sessionId);
|
|
63166
|
+
void this.skillLearner.flush(this.skillLearnerStatePath).catch((error) => {
|
|
63167
|
+
this.logger.warn("skill_learner_flush_failed", { error: error instanceof Error ? error.message : String(error) });
|
|
63168
|
+
});
|
|
61869
63169
|
} catch {
|
|
61870
63170
|
}
|
|
61871
63171
|
}
|
|
61872
|
-
/* ── Crystallization Pipeline
|
|
63172
|
+
/* ── Crystallization Pipeline ─────────────────────────────────── */
|
|
61873
63173
|
/** Run crystallization on mature Vidhis. Fire-and-forget safe. */
|
|
61874
63174
|
tryCrystallize(vidhis) {
|
|
61875
63175
|
try {
|
|
61876
|
-
if (
|
|
63176
|
+
if (vidhis.length === 0)
|
|
61877
63177
|
return 0;
|
|
63178
|
+
if (!this.crystallizer) {
|
|
63179
|
+
if (!this.loggedCrystallizerUnavailable) {
|
|
63180
|
+
this.loggedCrystallizerUnavailable = true;
|
|
63181
|
+
this.logger.warn("chitragupta_crystallizer_unavailable");
|
|
63182
|
+
}
|
|
63183
|
+
return 0;
|
|
63184
|
+
}
|
|
61878
63185
|
const results = this.crystallizer.crystallize([...vidhis]);
|
|
61879
63186
|
const ok = results.filter((s) => s.status === "registered" || s.status === "approved");
|
|
61880
|
-
if (ok.length > 0)
|
|
63187
|
+
if (ok.length > 0)
|
|
61881
63188
|
this.logger.info("chitragupta_crystallized_skills", { count: ok.length, names: ok.map((s) => s.skillName) });
|
|
61882
|
-
}
|
|
61883
63189
|
return ok.length;
|
|
61884
63190
|
} catch {
|
|
61885
63191
|
return 0;
|
|
61886
63192
|
}
|
|
61887
63193
|
}
|
|
61888
|
-
/* ── Proactive Scan / Vasana
|
|
63194
|
+
/* ── Proactive Scan / Vasana ──────────────────────────────────── */
|
|
61889
63195
|
/** Scan Vasana tendencies for proactive skill learning. Fire-and-forget safe. */
|
|
61890
63196
|
proactiveScan(vasanas) {
|
|
61891
63197
|
try {
|
|
61892
|
-
if (
|
|
63198
|
+
if (vasanas.length === 0)
|
|
61893
63199
|
return [];
|
|
63200
|
+
if (!this.shiksha) {
|
|
63201
|
+
if (!this.loggedShikshaUnavailable) {
|
|
63202
|
+
this.loggedShikshaUnavailable = true;
|
|
63203
|
+
this.logger.warn("chitragupta_shiksha_unavailable", { autoLearn: false });
|
|
63204
|
+
}
|
|
63205
|
+
return [];
|
|
63206
|
+
}
|
|
61894
63207
|
const suggestions = this.shiksha.proactiveScan(vasanas);
|
|
61895
|
-
if (suggestions.length > 0)
|
|
63208
|
+
if (suggestions.length > 0)
|
|
61896
63209
|
this.logger.info("chitragupta_proactive_suggestions", { count: suggestions.length, topics: suggestions.slice(0, 5) });
|
|
61897
|
-
}
|
|
61898
63210
|
return suggestions;
|
|
61899
63211
|
} catch {
|
|
61900
63212
|
return [];
|
|
61901
63213
|
}
|
|
61902
63214
|
}
|
|
61903
|
-
/* ── Turiya Bandit Routing
|
|
63215
|
+
/* ── Turiya Bandit Routing (delegated) ────────────────────────── */
|
|
61904
63216
|
/** Query Chitragupta's Turiya contextual bandit. Returns null when unavailable. */
|
|
61905
63217
|
async classifyTuriya(params) {
|
|
61906
|
-
|
|
61907
|
-
|
|
63218
|
+
return classifyTuriya(this.getMargaBaseUrlCandidates(), this.margaTimeoutMs, params);
|
|
63219
|
+
}
|
|
63220
|
+
/** Send reward feedback to Chitragupta's Turiya router. Fire-and-forget. */
|
|
63221
|
+
async recordTuriyaOutcome(params) {
|
|
63222
|
+
return recordTuriyaOutcome(this.getMargaBaseUrlCandidates(), this.margaTimeoutMs, params);
|
|
63223
|
+
}
|
|
63224
|
+
/* ── Skill Resolution Pipeline ────────────────────────────────── */
|
|
63225
|
+
/** Search for a skill matching the given intent. Returns first safe candidate or null. */
|
|
63226
|
+
async resolveSkill(intent) {
|
|
63227
|
+
try {
|
|
63228
|
+
const candidates = await this.skillResolver.search(intent);
|
|
63229
|
+
for (const candidate of candidates) {
|
|
63230
|
+
const guardResult = this.skillResolver.guard(candidate);
|
|
63231
|
+
if (guardResult.safe)
|
|
63232
|
+
return candidate;
|
|
63233
|
+
this.logger.debug("skill_candidate_blocked", { name: candidate.name, reasons: guardResult.blockedReasons });
|
|
63234
|
+
}
|
|
61908
63235
|
return null;
|
|
61909
|
-
|
|
61910
|
-
|
|
61911
|
-
|
|
61912
|
-
|
|
61913
|
-
|
|
61914
|
-
|
|
61915
|
-
|
|
61916
|
-
|
|
61917
|
-
|
|
61918
|
-
|
|
61919
|
-
|
|
61920
|
-
|
|
61921
|
-
memoryHits: params.memoryHits
|
|
61922
|
-
}),
|
|
61923
|
-
signal: controller.signal
|
|
63236
|
+
} catch {
|
|
63237
|
+
return null;
|
|
63238
|
+
}
|
|
63239
|
+
}
|
|
63240
|
+
/** Record a skill gap and auto-trigger search if threshold exceeded. */
|
|
63241
|
+
recordSkillGap(intent, sessionId) {
|
|
63242
|
+
try {
|
|
63243
|
+
this.skillLearner.recordGap(intent, sessionId);
|
|
63244
|
+
const actionable = this.skillLearner.getActionableGaps();
|
|
63245
|
+
if (actionable.length > 0) {
|
|
63246
|
+
this.logger.info("skill_gaps_actionable", { count: actionable.length, intents: actionable.map((g) => g.intent) });
|
|
63247
|
+
void this.autoResolveGaps(actionable).catch(() => {
|
|
61924
63248
|
});
|
|
61925
|
-
if (!response.ok)
|
|
61926
|
-
continue;
|
|
61927
|
-
const payload = await response.json();
|
|
61928
|
-
if (typeof payload.tier !== "string")
|
|
61929
|
-
continue;
|
|
61930
|
-
return {
|
|
61931
|
-
tier: payload.tier,
|
|
61932
|
-
confidence: typeof payload.confidence === "number" ? payload.confidence : 0.5,
|
|
61933
|
-
costEstimate: typeof payload.costEstimate === "number" ? payload.costEstimate : 0
|
|
61934
|
-
};
|
|
61935
|
-
} catch {
|
|
61936
|
-
} finally {
|
|
61937
|
-
clearTimeout(timeout);
|
|
61938
63249
|
}
|
|
63250
|
+
} catch {
|
|
61939
63251
|
}
|
|
61940
|
-
return null;
|
|
61941
63252
|
}
|
|
61942
|
-
/**
|
|
61943
|
-
|
|
61944
|
-
|
|
61945
|
-
|
|
61946
|
-
|
|
61947
|
-
|
|
61948
|
-
|
|
61949
|
-
|
|
61950
|
-
|
|
61951
|
-
|
|
61952
|
-
|
|
61953
|
-
|
|
61954
|
-
});
|
|
61955
|
-
return;
|
|
61956
|
-
} catch {
|
|
61957
|
-
} finally {
|
|
61958
|
-
clearTimeout(timeout);
|
|
63253
|
+
/**
|
|
63254
|
+
* Auto-resolve skill gaps by searching for and installing matching candidates.
|
|
63255
|
+
* Processes at most 3 gaps per invocation to avoid runaway resolution loops.
|
|
63256
|
+
*/
|
|
63257
|
+
async autoResolveGaps(gaps) {
|
|
63258
|
+
for (const gap of gaps.slice(0, 3)) {
|
|
63259
|
+
const candidate = await this.resolveSkill(gap.intent);
|
|
63260
|
+
if (candidate) {
|
|
63261
|
+
const installed = await this.skillResolver.install(candidate);
|
|
63262
|
+
if (installed) {
|
|
63263
|
+
this.logger.info("skill_auto_installed", { name: installed.name, source: installed.source });
|
|
63264
|
+
}
|
|
61959
63265
|
}
|
|
61960
63266
|
}
|
|
61961
63267
|
}
|
|
63268
|
+
/** Record skill execution result for learning. */
|
|
63269
|
+
recordSkillFeedback(skillName, intent, sessionId, success, feedback) {
|
|
63270
|
+
try {
|
|
63271
|
+
if (success) {
|
|
63272
|
+
this.skillLearner.recordSuccess(skillName, intent, sessionId, feedback);
|
|
63273
|
+
if (this.skillLearner.evaluatePromotion(skillName))
|
|
63274
|
+
this.logger.info("skill_promotion_ready", { skillName });
|
|
63275
|
+
} else {
|
|
63276
|
+
this.skillLearner.recordFailure(skillName, intent, sessionId, feedback ?? "unknown");
|
|
63277
|
+
if (this.skillLearner.evaluateDemotion(skillName))
|
|
63278
|
+
this.logger.warn("skill_demotion_triggered", { skillName });
|
|
63279
|
+
}
|
|
63280
|
+
} catch {
|
|
63281
|
+
}
|
|
63282
|
+
}
|
|
61962
63283
|
/* ── Cleanup ───────────────────────────────────────────────────── */
|
|
61963
63284
|
/** Persist state and release resources. */
|
|
61964
63285
|
dispose() {
|
|
61965
63286
|
try {
|
|
61966
63287
|
this.orchestrator.persist().catch(() => {
|
|
61967
63288
|
});
|
|
63289
|
+
void this.skillLearner.flush(this.skillLearnerStatePath).catch((error) => {
|
|
63290
|
+
this.logger.warn("skill_learner_flush_failed", { error: error instanceof Error ? error.message : String(error) });
|
|
63291
|
+
});
|
|
61968
63292
|
this.skillsUsedPerSession.clear();
|
|
61969
63293
|
this.recCache = null;
|
|
61970
63294
|
this.logger.info("chitragupta_bridge_disposed");
|
|
@@ -62508,22 +63832,22 @@ function json(res, status, body) {
|
|
|
62508
63832
|
res.end(JSON.stringify(body));
|
|
62509
63833
|
}
|
|
62510
63834
|
function readBody(req) {
|
|
62511
|
-
return new Promise((
|
|
63835
|
+
return new Promise((resolve3) => {
|
|
62512
63836
|
const chunks = [];
|
|
62513
63837
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
62514
63838
|
req.on("end", () => {
|
|
62515
63839
|
const raw = Buffer.concat(chunks).toString("utf8");
|
|
62516
63840
|
if (!raw) {
|
|
62517
|
-
|
|
63841
|
+
resolve3(void 0);
|
|
62518
63842
|
return;
|
|
62519
63843
|
}
|
|
62520
63844
|
try {
|
|
62521
|
-
|
|
63845
|
+
resolve3(JSON.parse(raw));
|
|
62522
63846
|
} catch {
|
|
62523
|
-
|
|
63847
|
+
resolve3(void 0);
|
|
62524
63848
|
}
|
|
62525
63849
|
});
|
|
62526
|
-
req.on("error", () =>
|
|
63850
|
+
req.on("error", () => resolve3(void 0));
|
|
62527
63851
|
});
|
|
62528
63852
|
}
|
|
62529
63853
|
|
|
@@ -65070,7 +66394,7 @@ ${issues}`
|
|
|
65070
66394
|
if (records.length === 0) {
|
|
65071
66395
|
return "No subagents have run yet.";
|
|
65072
66396
|
}
|
|
65073
|
-
const { buildAgentTree: buildAgentTree2 } = await import("./chunks/tree-
|
|
66397
|
+
const { buildAgentTree: buildAgentTree2 } = await import("./chunks/tree-FIUVGJ5J.js");
|
|
65074
66398
|
const roots = buildAgentTree2(records);
|
|
65075
66399
|
const lines = [];
|
|
65076
66400
|
const render = (nodes, depth) => {
|
|
@@ -65185,7 +66509,7 @@ import path46 from "node:path";
|
|
|
65185
66509
|
import fs45 from "node:fs";
|
|
65186
66510
|
import { Readable } from "node:stream";
|
|
65187
66511
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
65188
|
-
import { spawn as
|
|
66512
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
65189
66513
|
import { randomUUID as randomUUID42 } from "node:crypto";
|
|
65190
66514
|
function sanitizeArtifactFileName(value) {
|
|
65191
66515
|
const base = path46.basename(value || "file");
|
|
@@ -65244,15 +66568,15 @@ async function stageTelegramAttachment(params) {
|
|
|
65244
66568
|
return { localPath, downloadUrl: url };
|
|
65245
66569
|
}
|
|
65246
66570
|
async function extractPdfText(pdfPath) {
|
|
65247
|
-
return await new Promise((
|
|
65248
|
-
const child =
|
|
66571
|
+
return await new Promise((resolve3) => {
|
|
66572
|
+
const child = spawn7("pdftotext", ["-layout", pdfPath, "-"], {
|
|
65249
66573
|
stdio: ["ignore", "pipe", "pipe"]
|
|
65250
66574
|
});
|
|
65251
66575
|
let stdout = "";
|
|
65252
66576
|
let stderr = "";
|
|
65253
66577
|
const timeout = setTimeout(() => {
|
|
65254
66578
|
child.kill("SIGKILL");
|
|
65255
|
-
|
|
66579
|
+
resolve3({ ok: false, error: "pdftotext_timeout" });
|
|
65256
66580
|
}, 6e4);
|
|
65257
66581
|
child.stdout.on("data", (chunk) => {
|
|
65258
66582
|
stdout += chunk.toString();
|
|
@@ -65263,18 +66587,18 @@ async function extractPdfText(pdfPath) {
|
|
|
65263
66587
|
child.on("error", (err) => {
|
|
65264
66588
|
clearTimeout(timeout);
|
|
65265
66589
|
const code = err?.code;
|
|
65266
|
-
|
|
66590
|
+
resolve3({ ok: false, error: code === "ENOENT" ? "pdftotext_missing" : err.message });
|
|
65267
66591
|
});
|
|
65268
66592
|
child.on("close", (code) => {
|
|
65269
66593
|
clearTimeout(timeout);
|
|
65270
66594
|
if (code !== 0) {
|
|
65271
|
-
|
|
66595
|
+
resolve3({
|
|
65272
66596
|
ok: false,
|
|
65273
66597
|
error: stderr.trim() || `pdftotext_exit_${code}`
|
|
65274
66598
|
});
|
|
65275
66599
|
return;
|
|
65276
66600
|
}
|
|
65277
|
-
|
|
66601
|
+
resolve3({ ok: true, text: stdout });
|
|
65278
66602
|
});
|
|
65279
66603
|
});
|
|
65280
66604
|
}
|
|
@@ -66375,6 +67699,210 @@ function setupIMessage(deps) {
|
|
|
66375
67699
|
return adapter;
|
|
66376
67700
|
}
|
|
66377
67701
|
|
|
67702
|
+
// apps/gateway/dist/channel/tring-setup.js
|
|
67703
|
+
function setupTring(deps) {
|
|
67704
|
+
const { runtime, tringConfig, isChannelAllowed } = deps;
|
|
67705
|
+
const { config, logger, storage, broadcastEvent, sessionIdentityMap } = runtime;
|
|
67706
|
+
const resolveSession = (message) => resolveSessionWithPolicy(storage, {
|
|
67707
|
+
channel: message.channel,
|
|
67708
|
+
chatId: message.chatId,
|
|
67709
|
+
userId: message.userId,
|
|
67710
|
+
chatType: message.chatType,
|
|
67711
|
+
threadId: message.threadId,
|
|
67712
|
+
workspaceId: message.workspaceId
|
|
67713
|
+
}, config.session, sessionIdentityMap);
|
|
67714
|
+
const handler = async (message) => {
|
|
67715
|
+
try {
|
|
67716
|
+
const allowed = await isChannelAllowed(message.channel, message.chatId, message.userId);
|
|
67717
|
+
if (!allowed) {
|
|
67718
|
+
logger.debug("tring_message_rejected", {
|
|
67719
|
+
channel: message.channel,
|
|
67720
|
+
chatId: message.chatId,
|
|
67721
|
+
userId: message.userId,
|
|
67722
|
+
reason: "not_allowed"
|
|
67723
|
+
});
|
|
67724
|
+
return;
|
|
67725
|
+
}
|
|
67726
|
+
broadcastEvent("channel.message", {
|
|
67727
|
+
channel: message.channel,
|
|
67728
|
+
direction: "inbound",
|
|
67729
|
+
chatId: message.chatId,
|
|
67730
|
+
userId: message.userId,
|
|
67731
|
+
text: message.text,
|
|
67732
|
+
time: message.time
|
|
67733
|
+
});
|
|
67734
|
+
const session = await resolveSession(message);
|
|
67735
|
+
const result = await runtime.runAgent({
|
|
67736
|
+
providerId: tringConfig.providerId,
|
|
67737
|
+
model: tringConfig.model,
|
|
67738
|
+
system: tringConfig.system,
|
|
67739
|
+
message: {
|
|
67740
|
+
channel: message.channel,
|
|
67741
|
+
chatId: message.chatId,
|
|
67742
|
+
userId: message.userId,
|
|
67743
|
+
chatType: message.chatType ?? "dm",
|
|
67744
|
+
text: message.text,
|
|
67745
|
+
time: message.time,
|
|
67746
|
+
raw: message.raw
|
|
67747
|
+
}
|
|
67748
|
+
});
|
|
67749
|
+
const reply = result.response.content;
|
|
67750
|
+
if (!reply)
|
|
67751
|
+
return;
|
|
67752
|
+
const platform = message.channel;
|
|
67753
|
+
await adapter.sendMessage(platform, message.chatId, reply);
|
|
67754
|
+
broadcastEvent("channel.message", {
|
|
67755
|
+
channel: message.channel,
|
|
67756
|
+
direction: "outbound",
|
|
67757
|
+
chatId: message.chatId,
|
|
67758
|
+
userId: message.userId,
|
|
67759
|
+
text: reply,
|
|
67760
|
+
time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
67761
|
+
sessionId: session.id
|
|
67762
|
+
});
|
|
67763
|
+
} catch (error) {
|
|
67764
|
+
logger.error("tring_message_handler_error", {
|
|
67765
|
+
error: error instanceof Error ? error.message : String(error),
|
|
67766
|
+
channel: message.channel,
|
|
67767
|
+
chatId: message.chatId
|
|
67768
|
+
});
|
|
67769
|
+
}
|
|
67770
|
+
};
|
|
67771
|
+
const adapter = new TringAdapter({
|
|
67772
|
+
daemonUrl: tringConfig.daemonUrl ?? "http://localhost:8787",
|
|
67773
|
+
tringBin: tringConfig.tringBin,
|
|
67774
|
+
platforms: (tringConfig.platforms ?? ["whatsapp", "telegram", "signal"]).map((platform) => normalizeTringPlatform3(platform)).filter((platform) => Boolean(platform)),
|
|
67775
|
+
pollIntervalMs: tringConfig.pollIntervalMs ?? 2e3,
|
|
67776
|
+
autoStartDaemon: tringConfig.autoStartDaemon ?? true,
|
|
67777
|
+
allowedChats: tringConfig.allowedChats
|
|
67778
|
+
}, handler);
|
|
67779
|
+
return adapter;
|
|
67780
|
+
}
|
|
67781
|
+
function normalizeTringPlatform3(platform) {
|
|
67782
|
+
const normalized = platform.trim().toLowerCase();
|
|
67783
|
+
if (normalized === "whispr")
|
|
67784
|
+
return "signal";
|
|
67785
|
+
if (normalized === "whatsapp" || normalized === "telegram" || normalized === "signal")
|
|
67786
|
+
return normalized;
|
|
67787
|
+
return void 0;
|
|
67788
|
+
}
|
|
67789
|
+
|
|
67790
|
+
// apps/gateway/dist/channel/channel-autostart.js
|
|
67791
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync, mkdirSync } from "node:fs";
|
|
67792
|
+
import { join as join3, dirname as dirname3 } from "node:path";
|
|
67793
|
+
var STATE_FILE_NAME = "channel-pairings.json";
|
|
67794
|
+
var STATE_VERSION = 1;
|
|
67795
|
+
var ChannelAutoStart = class {
|
|
67796
|
+
stateFile;
|
|
67797
|
+
logger;
|
|
67798
|
+
states;
|
|
67799
|
+
constructor(options) {
|
|
67800
|
+
this.stateFile = join3(options.storageRoot, STATE_FILE_NAME);
|
|
67801
|
+
this.logger = options.logger;
|
|
67802
|
+
this.states = /* @__PURE__ */ new Map();
|
|
67803
|
+
}
|
|
67804
|
+
/** Load persisted pairing states from disk. */
|
|
67805
|
+
load() {
|
|
67806
|
+
if (!existsSync4(this.stateFile)) {
|
|
67807
|
+
this.logger.info("channel_autostart_no_state_file", {
|
|
67808
|
+
path: this.stateFile
|
|
67809
|
+
});
|
|
67810
|
+
return;
|
|
67811
|
+
}
|
|
67812
|
+
try {
|
|
67813
|
+
const raw = readFileSync3(this.stateFile, "utf-8");
|
|
67814
|
+
const parsed = JSON.parse(raw);
|
|
67815
|
+
if (!isPersistedState(parsed)) {
|
|
67816
|
+
this.logger.warn("channel_autostart_invalid_state", {
|
|
67817
|
+
path: this.stateFile
|
|
67818
|
+
});
|
|
67819
|
+
return;
|
|
67820
|
+
}
|
|
67821
|
+
for (const entry of parsed.channels) {
|
|
67822
|
+
this.states.set(entry.channel, entry);
|
|
67823
|
+
}
|
|
67824
|
+
this.logger.info("channel_autostart_loaded", {
|
|
67825
|
+
count: this.states.size,
|
|
67826
|
+
channels: [...this.states.keys()]
|
|
67827
|
+
});
|
|
67828
|
+
} catch (err) {
|
|
67829
|
+
this.logger.warn("channel_autostart_load_error", {
|
|
67830
|
+
error: err instanceof Error ? err.message : String(err),
|
|
67831
|
+
path: this.stateFile
|
|
67832
|
+
});
|
|
67833
|
+
}
|
|
67834
|
+
}
|
|
67835
|
+
/** Save current pairing states to disk. */
|
|
67836
|
+
save() {
|
|
67837
|
+
const data2 = {
|
|
67838
|
+
version: STATE_VERSION,
|
|
67839
|
+
channels: [...this.states.values()]
|
|
67840
|
+
};
|
|
67841
|
+
try {
|
|
67842
|
+
const dir = dirname3(this.stateFile);
|
|
67843
|
+
if (!existsSync4(dir)) {
|
|
67844
|
+
mkdirSync(dir, { recursive: true });
|
|
67845
|
+
}
|
|
67846
|
+
writeFileSync(this.stateFile, JSON.stringify(data2, null, 2), "utf-8");
|
|
67847
|
+
this.logger.info("channel_autostart_saved", {
|
|
67848
|
+
count: this.states.size,
|
|
67849
|
+
path: this.stateFile
|
|
67850
|
+
});
|
|
67851
|
+
} catch (err) {
|
|
67852
|
+
this.logger.warn("channel_autostart_save_error", {
|
|
67853
|
+
error: err instanceof Error ? err.message : String(err),
|
|
67854
|
+
path: this.stateFile
|
|
67855
|
+
});
|
|
67856
|
+
}
|
|
67857
|
+
}
|
|
67858
|
+
/** Mark a channel as paired (or unpaired). */
|
|
67859
|
+
setPaired(channel, paired, data2) {
|
|
67860
|
+
const existing = this.states.get(channel);
|
|
67861
|
+
const state = {
|
|
67862
|
+
channel,
|
|
67863
|
+
paired,
|
|
67864
|
+
pairingData: data2 ?? existing?.pairingData,
|
|
67865
|
+
lastActive: (/* @__PURE__ */ new Date()).toISOString()
|
|
67866
|
+
};
|
|
67867
|
+
this.states.set(channel, state);
|
|
67868
|
+
this.logger.info("channel_autostart_set_paired", {
|
|
67869
|
+
channel,
|
|
67870
|
+
paired,
|
|
67871
|
+
hasData: data2 !== void 0
|
|
67872
|
+
});
|
|
67873
|
+
}
|
|
67874
|
+
/** Check if a channel was previously paired. */
|
|
67875
|
+
isPaired(channel) {
|
|
67876
|
+
return this.states.get(channel)?.paired === true;
|
|
67877
|
+
}
|
|
67878
|
+
/** Get all channels currently marked as paired. */
|
|
67879
|
+
getPairedChannels() {
|
|
67880
|
+
return [...this.states.values()].filter((s) => s.paired);
|
|
67881
|
+
}
|
|
67882
|
+
/** Update the lastActive timestamp for a channel. */
|
|
67883
|
+
touch(channel) {
|
|
67884
|
+
const existing = this.states.get(channel);
|
|
67885
|
+
if (existing) {
|
|
67886
|
+
existing.lastActive = (/* @__PURE__ */ new Date()).toISOString();
|
|
67887
|
+
this.states.set(channel, existing);
|
|
67888
|
+
}
|
|
67889
|
+
}
|
|
67890
|
+
/** Get pairing data for a channel (e.g., tokens, config). */
|
|
67891
|
+
getPairingData(channel) {
|
|
67892
|
+
return this.states.get(channel)?.pairingData;
|
|
67893
|
+
}
|
|
67894
|
+
};
|
|
67895
|
+
function isPersistedState(value) {
|
|
67896
|
+
if (typeof value !== "object" || value === null)
|
|
67897
|
+
return false;
|
|
67898
|
+
const obj = value;
|
|
67899
|
+
if (typeof obj["version"] !== "number")
|
|
67900
|
+
return false;
|
|
67901
|
+
if (!Array.isArray(obj["channels"]))
|
|
67902
|
+
return false;
|
|
67903
|
+
return obj["channels"].every((c) => typeof c === "object" && c !== null && typeof c["channel"] === "string" && typeof c["paired"] === "boolean");
|
|
67904
|
+
}
|
|
67905
|
+
|
|
66378
67906
|
// apps/gateway/dist/gateway/restart-notice.js
|
|
66379
67907
|
import fs46 from "node:fs";
|
|
66380
67908
|
import path47 from "node:path";
|
|
@@ -66436,7 +67964,7 @@ async function maybeBootstrapSmritiDev(params) {
|
|
|
66436
67964
|
|
|
66437
67965
|
// apps/gateway/dist/gateway/start-runtime-surface.js
|
|
66438
67966
|
async function startRuntimeSurface(params) {
|
|
66439
|
-
const { state, repoRoot, methods, logger, runtime, idempotency, storage, providers, config, channelPairingStore, channelPairingTtlSeconds, cleanupPairings: cleanupPairings2, isChannelAllowed, sendChannelMessage, broadcastEvent, gwEnv, artifactsRoot, isValidPairingCode: isValidPairingCode2, handleMemoryCommand, handleForgetCommand, createToolApprovalRequest, guardToolExecution: guardToolExecution2, inferProviderFromModel: inferProviderFromModel2, providerModelAliasMap, resolveModelAlias: resolveModelAlias2, normalizeModelId: normalizeModelId2, listProviderModels, formatSafeErrorMessage: formatSafeErrorMessage2, updateWeatherDefaults, telegramAdapterRef, twitterAdapterRef, whatsappAdapterRef, imessageAdapterRef, proactiveManager, storageRoot, smritiClient, profile, smritiSource, smritiAutoMemoryEnabled, smritiAutoMemoryReady, smritiEnabled, smritiApiKey, smritiAutoMemoryRoot, inboxWorker, runtimeServices, flushSmritiMemoryOutbox, clearSessionResetListener, chitraguptaBridge, mcpManager } = params;
|
|
67967
|
+
const { state, repoRoot, methods, logger, runtime, idempotency, storage, providers, config, channelPairingStore, channelPairingTtlSeconds, cleanupPairings: cleanupPairings2, isChannelAllowed, sendChannelMessage, broadcastEvent, gwEnv, artifactsRoot, isValidPairingCode: isValidPairingCode2, handleMemoryCommand, handleForgetCommand, createToolApprovalRequest, guardToolExecution: guardToolExecution2, inferProviderFromModel: inferProviderFromModel2, providerModelAliasMap, resolveModelAlias: resolveModelAlias2, normalizeModelId: normalizeModelId2, listProviderModels, formatSafeErrorMessage: formatSafeErrorMessage2, updateWeatherDefaults, telegramAdapterRef, twitterAdapterRef, whatsappAdapterRef, imessageAdapterRef, tringAdapterRef, proactiveManager, storageRoot, smritiClient, profile, smritiSource, smritiAutoMemoryEnabled, smritiAutoMemoryReady, smritiEnabled, smritiApiKey, smritiAutoMemoryRoot, inboxWorker, runtimeServices, flushSmritiMemoryOutbox, clearSessionResetListener, chitraguptaBridge, mcpManager } = params;
|
|
66440
67968
|
const server = createHttpServer(state, repoRoot, methods, logger, {
|
|
66441
67969
|
storage,
|
|
66442
67970
|
storageConfig: config.storage,
|
|
@@ -66458,6 +67986,17 @@ async function startRuntimeSurface(params) {
|
|
|
66458
67986
|
server.listen(config.gateway.port, config.gateway.host, () => {
|
|
66459
67987
|
logger.info("gateway_listening", { host: config.gateway.host, port: config.gateway.port });
|
|
66460
67988
|
});
|
|
67989
|
+
const autoStart = new ChannelAutoStart({ storageRoot, logger });
|
|
67990
|
+
autoStart.load();
|
|
67991
|
+
for (const state2 of autoStart.getPairedChannels()) {
|
|
67992
|
+
const channelKey = state2.channel;
|
|
67993
|
+
if (!config.channels[channelKey]?.enabled) {
|
|
67994
|
+
logger.info("channel_auto_available", {
|
|
67995
|
+
channel: state2.channel,
|
|
67996
|
+
lastActive: state2.lastActive
|
|
67997
|
+
});
|
|
67998
|
+
}
|
|
67999
|
+
}
|
|
66461
68000
|
if (config.channels.telegram.enabled) {
|
|
66462
68001
|
const geoConfig = {
|
|
66463
68002
|
geoBaseUrl: gwEnv.weather.geoBaseUrl ?? "https://geocoding-api.open-meteo.com/v1",
|
|
@@ -66492,6 +68031,8 @@ async function startRuntimeSurface(params) {
|
|
|
66492
68031
|
});
|
|
66493
68032
|
telegramAdapterRef.set(adapter);
|
|
66494
68033
|
adapter.start();
|
|
68034
|
+
autoStart.setPaired("telegram", true);
|
|
68035
|
+
autoStart.save();
|
|
66495
68036
|
logger.info("telegram_adapter_started", { pollIntervalMs: config.channels.telegram.pollIntervalMs });
|
|
66496
68037
|
}
|
|
66497
68038
|
if (config.channels.twitter.enabled) {
|
|
@@ -66503,6 +68044,8 @@ async function startRuntimeSurface(params) {
|
|
|
66503
68044
|
});
|
|
66504
68045
|
twitterAdapterRef.set(twitterAdapter);
|
|
66505
68046
|
twitterAdapter.start();
|
|
68047
|
+
autoStart.setPaired("twitter", true);
|
|
68048
|
+
autoStart.save();
|
|
66506
68049
|
logger.info("twitter_adapter_started", {
|
|
66507
68050
|
pollIntervalMs: config.channels.twitter.pollIntervalMs,
|
|
66508
68051
|
monitorMentions: config.channels.twitter.monitorMentions
|
|
@@ -66517,6 +68060,8 @@ async function startRuntimeSurface(params) {
|
|
|
66517
68060
|
});
|
|
66518
68061
|
whatsappAdapterRef.set(waAdapter);
|
|
66519
68062
|
waAdapter.start();
|
|
68063
|
+
autoStart.setPaired("whatsapp", true);
|
|
68064
|
+
autoStart.save();
|
|
66520
68065
|
logger.info("whatsapp_adapter_started", { webhookPort: config.channels.whatsapp.webhookPort });
|
|
66521
68066
|
}
|
|
66522
68067
|
if (config.channels.imessage.enabled) {
|
|
@@ -66528,11 +68073,32 @@ async function startRuntimeSurface(params) {
|
|
|
66528
68073
|
});
|
|
66529
68074
|
imessageAdapterRef.set(imAdapter);
|
|
66530
68075
|
imAdapter.start();
|
|
68076
|
+
autoStart.setPaired("imessage", true);
|
|
68077
|
+
autoStart.save();
|
|
66531
68078
|
logger.info("imessage_adapter_started", { pollIntervalMs: config.channels.imessage.pollIntervalMs });
|
|
66532
68079
|
}
|
|
68080
|
+
if (config.channels.tring.enabled) {
|
|
68081
|
+
const tAdapter = setupTring({
|
|
68082
|
+
runtime,
|
|
68083
|
+
tringConfig: config.channels.tring,
|
|
68084
|
+
isChannelAllowed,
|
|
68085
|
+
formatSafeErrorMessage: formatSafeErrorMessage2
|
|
68086
|
+
});
|
|
68087
|
+
tringAdapterRef.set(tAdapter);
|
|
68088
|
+
tAdapter.start();
|
|
68089
|
+
autoStart.setPaired("tring", true);
|
|
68090
|
+
autoStart.save();
|
|
68091
|
+
logger.info("tring_adapter_started", {
|
|
68092
|
+
platforms: config.channels.tring.platforms,
|
|
68093
|
+
pollIntervalMs: config.channels.tring.pollIntervalMs
|
|
68094
|
+
});
|
|
68095
|
+
}
|
|
66533
68096
|
proactiveManager.registerChannel("hub", createHubDelivery(broadcastEvent));
|
|
66534
|
-
|
|
66535
|
-
|
|
68097
|
+
const tringPlatforms = (config.channels.tring.platforms ?? []).map((platform) => normalizeTringPlatform4(platform));
|
|
68098
|
+
const telegramViaTring = config.channels.tring.enabled && tringAdapterRef.get() && tringPlatforms.includes("telegram");
|
|
68099
|
+
const whatsappViaTring = config.channels.tring.enabled && tringAdapterRef.get() && tringPlatforms.includes("whatsapp");
|
|
68100
|
+
if (config.channels.telegram.enabled && telegramAdapterRef.get() || telegramViaTring) {
|
|
68101
|
+
const allowedChats = config.channels.telegram.enabled ? config.channels.telegram.allowedChats ?? [] : config.channels.tring.allowedChats ?? [];
|
|
66536
68102
|
proactiveManager.registerChannel("telegram", createTelegramDelivery((chatId, text) => sendChannelMessage("telegram", chatId, text), () => allowedChats));
|
|
66537
68103
|
logger.info("proactive_telegram_registered", { chatCount: allowedChats.length });
|
|
66538
68104
|
}
|
|
@@ -66541,8 +68107,8 @@ async function startRuntimeSurface(params) {
|
|
|
66541
68107
|
proactiveManager.registerChannel("twitter", createTwitterDelivery((userId, text) => sendChannelMessage("twitter", userId, text), () => allowedUsers));
|
|
66542
68108
|
logger.info("proactive_twitter_registered", { userCount: allowedUsers.length });
|
|
66543
68109
|
}
|
|
66544
|
-
if (config.channels.whatsapp.enabled && whatsappAdapterRef.get()) {
|
|
66545
|
-
const allowedNumbers = config.channels.whatsapp.allowedNumbers ?? [];
|
|
68110
|
+
if (config.channels.whatsapp.enabled && whatsappAdapterRef.get() || whatsappViaTring) {
|
|
68111
|
+
const allowedNumbers = config.channels.whatsapp.enabled ? config.channels.whatsapp.allowedNumbers ?? [] : config.channels.tring.allowedChats ?? [];
|
|
66546
68112
|
proactiveManager.registerChannel("whatsapp", createWhatsAppDelivery((to, text) => sendChannelMessage("whatsapp", to, text), () => allowedNumbers));
|
|
66547
68113
|
logger.info("proactive_whatsapp_registered", { numberCount: allowedNumbers.length });
|
|
66548
68114
|
}
|
|
@@ -66595,6 +68161,9 @@ async function startRuntimeSurface(params) {
|
|
|
66595
68161
|
const imAdapter = imessageAdapterRef.get();
|
|
66596
68162
|
if (imAdapter)
|
|
66597
68163
|
imAdapter.stop?.();
|
|
68164
|
+
const trAdapter = tringAdapterRef.get();
|
|
68165
|
+
if (trAdapter)
|
|
68166
|
+
trAdapter.stop?.();
|
|
66598
68167
|
mcpManager.stopAll?.();
|
|
66599
68168
|
wss.close();
|
|
66600
68169
|
server.close(() => {
|
|
@@ -66606,6 +68175,12 @@ async function startRuntimeSurface(params) {
|
|
|
66606
68175
|
process.on("SIGTERM", shutdown);
|
|
66607
68176
|
logger.info("gateway_started", { uptimeMs: Date.now() - state.startedAt });
|
|
66608
68177
|
}
|
|
68178
|
+
function normalizeTringPlatform4(platform) {
|
|
68179
|
+
const normalized = platform.trim().toLowerCase();
|
|
68180
|
+
if (normalized === "whispr")
|
|
68181
|
+
return "signal";
|
|
68182
|
+
return normalized;
|
|
68183
|
+
}
|
|
66609
68184
|
|
|
66610
68185
|
// apps/gateway/dist/rpc/methods/cores.js
|
|
66611
68186
|
function createCoreMethods(ctx) {
|
|
@@ -69920,11 +71495,11 @@ function createOnboardingMethods(_ctx) {
|
|
|
69920
71495
|
const fs48 = await import("node:fs");
|
|
69921
71496
|
const os12 = await import("node:os");
|
|
69922
71497
|
const path52 = await import("node:path");
|
|
69923
|
-
const { execSync } = await import("node:child_process");
|
|
71498
|
+
const { execSync: execSync2 } = await import("node:child_process");
|
|
69924
71499
|
let codexInstalled = false;
|
|
69925
71500
|
let codexLoggedIn = false;
|
|
69926
71501
|
try {
|
|
69927
|
-
|
|
71502
|
+
execSync2("which codex", { encoding: "utf-8", stdio: "pipe" });
|
|
69928
71503
|
codexInstalled = true;
|
|
69929
71504
|
const codexAuthPath = path52.default.join(process.env.CODEX_HOME ?? path52.default.join(os12.default.homedir(), ".codex"), "auth.json");
|
|
69930
71505
|
if (fs48.default.existsSync(codexAuthPath)) {
|
|
@@ -69935,7 +71510,7 @@ function createOnboardingMethods(_ctx) {
|
|
|
69935
71510
|
let claudeInstalled = false;
|
|
69936
71511
|
let claudeLoggedIn = false;
|
|
69937
71512
|
try {
|
|
69938
|
-
|
|
71513
|
+
execSync2("which claude", { encoding: "utf-8", stdio: "pipe" });
|
|
69939
71514
|
claudeInstalled = true;
|
|
69940
71515
|
const claudeCredPath = path52.default.join(os12.default.homedir(), ".claude", ".credentials.json");
|
|
69941
71516
|
if (fs48.default.existsSync(claudeCredPath)) {
|
|
@@ -70355,7 +71930,7 @@ function buildGatewayMethods(input) {
|
|
|
70355
71930
|
// apps/gateway/dist/gateway/start.js
|
|
70356
71931
|
async function startGateway() {
|
|
70357
71932
|
const core = await setupGatewayCore();
|
|
70358
|
-
let { configPath, config, repoRoot, storageRoot, artifactsRoot, soulPrompt, logger, state, idempotency, providers, providerModelAliasMap, lastAnthropicCallAt, sessionIdentityMap, listProviderModels, storage, profile, getProfile, updateProfile, memoryAllowed, memoryManager, gwEnv, smritiConfig, smritiEnabled, smritiBaseUrl, smritiApiKey, smritiPrefix, smritiOwner, smritiVectorProvider, smritiVectorFallbacks, smritiEmbeddingProviders, smritiRetrieveEnabled, smritiRetrieveLimit, smritiSource, smritiAutoMemoryEnabled, smritiAutoMemoryRoot, smritiAutoMemoryReady, smritiClient, smritiHelpers, toolRegistry, toolPolicy, loadToolPolicyFromFile, mcpManager, guardian, connections, connectionAuth, pendingChallenges, pairingStore, channelPairingStore, deviceActivity, smritiAutoMemorySessions, channelPairingTtlSeconds, telegramAdapterRef, twitterAdapterRef, whatsappAdapterRef, imessageAdapterRef, skillManifestsRef, broadcastEvent, getProvider, sendChannelMessage, isChannelAllowed, runTool, createToolApprovalRequest, executeApprovedTool, handleMemoryCommand, handleForgetCommand, updateWeatherDefaults, pairingStepSeconds, cleanupPairings: cleanupPairings2, isValidPairingCode: isValidPairingCode2 } = core;
|
|
71933
|
+
let { configPath, config, repoRoot, storageRoot, artifactsRoot, soulPrompt, logger, state, idempotency, providers, providerModelAliasMap, lastAnthropicCallAt, sessionIdentityMap, listProviderModels, storage, profile, getProfile, updateProfile, memoryAllowed, memoryManager, gwEnv, smritiConfig, smritiEnabled, smritiBaseUrl, smritiApiKey, smritiPrefix, smritiOwner, smritiVectorProvider, smritiVectorFallbacks, smritiEmbeddingProviders, smritiRetrieveEnabled, smritiRetrieveLimit, smritiSource, smritiAutoMemoryEnabled, smritiAutoMemoryRoot, smritiAutoMemoryReady, smritiClient, smritiHelpers, toolRegistry, toolPolicy, loadToolPolicyFromFile, mcpManager, guardian, connections, connectionAuth, pendingChallenges, pairingStore, channelPairingStore, deviceActivity, smritiAutoMemorySessions, channelPairingTtlSeconds, telegramAdapterRef, twitterAdapterRef, whatsappAdapterRef, imessageAdapterRef, tringAdapterRef, skillManifestsRef, broadcastEvent, getProvider, sendChannelMessage, isChannelAllowed, runTool, createToolApprovalRequest, executeApprovedTool, handleMemoryCommand, handleForgetCommand, updateWeatherDefaults, pairingStepSeconds, cleanupPairings: cleanupPairings2, isValidPairingCode: isValidPairingCode2 } = core;
|
|
70359
71934
|
const instanceLock = acquireGatewayInstanceLock({
|
|
70360
71935
|
rootDir: storageRoot,
|
|
70361
71936
|
host: config.gateway.host,
|
|
@@ -70384,6 +71959,20 @@ async function startGateway() {
|
|
|
70384
71959
|
logger,
|
|
70385
71960
|
enableAutoLearn: config.learnings?.autoLearn ?? false
|
|
70386
71961
|
});
|
|
71962
|
+
if (chitraguptaBridge) {
|
|
71963
|
+
const currentTools = toolRegistry.list();
|
|
71964
|
+
const registered = chitraguptaBridge.registerTools(currentTools.map((tool) => ({
|
|
71965
|
+
name: tool.name,
|
|
71966
|
+
description: tool.description,
|
|
71967
|
+
inputSchema: tool.inputSchema,
|
|
71968
|
+
tags: tool.tags,
|
|
71969
|
+
aliases: tool.aliases
|
|
71970
|
+
})));
|
|
71971
|
+
logger.info("chitragupta_tools_registered", {
|
|
71972
|
+
totalTools: currentTools.length,
|
|
71973
|
+
registeredTools: registered
|
|
71974
|
+
});
|
|
71975
|
+
}
|
|
70387
71976
|
setSessionResetListener((session) => {
|
|
70388
71977
|
chitraguptaBridge?.onSessionEnd(session.id);
|
|
70389
71978
|
});
|
|
@@ -70647,6 +72236,7 @@ async function startGateway() {
|
|
|
70647
72236
|
twitterAdapterRef,
|
|
70648
72237
|
whatsappAdapterRef,
|
|
70649
72238
|
imessageAdapterRef,
|
|
72239
|
+
tringAdapterRef,
|
|
70650
72240
|
proactiveManager,
|
|
70651
72241
|
storageRoot,
|
|
70652
72242
|
smritiClient,
|