@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.
Files changed (87) hide show
  1. package/dist/api.d.ts +22 -0
  2. package/dist/api.js +48 -0
  3. package/dist/config/direct.yaml +48 -0
  4. package/dist/config/embedding-model.yaml +30 -0
  5. package/dist/config/model.yaml +44 -0
  6. package/dist/config/orchestra.yaml +92 -0
  7. package/dist/config/runtime.yaml +47 -0
  8. package/dist/config/vector-store.yaml +26 -0
  9. package/dist/contracts/types.d.ts +359 -0
  10. package/dist/contracts/types.js +1 -0
  11. package/dist/extensions.d.ts +16 -0
  12. package/dist/extensions.js +251 -0
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.js +7 -0
  15. package/dist/persistence/file-store.d.ts +39 -0
  16. package/dist/persistence/file-store.js +282 -0
  17. package/dist/presentation.d.ts +4 -0
  18. package/dist/presentation.js +175 -0
  19. package/dist/runtime/agent-runtime-adapter.d.ts +33 -0
  20. package/dist/runtime/agent-runtime-adapter.js +445 -0
  21. package/dist/runtime/event-bus.d.ts +6 -0
  22. package/dist/runtime/event-bus.js +15 -0
  23. package/dist/runtime/file-checkpoint-saver.d.ts +20 -0
  24. package/dist/runtime/file-checkpoint-saver.js +91 -0
  25. package/dist/runtime/harness.d.ts +57 -0
  26. package/dist/runtime/harness.js +696 -0
  27. package/dist/runtime/index.d.ts +10 -0
  28. package/dist/runtime/index.js +10 -0
  29. package/dist/runtime/inventory.d.ts +25 -0
  30. package/dist/runtime/inventory.js +62 -0
  31. package/dist/runtime/parsing/index.d.ts +2 -0
  32. package/dist/runtime/parsing/index.js +2 -0
  33. package/dist/runtime/parsing/output-parsing.d.ts +12 -0
  34. package/dist/runtime/parsing/output-parsing.js +424 -0
  35. package/dist/runtime/parsing/stream-event-parsing.d.ts +27 -0
  36. package/dist/runtime/parsing/stream-event-parsing.js +161 -0
  37. package/dist/runtime/policy-engine.d.ts +9 -0
  38. package/dist/runtime/policy-engine.js +23 -0
  39. package/dist/runtime/store.d.ts +50 -0
  40. package/dist/runtime/store.js +118 -0
  41. package/dist/runtime/support/embedding-models.d.ts +4 -0
  42. package/dist/runtime/support/embedding-models.js +33 -0
  43. package/dist/runtime/support/harness-support.d.ts +27 -0
  44. package/dist/runtime/support/harness-support.js +116 -0
  45. package/dist/runtime/support/index.d.ts +4 -0
  46. package/dist/runtime/support/index.js +4 -0
  47. package/dist/runtime/support/llamaindex.d.ts +24 -0
  48. package/dist/runtime/support/llamaindex.js +108 -0
  49. package/dist/runtime/support/runtime-factories.d.ts +3 -0
  50. package/dist/runtime/support/runtime-factories.js +39 -0
  51. package/dist/runtime/support/skill-metadata.d.ts +1 -0
  52. package/dist/runtime/support/skill-metadata.js +34 -0
  53. package/dist/runtime/support/vector-stores.d.ts +7 -0
  54. package/dist/runtime/support/vector-stores.js +130 -0
  55. package/dist/runtime/thread-memory-sync.d.ts +14 -0
  56. package/dist/runtime/thread-memory-sync.js +88 -0
  57. package/dist/runtime/tool-hitl.d.ts +5 -0
  58. package/dist/runtime/tool-hitl.js +108 -0
  59. package/dist/utils/fs.d.ts +6 -0
  60. package/dist/utils/fs.js +39 -0
  61. package/dist/utils/id.d.ts +1 -0
  62. package/dist/utils/id.js +8 -0
  63. package/dist/vendor/builtins.d.ts +23 -0
  64. package/dist/vendor/builtins.js +103 -0
  65. package/dist/vendor/sources.d.ts +12 -0
  66. package/dist/vendor/sources.js +115 -0
  67. package/dist/workspace/agent-binding-compiler.d.ts +4 -0
  68. package/dist/workspace/agent-binding-compiler.js +181 -0
  69. package/dist/workspace/compile.d.ts +2 -0
  70. package/dist/workspace/compile.js +107 -0
  71. package/dist/workspace/index.d.ts +6 -0
  72. package/dist/workspace/index.js +6 -0
  73. package/dist/workspace/object-loader.d.ts +16 -0
  74. package/dist/workspace/object-loader.js +405 -0
  75. package/dist/workspace/resource-compilers.d.ts +13 -0
  76. package/dist/workspace/resource-compilers.js +182 -0
  77. package/dist/workspace/support/discovery.d.ts +5 -0
  78. package/dist/workspace/support/discovery.js +108 -0
  79. package/dist/workspace/support/index.d.ts +2 -0
  80. package/dist/workspace/support/index.js +2 -0
  81. package/dist/workspace/support/source-collectors.d.ts +3 -0
  82. package/dist/workspace/support/source-collectors.js +30 -0
  83. package/dist/workspace/support/workspace-ref-utils.d.ts +8 -0
  84. package/dist/workspace/support/workspace-ref-utils.js +50 -0
  85. package/dist/workspace/validate.d.ts +3 -0
  86. package/dist/workspace/validate.js +65 -0
  87. package/package.json +32 -0
