@gralkor/openclaw 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +32 -0
- package/README.md +77 -0
- package/config.yaml +16 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/ctx-to-messages.d.ts +36 -0
- package/dist/ctx-to-messages.d.ts.map +1 -0
- package/dist/ctx-to-messages.js +120 -0
- package/dist/ctx-to-messages.js.map +1 -0
- package/dist/ctx-to-turn.d.ts +32 -0
- package/dist/ctx-to-turn.d.ts.map +1 -0
- package/dist/ctx-to-turn.js +55 -0
- package/dist/ctx-to-turn.js.map +1 -0
- package/dist/gralkor/client/http.d.ts +55 -0
- package/dist/gralkor/client/http.d.ts.map +1 -0
- package/dist/gralkor/client/http.js +150 -0
- package/dist/gralkor/client/http.js.map +1 -0
- package/dist/gralkor/client/in-memory.d.ts +38 -0
- package/dist/gralkor/client/in-memory.d.ts.map +1 -0
- package/dist/gralkor/client/in-memory.js +72 -0
- package/dist/gralkor/client/in-memory.js.map +1 -0
- package/dist/gralkor/client.d.ts +64 -0
- package/dist/gralkor/client.d.ts.map +1 -0
- package/dist/gralkor/client.js +32 -0
- package/dist/gralkor/client.js.map +1 -0
- package/dist/gralkor/config.d.ts +33 -0
- package/dist/gralkor/config.d.ts.map +1 -0
- package/dist/gralkor/config.js +58 -0
- package/dist/gralkor/config.js.map +1 -0
- package/dist/gralkor/connection.d.ts +20 -0
- package/dist/gralkor/connection.d.ts.map +1 -0
- package/dist/gralkor/connection.js +31 -0
- package/dist/gralkor/connection.js.map +1 -0
- package/dist/gralkor/index.d.ts +11 -0
- package/dist/gralkor/index.d.ts.map +1 -0
- package/dist/gralkor/index.js +6 -0
- package/dist/gralkor/index.js.map +1 -0
- package/dist/gralkor/server-env.d.ts +11 -0
- package/dist/gralkor/server-env.d.ts.map +1 -0
- package/dist/gralkor/server-env.js +26 -0
- package/dist/gralkor/server-env.js.map +1 -0
- package/dist/gralkor/server-manager.d.ts +58 -0
- package/dist/gralkor/server-manager.d.ts.map +1 -0
- package/dist/gralkor/server-manager.js +390 -0
- package/dist/gralkor/server-manager.js.map +1 -0
- package/dist/gralkor/testing.d.ts +10 -0
- package/dist/gralkor/testing.d.ts.map +1 -0
- package/dist/gralkor/testing.js +10 -0
- package/dist/gralkor/testing.js.map +1 -0
- package/dist/hooks/agent-end.d.ts +25 -0
- package/dist/hooks/agent-end.d.ts.map +1 -0
- package/dist/hooks/agent-end.js +51 -0
- package/dist/hooks/agent-end.js.map +1 -0
- package/dist/hooks/before-prompt-build.d.ts +12 -0
- package/dist/hooks/before-prompt-build.d.ts.map +1 -0
- package/dist/hooks/before-prompt-build.js +15 -0
- package/dist/hooks/before-prompt-build.js.map +1 -0
- package/dist/hooks/session-end.d.ts +18 -0
- package/dist/hooks/session-end.d.ts.map +1 -0
- package/dist/hooks/session-end.js +19 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +133 -0
- package/dist/index.js.map +1 -0
- package/dist/native-indexer.d.ts +43 -0
- package/dist/native-indexer.d.ts.map +1 -0
- package/dist/native-indexer.js +107 -0
- package/dist/native-indexer.js.map +1 -0
- package/dist/register.d.ts +25 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +184 -0
- package/dist/register.js.map +1 -0
- package/dist/session-map.d.ts +13 -0
- package/dist/session-map.d.ts.map +1 -0
- package/dist/session-map.js +32 -0
- package/dist/session-map.js.map +1 -0
- package/dist/tools/memory-add.d.ts +15 -0
- package/dist/tools/memory-add.d.ts.map +1 -0
- package/dist/tools/memory-add.js +15 -0
- package/dist/tools/memory-add.js.map +1 -0
- package/dist/tools/memory-build-communities.d.ts +19 -0
- package/dist/tools/memory-build-communities.d.ts.map +1 -0
- package/dist/tools/memory-build-communities.js +18 -0
- package/dist/tools/memory-build-communities.js.map +1 -0
- package/dist/tools/memory-build-indices.d.ts +12 -0
- package/dist/tools/memory-build-indices.d.ts.map +1 -0
- package/dist/tools/memory-build-indices.js +11 -0
- package/dist/tools/memory-build-indices.js.map +1 -0
- package/dist/tools/memory-search.d.ts +20 -0
- package/dist/tools/memory-search.d.ts.map +1 -0
- package/dist/tools/memory-search.js +18 -0
- package/dist/tools/memory-search.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/openclaw.plugin.json +130 -0
- package/package.json +75 -0
- package/server/server/.python-version +1 -0
- package/server/server/main.py +902 -0
- package/server/server/pipelines/__init__.py +0 -0
- package/server/server/pipelines/capture_buffer.py +170 -0
- package/server/server/pipelines/distill.py +122 -0
- package/server/server/pipelines/formatting.py +48 -0
- package/server/server/pipelines/interpret.py +165 -0
- package/server/server/pipelines/messages.py +13 -0
- package/server/server/pyproject.toml +19 -0
- package/server/server/pytest.ini +4 -0
- package/server/server/requirements-dev.txt +3 -0
- package/server/server/requirements.txt +5 -0
- package/server/server/uv.lock +1162 -0
- package/server/wheels/falkordblite-0.9.0-py3-none-manylinux_2_36_aarch64.whl +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ModelConfig, OntologyConfig } from "./config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Path to the Python server source bundled with this package. Resolves at
|
|
4
|
+
* runtime relative to this module's compiled location — at publish time the
|
|
5
|
+
* server is copied into `<pkg>/server/` by `scripts/bundle-server.mjs`, and
|
|
6
|
+
* this module ends up at `<pkg>/dist/server-manager.js`, so `../server`
|
|
7
|
+
* resolves to the bundled directory. Mirrors the Elixir side's
|
|
8
|
+
* `:code.priv_dir(:gralkor_ex) ++ "/server"`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function bundledServerDir(): string;
|
|
11
|
+
export interface ServerManagerOptions {
|
|
12
|
+
dataDir: string;
|
|
13
|
+
/**
|
|
14
|
+
* Path to the Python server directory. Defaults to the bundled copy
|
|
15
|
+
* that ships inside this npm package. Override if you want to point
|
|
16
|
+
* at a development checkout of `gralkor/server/`.
|
|
17
|
+
*/
|
|
18
|
+
serverDir?: string;
|
|
19
|
+
port: number;
|
|
20
|
+
/** Plugin version — used to fetch the arm64 wheel from GitHub Releases when not bundled. */
|
|
21
|
+
version: string;
|
|
22
|
+
/**
|
|
23
|
+
* GitHub repo (`owner/name`) that hosts the prebuilt `falkordblite` wheel as a release asset.
|
|
24
|
+
* Used on linux/arm64 only; the URL is `https://github.com/${wheelRepo}/releases/download/v${version}/<wheel>`.
|
|
25
|
+
* The consumer is the publisher (the one whose CI uploads the wheel via `gh release upload`),
|
|
26
|
+
* so the consumer must tell us where it published — there is no defensible default here.
|
|
27
|
+
*/
|
|
28
|
+
wheelRepo: string;
|
|
29
|
+
env?: Record<string, string>;
|
|
30
|
+
secretEnv?: Record<string, string>;
|
|
31
|
+
llmConfig?: ModelConfig;
|
|
32
|
+
embedderConfig?: ModelConfig;
|
|
33
|
+
ontologyConfig?: OntologyConfig;
|
|
34
|
+
test?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare function wheelDownloadUrl(wheelRepo: string, version: string): string;
|
|
37
|
+
export interface ServerManager {
|
|
38
|
+
start(): Promise<void>;
|
|
39
|
+
stop(): Promise<void>;
|
|
40
|
+
isRunning(): boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare function createServerManager(opts: ServerManagerOptions): ServerManager;
|
|
43
|
+
/**
|
|
44
|
+
* Build the `config.yaml` contents for the Python server.
|
|
45
|
+
*
|
|
46
|
+
* Sections are emitted only when the consumer passes that piece of config.
|
|
47
|
+
* When `llmConfig` / `embedderConfig` are omitted, the corresponding blocks
|
|
48
|
+
* are absent from the YAML and the server falls back to its own defaults in
|
|
49
|
+
* `server/main.py` — the single source of truth for model choice.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildConfigYaml(opts: {
|
|
52
|
+
llmConfig?: ModelConfig;
|
|
53
|
+
embedderConfig?: ModelConfig;
|
|
54
|
+
ontologyConfig?: OntologyConfig;
|
|
55
|
+
test?: boolean;
|
|
56
|
+
}): string;
|
|
57
|
+
export declare function serializeOntologyYaml(ontology: OntologyConfig): string;
|
|
58
|
+
//# sourceMappingURL=server-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-manager.d.ts","sourceRoot":"","sources":["../../src/gralkor/server-manager.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC;AAevF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAMD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,aAAa,CA+L7E;AAOD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,MAAM,CAQT;AAkDD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAwBtE"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
3
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { buildSyncEnv, buildPipEnv, buildSpawnEnv } from "./server-env.js";
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const HEALTH_POLL_INTERVAL_MS = 500;
|
|
10
|
+
const HEALTH_TIMEOUT_MS = 120_000;
|
|
11
|
+
const STOP_GRACE_MS = 5_000;
|
|
12
|
+
// OTP default — 3 restarts in 5s; the 4th unexpected exit inside the window
|
|
13
|
+
// escalates by exiting the Node process so the next-level supervisor (Docker
|
|
14
|
+
// restart: unless-stopped in agents/) takes over.
|
|
15
|
+
const RESTART_INTENSITY_LIMIT = 3;
|
|
16
|
+
const RESTART_INTENSITY_WINDOW_MS = 5_000;
|
|
17
|
+
/**
|
|
18
|
+
* Path to the Python server source bundled with this package. Resolves at
|
|
19
|
+
* runtime relative to this module's compiled location — at publish time the
|
|
20
|
+
* server is copied into `<pkg>/server/` by `scripts/bundle-server.mjs`, and
|
|
21
|
+
* this module ends up at `<pkg>/dist/server-manager.js`, so `../server`
|
|
22
|
+
* resolves to the bundled directory. Mirrors the Elixir side's
|
|
23
|
+
* `:code.priv_dir(:gralkor_ex) ++ "/server"`.
|
|
24
|
+
*/
|
|
25
|
+
export function bundledServerDir() {
|
|
26
|
+
return fileURLToPath(new URL("../server", import.meta.url));
|
|
27
|
+
}
|
|
28
|
+
// Bundled wheel filename — must match the wheel produced by consumer publish scripts
|
|
29
|
+
// (e.g. openclaw_gralkor's scripts/build-arm64-wheel.sh).
|
|
30
|
+
const WHEEL_FILENAME = "falkordblite-0.9.0-py3-none-manylinux_2_36_aarch64.whl";
|
|
31
|
+
export function wheelDownloadUrl(wheelRepo, version) {
|
|
32
|
+
return `https://github.com/${wheelRepo}/releases/download/v${version}/${WHEEL_FILENAME}`;
|
|
33
|
+
}
|
|
34
|
+
export function createServerManager(opts) {
|
|
35
|
+
const serverDir = opts.serverDir ?? bundledServerDir();
|
|
36
|
+
let proc = null;
|
|
37
|
+
let stopping = false;
|
|
38
|
+
const recentUnexpectedExits = [];
|
|
39
|
+
let spawnEnv = null;
|
|
40
|
+
let venvPython = null;
|
|
41
|
+
let startPromise = null;
|
|
42
|
+
function start() {
|
|
43
|
+
return (startPromise ??= doStart());
|
|
44
|
+
}
|
|
45
|
+
async function doStart() {
|
|
46
|
+
const bootStart = Date.now();
|
|
47
|
+
await mkdir(opts.dataDir, { recursive: true });
|
|
48
|
+
console.log("[gralkor] boot: starting...");
|
|
49
|
+
const venvDir = join(opts.dataDir, "venv");
|
|
50
|
+
venvPython = join(venvDir, "bin", "python");
|
|
51
|
+
// Ensure uv is available
|
|
52
|
+
try {
|
|
53
|
+
await execFileAsync("uv", ["--version"]);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
throw new Error("uv is required but not found on PATH. " +
|
|
57
|
+
"Install: curl -LsSf https://astral.sh/uv/install.sh | sh");
|
|
58
|
+
}
|
|
59
|
+
// Sync Python environment.
|
|
60
|
+
// Skip falkordblite when a bundled arch-specific wheel is present — the PyPI
|
|
61
|
+
// arm64 wheel requires manylinux_2_39 (glibc 2.39+) but many linux/arm64 hosts
|
|
62
|
+
// run glibc 2.36 (Debian Bookworm), causing uv to fall back to the sdist which
|
|
63
|
+
// embeds x86-64 binaries. The bundled wheel is built for the correct arch.
|
|
64
|
+
// On linux/arm64, PyPI's falkordblite sdist embeds x86-64 binaries on
|
|
65
|
+
// glibc < 2.39 hosts (e.g. Bookworm), so we must install a prebuilt wheel.
|
|
66
|
+
// Look for it bundled in the install (npm path), else download from
|
|
67
|
+
// GitHub Releases (ClawHub path — wheel exceeds ClawHub's 20 MB limit).
|
|
68
|
+
const useBundledWheels = process.platform === "linux" && process.arch === "arm64";
|
|
69
|
+
const bundledWheels = useBundledWheels
|
|
70
|
+
? await resolveBundledWheels(serverDir, opts.dataDir, opts.wheelRepo, opts.version)
|
|
71
|
+
: [];
|
|
72
|
+
const syncEnv = buildSyncEnv(venvDir);
|
|
73
|
+
const syncArgs = [
|
|
74
|
+
"sync", "--no-dev", "--frozen", "--directory", serverDir,
|
|
75
|
+
...(bundledWheels.length > 0 ? ["--no-install-package", "falkordblite"] : []),
|
|
76
|
+
];
|
|
77
|
+
console.log("[gralkor] boot: syncing python env...");
|
|
78
|
+
await execFileAsync("uv", syncArgs, { env: syncEnv, timeout: 300_000 });
|
|
79
|
+
console.log("[gralkor] boot: python env ready");
|
|
80
|
+
// Install bundled wheels — no PyPI fallback, must succeed.
|
|
81
|
+
const pipEnv = buildPipEnv(venvDir);
|
|
82
|
+
for (const wheelPath of bundledWheels) {
|
|
83
|
+
console.log("[gralkor] Installing bundled wheel:", wheelPath);
|
|
84
|
+
await execFileAsync("uv", ["pip", "install", "--no-deps", wheelPath], { env: pipEnv, timeout: 60_000 });
|
|
85
|
+
}
|
|
86
|
+
const configPath = join(opts.dataDir, "config.yaml");
|
|
87
|
+
await writeFile(configPath, buildConfigYaml(opts), "utf-8");
|
|
88
|
+
spawnEnv = buildSpawnEnv({
|
|
89
|
+
extra: opts.env,
|
|
90
|
+
secretEnv: opts.secretEnv,
|
|
91
|
+
falkordbDataDir: join(opts.dataDir, "falkordb"),
|
|
92
|
+
configPath,
|
|
93
|
+
});
|
|
94
|
+
await spawnAndAwaitHealth();
|
|
95
|
+
const bootDuration = ((Date.now() - bootStart) / 1000).toFixed(1);
|
|
96
|
+
console.log(`[gralkor] boot: ready (${bootDuration}s)`);
|
|
97
|
+
}
|
|
98
|
+
async function spawnAndAwaitHealth() {
|
|
99
|
+
if (venvPython === null || spawnEnv === null) {
|
|
100
|
+
throw new Error("[gralkor] spawnAndAwaitHealth called before start() prepared the env");
|
|
101
|
+
}
|
|
102
|
+
// Reap prior-run orphans before claiming the port. Two paths:
|
|
103
|
+
// (1) anything listening on the bind port — our previous uvicorn after a
|
|
104
|
+
// module re-eval, or a crashed sibling
|
|
105
|
+
// (2) any redislite/bin/redis-server grandchild reparented to PID 1 when
|
|
106
|
+
// a previous uvicorn died — the path is unique to falkordblite, so
|
|
107
|
+
// pre-spawn matches are by definition not ours-yet
|
|
108
|
+
await killHoldersOfPort(opts.port);
|
|
109
|
+
await killOrphanRedisServers();
|
|
110
|
+
console.log("[gralkor] Starting Graphiti server on port", opts.port);
|
|
111
|
+
const child = spawn(venvPython, ["-m", "uvicorn", "main:app", "--host", "127.0.0.1", "--port", String(opts.port), "--no-access-log"], {
|
|
112
|
+
cwd: serverDir,
|
|
113
|
+
env: spawnEnv,
|
|
114
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
115
|
+
});
|
|
116
|
+
proc = child;
|
|
117
|
+
// Forward stdout/stderr
|
|
118
|
+
child.stdout?.on("data", (data) => {
|
|
119
|
+
for (const line of data.toString().split("\n").filter(Boolean)) {
|
|
120
|
+
console.log("[gralkor] [server]", line);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
child.stderr?.on("data", (data) => {
|
|
124
|
+
for (const line of data.toString().split("\n").filter(Boolean)) {
|
|
125
|
+
console.log("[gralkor] [server]", line);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
child.on("error", (err) => {
|
|
129
|
+
console.error("[gralkor] Server process error:", err.message);
|
|
130
|
+
});
|
|
131
|
+
child.on("exit", (code, signal) => {
|
|
132
|
+
console.log("[gralkor] Server process exited — code:", code, "signal:", signal);
|
|
133
|
+
if (proc === child)
|
|
134
|
+
proc = null;
|
|
135
|
+
if (stopping)
|
|
136
|
+
return;
|
|
137
|
+
const now = Date.now();
|
|
138
|
+
while (recentUnexpectedExits.length > 0 && now - recentUnexpectedExits[0] > RESTART_INTENSITY_WINDOW_MS) {
|
|
139
|
+
recentUnexpectedExits.shift();
|
|
140
|
+
}
|
|
141
|
+
recentUnexpectedExits.push(now);
|
|
142
|
+
if (recentUnexpectedExits.length > RESTART_INTENSITY_LIMIT) {
|
|
143
|
+
console.error(`[gralkor] restart intensity exceeded (${recentUnexpectedExits.length} unexpected exits within ${RESTART_INTENSITY_WINDOW_MS}ms) — escalating via process.exit(1)`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
console.warn(`[gralkor] respawning after unexpected exit (attempt ${recentUnexpectedExits.length} in current ${RESTART_INTENSITY_WINDOW_MS}ms window)`);
|
|
147
|
+
void spawnAndAwaitHealth().catch((err) => {
|
|
148
|
+
console.error("[gralkor] respawn failed:", err instanceof Error ? err.message : err);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
console.log("[gralkor] boot: server process spawned (pid:", child.pid, "), polling health...");
|
|
152
|
+
await waitForHealth(opts.port);
|
|
153
|
+
console.log("[gralkor] boot: server healthy");
|
|
154
|
+
}
|
|
155
|
+
async function stop() {
|
|
156
|
+
stopping = true;
|
|
157
|
+
if (!proc)
|
|
158
|
+
return;
|
|
159
|
+
const child = proc;
|
|
160
|
+
proc = null;
|
|
161
|
+
// Try graceful SIGTERM first
|
|
162
|
+
child.kill("SIGTERM");
|
|
163
|
+
await new Promise((resolve) => {
|
|
164
|
+
const forceKill = setTimeout(() => {
|
|
165
|
+
child.kill("SIGKILL");
|
|
166
|
+
resolve();
|
|
167
|
+
}, STOP_GRACE_MS);
|
|
168
|
+
child.on("exit", () => {
|
|
169
|
+
clearTimeout(forceKill);
|
|
170
|
+
resolve();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function isRunning() {
|
|
175
|
+
return proc !== null;
|
|
176
|
+
}
|
|
177
|
+
return { start, stop, isRunning };
|
|
178
|
+
}
|
|
179
|
+
function providerSection(key, cfg) {
|
|
180
|
+
if (!cfg)
|
|
181
|
+
return "";
|
|
182
|
+
return `${key}:\n provider: "${cfg.provider}"\n model: "${cfg.model}"`;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Build the `config.yaml` contents for the Python server.
|
|
186
|
+
*
|
|
187
|
+
* Sections are emitted only when the consumer passes that piece of config.
|
|
188
|
+
* When `llmConfig` / `embedderConfig` are omitted, the corresponding blocks
|
|
189
|
+
* are absent from the YAML and the server falls back to its own defaults in
|
|
190
|
+
* `server/main.py` — the single source of truth for model choice.
|
|
191
|
+
*/
|
|
192
|
+
export function buildConfigYaml(opts) {
|
|
193
|
+
const sections = [
|
|
194
|
+
providerSection("llm", opts.llmConfig),
|
|
195
|
+
providerSection("embedder", opts.embedderConfig),
|
|
196
|
+
].filter((s) => s !== "");
|
|
197
|
+
if (opts.test)
|
|
198
|
+
sections.push("test: true");
|
|
199
|
+
if (opts.ontologyConfig)
|
|
200
|
+
sections.push(serializeOntologyYaml(opts.ontologyConfig).trimEnd());
|
|
201
|
+
return sections.length === 0 ? "" : sections.join("\n") + "\n";
|
|
202
|
+
}
|
|
203
|
+
function yamlQuote(s) {
|
|
204
|
+
if (/[:#{}[\]|>&*!%@`]/.test(s) || s !== s.trim()) {
|
|
205
|
+
return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
206
|
+
}
|
|
207
|
+
return `"${s}"`;
|
|
208
|
+
}
|
|
209
|
+
function serializeAttrValue(attr, indent) {
|
|
210
|
+
if (typeof attr === "string") {
|
|
211
|
+
return ` ${yamlQuote(attr)}`;
|
|
212
|
+
}
|
|
213
|
+
if (Array.isArray(attr)) {
|
|
214
|
+
return "\n" + attr.map((v) => `${indent} - ${yamlQuote(v)}`).join("\n");
|
|
215
|
+
}
|
|
216
|
+
if ("enum" in attr) {
|
|
217
|
+
const lines = [
|
|
218
|
+
`\n${indent} enum:`,
|
|
219
|
+
...attr.enum.map((v) => `${indent} - ${yamlQuote(v)}`),
|
|
220
|
+
`${indent} description: ${yamlQuote(attr.description)}`,
|
|
221
|
+
];
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
224
|
+
// { type, description }
|
|
225
|
+
return [
|
|
226
|
+
"",
|
|
227
|
+
`${indent} type: ${yamlQuote(attr.type)}`,
|
|
228
|
+
`${indent} description: ${yamlQuote(attr.description)}`,
|
|
229
|
+
].join("\n");
|
|
230
|
+
}
|
|
231
|
+
function serializeTypeDefs(defs, indent) {
|
|
232
|
+
const lines = [];
|
|
233
|
+
for (const [name, def] of Object.entries(defs)) {
|
|
234
|
+
lines.push(`${indent}${name}:`);
|
|
235
|
+
lines.push(`${indent} description: ${yamlQuote(def.description)}`);
|
|
236
|
+
if (def.attributes && Object.keys(def.attributes).length > 0) {
|
|
237
|
+
lines.push(`${indent} attributes:`);
|
|
238
|
+
for (const [attr, val] of Object.entries(def.attributes)) {
|
|
239
|
+
lines.push(`${indent} ${attr}:${serializeAttrValue(val, `${indent} `)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return lines;
|
|
244
|
+
}
|
|
245
|
+
export function serializeOntologyYaml(ontology) {
|
|
246
|
+
const lines = ["ontology:"];
|
|
247
|
+
if (ontology.entities && Object.keys(ontology.entities).length > 0) {
|
|
248
|
+
lines.push(" entities:");
|
|
249
|
+
lines.push(...serializeTypeDefs(ontology.entities, " "));
|
|
250
|
+
}
|
|
251
|
+
if (ontology.edges && Object.keys(ontology.edges).length > 0) {
|
|
252
|
+
lines.push(" edges:");
|
|
253
|
+
lines.push(...serializeTypeDefs(ontology.edges, " "));
|
|
254
|
+
}
|
|
255
|
+
if (ontology.edgeMap && Object.keys(ontology.edgeMap).length > 0) {
|
|
256
|
+
lines.push(" edgeMap:");
|
|
257
|
+
for (const [key, values] of Object.entries(ontology.edgeMap)) {
|
|
258
|
+
lines.push(` ${yamlQuote(key)}:`);
|
|
259
|
+
for (const v of values) {
|
|
260
|
+
lines.push(` - ${yamlQuote(v)}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return lines.join("\n") + "\n";
|
|
265
|
+
}
|
|
266
|
+
async function resolveBundledWheels(serverDir, dataDir, wheelRepo, version) {
|
|
267
|
+
const installed = join(serverDir, "wheels");
|
|
268
|
+
if (existsSync(installed)) {
|
|
269
|
+
const files = readdirSync(installed).filter((f) => f.endsWith(".whl"));
|
|
270
|
+
if (files.length > 0)
|
|
271
|
+
return files.map((f) => join(installed, f));
|
|
272
|
+
}
|
|
273
|
+
const dest = join(dataDir, "wheels", WHEEL_FILENAME);
|
|
274
|
+
if (!existsSync(dest)) {
|
|
275
|
+
await mkdir(join(dataDir, "wheels"), { recursive: true });
|
|
276
|
+
const url = wheelDownloadUrl(wheelRepo, version);
|
|
277
|
+
console.log(`[gralkor] boot: downloading wheel ${url}`);
|
|
278
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
279
|
+
if (!res.ok)
|
|
280
|
+
throw new Error(`bundled wheel download failed: HTTP ${res.status} ${url}`);
|
|
281
|
+
await writeFile(dest, Buffer.from(await res.arrayBuffer()));
|
|
282
|
+
}
|
|
283
|
+
return [dest];
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Kill any redislite redis-server process left behind by a prior uvicorn
|
|
287
|
+
* incarnation. falkordblite spawns redis-server as a grandchild; when uvicorn
|
|
288
|
+
* dies, the grandchild reparents to PID 1 and keeps holding the data dir,
|
|
289
|
+
* unix socket, and ~80 MB RSS — and would conflict with the next boot.
|
|
290
|
+
*
|
|
291
|
+
* Mirrors :gralkor_ex's `Gralkor.OrphanReaper`. Identification keys on argv
|
|
292
|
+
* substring (`redislite/bin/redis-server`) — the path is unique to falkordblite
|
|
293
|
+
* with no other plausible owner. Safe to nuke unconditionally because this
|
|
294
|
+
* runs before our own spawn, so anything matching is by definition not
|
|
295
|
+
* ours-yet.
|
|
296
|
+
*/
|
|
297
|
+
async function killOrphanRedisServers() {
|
|
298
|
+
let stdout;
|
|
299
|
+
try {
|
|
300
|
+
const result = await execFileAsync("pgrep", ["-f", "redislite/bin/redis-server"]);
|
|
301
|
+
stdout = result.stdout;
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// pgrep exits non-zero when nothing matches — treat as empty
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const pids = stdout.split("\n").map(s => Number(s.trim())).filter(n => Number.isInteger(n) && n > 0);
|
|
308
|
+
if (pids.length === 0)
|
|
309
|
+
return;
|
|
310
|
+
console.log(`[gralkor] boot: orphan redislite redis-server pid(s) ${pids.join(",")} — killing`);
|
|
311
|
+
for (const pid of pids) {
|
|
312
|
+
try {
|
|
313
|
+
process.kill(pid, "SIGKILL");
|
|
314
|
+
}
|
|
315
|
+
catch { /* already gone */ }
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function killHoldersOfPort(port) {
|
|
319
|
+
const pids = await findPortHolders(port);
|
|
320
|
+
if (pids.length === 0)
|
|
321
|
+
return;
|
|
322
|
+
console.log(`[gralkor] boot: port ${port} held by pid(s) ${pids.join(",")} — killing`);
|
|
323
|
+
for (const pid of pids) {
|
|
324
|
+
try {
|
|
325
|
+
process.kill(pid, "SIGTERM");
|
|
326
|
+
}
|
|
327
|
+
catch { /* already gone */ }
|
|
328
|
+
}
|
|
329
|
+
if (await waitForPortFree(port, 5_000))
|
|
330
|
+
return;
|
|
331
|
+
for (const pid of await findPortHolders(port)) {
|
|
332
|
+
try {
|
|
333
|
+
process.kill(pid, "SIGKILL");
|
|
334
|
+
}
|
|
335
|
+
catch { /* already gone */ }
|
|
336
|
+
}
|
|
337
|
+
if (!(await waitForPortFree(port, 2_000))) {
|
|
338
|
+
throw new Error(`port ${port} still bound after SIGTERM+SIGKILL`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async function findPortHolders(port) {
|
|
342
|
+
try {
|
|
343
|
+
const { stdout } = await execFileAsync("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"]);
|
|
344
|
+
return stdout.split("\n").map(s => Number(s.trim())).filter(n => Number.isInteger(n) && n > 0);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// lsof exits non-zero when nothing matches — treat as empty
|
|
348
|
+
return [];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function waitForPortFree(port, timeoutMs) {
|
|
352
|
+
const deadline = Date.now() + timeoutMs;
|
|
353
|
+
while (Date.now() < deadline) {
|
|
354
|
+
if ((await findPortHolders(port)).length === 0)
|
|
355
|
+
return true;
|
|
356
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
357
|
+
}
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
async function waitForHealth(port) {
|
|
361
|
+
const deadline = Date.now() + HEALTH_TIMEOUT_MS;
|
|
362
|
+
const start = Date.now();
|
|
363
|
+
let polls = 0;
|
|
364
|
+
let lastError = "";
|
|
365
|
+
while (Date.now() < deadline) {
|
|
366
|
+
polls++;
|
|
367
|
+
try {
|
|
368
|
+
const res = await fetch(`http://127.0.0.1:${port}/health`);
|
|
369
|
+
if (res.ok) {
|
|
370
|
+
console.log(`[gralkor] boot: health poll succeeded after ${polls} attempts (${((Date.now() - start) / 1000).toFixed(1)}s)`);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const newError = `HTTP ${res.status}`;
|
|
374
|
+
if (newError !== lastError) {
|
|
375
|
+
console.log(`[gralkor] boot: health poll — ${newError}`);
|
|
376
|
+
lastError = newError;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch (err) {
|
|
380
|
+
const newError = err instanceof Error ? err.message : String(err);
|
|
381
|
+
if (newError !== lastError) {
|
|
382
|
+
console.log(`[gralkor] boot: health poll — ${newError}`);
|
|
383
|
+
lastError = newError;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
await new Promise((r) => setTimeout(r, HEALTH_POLL_INTERVAL_MS));
|
|
387
|
+
}
|
|
388
|
+
throw new Error(`Graphiti server did not become healthy within ${HEALTH_TIMEOUT_MS / 1000}s (${polls} polls, last error: ${lastError})`);
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=server-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../../src/gralkor/server-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test helpers for `@susulabs/gralkor`.
|
|
3
|
+
*
|
|
4
|
+
* Import from "@susulabs/gralkor/testing" in test files only. Keeps the
|
|
5
|
+
* production bundle free of the in-memory twin (it's ~100 lines; small, but
|
|
6
|
+
* keeping the separation matches what the Elixir side does with
|
|
7
|
+
* `Gralkor.Client.InMemory` shipped as a separately-named module).
|
|
8
|
+
*/
|
|
9
|
+
export { GralkorInMemoryClient } from "./client/in-memory.js";
|
|
10
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/gralkor/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test helpers for `@susulabs/gralkor`.
|
|
3
|
+
*
|
|
4
|
+
* Import from "@susulabs/gralkor/testing" in test files only. Keeps the
|
|
5
|
+
* production bundle free of the in-memory twin (it's ~100 lines; small, but
|
|
6
|
+
* keeping the separation matches what the Elixir side does with
|
|
7
|
+
* `Gralkor.Client.InMemory` shipped as a separately-named module).
|
|
8
|
+
*/
|
|
9
|
+
export { GralkorInMemoryClient } from "./client/in-memory.js";
|
|
10
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/gralkor/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { GralkorClient, Result } from "../gralkor/index.js";
|
|
2
|
+
import { type MessageEntry } from "../ctx-to-messages.js";
|
|
3
|
+
export interface AgentEndCtx {
|
|
4
|
+
sessionKey: string;
|
|
5
|
+
agentName: string;
|
|
6
|
+
messages: MessageEntry[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* `agent_end` hook: OpenClaw fires this at the end of an agent run.
|
|
10
|
+
*
|
|
11
|
+
* In the old architecture this handler buffered the messages client-side
|
|
12
|
+
* via a keyed debouncer and later flushed them as a whole-session episode.
|
|
13
|
+
* In the Python-server-heavy architecture, the server owns the capture
|
|
14
|
+
* buffer — so all this hook does is extract the just-finished turn and
|
|
15
|
+
* POST it to `/capture`. The server appends to its session-keyed buffer
|
|
16
|
+
* and flushes on explicit `session_end` (which OpenClaw fires on
|
|
17
|
+
* idle-rollover or reset) or on lifespan shutdown.
|
|
18
|
+
*
|
|
19
|
+
* Skipped when:
|
|
20
|
+
* - ctx has no messages,
|
|
21
|
+
* - ctx doesn't contain both a user message and a final assistant
|
|
22
|
+
* message (nothing coherent to capture).
|
|
23
|
+
*/
|
|
24
|
+
export declare function runAgentEnd(client: GralkorClient, ctx: AgentEndCtx): Promise<Result<true>>;
|
|
25
|
+
//# sourceMappingURL=agent-end.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-end.d.ts","sourceRoot":"","sources":["../../src/hooks/agent-end.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGzE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAmBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAiBvB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ctxToMessages } from "../ctx-to-messages.js";
|
|
2
|
+
import { getSessionGroup } from "../session-map.js";
|
|
3
|
+
/**
|
|
4
|
+
* OpenClaw's `llm-slug-generator` runs an embedded sub-agent with this fixed
|
|
5
|
+
* `sessionKey` to produce a filename for `/new`/`/reset` memory archival. It
|
|
6
|
+
* fires `agent_end` like any other run; without this guard the sub-agent's
|
|
7
|
+
* prompt (which contains an inline dump of the real conversation) would be
|
|
8
|
+
* captured as if it were a user turn.
|
|
9
|
+
*/
|
|
10
|
+
const SLUG_GENERATOR_SESSION_KEY = "temp:slug-generator";
|
|
11
|
+
/**
|
|
12
|
+
* OpenClaw's session-reset flow replaces the user's `/new` or `/reset` command
|
|
13
|
+
* with a synthetic meta-prompt instructing the agent to run its startup
|
|
14
|
+
* sequence and greet the user. Stable prefix from
|
|
15
|
+
* `openclaw/src/auto-reply/reply/session-reset-prompt.ts`.
|
|
16
|
+
*/
|
|
17
|
+
const SESSION_RESET_PROMPT_PREFIX = "A new session was started via /new or /reset";
|
|
18
|
+
/**
|
|
19
|
+
* `agent_end` hook: OpenClaw fires this at the end of an agent run.
|
|
20
|
+
*
|
|
21
|
+
* In the old architecture this handler buffered the messages client-side
|
|
22
|
+
* via a keyed debouncer and later flushed them as a whole-session episode.
|
|
23
|
+
* In the Python-server-heavy architecture, the server owns the capture
|
|
24
|
+
* buffer — so all this hook does is extract the just-finished turn and
|
|
25
|
+
* POST it to `/capture`. The server appends to its session-keyed buffer
|
|
26
|
+
* and flushes on explicit `session_end` (which OpenClaw fires on
|
|
27
|
+
* idle-rollover or reset) or on lifespan shutdown.
|
|
28
|
+
*
|
|
29
|
+
* Skipped when:
|
|
30
|
+
* - ctx has no messages,
|
|
31
|
+
* - ctx doesn't contain both a user message and a final assistant
|
|
32
|
+
* message (nothing coherent to capture).
|
|
33
|
+
*/
|
|
34
|
+
export async function runAgentEnd(client, ctx) {
|
|
35
|
+
if (ctx.messages.length === 0)
|
|
36
|
+
return { ok: true };
|
|
37
|
+
if (ctx.sessionKey === SLUG_GENERATOR_SESSION_KEY)
|
|
38
|
+
return { ok: true };
|
|
39
|
+
const messages = ctxToMessages(ctx.messages);
|
|
40
|
+
if (messages === null)
|
|
41
|
+
return { ok: true };
|
|
42
|
+
const userMessage = messages.find((m) => m.role === "user");
|
|
43
|
+
if (userMessage && userMessage.content.startsWith(SESSION_RESET_PROMPT_PREFIX)) {
|
|
44
|
+
return { ok: true };
|
|
45
|
+
}
|
|
46
|
+
const groupId = getSessionGroup(ctx.sessionKey);
|
|
47
|
+
if (groupId === null)
|
|
48
|
+
return { error: "session_not_registered" };
|
|
49
|
+
return client.capture(ctx.sessionKey, groupId, ctx.agentName, messages);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=agent-end.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-end.js","sourceRoot":"","sources":["../../src/hooks/agent-end.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD;;;;;;GAMG;AACH,MAAM,0BAA0B,GAAG,qBAAqB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,2BAA2B,GAAG,8CAA8C,CAAC;AAEnF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAqB,EACrB,GAAgB;IAEhB,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEnD,IAAI,GAAG,CAAC,UAAU,KAAK,0BAA0B;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEvE,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAE3C,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC5D,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAEjE,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type GralkorClient, type Result } from "../gralkor/index.js";
|
|
2
|
+
export interface BeforePromptBuildCtx {
|
|
3
|
+
sessionKey: string;
|
|
4
|
+
agentId: string;
|
|
5
|
+
agentName: string;
|
|
6
|
+
prompt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface BeforePromptBuildOutput {
|
|
9
|
+
prependContext?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function runBeforePromptBuild(client: GralkorClient, ctx: BeforePromptBuildCtx): Promise<Result<BeforePromptBuildOutput>>;
|
|
12
|
+
//# sourceMappingURL=before-prompt-build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before-prompt-build.d.ts","sourceRoot":"","sources":["../../src/hooks/before-prompt-build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGvF,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAqB1C"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { sanitizeGroupId } from "../gralkor/index.js";
|
|
2
|
+
import { setSessionGroup } from "../session-map.js";
|
|
3
|
+
export async function runBeforePromptBuild(client, ctx) {
|
|
4
|
+
setSessionGroup(ctx.sessionKey, ctx.agentId);
|
|
5
|
+
const query = ctx.prompt.trim();
|
|
6
|
+
if (query === "")
|
|
7
|
+
return { ok: {} };
|
|
8
|
+
const recalled = await client.recall(sanitizeGroupId(ctx.agentId), ctx.sessionKey, query, ctx.agentName);
|
|
9
|
+
if ("error" in recalled) {
|
|
10
|
+
console.warn("[openclaw_gralkor] recall failed — continuing turn without memory context:", recalled.error);
|
|
11
|
+
return { ok: {} };
|
|
12
|
+
}
|
|
13
|
+
return { ok: { prependContext: recalled.ok } };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=before-prompt-build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"before-prompt-build.js","sourceRoot":"","sources":["../../src/hooks/before-prompt-build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAmC,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAapD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAqB,EACrB,GAAyB;IAEzB,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAClC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAC5B,GAAG,CAAC,UAAU,EACd,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;IACF,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CACV,4EAA4E,EAC5E,QAAQ,CAAC,KAAK,CACf,CAAC;QACF,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;AACjD,CAAC"}
|