@botbotgo/agent-harness 0.0.1
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/api.d.ts +22 -0
- package/dist/api.js +48 -0
- package/dist/config/direct.yaml +48 -0
- package/dist/config/embedding-model.yaml +30 -0
- package/dist/config/model.yaml +44 -0
- package/dist/config/orchestra.yaml +92 -0
- package/dist/config/runtime.yaml +47 -0
- package/dist/config/vector-store.yaml +26 -0
- package/dist/contracts/types.d.ts +359 -0
- package/dist/contracts/types.js +1 -0
- package/dist/extensions.d.ts +16 -0
- package/dist/extensions.js +251 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/persistence/file-store.d.ts +39 -0
- package/dist/persistence/file-store.js +282 -0
- package/dist/presentation.d.ts +4 -0
- package/dist/presentation.js +175 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +33 -0
- package/dist/runtime/agent-runtime-adapter.js +445 -0
- package/dist/runtime/event-bus.d.ts +6 -0
- package/dist/runtime/event-bus.js +15 -0
- package/dist/runtime/file-checkpoint-saver.d.ts +20 -0
- package/dist/runtime/file-checkpoint-saver.js +91 -0
- package/dist/runtime/harness.d.ts +57 -0
- package/dist/runtime/harness.js +696 -0
- package/dist/runtime/index.d.ts +10 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/inventory.d.ts +25 -0
- package/dist/runtime/inventory.js +62 -0
- package/dist/runtime/parsing/index.d.ts +2 -0
- package/dist/runtime/parsing/index.js +2 -0
- package/dist/runtime/parsing/output-parsing.d.ts +12 -0
- package/dist/runtime/parsing/output-parsing.js +424 -0
- package/dist/runtime/parsing/stream-event-parsing.d.ts +27 -0
- package/dist/runtime/parsing/stream-event-parsing.js +161 -0
- package/dist/runtime/policy-engine.d.ts +9 -0
- package/dist/runtime/policy-engine.js +23 -0
- package/dist/runtime/store.d.ts +50 -0
- package/dist/runtime/store.js +118 -0
- package/dist/runtime/support/embedding-models.d.ts +4 -0
- package/dist/runtime/support/embedding-models.js +33 -0
- package/dist/runtime/support/harness-support.d.ts +27 -0
- package/dist/runtime/support/harness-support.js +116 -0
- package/dist/runtime/support/index.d.ts +4 -0
- package/dist/runtime/support/index.js +4 -0
- package/dist/runtime/support/llamaindex.d.ts +24 -0
- package/dist/runtime/support/llamaindex.js +108 -0
- package/dist/runtime/support/runtime-factories.d.ts +3 -0
- package/dist/runtime/support/runtime-factories.js +39 -0
- package/dist/runtime/support/skill-metadata.d.ts +1 -0
- package/dist/runtime/support/skill-metadata.js +34 -0
- package/dist/runtime/support/vector-stores.d.ts +7 -0
- package/dist/runtime/support/vector-stores.js +130 -0
- package/dist/runtime/thread-memory-sync.d.ts +14 -0
- package/dist/runtime/thread-memory-sync.js +88 -0
- package/dist/runtime/tool-hitl.d.ts +5 -0
- package/dist/runtime/tool-hitl.js +108 -0
- package/dist/utils/fs.d.ts +6 -0
- package/dist/utils/fs.js +39 -0
- package/dist/utils/id.d.ts +1 -0
- package/dist/utils/id.js +8 -0
- package/dist/vendor/builtins.d.ts +23 -0
- package/dist/vendor/builtins.js +103 -0
- package/dist/vendor/sources.d.ts +12 -0
- package/dist/vendor/sources.js +115 -0
- package/dist/workspace/agent-binding-compiler.d.ts +4 -0
- package/dist/workspace/agent-binding-compiler.js +181 -0
- package/dist/workspace/compile.d.ts +2 -0
- package/dist/workspace/compile.js +107 -0
- package/dist/workspace/index.d.ts +6 -0
- package/dist/workspace/index.js +6 -0
- package/dist/workspace/object-loader.d.ts +16 -0
- package/dist/workspace/object-loader.js +405 -0
- package/dist/workspace/resource-compilers.d.ts +13 -0
- package/dist/workspace/resource-compilers.js +182 -0
- package/dist/workspace/support/discovery.d.ts +5 -0
- package/dist/workspace/support/discovery.js +108 -0
- package/dist/workspace/support/index.d.ts +2 -0
- package/dist/workspace/support/index.js +2 -0
- package/dist/workspace/support/source-collectors.d.ts +3 -0
- package/dist/workspace/support/source-collectors.js +30 -0
- package/dist/workspace/support/workspace-ref-utils.d.ts +8 -0
- package/dist/workspace/support/workspace-ref-utils.js +50 -0
- package/dist/workspace/validate.d.ts +3 -0
- package/dist/workspace/validate.js +65 -0
- package/package.json +32 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { builtinConfigRoot, builtinSkillsRoot } from "../../vendor/builtins.js";
|
|
4
|
+
import { ensureExternalSource, isDirectoryPath, isExternalSourceLocator, resolveExternalSourcePath } from "../../vendor/sources.js";
|
|
5
|
+
import { parseAgentItem, readYamlItems } from "../object-loader.js";
|
|
6
|
+
function resolveBuiltinPath(kind, ref) {
|
|
7
|
+
const normalized = ref.replace(/^builtin:\/\//, "").replace(/^\/+/, "");
|
|
8
|
+
if (kind === "skills") {
|
|
9
|
+
if (!normalized.startsWith("skills")) {
|
|
10
|
+
throw new Error(`Unsupported builtin skill discovery path ${ref}`);
|
|
11
|
+
}
|
|
12
|
+
const suffix = normalized.replace(/^skills\/?/, "");
|
|
13
|
+
return suffix ? path.join(builtinSkillsRoot(), suffix) : builtinSkillsRoot();
|
|
14
|
+
}
|
|
15
|
+
if (!normalized.startsWith("agents")) {
|
|
16
|
+
throw new Error(`Unsupported builtin subagent discovery path ${ref}`);
|
|
17
|
+
}
|
|
18
|
+
const suffix = normalized.replace(/^agents\/?/, "");
|
|
19
|
+
return suffix ? path.join(builtinConfigRoot(), "agents", suffix) : path.join(builtinConfigRoot(), "agents");
|
|
20
|
+
}
|
|
21
|
+
function preferPackageConvention(root, kind) {
|
|
22
|
+
const candidates = kind === "skills"
|
|
23
|
+
? [path.join(root, "skills"), root]
|
|
24
|
+
: [path.join(root, "config", "agents"), path.join(root, "agents"), root];
|
|
25
|
+
for (const candidate of candidates) {
|
|
26
|
+
if (isDirectoryPath(candidate)) {
|
|
27
|
+
return candidate;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return root;
|
|
31
|
+
}
|
|
32
|
+
export async function ensureDiscoverySources(locators, workspaceRoot) {
|
|
33
|
+
await Promise.all(Array.from(new Set(locators))
|
|
34
|
+
.filter((locator) => isExternalSourceLocator(locator))
|
|
35
|
+
.map((locator) => ensureExternalSource(locator, workspaceRoot)));
|
|
36
|
+
}
|
|
37
|
+
export function resolveDiscoveryRoot(ref, workspaceRoot, kind) {
|
|
38
|
+
if (ref.startsWith("builtin://")) {
|
|
39
|
+
return resolveBuiltinPath(kind, ref);
|
|
40
|
+
}
|
|
41
|
+
if (isExternalSourceLocator(ref)) {
|
|
42
|
+
return preferPackageConvention(resolveExternalSourcePath(ref, workspaceRoot), kind);
|
|
43
|
+
}
|
|
44
|
+
return path.resolve(workspaceRoot, ref);
|
|
45
|
+
}
|
|
46
|
+
async function resolveDiscoveryRootAsync(ref, workspaceRoot, kind) {
|
|
47
|
+
if (ref.startsWith("builtin://")) {
|
|
48
|
+
return resolveBuiltinPath(kind, ref);
|
|
49
|
+
}
|
|
50
|
+
if (isExternalSourceLocator(ref)) {
|
|
51
|
+
return preferPackageConvention(await ensureExternalSource(ref, workspaceRoot), kind);
|
|
52
|
+
}
|
|
53
|
+
return path.resolve(workspaceRoot, ref);
|
|
54
|
+
}
|
|
55
|
+
export function discoverSkillPaths(rootRefs, workspaceRoot) {
|
|
56
|
+
const discovered = new Map();
|
|
57
|
+
for (const rootRef of rootRefs) {
|
|
58
|
+
const root = resolveDiscoveryRoot(rootRef, workspaceRoot, "skills");
|
|
59
|
+
if (!existsSync(root) || !statSync(root).isDirectory()) {
|
|
60
|
+
throw new Error(`Skill discovery root ${rootRef} does not exist`);
|
|
61
|
+
}
|
|
62
|
+
if (existsSync(path.join(root, "SKILL.md"))) {
|
|
63
|
+
discovered.set(path.basename(root), root);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
67
|
+
if (!entry.isDirectory()) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const skillRoot = path.join(root, entry.name);
|
|
71
|
+
if (existsSync(path.join(skillRoot, "SKILL.md"))) {
|
|
72
|
+
discovered.set(entry.name, skillRoot);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return Array.from(discovered.values());
|
|
77
|
+
}
|
|
78
|
+
export async function discoverSubagents(agents, workspaceRoot) {
|
|
79
|
+
const discovered = new Map(agents.map((agent) => [agent.id, agent]));
|
|
80
|
+
const visitedRoots = new Set();
|
|
81
|
+
let cursor = 0;
|
|
82
|
+
const queue = [...agents];
|
|
83
|
+
while (cursor < queue.length) {
|
|
84
|
+
const agent = queue[cursor++];
|
|
85
|
+
for (const rootRef of agent.subagentPathRefs) {
|
|
86
|
+
const root = await resolveDiscoveryRootAsync(rootRef, workspaceRoot, "subagents");
|
|
87
|
+
const cacheKey = `${agent.id}:${root}`;
|
|
88
|
+
if (visitedRoots.has(cacheKey)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
visitedRoots.add(cacheKey);
|
|
92
|
+
if (!existsSync(root) || !statSync(root).isDirectory()) {
|
|
93
|
+
throw new Error(`Subagent discovery root ${rootRef} does not exist`);
|
|
94
|
+
}
|
|
95
|
+
const discoveredRefs = [];
|
|
96
|
+
for (const { item, sourcePath } of await readYamlItems(root, undefined, { recursive: true })) {
|
|
97
|
+
const discoveredAgent = parseAgentItem(item, sourcePath);
|
|
98
|
+
discovered.set(discoveredAgent.id, discoveredAgent);
|
|
99
|
+
discoveredRefs.push(`agent/${discoveredAgent.id}`);
|
|
100
|
+
if (!queue.some((queued) => queued.id === discoveredAgent.id)) {
|
|
101
|
+
queue.push(discoveredAgent);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
agent.subagentRefs = Array.from(new Set([...agent.subagentRefs, ...discoveredRefs]));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return Array.from(discovered.values());
|
|
108
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ParsedAgentObject, ParsedToolObject, WorkspaceLoadOptions } from "../../contracts/types.js";
|
|
2
|
+
export declare function collectToolSourceRefs(tools: Map<string, ParsedToolObject>, agents: ParsedAgentObject[], options: WorkspaceLoadOptions): string[];
|
|
3
|
+
export declare function collectAgentDiscoverySourceRefs(agents: ParsedAgentObject[]): string[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isExternalSourceLocator } from "../../vendor/sources.js";
|
|
2
|
+
export function collectToolSourceRefs(tools, agents, options) {
|
|
3
|
+
const refs = new Set(options.builtinSources ?? []);
|
|
4
|
+
for (const tool of tools.values()) {
|
|
5
|
+
for (const ref of tool.bundleRefs) {
|
|
6
|
+
if (isExternalSourceLocator(ref)) {
|
|
7
|
+
refs.add(ref);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
for (const agent of agents) {
|
|
12
|
+
for (const ref of agent.toolRefs) {
|
|
13
|
+
if (isExternalSourceLocator(ref)) {
|
|
14
|
+
refs.add(ref);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return Array.from(refs);
|
|
19
|
+
}
|
|
20
|
+
export function collectAgentDiscoverySourceRefs(agents) {
|
|
21
|
+
const refs = new Set();
|
|
22
|
+
for (const agent of agents) {
|
|
23
|
+
for (const ref of [...agent.skillPathRefs, ...agent.subagentPathRefs]) {
|
|
24
|
+
if (isExternalSourceLocator(ref)) {
|
|
25
|
+
refs.add(ref);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return Array.from(refs);
|
|
30
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParsedAgentObject, WorkspaceObject } from "../../contracts/types.js";
|
|
2
|
+
export declare function getWorkspaceObject(refs: Map<string, WorkspaceObject | ParsedAgentObject>, ref: string | undefined): WorkspaceObject | undefined;
|
|
3
|
+
export declare function getRuntimeDefaults(refs: Map<string, WorkspaceObject | ParsedAgentObject>): Record<string, unknown> | undefined;
|
|
4
|
+
export declare function getRoutingSystemPrompt(refs: Map<string, WorkspaceObject | ParsedAgentObject>): string | undefined;
|
|
5
|
+
export declare function resolvePromptValue(promptConfig: unknown): string | undefined;
|
|
6
|
+
export declare function resolveRefId(ref: string): string;
|
|
7
|
+
export declare function resolvePathList(refs: Map<string, WorkspaceObject | ParsedAgentObject>, workspaceRoot: string, refList: string[]): string[];
|
|
8
|
+
export declare function compileAgentMemories(workspaceRoot: string, sources: string[]): string[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export function getWorkspaceObject(refs, ref) {
|
|
3
|
+
if (!ref) {
|
|
4
|
+
return undefined;
|
|
5
|
+
}
|
|
6
|
+
const object = refs.get(ref);
|
|
7
|
+
if (!object || "executionMode" in object) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
return object;
|
|
11
|
+
}
|
|
12
|
+
export function getRuntimeDefaults(refs) {
|
|
13
|
+
const runtimes = Array.from(refs.values()).filter((object) => !("executionMode" in object) && object.kind === "runtime");
|
|
14
|
+
if (runtimes.length === 0) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (runtimes.length > 1) {
|
|
18
|
+
throw new Error(`Expected at most one Runtime object, found ${runtimes.length}`);
|
|
19
|
+
}
|
|
20
|
+
return runtimes[0].value;
|
|
21
|
+
}
|
|
22
|
+
export function getRoutingSystemPrompt(refs) {
|
|
23
|
+
const runtimeDefaults = getRuntimeDefaults(refs);
|
|
24
|
+
const routing = typeof runtimeDefaults?.routing === "object" && runtimeDefaults.routing
|
|
25
|
+
? runtimeDefaults.routing
|
|
26
|
+
: undefined;
|
|
27
|
+
return typeof routing?.systemPrompt === "string" && routing.systemPrompt.trim() ? routing.systemPrompt : undefined;
|
|
28
|
+
}
|
|
29
|
+
export function resolvePromptValue(promptConfig) {
|
|
30
|
+
if (typeof promptConfig === "string" && promptConfig.trim()) {
|
|
31
|
+
return promptConfig;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
export function resolveRefId(ref) {
|
|
36
|
+
if (ref.startsWith("builtin/")) {
|
|
37
|
+
return ref;
|
|
38
|
+
}
|
|
39
|
+
return ref.split("/").slice(1).join("/");
|
|
40
|
+
}
|
|
41
|
+
export function resolvePathList(refs, workspaceRoot, refList) {
|
|
42
|
+
return refList.map((ref) => {
|
|
43
|
+
const object = getWorkspaceObject(refs, ref);
|
|
44
|
+
const maybePath = typeof object?.value.path === "string" ? object.value.path : resolveRefId(ref);
|
|
45
|
+
return path.isAbsolute(maybePath) ? maybePath : path.resolve(workspaceRoot, maybePath);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export function compileAgentMemories(workspaceRoot, sources) {
|
|
49
|
+
return sources.map((source) => (path.isAbsolute(source) ? source : path.resolve(workspaceRoot, source)));
|
|
50
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const allowedExecutionModes = new Set(["deepagent", "langchain-v1"]);
|
|
2
|
+
function hasPromptContent(value) {
|
|
3
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
4
|
+
}
|
|
5
|
+
function validateCheckpointerConfig(agent) {
|
|
6
|
+
const checkpointer = (typeof agent.deepAgentConfig?.checkpointer === "object" && agent.deepAgentConfig.checkpointer) ||
|
|
7
|
+
(typeof agent.langchainAgentConfig?.checkpointer === "object" && agent.langchainAgentConfig.checkpointer);
|
|
8
|
+
if (!checkpointer) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const typedCheckpointer = checkpointer;
|
|
12
|
+
const kind = typeof typedCheckpointer.kind === "string" ? typedCheckpointer.kind : "FileCheckpointer";
|
|
13
|
+
const hasPath = typeof typedCheckpointer.path === "string" && typedCheckpointer.path.trim().length > 0;
|
|
14
|
+
if (kind === "MemorySaver" && hasPath) {
|
|
15
|
+
throw new Error(`Agent ${agent.id} checkpointer.path is not supported for kind MemorySaver`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function validateAgent(agent) {
|
|
19
|
+
if (!agent.id) {
|
|
20
|
+
throw new Error(`Agent id is required in ${agent.sourcePath}`);
|
|
21
|
+
}
|
|
22
|
+
if (!allowedExecutionModes.has(agent.executionMode)) {
|
|
23
|
+
throw new Error(`Agent ${agent.id} has unsupported execution mode ${agent.executionMode}`);
|
|
24
|
+
}
|
|
25
|
+
if (!agent.description.trim()) {
|
|
26
|
+
throw new Error(`Agent ${agent.id} description must not be empty`);
|
|
27
|
+
}
|
|
28
|
+
if (agent.executionMode === "langchain-v1" && (agent.subagentRefs.length > 0 || agent.subagentPathRefs.length > 0)) {
|
|
29
|
+
throw new Error(`Agent ${agent.id} cannot define subagents unless execution.mode is deepagent`);
|
|
30
|
+
}
|
|
31
|
+
if (agent.executionMode === "langchain-v1" && agent.memorySources.length > 0) {
|
|
32
|
+
throw new Error(`Agent ${agent.id} cannot define memory unless execution.mode is deepagent`);
|
|
33
|
+
}
|
|
34
|
+
if ((agent.subagentRefs.length > 0 || agent.subagentPathRefs.length > 0) && agent.executionMode !== "deepagent") {
|
|
35
|
+
throw new Error(`Agent ${agent.id} must use deepagent execution when subagents are defined`);
|
|
36
|
+
}
|
|
37
|
+
validateCheckpointerConfig(agent);
|
|
38
|
+
}
|
|
39
|
+
export function validateTopology(agents) {
|
|
40
|
+
const ids = new Set();
|
|
41
|
+
const referencedSubagentIds = new Set();
|
|
42
|
+
for (const agent of agents) {
|
|
43
|
+
if (ids.has(agent.id)) {
|
|
44
|
+
throw new Error(`Duplicate agent id ${agent.id}`);
|
|
45
|
+
}
|
|
46
|
+
ids.add(agent.id);
|
|
47
|
+
for (const ref of agent.subagentRefs) {
|
|
48
|
+
referencedSubagentIds.add(ref.replace(/^agent\//, ""));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const agent of agents) {
|
|
52
|
+
if (!referencedSubagentIds.has(agent.id) && !agent.modelRef) {
|
|
53
|
+
throw new Error(`Agent ${agent.id} modelRef is required`);
|
|
54
|
+
}
|
|
55
|
+
if (!referencedSubagentIds.has(agent.id)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (agent.executionMode !== "deepagent") {
|
|
59
|
+
throw new Error(`Subagent ${agent.id} must use deepagent execution`);
|
|
60
|
+
}
|
|
61
|
+
if (!hasPromptContent(agent.deepAgentConfig?.systemPrompt)) {
|
|
62
|
+
throw new Error(`Subagent ${agent.id} requires deepagent.systemPrompt`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@botbotgo/agent-harness",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Agent Harness framework package",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/botbotgo/agent-harness.git",
|
|
17
|
+
"directory": "packages/framework"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"default": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@botbotgo/agent-harness-builtin": "workspace:*"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
|
|
30
|
+
"check": "tsc -p tsconfig.json --noEmit"
|
|
31
|
+
}
|
|
32
|
+
}
|