@botbotgo/agent-harness 0.0.243 → 0.0.245
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/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/harness/system/store.js +3 -2
- package/dist/runtime/support/runtime-factories.js +38 -3
- package/dist/runtime/support/sqlite-drivers.d.ts +12 -0
- package/dist/runtime/support/sqlite-drivers.js +24 -0
- package/dist/workspace/object-loader.js +27 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.244";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.244";
|
|
@@ -2,7 +2,7 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { mkdirSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { InMemoryStore } from "@langchain/langgraph";
|
|
5
|
-
import
|
|
5
|
+
import { loadBetterSqlite3 } from "../../support/sqlite-drivers.js";
|
|
6
6
|
const NAMESPACE_SEPARATOR = "\u001f";
|
|
7
7
|
function encodeValue(value) {
|
|
8
8
|
if (value instanceof Date) {
|
|
@@ -152,7 +152,8 @@ export class SqliteBackedStore {
|
|
|
152
152
|
constructor(filePath) {
|
|
153
153
|
this.filePath = filePath;
|
|
154
154
|
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
155
|
-
|
|
155
|
+
const SqliteDatabase = loadBetterSqlite3();
|
|
156
|
+
this.db = new SqliteDatabase(filePath);
|
|
156
157
|
this.db.pragma("journal_mode = WAL");
|
|
157
158
|
this.db.exec(`
|
|
158
159
|
CREATE TABLE IF NOT EXISTS store_entries (
|
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { MemorySaver } from "@langchain/langgraph";
|
|
3
|
-
import { SqliteSaver } from "@langchain/langgraph-checkpoint-sqlite";
|
|
4
3
|
import { FileCheckpointSaver } from "../maintenance/file-checkpoint-saver.js";
|
|
5
|
-
import { ManagedSqliteSaver } from "../maintenance/sqlite-maintained-checkpoint-saver.js";
|
|
6
4
|
import { createInMemoryStore, FileBackedStore, SqliteBackedStore } from "../harness/system/store.js";
|
|
5
|
+
import { loadLanggraphSqliteCheckpointModule } from "./sqlite-drivers.js";
|
|
6
|
+
function createManagedSqliteSaver(SqliteSaver, db) {
|
|
7
|
+
class RuntimeManagedSqliteSaver extends SqliteSaver {
|
|
8
|
+
setup() {
|
|
9
|
+
super.setup();
|
|
10
|
+
this.db.exec(`
|
|
11
|
+
CREATE TABLE IF NOT EXISTS checkpoint_maintenance_meta (
|
|
12
|
+
thread_id TEXT NOT NULL,
|
|
13
|
+
checkpoint_ns TEXT NOT NULL DEFAULT '',
|
|
14
|
+
checkpoint_id TEXT NOT NULL,
|
|
15
|
+
created_at_ms INTEGER NOT NULL,
|
|
16
|
+
PRIMARY KEY (thread_id, checkpoint_ns, checkpoint_id)
|
|
17
|
+
);`);
|
|
18
|
+
}
|
|
19
|
+
async put(config, checkpoint, metadata) {
|
|
20
|
+
const result = await super.put(config, checkpoint, metadata);
|
|
21
|
+
const threadId = result.configurable?.thread_id;
|
|
22
|
+
const checkpointNs = result.configurable?.checkpoint_ns ?? "";
|
|
23
|
+
const checkpointId = result.configurable?.checkpoint_id;
|
|
24
|
+
if (!threadId || !checkpointId) {
|
|
25
|
+
throw new Error("Missing checkpoint identity after SqliteSaver.put");
|
|
26
|
+
}
|
|
27
|
+
this.db
|
|
28
|
+
.prepare(`INSERT OR IGNORE INTO checkpoint_maintenance_meta
|
|
29
|
+
(thread_id, checkpoint_ns, checkpoint_id, created_at_ms)
|
|
30
|
+
VALUES (?, ?, ?, ?)`)
|
|
31
|
+
.run(threadId, checkpointNs, checkpointId, Date.now());
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
async deleteThread(threadId) {
|
|
35
|
+
await super.deleteThread(threadId);
|
|
36
|
+
this.db.prepare(`DELETE FROM checkpoint_maintenance_meta WHERE thread_id = ?`).run(threadId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return new RuntimeManagedSqliteSaver(db);
|
|
40
|
+
}
|
|
7
41
|
export function createStoreForConfig(storeConfig, runRoot) {
|
|
8
42
|
const kind = typeof storeConfig.kind === "string" ? storeConfig.kind : "FileStore";
|
|
9
43
|
switch (kind) {
|
|
@@ -36,7 +70,8 @@ export function createCheckpointerForConfig(checkpointerConfig, runRoot) {
|
|
|
36
70
|
case "SqliteSaver": {
|
|
37
71
|
const configuredPath = typeof checkpointerConfig.path === "string" ? String(checkpointerConfig.path) : "checkpoints.sqlite";
|
|
38
72
|
const resolvedPath = path.isAbsolute(configuredPath) ? configuredPath : path.join(runRoot, configuredPath);
|
|
39
|
-
|
|
73
|
+
const { SqliteSaver } = loadLanggraphSqliteCheckpointModule();
|
|
74
|
+
return createManagedSqliteSaver(SqliteSaver, SqliteSaver.fromConnString(resolvedPath).db);
|
|
40
75
|
}
|
|
41
76
|
case "FileCheckpointer": {
|
|
42
77
|
const configuredPath = typeof checkpointerConfig.path === "string" ? String(checkpointerConfig.path) : "checkpoints.json";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type BetterSqlite3Constructor = typeof import("better-sqlite3");
|
|
2
|
+
type SqliteCheckpointModule = typeof import("@langchain/langgraph-checkpoint-sqlite");
|
|
3
|
+
declare const defaultBetterSqlite3Loader: () => BetterSqlite3Constructor;
|
|
4
|
+
declare const defaultLanggraphSqliteCheckpointLoader: () => SqliteCheckpointModule;
|
|
5
|
+
export declare function loadBetterSqlite3(): BetterSqlite3Constructor;
|
|
6
|
+
export declare function loadLanggraphSqliteCheckpointModule(): SqliteCheckpointModule;
|
|
7
|
+
export declare function setSqliteModuleLoadersForTest(loaders: {
|
|
8
|
+
betterSqlite3?: typeof defaultBetterSqlite3Loader;
|
|
9
|
+
langgraphCheckpointSqlite?: typeof defaultLanggraphSqliteCheckpointLoader;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function resetSqliteModuleLoadersForTest(): void;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
const defaultBetterSqlite3Loader = () => require("better-sqlite3");
|
|
4
|
+
const defaultLanggraphSqliteCheckpointLoader = () => require("@langchain/langgraph-checkpoint-sqlite");
|
|
5
|
+
let betterSqlite3Loader = defaultBetterSqlite3Loader;
|
|
6
|
+
let langgraphSqliteCheckpointLoader = defaultLanggraphSqliteCheckpointLoader;
|
|
7
|
+
export function loadBetterSqlite3() {
|
|
8
|
+
return betterSqlite3Loader();
|
|
9
|
+
}
|
|
10
|
+
export function loadLanggraphSqliteCheckpointModule() {
|
|
11
|
+
return langgraphSqliteCheckpointLoader();
|
|
12
|
+
}
|
|
13
|
+
export function setSqliteModuleLoadersForTest(loaders) {
|
|
14
|
+
if (loaders.betterSqlite3) {
|
|
15
|
+
betterSqlite3Loader = loaders.betterSqlite3;
|
|
16
|
+
}
|
|
17
|
+
if (loaders.langgraphCheckpointSqlite) {
|
|
18
|
+
langgraphSqliteCheckpointLoader = loaders.langgraphCheckpointSqlite;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function resetSqliteModuleLoadersForTest() {
|
|
22
|
+
betterSqlite3Loader = defaultBetterSqlite3Loader;
|
|
23
|
+
langgraphSqliteCheckpointLoader = defaultLanggraphSqliteCheckpointLoader;
|
|
24
|
+
}
|
|
@@ -616,7 +616,7 @@ async function loadModuleAgentsForRoot(root, mergedAgents) {
|
|
|
616
616
|
async function loadConventionalObjectsForRoot(root, mergedObjects) {
|
|
617
617
|
for (const directory of CONVENTIONAL_OBJECT_DIRECTORIES) {
|
|
618
618
|
for (const objectRoot of conventionalDirectoryRoots(root, directory)) {
|
|
619
|
-
for (const { item, sourcePath } of await
|
|
619
|
+
for (const { item, sourcePath } of await readYamlItemsIgnoringNodeModules(objectRoot)) {
|
|
620
620
|
const workspaceObject = parseWorkspaceObject(item, sourcePath);
|
|
621
621
|
if (!workspaceObject) {
|
|
622
622
|
continue;
|
|
@@ -633,6 +633,32 @@ async function loadConventionalObjectsForRoot(root, mergedObjects) {
|
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
635
|
}
|
|
636
|
+
async function readYamlItemsIgnoringNodeModules(root) {
|
|
637
|
+
if (!(await fileExists(root))) {
|
|
638
|
+
return [];
|
|
639
|
+
}
|
|
640
|
+
const records = [];
|
|
641
|
+
const pending = [root];
|
|
642
|
+
while (pending.length > 0) {
|
|
643
|
+
const current = pending.shift();
|
|
644
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
645
|
+
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
646
|
+
const entryPath = path.join(current, entry.name);
|
|
647
|
+
if (entry.isDirectory()) {
|
|
648
|
+
if (entry.name === "node_modules") {
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
pending.push(entryPath);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
if (!entry.isFile() || (!entry.name.endsWith(".yaml") && !entry.name.endsWith(".yml"))) {
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
records.push(...(await readNamedYamlItems(current, [entry.name])));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return records;
|
|
661
|
+
}
|
|
636
662
|
async function readModuleToolItems(root) {
|
|
637
663
|
const modulesRoot = moduleCollectionRoot(root, "tools");
|
|
638
664
|
if (!(await fileExists(modulesRoot))) {
|