@@ -0,0 +1,103 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import { ensureExternalSource, isExternalSourceLocator, parseExternalSourceLocator } from "./sources.js";
6
+ const vendorDir = path.dirname(fileURLToPath(import.meta.url));
7
+ const builtinsDist = path.resolve(vendorDir, "../../../builtins/dist/src/index.js");
8
+ const builtinsSource = path.resolve(vendorDir, "../../../builtins/src/index.ts");
9
+ function preferSourceWhenAvailable(distPath, sourcePath) {
10
+ if (!existsSync(sourcePath)) {
11
+ return distPath;
12
+ }
13
+ return sourcePath;
14
+ }
15
+ const builtinsEntry = preferSourceWhenAvailable(builtinsDist, builtinsSource);
16
+ const localBuiltins = await import(pathToFileURL(builtinsEntry).href);
17
+ const remoteProviderCache = new Map();
18
+ function resolvePackageEntry(packageRoot, pkg) {
19
+ const exportsField = pkg.exports;
20
+ if (typeof exportsField === "string") {
21
+ return path.resolve(packageRoot, exportsField);
22
+ }
23
+ if (exportsField && typeof exportsField === "object" && "." in exportsField) {
24
+ const rootExport = exportsField["."];
25
+ if (typeof rootExport === "string") {
26
+ return path.resolve(packageRoot, rootExport);
27
+ }
28
+ if (rootExport && typeof rootExport === "object") {
29
+ const importEntry = rootExport.import ?? rootExport.default;
30
+ if (typeof importEntry === "string") {
31
+ return path.resolve(packageRoot, importEntry);
32
+ }
33
+ }
34
+ }
35
+ if (typeof pkg.module === "string") {
36
+ return path.resolve(packageRoot, pkg.module);
37
+ }
38
+ if (typeof pkg.main === "string") {
39
+ return path.resolve(packageRoot, pkg.main);
40
+ }
41
+ return path.resolve(packageRoot, "index.js");
42
+ }
43
+ async function loadRemoteProvider(source, workspaceRoot) {
44
+ const cached = remoteProviderCache.get(source);
45
+ if (cached) {
46
+ return cached;
47
+ }
48
+ if (!isExternalSourceLocator(source)) {
49
+ throw new Error(`Unsupported builtin source ${source}. Use npm:, tgz:, or file:.`);
50
+ }
51
+ const parsed = parseExternalSourceLocator(source);
52
+ if (parsed.subpath) {
53
+ throw new Error(`Builtin source ${source} must point at a package root, not a subpath`);
54
+ }
55
+ const packageRoot = await ensureExternalSource(source, workspaceRoot);
56
+ const pkg = JSON.parse(await readFile(path.join(packageRoot, "package.json"), "utf8"));
57
+ const entry = resolvePackageEntry(packageRoot, pkg);
58
+ const imported = await import(pathToFileURL(entry).href);
59
+ const provider = (imported.default ?? imported);
60
+ if (typeof provider.listBuiltinTools !== "function" || typeof provider.createBuiltinToolResolver !== "function") {
61
+ throw new Error(`Remote builtin source ${source} must export listBuiltinTools() and createBuiltinToolResolver().`);
62
+ }
63
+ const typedProvider = provider;
64
+ remoteProviderCache.set(source, typedProvider);
65
+ return typedProvider;
66
+ }
67
+ export async function ensureBuiltinSources(sources = [], workspaceRoot = process.cwd()) {
68
+ await Promise.all(sources.map((source) => loadRemoteProvider(source, workspaceRoot)));
69
+ }
70
+ export const builtinSkillsRoot = localBuiltins.builtinSkillsRoot;
71
+ export const builtinConfigRoot = (localBuiltins.builtinConfigRoot ?? localBuiltins.builtinDefaultsRoot);
72
+ export async function listBuiltinTools(sources = [], workspaceRoot = process.cwd()) {
73
+ await ensureBuiltinSources(sources, workspaceRoot);
74
+ const deduped = new Map();
75
+ const local = localBuiltins.listBuiltinTools;
76
+ for (const tool of local()) {
77
+ deduped.set(tool.builtinPath, tool);
78
+ }
79
+ for (const source of sources) {
80
+ for (const tool of remoteProviderCache.get(source)?.listBuiltinTools() ?? []) {
81
+ deduped.set(tool.builtinPath, tool);
82
+ }
83
+ }
84
+ return Array.from(deduped.values());
85
+ }
86
+ export async function listBuiltinToolsForSource(source, workspaceRoot = process.cwd()) {
87
+ await ensureBuiltinSources([source], workspaceRoot);
88
+ return remoteProviderCache.get(source)?.listBuiltinTools() ?? [];
89
+ }
90
+ export function createBuiltinBackendResolver(workspace) {
91
+ return localBuiltins.createBuiltinBackendResolver(workspace);
92
+ }
93
+ export function createBuiltinToolResolver(workspace, options = {}) {
94
+ const localResolver = localBuiltins.createBuiltinToolResolver(workspace, options);
95
+ const remoteResolvers = workspace.builtinSources
96
+ .map((source) => remoteProviderCache.get(source))
97
+ .filter((provider) => Boolean(provider))
98
+ .map((provider) => provider.createBuiltinToolResolver(workspace));
99
+ return (toolIds, binding) => [
100
+ ...localResolver(toolIds, binding),
101
+ ...remoteResolvers.flatMap((resolver) => resolver(toolIds, binding)),
102
+ ];
103
+ }
@@ -0,0 +1,12 @@
1
+ type ParsedLocator = {
2
+ kind: "npm" | "tgz" | "file";
3
+ spec: string;
4
+ subpath?: string;
5
+ };
6
+ export declare function isExternalSourceLocator(value: unknown): boolean;
7
+ export declare function parseExternalSourceLocator(locator: string): ParsedLocator;
8
+ export declare function ensureExternalSource(locator: string, workspaceRoot: string): Promise<string>;
9
+ export declare function ensureExternalSources(locators: string[], workspaceRoot: string): Promise<void>;
10
+ export declare function resolveExternalSourcePath(locator: string, workspaceRoot: string): string;
11
+ export declare function isDirectoryPath(candidate: string): boolean;
12
+ export {};
@@ -0,0 +1,115 @@
1
+ import { execFile } from "node:child_process";
2
+ import { existsSync, statSync } from "node:fs";
3
+ import { mkdir } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { createHash } from "node:crypto";
7
+ import { promisify } from "node:util";
8
+ const execFileAsync = promisify(execFile);
9
+ const sourceCache = new Map();
10
+ function cacheRoot() {
11
+ return path.join(os.tmpdir(), "agent-harness-external-sources");
12
+ }
13
+ function sourceCacheDir(locator) {
14
+ const digest = createHash("sha256").update(locator).digest("hex").slice(0, 16);
15
+ return path.join(cacheRoot(), digest);
16
+ }
17
+ export function isExternalSourceLocator(value) {
18
+ return typeof value === "string" && /^(npm|tgz|file):/.test(value);
19
+ }
20
+ export function parseExternalSourceLocator(locator) {
21
+ const separator = locator.indexOf("::");
22
+ const rawBase = separator >= 0 ? locator.slice(0, separator) : locator;
23
+ const subpath = separator >= 0 ? locator.slice(separator + 2) : undefined;
24
+ if (rawBase.startsWith("npm:")) {
25
+ return { kind: "npm", spec: rawBase.slice(4), subpath };
26
+ }
27
+ if (rawBase.startsWith("tgz:")) {
28
+ return { kind: "tgz", spec: rawBase.slice(4), subpath };
29
+ }
30
+ if (rawBase.startsWith("file:")) {
31
+ return { kind: "file", spec: rawBase.slice(5), subpath };
32
+ }
33
+ throw new Error(`Unsupported external source locator ${locator}. Use npm:, tgz:, or file:.`);
34
+ }
35
+ function resolveFileSpec(spec, workspaceRoot) {
36
+ if (path.isAbsolute(spec)) {
37
+ return spec;
38
+ }
39
+ return path.resolve(workspaceRoot, spec);
40
+ }
41
+ async function packAndExtract(packageSpec, cacheKey) {
42
+ const root = sourceCacheDir(cacheKey);
43
+ const extractRoot = path.join(root, "extract");
44
+ const packageRoot = path.join(extractRoot, "package");
45
+ if (existsSync(path.join(packageRoot, "package.json"))) {
46
+ return packageRoot;
47
+ }
48
+ await mkdir(root, { recursive: true });
49
+ await mkdir(extractRoot, { recursive: true });
50
+ const packed = await execFileAsync("npm", ["pack", packageSpec, "--silent"], {
51
+ cwd: root,
52
+ maxBuffer: 1024 * 1024 * 10,
53
+ });
54
+ const tarballName = packed.stdout.trim().split(/\r?\n/).filter(Boolean).at(-1);
55
+ if (!tarballName) {
56
+ throw new Error(`Failed to pack external source ${cacheKey}`);
57
+ }
58
+ await execFileAsync("tar", ["-xzf", tarballName, "-C", extractRoot], {
59
+ cwd: root,
60
+ maxBuffer: 1024 * 1024 * 10,
61
+ });
62
+ return packageRoot;
63
+ }
64
+ export async function ensureExternalSource(locator, workspaceRoot) {
65
+ const parsed = parseExternalSourceLocator(locator);
66
+ const cacheKey = `${parsed.kind}:${parsed.spec}`;
67
+ const cached = sourceCache.get(cacheKey);
68
+ if (cached) {
69
+ return parsed.subpath ? path.join(cached, parsed.subpath) : cached;
70
+ }
71
+ let basePath;
72
+ if (parsed.kind === "npm") {
73
+ basePath = await packAndExtract(parsed.spec, cacheKey);
74
+ }
75
+ else if (parsed.kind === "tgz") {
76
+ const resolved = resolveFileSpec(parsed.spec, workspaceRoot);
77
+ basePath = await packAndExtract(resolved, cacheKey);
78
+ }
79
+ else {
80
+ const resolved = resolveFileSpec(parsed.spec, workspaceRoot);
81
+ if (!existsSync(resolved)) {
82
+ throw new Error(`External file source ${locator} does not exist`);
83
+ }
84
+ if (resolved.endsWith(".tgz") || resolved.endsWith(".tar.gz")) {
85
+ basePath = await packAndExtract(resolved, cacheKey);
86
+ }
87
+ else {
88
+ basePath = resolved;
89
+ }
90
+ }
91
+ sourceCache.set(cacheKey, basePath);
92
+ return parsed.subpath ? path.join(basePath, parsed.subpath) : basePath;
93
+ }
94
+ export async function ensureExternalSources(locators, workspaceRoot) {
95
+ await Promise.all(Array.from(new Set(locators)).map((locator) => ensureExternalSource(locator, workspaceRoot)));
96
+ }
97
+ export function resolveExternalSourcePath(locator, workspaceRoot) {
98
+ const parsed = parseExternalSourceLocator(locator);
99
+ const cacheKey = `${parsed.kind}:${parsed.spec}`;
100
+ const cached = sourceCache.get(cacheKey);
101
+ if (cached) {
102
+ return parsed.subpath ? path.join(cached, parsed.subpath) : cached;
103
+ }
104
+ if (parsed.kind === "file") {
105
+ const resolved = resolveFileSpec(parsed.spec, workspaceRoot);
106
+ if (resolved.endsWith(".tgz") || resolved.endsWith(".tar.gz")) {
107
+ throw new Error(`External source ${locator} must be preloaded before synchronous resolution`);
108
+ }
109
+ return parsed.subpath ? path.join(resolved, parsed.subpath) : resolved;
110
+ }
111
+ throw new Error(`External source ${locator} must be preloaded before synchronous resolution`);
112
+ }
113
+ export function isDirectoryPath(candidate) {
114
+ return existsSync(candidate) && statSync(candidate).isDirectory();
115
+ }
@@ -0,0 +1,4 @@
1
+ import type { CompiledAgentBinding, CompiledTool, ParsedAgentObject, ParsedModelObject, ParsedToolObject, WorkspaceObject } from "../contracts/types.js";
2
+ export declare function compileAgentSkills(workspaceRoot: string, agent: ParsedAgentObject, parentSkills?: string[]): string[];
3
+ export declare function requireTools(tools: Map<string, ParsedToolObject>, refs: string[], ownerId: string): CompiledTool[];
4
+ export declare function compileBinding(workspaceRoot: string, agent: ParsedAgentObject, agents: Map<string, ParsedAgentObject>, referencedSubagentIds: Set<string>, refs: Map<string, WorkspaceObject | ParsedAgentObject>, models: Map<string, ParsedModelObject>, tools: Map<string, ParsedToolObject>): CompiledAgentBinding;
@@ -0,0 +1,181 @@
1
+ import path from "node:path";
2
+ import { getSkillInheritancePolicy, resolveToolTargets } from "../extensions.js";
3
+ import { compileModel, compileTool } from "./resource-compilers.js";
4
+ import { discoverSkillPaths } from "./support/discovery.js";
5
+ import { compileAgentMemories, getRuntimeDefaults, resolvePromptValue, resolveRefId } from "./support/workspace-ref-utils.js";
6
+ function requireSkills(pathEntries, workspaceRoot) {
7
+ return Array.from(new Set(discoverSkillPaths(pathEntries, workspaceRoot)));
8
+ }
9
+ function resolveInheritancePolicy(agent) {
10
+ const langchainPolicy = typeof agent.langchainAgentConfig?.skillInheritancePolicy === "string" ? agent.langchainAgentConfig.skillInheritancePolicy : undefined;
11
+ const deepagentPolicy = typeof agent.deepAgentConfig?.skillInheritancePolicy === "string" ? agent.deepAgentConfig.skillInheritancePolicy : undefined;
12
+ return (langchainPolicy ?? deepagentPolicy ?? "default").trim();
13
+ }
14
+ export function compileAgentSkills(workspaceRoot, agent, parentSkills = []) {
15
+ const policyName = resolveInheritancePolicy(agent);
16
+ const policy = getSkillInheritancePolicy(policyName);
17
+ if (!policy) {
18
+ throw new Error(`Agent ${agent.id} skill inheritance policy ${policyName} is not registered`);
19
+ }
20
+ return Array.from(new Set(policy.apply({
21
+ agent,
22
+ ownSkills: requireSkills(agent.skillPathRefs, workspaceRoot),
23
+ parentSkills,
24
+ })));
25
+ }
26
+ function requireModel(models, ref, ownerId) {
27
+ const model = models.get(resolveRefId(ref));
28
+ if (!model) {
29
+ throw new Error(`Agent ${ownerId} references missing model ${ref}`);
30
+ }
31
+ return compileModel(model);
32
+ }
33
+ function resolveAgentRuntimeName(agent) {
34
+ const baseName = agent.id;
35
+ if (baseName.includes(".")) {
36
+ return baseName;
37
+ }
38
+ const normalizedSourcePath = agent.sourcePath.split(path.sep).join("/");
39
+ if (normalizedSourcePath.includes("/packages/builtins/")) {
40
+ return `builtin.${baseName}`;
41
+ }
42
+ if (normalizedSourcePath.includes("/packages/framework/")) {
43
+ return `core.${baseName}`;
44
+ }
45
+ if (["direct", "orchestra", "research-lite"].includes(baseName)) {
46
+ return `core.${baseName}`;
47
+ }
48
+ return baseName;
49
+ }
50
+ export function requireTools(tools, refs, ownerId) {
51
+ const compiled = refs.flatMap((ref) => {
52
+ const targets = resolveToolTargets(tools, ref);
53
+ if (targets.length === 0) {
54
+ throw new Error(`Agent ${ownerId} references missing tool ${ref}`);
55
+ }
56
+ return targets.flatMap((tool) => compileTool(tool, tools));
57
+ });
58
+ const deduped = new Map();
59
+ for (const tool of compiled) {
60
+ deduped.set(tool.name, tool);
61
+ }
62
+ return Array.from(deduped.values());
63
+ }
64
+ function buildSubagent(agent, workspaceRoot, models, tools, parentSkills, parentModel, parentMemory) {
65
+ const ownMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
66
+ return {
67
+ name: resolveAgentRuntimeName(agent),
68
+ description: agent.description,
69
+ systemPrompt: resolvePromptValue(agent.deepAgentConfig?.systemPrompt) ?? "",
70
+ tools: requireTools(tools, agent.toolRefs, agent.id),
71
+ model: agent.modelRef ? requireModel(models, agent.modelRef, agent.id) : parentModel,
72
+ interruptOn: agent.deepAgentConfig?.interruptOn,
73
+ skills: compileAgentSkills(workspaceRoot, agent, parentSkills),
74
+ memory: ownMemory.length > 0 ? ownMemory : parentMemory,
75
+ };
76
+ }
77
+ function resolveDirectPrompt(agent) {
78
+ return resolvePromptValue(agent.langchainAgentConfig?.systemPrompt);
79
+ }
80
+ function resolveSystemPrompt(agent) {
81
+ if (agent.executionMode !== "deepagent") {
82
+ return resolveDirectPrompt(agent);
83
+ }
84
+ const deepagentPrompt = resolvePromptValue(agent.deepAgentConfig?.systemPrompt);
85
+ if (deepagentPrompt) {
86
+ return deepagentPrompt;
87
+ }
88
+ return resolveDirectPrompt(agent);
89
+ }
90
+ function resolveInterruptOn(agent) {
91
+ if (agent.executionMode !== "deepagent") {
92
+ return undefined;
93
+ }
94
+ return (agent.deepAgentConfig?.interruptOn ??
95
+ agent.langchainAgentConfig?.interruptOn);
96
+ }
97
+ function resolveBackendConfig(agent) {
98
+ if (agent.executionMode !== "deepagent") {
99
+ return undefined;
100
+ }
101
+ const backendConfig = typeof agent.deepAgentConfig?.backend === "object" && agent.deepAgentConfig.backend
102
+ ? agent.deepAgentConfig.backend
103
+ : undefined;
104
+ return backendConfig ? { config: backendConfig } : undefined;
105
+ }
106
+ function resolveStoreConfig(agent) {
107
+ if (agent.executionMode !== "deepagent") {
108
+ return undefined;
109
+ }
110
+ const inlineStore = typeof agent.deepAgentConfig?.store === "object" && agent.deepAgentConfig.store
111
+ ? agent.deepAgentConfig.store
112
+ : undefined;
113
+ return inlineStore ? { config: inlineStore } : undefined;
114
+ }
115
+ function resolveCheckpointerConfig(agent) {
116
+ const inlineAgentCheckpointer = typeof agent.deepAgentConfig?.checkpointer === "object" && agent.deepAgentConfig.checkpointer
117
+ ? agent.deepAgentConfig.checkpointer
118
+ : typeof agent.langchainAgentConfig?.checkpointer === "object" && agent.langchainAgentConfig.checkpointer
119
+ ? agent.langchainAgentConfig.checkpointer
120
+ : undefined;
121
+ return inlineAgentCheckpointer ? { config: inlineAgentCheckpointer } : undefined;
122
+ }
123
+ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentIds, refs, models, tools) {
124
+ const internalSubagent = referencedSubagentIds.has(agent.id);
125
+ const runtimeDefaults = getRuntimeDefaults(refs);
126
+ const compiledAgentSkills = compileAgentSkills(workspaceRoot, agent);
127
+ const compiledAgentMemory = compileAgentMemories(workspaceRoot, agent.memorySources);
128
+ const compiledAgentModel = requireModel(models, agent.modelRef || (internalSubagent ? "model/default" : ""), agent.id);
129
+ const backend = resolveBackendConfig(agent);
130
+ const store = resolveStoreConfig(agent);
131
+ const checkpointer = resolveCheckpointerConfig(agent);
132
+ const runRoot = typeof agent.runRoot === "string" && agent.runRoot.trim().length > 0
133
+ ? path.resolve(workspaceRoot, agent.runRoot)
134
+ : typeof runtimeDefaults?.runRoot === "string" && runtimeDefaults.runRoot.trim().length > 0
135
+ ? path.resolve(workspaceRoot, runtimeDefaults.runRoot)
136
+ : path.join(workspaceRoot, "run-data");
137
+ const base = {
138
+ agent,
139
+ harnessRuntime: {
140
+ runRoot,
141
+ hostFacing: !internalSubagent,
142
+ ...(checkpointer ? { checkpointer: checkpointer.config } : {}),
143
+ ...(store ? { store: store.config } : {}),
144
+ },
145
+ };
146
+ if (agent.executionMode !== "deepagent") {
147
+ const langchainAgentParams = {
148
+ model: compiledAgentModel,
149
+ tools: requireTools(tools, agent.toolRefs, agent.id),
150
+ systemPrompt: resolveSystemPrompt(agent),
151
+ description: agent.description,
152
+ };
153
+ return {
154
+ ...base,
155
+ langchainAgentParams,
156
+ directAgentParams: langchainAgentParams,
157
+ };
158
+ }
159
+ return {
160
+ ...base,
161
+ deepAgentParams: {
162
+ model: compiledAgentModel,
163
+ tools: requireTools(tools, agent.toolRefs, agent.id),
164
+ systemPrompt: resolveSystemPrompt(agent),
165
+ description: agent.description,
166
+ subagents: agent.subagentRefs.map((ref) => {
167
+ const subagent = agents.get(resolveRefId(ref));
168
+ if (!subagent) {
169
+ throw new Error(`Missing subagent ${ref} for agent ${agent.id}`);
170
+ }
171
+ return buildSubagent(subagent, workspaceRoot, models, tools, compiledAgentSkills, compiledAgentModel, compiledAgentMemory);
172
+ }),
173
+ interruptOn: resolveInterruptOn(agent),
174
+ ...(backend ? { backend: backend.config } : {}),
175
+ ...(store ? { store: store.config } : {}),
176
+ name: resolveAgentRuntimeName(agent),
177
+ memory: compiledAgentMemory,
178
+ skills: compiledAgentSkills,
179
+ },
180
+ };
181
+ }
@@ -0,0 +1,2 @@
1
+ import type { WorkspaceBundle, WorkspaceLoadOptions } from "../contracts/types.js";
2
+ export declare function loadWorkspace(workspaceRoot: string, options?: WorkspaceLoadOptions): Promise<WorkspaceBundle>;
@@ -0,0 +1,107 @@
1
+ import { ensureBuiltinSources, listBuiltinTools, listBuiltinToolsForSource } from "../vendor/builtins.js";
2
+ import { isExternalSourceLocator } from "../vendor/sources.js";
3
+ import { loadWorkspaceObjects } from "./object-loader.js";
4
+ import { parseEmbeddingModelObject, parseModelObject, parseToolObject, parseVectorStoreObject, validateEmbeddingModelObject, validateModelObject, validateToolObject, validateVectorStoreObject, } from "./resource-compilers.js";
5
+ import { validateAgent, validateTopology } from "./validate.js";
6
+ import { compileBinding } from "./agent-binding-compiler.js";
7
+ import { discoverSubagents, ensureDiscoverySources } from "./support/discovery.js";
8
+ import { collectAgentDiscoverySourceRefs, collectToolSourceRefs } from "./support/source-collectors.js";
9
+ import { resolveRefId } from "./support/workspace-ref-utils.js";
10
+ function collectParsedResources(refs) {
11
+ const embeddings = new Map();
12
+ const models = new Map();
13
+ const vectorStores = new Map();
14
+ const tools = new Map();
15
+ for (const [ref, object] of refs) {
16
+ if (typeof object !== "object" || !object || "executionMode" in object) {
17
+ continue;
18
+ }
19
+ const typed = object;
20
+ if (ref.startsWith("embedding-model/")) {
21
+ embeddings.set(typed.id, parseEmbeddingModelObject(object));
22
+ }
23
+ else if (ref.startsWith("vector-store/")) {
24
+ vectorStores.set(typed.id, parseVectorStoreObject(object));
25
+ }
26
+ else if (ref.startsWith("model/")) {
27
+ models.set(typed.id, parseModelObject(object));
28
+ }
29
+ else if (ref.startsWith("tool/")) {
30
+ tools.set(typed.id, parseToolObject(object));
31
+ }
32
+ }
33
+ return { embeddings, models, vectorStores, tools };
34
+ }
35
+ async function hydrateBuiltinAndExternalTools(tools, toolSourceRefs, workspaceRoot) {
36
+ for (const source of toolSourceRefs) {
37
+ if (isExternalSourceLocator(source)) {
38
+ const sourceTools = await listBuiltinToolsForSource(source, workspaceRoot);
39
+ if (sourceTools.length > 0) {
40
+ tools.set(source, {
41
+ id: source,
42
+ type: "bundle",
43
+ name: source,
44
+ description: `External builtin tool bundle loaded from ${source}`,
45
+ bundleRefs: sourceTools.map((tool) => tool.builtinPath),
46
+ sourcePath: source,
47
+ });
48
+ }
49
+ }
50
+ }
51
+ for (const builtinTool of await listBuiltinTools(toolSourceRefs, workspaceRoot)) {
52
+ const existing = tools.get(builtinTool.builtinPath);
53
+ tools.set(builtinTool.builtinPath, {
54
+ id: builtinTool.builtinPath,
55
+ type: existing?.type ?? "backend",
56
+ name: existing?.name || builtinTool.name,
57
+ description: existing?.description || builtinTool.description,
58
+ config: existing?.config,
59
+ backendOperation: existing?.backendOperation ?? builtinTool.backendOperation,
60
+ bundleRefs: existing?.bundleRefs ?? [],
61
+ hitl: existing?.hitl ?? builtinTool.hitl,
62
+ sourcePath: existing?.sourcePath ?? builtinTool.builtinPath,
63
+ });
64
+ }
65
+ }
66
+ function validateWorkspaceResources(embeddings, models, vectorStores, tools, agents) {
67
+ embeddings.forEach((embedding) => validateEmbeddingModelObject(embedding));
68
+ models.forEach((model) => validateModelObject(model, models));
69
+ vectorStores.forEach((vectorStore) => validateVectorStoreObject(vectorStore));
70
+ tools.forEach((tool) => validateToolObject(tool, tools));
71
+ agents.forEach(validateAgent);
72
+ validateTopology(agents);
73
+ }
74
+ function compileBindings(workspaceRoot, refs, agentsList, models, tools) {
75
+ const agents = new Map(agentsList.map((agent) => [agent.id, agent]));
76
+ const referencedSubagentIds = new Set(agentsList.flatMap((agent) => agent.subagentRefs.map((ref) => resolveRefId(ref))));
77
+ const bindings = new Map();
78
+ for (const agent of agentsList) {
79
+ bindings.set(agent.id, compileBinding(workspaceRoot, agent, agents, referencedSubagentIds, refs, models, tools));
80
+ }
81
+ return bindings;
82
+ }
83
+ export async function loadWorkspace(workspaceRoot, options = {}) {
84
+ const loaded = await loadWorkspaceObjects(workspaceRoot, options);
85
+ loaded.agents = await discoverSubagents(loaded.agents, workspaceRoot);
86
+ const discoverySourceRefs = collectAgentDiscoverySourceRefs(loaded.agents);
87
+ await ensureDiscoverySources(discoverySourceRefs, workspaceRoot);
88
+ for (const agent of loaded.agents) {
89
+ loaded.refs.set(`agent/${agent.id}`, agent);
90
+ }
91
+ const { embeddings, models, vectorStores, tools } = collectParsedResources(loaded.refs);
92
+ const toolSourceRefs = collectToolSourceRefs(tools, loaded.agents, options);
93
+ await ensureBuiltinSources(toolSourceRefs, workspaceRoot);
94
+ await hydrateBuiltinAndExternalTools(tools, toolSourceRefs, workspaceRoot);
95
+ validateWorkspaceResources(embeddings, models, vectorStores, tools, loaded.agents);
96
+ return {
97
+ workspaceRoot,
98
+ builtinSources: [...toolSourceRefs],
99
+ refs: loaded.refs,
100
+ embeddings,
101
+ models,
102
+ vectorStores,
103
+ tools,
104
+ agents: new Map(loaded.agents.map((agent) => [agent.id, agent])),
105
+ bindings: compileBindings(workspaceRoot, loaded.refs, loaded.agents, models, tools),
106
+ };
107
+ }
@@ -0,0 +1,6 @@
1
+ export { compileBinding, compileAgentSkills, requireTools } from "./agent-binding-compiler.js";
2
+ export { loadWorkspace } from "./compile.js";
3
+ export { loadWorkspaceObjects } from "./object-loader.js";
4
+ export { compileEmbeddingModel, compileModel, compileTool, compileVectorStore, parseEmbeddingModelObject, parseModelObject, parseToolObject, parseVectorStoreObject, validateEmbeddingModelObject, validateModelObject, validateToolObject, validateVectorStoreObject, } from "./resource-compilers.js";
5
+ export * from "./support/index.js";
6
+ export { validateAgent, validateTopology } from "./validate.js";
@@ -0,0 +1,6 @@
1
+ export { compileBinding, compileAgentSkills, requireTools } from "./agent-binding-compiler.js";
2
+ export { loadWorkspace } from "./compile.js";
3
+ export { loadWorkspaceObjects } from "./object-loader.js";
4
+ export { compileEmbeddingModel, compileModel, compileTool, compileVectorStore, parseEmbeddingModelObject, parseModelObject, parseToolObject, parseVectorStoreObject, validateEmbeddingModelObject, validateModelObject, validateToolObject, validateVectorStoreObject, } from "./resource-compilers.js";
5
+ export * from "./support/index.js";
6
+ export { validateAgent, validateTopology } from "./validate.js";
@@ -0,0 +1,16 @@
1
+ import type { ParsedAgentObject, WorkspaceLoadOptions, WorkspaceObject } from "../contracts/types.js";
2
+ type RefMap = Map<string, WorkspaceObject | ParsedAgentObject>;
3
+ export type WorkspaceObjects = {
4
+ refs: RefMap;
5
+ agents: ParsedAgentObject[];
6
+ };
7
+ export declare function normalizeYamlItem(item: Record<string, unknown>): Record<string, unknown>;
8
+ export declare function parseAgentItem(item: Record<string, unknown>, sourcePath: string): ParsedAgentObject;
9
+ export declare function readYamlItems(root: string, relativeDir?: string, options?: {
10
+ recursive?: boolean;
11
+ }): Promise<Array<{
12
+ item: Record<string, unknown>;
13
+ sourcePath: string;
14
+ }>>;
15
+ export declare function loadWorkspaceObjects(workspaceRoot: string, options?: WorkspaceLoadOptions): Promise<WorkspaceObjects>;
16
+ export {};