@botbotgo/agent-harness 0.0.475 → 0.0.476
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/README.md +3 -1234
- package/README.zh.md +3 -1191
- package/dist/acp.js +1 -1
- package/dist/api.js +1 -404
- package/dist/benchmark/checkpoint-resume-cost-benchmark.js +1 -55
- package/dist/benchmark/deepagent-local-model-benchmark.js +2 -35
- package/dist/benchmark/upstream-runtime-ab-benchmark.js +1 -179
- package/dist/cli/chat-interactive.js +25 -244
- package/dist/cli/chat-rendering.js +6 -100
- package/dist/cli/chat-stream.js +23 -512
- package/dist/cli/chat-ui.js +21 -199
- package/dist/cli/chat-workspace.js +2 -210
- package/dist/cli/main.js +21 -428
- package/dist/cli/managed-service-commands.js +9 -63
- package/dist/cli/managed-service.js +2 -137
- package/dist/cli/options-init-chat.js +1 -108
- package/dist/cli/options-runtime.js +1 -158
- package/dist/cli/options-serve.js +1 -282
- package/dist/cli/options.js +2 -19
- package/dist/cli/process-guards.js +1 -139
- package/dist/cli/request-tree.js +7 -296
- package/dist/cli/runtime-commands.js +12 -258
- package/dist/cli/runtime-output.js +16 -155
- package/dist/cli/server-commands.js +16 -270
- package/dist/cli/workspace.js +1 -67
- package/dist/cli.js +1 -7
- package/dist/client/acp.js +1 -1
- package/dist/client/in-process.js +1 -67
- package/dist/client/index.js +1 -2
- package/dist/client/types.js +0 -1
- package/dist/client.js +1 -1
- package/dist/contracts/core.js +1 -1
- package/dist/contracts/runtime-evaluation.js +0 -1
- package/dist/contracts/runtime-memory.js +0 -1
- package/dist/contracts/runtime-observability.js +0 -1
- package/dist/contracts/runtime-requests.js +0 -1
- package/dist/contracts/runtime-scheduling.js +0 -1
- package/dist/contracts/runtime.js +1 -27
- package/dist/contracts/types.js +1 -3
- package/dist/contracts/workspace.js +0 -1
- package/dist/flow/build-flow-graph.js +1 -50
- package/dist/flow/export-mermaid.js +2 -464
- package/dist/flow/export-sequence-mermaid.js +2 -325
- package/dist/flow/flow-graph-normalization.js +1 -214
- package/dist/flow/flow-graph-runtime.js +1 -107
- package/dist/flow/flow-graph-upstream.js +1 -494
- package/dist/flow/index.js +1 -3
- package/dist/flow/types.js +0 -1
- package/dist/index.js +1 -5
- package/dist/init-project.js +1 -1
- package/dist/knowledge/config.js +1 -32
- package/dist/knowledge/contracts.js +0 -1
- package/dist/knowledge/index.js +1 -2
- package/dist/knowledge/module.js +12 -909
- package/dist/knowledge/procedural/config.js +1 -125
- package/dist/knowledge/procedural/index.js +1 -2
- package/dist/knowledge/procedural/manager.js +9 -345
- package/dist/mcp.js +1 -2
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -2
- package/dist/persistence/file-store.js +3 -758
- package/dist/persistence/sqlite-request-context-store.js +5 -54
- package/dist/persistence/sqlite-request-queue-store.js +10 -108
- package/dist/persistence/sqlite-runtime.js +1 -86
- package/dist/persistence/sqlite-store.js +62 -810
- package/dist/persistence/types.js +0 -1
- package/dist/projections/presentation.js +37 -206
- package/dist/projections/request-events.js +2 -502
- package/dist/projections/upstream-events.js +1 -201
- package/dist/protocol/a2a/http-discovery.js +1 -178
- package/dist/protocol/a2a/http-rpc.js +6 -622
- package/dist/protocol/a2a/http.js +1 -138
- package/dist/protocol/a2a/task-state.js +3 -317
- package/dist/protocol/acp/client.js +8 -294
- package/dist/protocol/acp/harness-client.js +1 -218
- package/dist/protocol/acp/http.js +5 -130
- package/dist/protocol/acp/server.js +1 -310
- package/dist/protocol/acp/stdio.js +2 -69
- package/dist/protocol/ag-ui/http.js +3 -378
- package/dist/protocol/mcp/server.js +1 -428
- package/dist/resource/backend/workspace-scoped-backend.js +1 -319
- package/dist/resource/isolation.js +1 -237
- package/dist/resource/mcp/tool-support.js +3 -296
- package/dist/resource/mcp-tool-support.js +1 -2
- package/dist/resource/providers/resource-provider.js +1 -215
- package/dist/resource/resource-impl.js +1 -3
- package/dist/resource/resource-types.js +0 -1
- package/dist/resource/resource.js +1 -1
- package/dist/resource/sources.js +1 -247
- package/dist/resource/tools/function-tool-resolver.js +2 -272
- package/dist/runtime/adapter/compat/deepagent-compat.js +1 -29
- package/dist/runtime/adapter/compat/openai-compatible.js +1 -55
- package/dist/runtime/adapter/direct-builtin-utility.js +2 -90
- package/dist/runtime/adapter/flow/execution-context.js +1 -71
- package/dist/runtime/adapter/flow/invocation-flow.js +8 -425
- package/dist/runtime/adapter/flow/invoke-runtime.js +1 -20
- package/dist/runtime/adapter/flow/stream-runtime.js +11 -1395
- package/dist/runtime/adapter/invocation-result.js +2 -473
- package/dist/runtime/adapter/local-tool-invocation.js +6 -638
- package/dist/runtime/adapter/middleware/context-hygiene.js +1 -83
- package/dist/runtime/adapter/middleware-assembly.js +5 -477
- package/dist/runtime/adapter/model/invocation-request.js +3 -183
- package/dist/runtime/adapter/model/message-assembly.js +1 -28
- package/dist/runtime/adapter/model/model-providers.js +23 -1115
- package/dist/runtime/adapter/model/prompted-json-tool-call-capture.js +1 -40
- package/dist/runtime/adapter/model/prompted-json-tool-policy.js +1 -22
- package/dist/runtime/adapter/resilience.js +1 -104
- package/dist/runtime/adapter/runtime-adapter-support.js +3 -141
- package/dist/runtime/adapter/runtime-shell.js +5 -166
- package/dist/runtime/adapter/stream-event-projection.js +2 -622
- package/dist/runtime/adapter/stream-text-consumption.js +1 -18
- package/dist/runtime/adapter/terminal-status.js +2 -67
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +6 -627
- package/dist/runtime/adapter/tool/declared-middleware.js +1 -154
- package/dist/runtime/adapter/tool/interrupt-policy.js +1 -34
- package/dist/runtime/adapter/tool/provider-tool.js +1 -25
- package/dist/runtime/adapter/tool/resolved-tool.js +1 -225
- package/dist/runtime/adapter/tool/tool-arguments.js +3 -486
- package/dist/runtime/adapter/tool/tool-hitl.js +1 -346
- package/dist/runtime/adapter/tool/tool-name-mapping.js +1 -128
- package/dist/runtime/adapter/tool/tool-output-artifacts.js +2 -88
- package/dist/runtime/adapter/tool/tool-replay.js +1 -37
- package/dist/runtime/adapter/tool-resolution.js +1 -86
- package/dist/runtime/adapter/upstream-configurable-keys.js +1 -2
- package/dist/runtime/agent-runtime-adapter.js +60 -2338
- package/dist/runtime/agent-runtime-assembly.js +7 -249
- package/dist/runtime/env/runtime-env.js +1 -62
- package/dist/runtime/harness/background-runtime.js +1 -8
- package/dist/runtime/harness/bindings.js +1 -58
- package/dist/runtime/harness/events/event-bus.js +1 -16
- package/dist/runtime/harness/events/event-sink.js +1 -61
- package/dist/runtime/harness/events/events.js +1 -80
- package/dist/runtime/harness/events/listener-runtime.js +1 -13
- package/dist/runtime/harness/events/runtime-event-operations.js +1 -9
- package/dist/runtime/harness/events/streaming.js +1 -100
- package/dist/runtime/harness/events/timeline.js +1 -52
- package/dist/runtime/harness/public-shapes.js +1 -186
- package/dist/runtime/harness/run/artifact-paths.js +1 -15
- package/dist/runtime/harness/run/governance.js +1 -295
- package/dist/runtime/harness/run/helpers.js +1 -71
- package/dist/runtime/harness/run/inspection.js +1 -409
- package/dist/runtime/harness/run/operator-overview.js +1 -80
- package/dist/runtime/harness/run/queue-diagnostics.js +1 -15
- package/dist/runtime/harness/run/recovery.js +1 -162
- package/dist/runtime/harness/run/resources.js +1 -60
- package/dist/runtime/harness/run/resume.js +1 -56
- package/dist/runtime/harness/run/routing.js +1 -48
- package/dist/runtime/harness/run/run-lifecycle.js +1 -66
- package/dist/runtime/harness/run/run-operations.js +1 -217
- package/dist/runtime/harness/run/run-queue.js +1 -43
- package/dist/runtime/harness/run/run-slot-acquisition.js +1 -157
- package/dist/runtime/harness/run/session-records.js +1 -97
- package/dist/runtime/harness/run/start-run.js +1 -120
- package/dist/runtime/harness/run/startup-runtime.js +1 -69
- package/dist/runtime/harness/run/stream-run.js +8 -1418
- package/dist/runtime/harness/run/surface-semantics.js +1 -79
- package/dist/runtime/harness/runtime-defaults.js +1 -39
- package/dist/runtime/harness/system/boundary-analysis.js +1 -234
- package/dist/runtime/harness/system/health-monitor.js +1 -258
- package/dist/runtime/harness/system/inventory.js +1 -129
- package/dist/runtime/harness/system/mem0-ingestion-sync.js +5 -345
- package/dist/runtime/harness/system/policy-engine.js +1 -175
- package/dist/runtime/harness/system/runtime-memory-candidates.js +4 -110
- package/dist/runtime/harness/system/runtime-memory-consolidation.js +1 -51
- package/dist/runtime/harness/system/runtime-memory-manager.js +10 -693
- package/dist/runtime/harness/system/runtime-memory-policy.js +1 -155
- package/dist/runtime/harness/system/runtime-memory-records.js +11 -577
- package/dist/runtime/harness/system/runtime-memory-sync.js +5 -206
- package/dist/runtime/harness/system/session-memory-sync.js +3 -113
- package/dist/runtime/harness/system/skill-requirements.js +1 -112
- package/dist/runtime/harness/system/store.js +9 -365
- package/dist/runtime/harness/tool-gateway/index.js +1 -2
- package/dist/runtime/harness/tool-gateway/policy.js +1 -45
- package/dist/runtime/harness/tool-gateway/validation.js +1 -176
- package/dist/runtime/harness/tool-schema.js +1 -3
- package/dist/runtime/harness.js +3 -1490
- package/dist/runtime/index.js +1 -3
- package/dist/runtime/layout/runtime-layout.js +1 -31
- package/dist/runtime/maintenance/checkpoint-maintenance.js +2 -178
- package/dist/runtime/maintenance/file-checkpoint-saver.js +1 -106
- package/dist/runtime/maintenance/runtime-record-maintenance.js +2 -169
- package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +4 -289
- package/dist/runtime/parsing/output-content.js +10 -550
- package/dist/runtime/parsing/output-parsing.js +1 -4
- package/dist/runtime/parsing/output-recovery.js +3 -213
- package/dist/runtime/parsing/output-tool-args.js +7 -663
- package/dist/runtime/parsing/stream-event-parsing.js +3 -362
- package/dist/runtime/prompts/runtime-prompts.js +4 -73
- package/dist/runtime/scheduling/system-schedule-manager.js +11 -532
- package/dist/runtime/skills/skill-metadata.js +1 -197
- package/dist/runtime/startup-tracing.js +2 -37
- package/dist/runtime/support/compiled-binding.js +1 -290
- package/dist/runtime/support/embedding-models.js +1 -118
- package/dist/runtime/support/harness-support.js +5 -137
- package/dist/runtime/support/llamaindex.js +1 -108
- package/dist/runtime/support/runtime-adapter-options.js +1 -29
- package/dist/runtime/support/runtime-factories.js +1 -51
- package/dist/runtime/support/vector-stores.js +9 -270
- package/dist/scaffold/init-project.js +54 -233
- package/dist/tooling/extensions.js +1 -311
- package/dist/tooling/module-loader.js +1 -55
- package/dist/tools.js +1 -176
- package/dist/utils/agent-display.js +1 -18
- package/dist/utils/bundled-text.js +4 -39
- package/dist/utils/compiled-binding.js +1 -33
- package/dist/utils/fs.js +2 -45
- package/dist/utils/id.js +1 -9
- package/dist/utils/message-content.js +1 -30
- package/dist/utils/object.js +1 -6
- package/dist/workspace/agent-binding-compiler.js +3 -613
- package/dist/workspace/compile.js +1 -472
- package/dist/workspace/framework-contract-validation.js +2 -322
- package/dist/workspace/index.js +1 -1
- package/dist/workspace/object-loader-paths.js +1 -71
- package/dist/workspace/object-loader-readers.js +1 -187
- package/dist/workspace/object-loader.js +1 -754
- package/dist/workspace/resource-compilers.js +1 -374
- package/dist/workspace/support/agent-capabilities.js +1 -37
- package/dist/workspace/support/agent-execution-config.js +1 -44
- package/dist/workspace/support/discovery.js +1 -147
- package/dist/workspace/support/source-collectors.js +1 -30
- package/dist/workspace/support/source-protocols.js +2 -192
- package/dist/workspace/support/workspace-ref-utils.js +1 -362
- package/dist/workspace/tool-hydration.js +1 -280
- package/dist/workspace/validate.js +1 -99
- package/dist/workspace/yaml-object-reader.js +1 -285
- package/package.json +7 -3
|
@@ -1,319 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { CompositeBackend, LangSmithSandbox, LocalShellBackend, StateBackend, StoreBackend } from "deepagents";
|
|
4
|
-
import { getBindingBackendConfig } from "../../runtime/support/compiled-binding.js";
|
|
5
|
-
import { createRuntimeEnv } from "../../runtime/env/runtime-env.js";
|
|
6
|
-
function listVirtualRootEntries(rootDir) {
|
|
7
|
-
try {
|
|
8
|
-
return new Set(readdirSync(rootDir, { withFileTypes: true }).map((entry) => entry.name));
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return new Set();
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function normalizeVirtualExecuteCommand(command, rootDir) {
|
|
15
|
-
if (typeof command !== "string" || command.length === 0) {
|
|
16
|
-
return command;
|
|
17
|
-
}
|
|
18
|
-
const rootEntries = listVirtualRootEntries(rootDir);
|
|
19
|
-
if (rootEntries.size === 0) {
|
|
20
|
-
return command;
|
|
21
|
-
}
|
|
22
|
-
return command.replace(/(^|[\s=:(\[{,;|&])(?<quote>["']?)(?<virtualPath>\/(?:[^\s"'`;|&()<>]+))(?:\k<quote>)/g, (match, prefix, quote = "", virtualPath) => {
|
|
23
|
-
const normalizedVirtualPath = virtualPath.replace(/\/+/g, "/");
|
|
24
|
-
const segments = normalizedVirtualPath.split("/").filter((segment) => segment.length > 0);
|
|
25
|
-
const firstSegment = segments[0];
|
|
26
|
-
if (!firstSegment || !rootEntries.has(firstSegment)) {
|
|
27
|
-
return match;
|
|
28
|
-
}
|
|
29
|
-
const translatedPath = path.resolve(rootDir, ...segments);
|
|
30
|
-
return `${prefix}${quote}${translatedPath}${quote}`;
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export function normalizeWorkspaceScopedPath(rootDir, inputPath, options = {}) {
|
|
34
|
-
if (typeof inputPath !== "string" || inputPath.length === 0 || !path.isAbsolute(inputPath)) {
|
|
35
|
-
return inputPath;
|
|
36
|
-
}
|
|
37
|
-
if (inputPath.startsWith("/large_tool_results/")) {
|
|
38
|
-
throw new Error(`Path '${inputPath}' is an internal runtime spill path, not a workspace file. Do not read internal runtime spill files such as '/large_tool_results/...'. Use the preview already in context, rerun the producing tool with narrower output, or write the needed data to a workspace-relative file instead.`);
|
|
39
|
-
}
|
|
40
|
-
if (inputPath === "/") {
|
|
41
|
-
return ".";
|
|
42
|
-
}
|
|
43
|
-
const virtualSegments = inputPath.replace(/\/+/g, "/").split("/").filter((segment) => segment.length > 0);
|
|
44
|
-
if (virtualSegments.length > 0) {
|
|
45
|
-
const rootEntries = listVirtualRootEntries(rootDir);
|
|
46
|
-
const firstSegment = virtualSegments[0];
|
|
47
|
-
if (rootEntries.has(firstSegment)) {
|
|
48
|
-
return path.join(...virtualSegments);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const normalizedRootDir = path.resolve(rootDir);
|
|
52
|
-
const normalizedInputPath = path.resolve(inputPath);
|
|
53
|
-
if (normalizedInputPath === normalizedRootDir || normalizedInputPath.startsWith(`${normalizedRootDir}${path.sep}`)) {
|
|
54
|
-
return path.relative(normalizedRootDir, normalizedInputPath) || ".";
|
|
55
|
-
}
|
|
56
|
-
if (options.allowVirtualAbsolutePath === true) {
|
|
57
|
-
return inputPath.replace(/\/+/g, "/");
|
|
58
|
-
}
|
|
59
|
-
throw new Error(`Path '${inputPath}' is outside the workspace root '${normalizedRootDir}'. Use a workspace-relative path instead.`);
|
|
60
|
-
}
|
|
61
|
-
function normalizeWorkspaceScopedNullablePath(rootDir, inputPath, options = {}) {
|
|
62
|
-
return typeof inputPath === "string" ? normalizeWorkspaceScopedPath(rootDir, inputPath, options) : inputPath;
|
|
63
|
-
}
|
|
64
|
-
export class WorkspaceScopedBackend {
|
|
65
|
-
backend;
|
|
66
|
-
options;
|
|
67
|
-
id;
|
|
68
|
-
cwd;
|
|
69
|
-
rootDir;
|
|
70
|
-
root;
|
|
71
|
-
virtualMode;
|
|
72
|
-
execute;
|
|
73
|
-
constructor(backend, rootDir, options = {}) {
|
|
74
|
-
this.backend = backend;
|
|
75
|
-
this.options = options;
|
|
76
|
-
this.rootDir = path.resolve(rootDir);
|
|
77
|
-
this.root = this.rootDir;
|
|
78
|
-
this.cwd = this.rootDir;
|
|
79
|
-
this.id = typeof backend.id === "string" ? backend.id : undefined;
|
|
80
|
-
this.virtualMode = backend.virtualMode === true;
|
|
81
|
-
this.execute = typeof backend.execute === "function"
|
|
82
|
-
? (command) => backend.execute(command)
|
|
83
|
-
: undefined;
|
|
84
|
-
}
|
|
85
|
-
ls(filePath) {
|
|
86
|
-
return this.backend.ls(normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options));
|
|
87
|
-
}
|
|
88
|
-
read(filePath, offset, limit) {
|
|
89
|
-
return this.backend.read(normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options), offset, limit);
|
|
90
|
-
}
|
|
91
|
-
readRaw(filePath) {
|
|
92
|
-
return this.backend.readRaw(normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options));
|
|
93
|
-
}
|
|
94
|
-
grep(pattern, filePath, glob) {
|
|
95
|
-
return this.backend.grep(pattern, normalizeWorkspaceScopedNullablePath(this.rootDir, filePath, this.options), glob);
|
|
96
|
-
}
|
|
97
|
-
grepRaw(pattern, filePath, glob) {
|
|
98
|
-
return this.backend.grepRaw(pattern, normalizeWorkspaceScopedNullablePath(this.rootDir, filePath, this.options), glob);
|
|
99
|
-
}
|
|
100
|
-
glob(pattern, filePath) {
|
|
101
|
-
return this.backend.glob(pattern, typeof filePath === "string" ? normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options) : filePath);
|
|
102
|
-
}
|
|
103
|
-
write(filePath, content) {
|
|
104
|
-
return this.backend.write(normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options), content);
|
|
105
|
-
}
|
|
106
|
-
edit(filePath, oldString, newString, replaceAll) {
|
|
107
|
-
return this.backend.edit(normalizeWorkspaceScopedPath(this.rootDir, filePath, this.options), oldString, newString, replaceAll);
|
|
108
|
-
}
|
|
109
|
-
uploadFiles(files) {
|
|
110
|
-
return this.backend.uploadFiles(files);
|
|
111
|
-
}
|
|
112
|
-
downloadFiles(paths) {
|
|
113
|
-
const normalizedPaths = Array.isArray(paths)
|
|
114
|
-
? paths.map((currentPath) => normalizeWorkspaceScopedPath(this.rootDir, currentPath, this.options))
|
|
115
|
-
: paths;
|
|
116
|
-
return this.backend.downloadFiles(normalizedPaths);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
class CompatibleCompositeBackend {
|
|
120
|
-
id;
|
|
121
|
-
execute;
|
|
122
|
-
composite;
|
|
123
|
-
routePrefixes;
|
|
124
|
-
constructor(defaultBackend, routes) {
|
|
125
|
-
this.composite = new CompositeBackend(defaultBackend, routes);
|
|
126
|
-
this.routePrefixes = Object.keys(routes).filter((route) => route.startsWith("/"));
|
|
127
|
-
const sandboxLike = defaultBackend;
|
|
128
|
-
if (typeof sandboxLike.id === "string" && typeof sandboxLike.execute === "function") {
|
|
129
|
-
this.id = sandboxLike.id;
|
|
130
|
-
const virtualCwd = typeof sandboxLike.cwd === "string" && sandboxLike.virtualMode === true ? sandboxLike.cwd : null;
|
|
131
|
-
this.execute =
|
|
132
|
-
virtualCwd
|
|
133
|
-
? (command) => this.composite.execute(normalizeVirtualExecuteCommand(command, virtualCwd))
|
|
134
|
-
: (command) => this.composite.execute(command);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
normalizeCompositePath(filePath) {
|
|
138
|
-
if (!path.isAbsolute(filePath)) {
|
|
139
|
-
return filePath;
|
|
140
|
-
}
|
|
141
|
-
const normalized = filePath.replace(/\/+/g, "/");
|
|
142
|
-
if (this.routePrefixes.some((route) => normalized === route || normalized.startsWith(route))) {
|
|
143
|
-
return normalized;
|
|
144
|
-
}
|
|
145
|
-
return path.join(...normalized.split("/").filter(Boolean));
|
|
146
|
-
}
|
|
147
|
-
ls(filePath) {
|
|
148
|
-
return this.composite.ls(this.normalizeCompositePath(filePath));
|
|
149
|
-
}
|
|
150
|
-
read(filePath, offset, limit) {
|
|
151
|
-
return this.composite.read(this.normalizeCompositePath(filePath), offset, limit);
|
|
152
|
-
}
|
|
153
|
-
readRaw(filePath) {
|
|
154
|
-
return this.composite.readRaw(this.normalizeCompositePath(filePath));
|
|
155
|
-
}
|
|
156
|
-
grep(pattern, filePath, glob) {
|
|
157
|
-
return this.composite.grep(pattern, filePath ? this.normalizeCompositePath(filePath) : undefined, glob ?? undefined);
|
|
158
|
-
}
|
|
159
|
-
glob(pattern, filePath) {
|
|
160
|
-
return this.composite.glob(pattern, filePath ? this.normalizeCompositePath(filePath) : filePath);
|
|
161
|
-
}
|
|
162
|
-
write(filePath, content) {
|
|
163
|
-
return this.composite.write(this.normalizeCompositePath(filePath), content);
|
|
164
|
-
}
|
|
165
|
-
edit(filePath, oldString, newString, replaceAll) {
|
|
166
|
-
return this.composite.edit(this.normalizeCompositePath(filePath), oldString, newString, replaceAll);
|
|
167
|
-
}
|
|
168
|
-
uploadFiles(files) {
|
|
169
|
-
return this.composite.uploadFiles(files);
|
|
170
|
-
}
|
|
171
|
-
downloadFiles(paths) {
|
|
172
|
-
const normalizedPaths = Array.isArray(paths) ? paths.map((currentPath) => this.normalizeCompositePath(currentPath)) : paths;
|
|
173
|
-
return this.composite.downloadFiles(normalizedPaths);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function omitKind(config) {
|
|
177
|
-
const { kind: _kind, ...rest } = config ?? {};
|
|
178
|
-
return rest;
|
|
179
|
-
}
|
|
180
|
-
class LazyLangSmithSandbox {
|
|
181
|
-
config;
|
|
182
|
-
sandboxPromise = null;
|
|
183
|
-
constructor(config) {
|
|
184
|
-
this.config = config;
|
|
185
|
-
}
|
|
186
|
-
get id() {
|
|
187
|
-
return "langsmith-pending";
|
|
188
|
-
}
|
|
189
|
-
get isRunning() {
|
|
190
|
-
return this.sandboxPromise !== null;
|
|
191
|
-
}
|
|
192
|
-
getSandbox() {
|
|
193
|
-
if (!this.sandboxPromise) {
|
|
194
|
-
this.sandboxPromise = LangSmithSandbox.create(omitKind(this.config));
|
|
195
|
-
}
|
|
196
|
-
return this.sandboxPromise;
|
|
197
|
-
}
|
|
198
|
-
async read(filePath, offset, limit) {
|
|
199
|
-
return (await this.getSandbox()).read(filePath, offset, limit);
|
|
200
|
-
}
|
|
201
|
-
async edit(filePath, oldString, newString, replaceAll) {
|
|
202
|
-
return (await this.getSandbox()).edit(filePath, oldString, newString, replaceAll);
|
|
203
|
-
}
|
|
204
|
-
async ls(dirPath) {
|
|
205
|
-
return (await this.getSandbox()).ls(dirPath);
|
|
206
|
-
}
|
|
207
|
-
async glob(pattern, searchPath) {
|
|
208
|
-
return (await this.getSandbox()).glob(pattern, searchPath);
|
|
209
|
-
}
|
|
210
|
-
async write(filePath, content) {
|
|
211
|
-
return (await this.getSandbox()).write(filePath, content);
|
|
212
|
-
}
|
|
213
|
-
async execute(command) {
|
|
214
|
-
return (await this.getSandbox()).execute(command);
|
|
215
|
-
}
|
|
216
|
-
async uploadFiles(files) {
|
|
217
|
-
return (await this.getSandbox()).uploadFiles(files);
|
|
218
|
-
}
|
|
219
|
-
async downloadFiles(paths) {
|
|
220
|
-
return (await this.getSandbox()).downloadFiles(paths);
|
|
221
|
-
}
|
|
222
|
-
async close() {
|
|
223
|
-
if (!this.sandboxPromise) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
await (await this.sandboxPromise).close();
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
const INLINE_BACKEND_ERROR = 'Unsupported DeepAgent backend kind "%s". Supported inline kinds: LocalShellBackend, VfsSandbox, StateBackend, StoreBackend, CompositeBackend, LangSmithSandbox.';
|
|
230
|
-
function unsupportedInlineBackend(kind) {
|
|
231
|
-
throw new Error(INLINE_BACKEND_ERROR.replace("%s", kind));
|
|
232
|
-
}
|
|
233
|
-
function resolveInlineBackendRootDir(workspaceRoot, configuredRootDir) {
|
|
234
|
-
if (typeof configuredRootDir === "string" && configuredRootDir.trim().length > 0) {
|
|
235
|
-
return path.isAbsolute(configuredRootDir)
|
|
236
|
-
? configuredRootDir
|
|
237
|
-
: path.resolve(workspaceRoot, configuredRootDir);
|
|
238
|
-
}
|
|
239
|
-
return workspaceRoot;
|
|
240
|
-
}
|
|
241
|
-
function readStringRecord(value) {
|
|
242
|
-
if (typeof value !== "object" || !value) {
|
|
243
|
-
return undefined;
|
|
244
|
-
}
|
|
245
|
-
const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
|
|
246
|
-
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
247
|
-
}
|
|
248
|
-
function createLocalShellStyleBackend(workspaceRoot, config, options) {
|
|
249
|
-
const rootDir = resolveInlineBackendRootDir(workspaceRoot, config?.rootDir);
|
|
250
|
-
mkdirSync(rootDir, { recursive: true });
|
|
251
|
-
const inheritedEnv = config?.inheritEnv === false ? {} : process.env;
|
|
252
|
-
return new WorkspaceScopedBackend(new LocalShellBackend({
|
|
253
|
-
rootDir,
|
|
254
|
-
virtualMode: options.virtualMode,
|
|
255
|
-
timeout: typeof config?.timeout === "number" ? config.timeout : undefined,
|
|
256
|
-
maxOutputBytes: typeof config?.maxOutputBytes === "number" ? config.maxOutputBytes : undefined,
|
|
257
|
-
env: createRuntimeEnv(readStringRecord(config?.env), inheritedEnv),
|
|
258
|
-
inheritEnv: config?.inheritEnv !== false,
|
|
259
|
-
}), rootDir);
|
|
260
|
-
}
|
|
261
|
-
function createInlineBackendInstance(workspaceRoot, kind, config, runtimeLike) {
|
|
262
|
-
switch (kind) {
|
|
263
|
-
case "LocalShellBackend":
|
|
264
|
-
return createLocalShellStyleBackend(workspaceRoot, config, {
|
|
265
|
-
virtualMode: config?.virtualMode === true,
|
|
266
|
-
});
|
|
267
|
-
case "VfsSandbox":
|
|
268
|
-
return createLocalShellStyleBackend(workspaceRoot, config, {
|
|
269
|
-
virtualMode: config?.virtualMode === false ? false : true,
|
|
270
|
-
});
|
|
271
|
-
case "StateBackend":
|
|
272
|
-
return new StateBackend(runtimeLike);
|
|
273
|
-
case "StoreBackend":
|
|
274
|
-
return new StoreBackend(runtimeLike);
|
|
275
|
-
case "LangSmithSandbox":
|
|
276
|
-
return new LazyLangSmithSandbox(config);
|
|
277
|
-
default:
|
|
278
|
-
return unsupportedInlineBackend(kind);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
export function createInlineBackendResolver(workspace) {
|
|
282
|
-
return (binding) => {
|
|
283
|
-
const backendConfig = getBindingBackendConfig(binding);
|
|
284
|
-
if (!backendConfig || typeof backendConfig !== "object") {
|
|
285
|
-
return undefined;
|
|
286
|
-
}
|
|
287
|
-
return (runtimeLike) => {
|
|
288
|
-
const kind = typeof backendConfig.kind === "string" ? backendConfig.kind : "CompositeBackend";
|
|
289
|
-
switch (kind) {
|
|
290
|
-
case "LocalShellBackend":
|
|
291
|
-
return createInlineBackendInstance(workspace.workspaceRoot, "LocalShellBackend", backendConfig, runtimeLike);
|
|
292
|
-
case "VfsSandbox":
|
|
293
|
-
return createInlineBackendInstance(workspace.workspaceRoot, "VfsSandbox", backendConfig, runtimeLike);
|
|
294
|
-
case "StateBackend":
|
|
295
|
-
return createInlineBackendInstance(workspace.workspaceRoot, "StateBackend", backendConfig, runtimeLike);
|
|
296
|
-
case "StoreBackend":
|
|
297
|
-
return createInlineBackendInstance(workspace.workspaceRoot, "StoreBackend", backendConfig, runtimeLike);
|
|
298
|
-
case "LangSmithSandbox":
|
|
299
|
-
return createInlineBackendInstance(workspace.workspaceRoot, "LangSmithSandbox", backendConfig, runtimeLike);
|
|
300
|
-
case "CompositeBackend": {
|
|
301
|
-
const stateConfig = typeof backendConfig.state === "object" && backendConfig.state
|
|
302
|
-
? backendConfig.state
|
|
303
|
-
: { kind: "StateBackend" };
|
|
304
|
-
const defaultBackendKind = typeof stateConfig.kind === "string" ? stateConfig.kind : "StateBackend";
|
|
305
|
-
const routes = typeof backendConfig.routes === "object" && backendConfig.routes
|
|
306
|
-
? backendConfig.routes
|
|
307
|
-
: { "/memories/": { kind: "StoreBackend" } };
|
|
308
|
-
const mappedRoutes = Object.fromEntries(Object.entries(routes).map(([route, routeConfig]) => {
|
|
309
|
-
const routeKind = typeof routeConfig?.kind === "string" ? routeConfig.kind : "StoreBackend";
|
|
310
|
-
return [route, createInlineBackendInstance(workspace.workspaceRoot, routeKind, routeConfig, runtimeLike)];
|
|
311
|
-
}));
|
|
312
|
-
return new WorkspaceScopedBackend(new CompatibleCompositeBackend(createInlineBackendInstance(workspace.workspaceRoot, defaultBackendKind, stateConfig, runtimeLike), mappedRoutes), workspace.workspaceRoot, { allowVirtualAbsolutePath: true });
|
|
313
|
-
}
|
|
314
|
-
default:
|
|
315
|
-
return unsupportedInlineBackend(kind);
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
};
|
|
319
|
-
}
|
|
1
|
+
import{mkdirSync as k,readdirSync as x}from"node:fs";import s from"node:path";import{CompositeBackend as y,LangSmithSandbox as B,LocalShellBackend as v,StateBackend as z,StoreBackend as C}from"deepagents";import{getBindingBackendConfig as R}from"../../runtime/support/compiled-binding.js";import{createRuntimeEnv as E}from"../../runtime/env/runtime-env.js";function f(o){try{return new Set(x(o,{withFileTypes:!0}).map(e=>e.name))}catch{return new Set}}function D(o,e){if(typeof o!="string"||o.length===0)return o;const t=f(e);return t.size===0?o:o.replace(/(^|[\s=:(\[{,;|&])(?<quote>["']?)(?<virtualPath>\/(?:[^\s"'`;|&()<>]+))(?:\k<quote>)/g,(r,n,i="",d)=>{const h=d.replace(/\/+/g,"/").split("/").filter(m=>m.length>0),p=h[0];if(!p||!t.has(p))return r;const l=s.resolve(e,...h);return`${n}${i}${l}${i}`})}function a(o,e,t={}){if(typeof e!="string"||e.length===0||!s.isAbsolute(e))return e;if(e.startsWith("/large_tool_results/"))throw new Error(`Path '${e}' is an internal runtime spill path, not a workspace file. Do not read internal runtime spill files such as '/large_tool_results/...'. Use the preview already in context, rerun the producing tool with narrower output, or write the needed data to a workspace-relative file instead.`);if(e==="/")return".";const r=e.replace(/\/+/g,"/").split("/").filter(d=>d.length>0);if(r.length>0){const d=f(o),u=r[0];if(d.has(u))return s.join(...r)}const n=s.resolve(o),i=s.resolve(e);if(i===n||i.startsWith(`${n}${s.sep}`))return s.relative(n,i)||".";if(t.allowVirtualAbsolutePath===!0)return e.replace(/\/+/g,"/");throw new Error(`Path '${e}' is outside the workspace root '${n}'. Use a workspace-relative path instead.`)}function w(o,e,t={}){return typeof e=="string"?a(o,e,t):e}class b{backend;options;id;cwd;rootDir;root;virtualMode;execute;constructor(e,t,r={}){this.backend=e,this.options=r,this.rootDir=s.resolve(t),this.root=this.rootDir,this.cwd=this.rootDir,this.id=typeof e.id=="string"?e.id:void 0,this.virtualMode=e.virtualMode===!0,this.execute=typeof e.execute=="function"?n=>e.execute(n):void 0}ls(e){return this.backend.ls(a(this.rootDir,e,this.options))}read(e,t,r){return this.backend.read(a(this.rootDir,e,this.options),t,r)}readRaw(e){return this.backend.readRaw(a(this.rootDir,e,this.options))}grep(e,t,r){return this.backend.grep(e,w(this.rootDir,t,this.options),r)}grepRaw(e,t,r){return this.backend.grepRaw(e,w(this.rootDir,t,this.options),r)}glob(e,t){return this.backend.glob(e,typeof t=="string"?a(this.rootDir,t,this.options):t)}write(e,t){return this.backend.write(a(this.rootDir,e,this.options),t)}edit(e,t,r,n){return this.backend.edit(a(this.rootDir,e,this.options),t,r,n)}uploadFiles(e){return this.backend.uploadFiles(e)}downloadFiles(e){const t=Array.isArray(e)?e.map(r=>a(this.rootDir,r,this.options)):e;return this.backend.downloadFiles(t)}}class F{id;execute;composite;routePrefixes;constructor(e,t){this.composite=new y(e,t),this.routePrefixes=Object.keys(t).filter(n=>n.startsWith("/"));const r=e;if(typeof r.id=="string"&&typeof r.execute=="function"){this.id=r.id;const n=typeof r.cwd=="string"&&r.virtualMode===!0?r.cwd:null;this.execute=n?i=>this.composite.execute(D(i,n)):i=>this.composite.execute(i)}}normalizeCompositePath(e){if(!s.isAbsolute(e))return e;const t=e.replace(/\/+/g,"/");return this.routePrefixes.some(r=>t===r||t.startsWith(r))?t:s.join(...t.split("/").filter(Boolean))}ls(e){return this.composite.ls(this.normalizeCompositePath(e))}read(e,t,r){return this.composite.read(this.normalizeCompositePath(e),t,r)}readRaw(e){return this.composite.readRaw(this.normalizeCompositePath(e))}grep(e,t,r){return this.composite.grep(e,t?this.normalizeCompositePath(t):void 0,r??void 0)}glob(e,t){return this.composite.glob(e,t&&this.normalizeCompositePath(t))}write(e,t){return this.composite.write(this.normalizeCompositePath(e),t)}edit(e,t,r,n){return this.composite.edit(this.normalizeCompositePath(e),t,r,n)}uploadFiles(e){return this.composite.uploadFiles(e)}downloadFiles(e){const t=Array.isArray(e)?e.map(r=>this.normalizeCompositePath(r)):e;return this.composite.downloadFiles(t)}}function P(o){const{kind:e,...t}=o??{};return t}class j{config;sandboxPromise=null;constructor(e){this.config=e}get id(){return"langsmith-pending"}get isRunning(){return this.sandboxPromise!==null}getSandbox(){return this.sandboxPromise||(this.sandboxPromise=B.create(P(this.config))),this.sandboxPromise}async read(e,t,r){return(await this.getSandbox()).read(e,t,r)}async edit(e,t,r,n){return(await this.getSandbox()).edit(e,t,r,n)}async ls(e){return(await this.getSandbox()).ls(e)}async glob(e,t){return(await this.getSandbox()).glob(e,t)}async write(e,t){return(await this.getSandbox()).write(e,t)}async execute(e){return(await this.getSandbox()).execute(e)}async uploadFiles(e){return(await this.getSandbox()).uploadFiles(e)}async downloadFiles(e){return(await this.getSandbox()).downloadFiles(e)}async close(){this.sandboxPromise&&await(await this.sandboxPromise).close()}}const A='Unsupported DeepAgent backend kind "%s". Supported inline kinds: LocalShellBackend, VfsSandbox, StateBackend, StoreBackend, CompositeBackend, LangSmithSandbox.';function S(o){throw new Error(A.replace("%s",o))}function M(o,e){return typeof e=="string"&&e.trim().length>0?s.isAbsolute(e)?e:s.resolve(o,e):o}function V(o){if(typeof o!="object"||!o)return;const e=Object.entries(o).filter(t=>typeof t[1]=="string");return e.length>0?Object.fromEntries(e):void 0}function g(o,e,t){const r=M(o,e?.rootDir);k(r,{recursive:!0});const n=e?.inheritEnv===!1?{}:process.env;return new b(new v({rootDir:r,virtualMode:t.virtualMode,timeout:typeof e?.timeout=="number"?e.timeout:void 0,maxOutputBytes:typeof e?.maxOutputBytes=="number"?e.maxOutputBytes:void 0,env:E(V(e?.env),n),inheritEnv:e?.inheritEnv!==!1}),r)}function c(o,e,t,r){switch(e){case"LocalShellBackend":return g(o,t,{virtualMode:t?.virtualMode===!0});case"VfsSandbox":return g(o,t,{virtualMode:t?.virtualMode!==!1});case"StateBackend":return new z(r);case"StoreBackend":return new C(r);case"LangSmithSandbox":return new j(t);default:return S(e)}}function _(o){return e=>{const t=R(e);if(!(!t||typeof t!="object"))return r=>{const n=typeof t.kind=="string"?t.kind:"CompositeBackend";switch(n){case"LocalShellBackend":return c(o.workspaceRoot,"LocalShellBackend",t,r);case"VfsSandbox":return c(o.workspaceRoot,"VfsSandbox",t,r);case"StateBackend":return c(o.workspaceRoot,"StateBackend",t,r);case"StoreBackend":return c(o.workspaceRoot,"StoreBackend",t,r);case"LangSmithSandbox":return c(o.workspaceRoot,"LangSmithSandbox",t,r);case"CompositeBackend":{const i=typeof t.state=="object"&&t.state?t.state:{kind:"StateBackend"},d=typeof i.kind=="string"?i.kind:"StateBackend",u=typeof t.routes=="object"&&t.routes?t.routes:{"/memories/":{kind:"StoreBackend"}},h=Object.fromEntries(Object.entries(u).map(([p,l])=>{const m=typeof l?.kind=="string"?l.kind:"StoreBackend";return[p,c(o.workspaceRoot,m,l,r)]}));return new b(new F(c(o.workspaceRoot,d,i,r),h),o.workspaceRoot,{allowVirtualAbsolutePath:!0})}default:return S(n)}}}}export{b as WorkspaceScopedBackend,_ as createInlineBackendResolver,a as normalizeWorkspaceScopedPath};
|
|
@@ -1,237 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
6
|
-
import { cp, mkdir, readFile, realpath, stat, symlink } from "node:fs/promises";
|
|
7
|
-
const HARNESS_PACKAGE_NAME = "@botbotgo/agent-harness";
|
|
8
|
-
const HARNESS_PACKAGE_ROOT = path.resolve(import.meta.dirname, "..", "..");
|
|
9
|
-
const HARNESS_TOOL_AUTHORING_DEPENDENCIES = [
|
|
10
|
-
"@langchain/core",
|
|
11
|
-
"zod",
|
|
12
|
-
];
|
|
13
|
-
const isolatedResourceRootCache = new Map();
|
|
14
|
-
const isolatedResourceRootBuilds = new Map();
|
|
15
|
-
function isolationCacheRoot() {
|
|
16
|
-
return path.join(os.tmpdir(), "agent-harness-resource-isolation");
|
|
17
|
-
}
|
|
18
|
-
function isolationDirPrefix(packageRoot) {
|
|
19
|
-
const digest = createHash("sha256").update(packageRoot).digest("hex").slice(0, 16);
|
|
20
|
-
return path.join(isolationCacheRoot(), `${path.basename(packageRoot)}-${digest}`);
|
|
21
|
-
}
|
|
22
|
-
function createIsolatedSnapshotDir(packageRoot) {
|
|
23
|
-
return `${isolationDirPrefix(packageRoot)}-${Date.now().toString(36)}-${randomUUID()}`;
|
|
24
|
-
}
|
|
25
|
-
function declaredDependencyNames(manifest) {
|
|
26
|
-
return Array.from(new Set([
|
|
27
|
-
...Object.keys(manifest.dependencies ?? {}),
|
|
28
|
-
...Object.keys(manifest.optionalDependencies ?? {}),
|
|
29
|
-
...Object.keys(manifest.peerDependencies ?? {}),
|
|
30
|
-
])).sort();
|
|
31
|
-
}
|
|
32
|
-
function dependencyLinkPath(isolatedRoot, dependencyName) {
|
|
33
|
-
return path.join(isolatedRoot, "node_modules", ...dependencyName.split("/"));
|
|
34
|
-
}
|
|
35
|
-
function resourcePackageManifestPath(packageRoot) {
|
|
36
|
-
return path.join(packageRoot, "package.json");
|
|
37
|
-
}
|
|
38
|
-
function hasResourcePackageManifest(packageRoot) {
|
|
39
|
-
return existsSync(resourcePackageManifestPath(packageRoot));
|
|
40
|
-
}
|
|
41
|
-
function hasInstalledNodeModules(packageRoot) {
|
|
42
|
-
return existsSync(path.join(packageRoot, "node_modules"));
|
|
43
|
-
}
|
|
44
|
-
async function dependencyPackageRoot(packageJsonPath) {
|
|
45
|
-
return realpath(path.dirname(packageJsonPath)).catch(() => path.dirname(packageJsonPath));
|
|
46
|
-
}
|
|
47
|
-
function declaredDependencySpec(manifest, dependencyName) {
|
|
48
|
-
return manifest.dependencies?.[dependencyName]
|
|
49
|
-
?? manifest.optionalDependencies?.[dependencyName]
|
|
50
|
-
?? manifest.peerDependencies?.[dependencyName]
|
|
51
|
-
?? null;
|
|
52
|
-
}
|
|
53
|
-
function resolveDeclaredFileDependency(packageRoot, spec) {
|
|
54
|
-
if (!spec.startsWith("file:")) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
const relativePath = spec.slice("file:".length).trim();
|
|
58
|
-
if (!relativePath) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
const resolvedPath = path.resolve(packageRoot, relativePath);
|
|
62
|
-
const packageJsonPath = resolvedPath.endsWith("package.json")
|
|
63
|
-
? resolvedPath
|
|
64
|
-
: path.join(resolvedPath, "package.json");
|
|
65
|
-
if (!existsSync(packageJsonPath)) {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
return path.dirname(packageJsonPath);
|
|
69
|
-
}
|
|
70
|
-
async function resolveDeclaredDependency(packageRoot, manifest, dependencyName) {
|
|
71
|
-
const localPath = path.join(packageRoot, "node_modules", ...dependencyName.split("/"), "package.json");
|
|
72
|
-
if (existsSync(localPath)) {
|
|
73
|
-
return dependencyPackageRoot(localPath);
|
|
74
|
-
}
|
|
75
|
-
const declaredSpec = declaredDependencySpec(manifest, dependencyName);
|
|
76
|
-
const localFileDependency = declaredSpec ? resolveDeclaredFileDependency(packageRoot, declaredSpec) : null;
|
|
77
|
-
if (localFileDependency) {
|
|
78
|
-
return realpath(localFileDependency).catch(() => localFileDependency);
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const requireFromPackage = createRequire(path.join(packageRoot, "package.json"));
|
|
82
|
-
return dependencyPackageRoot(requireFromPackage.resolve(`${dependencyName}/package.json`));
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
async function linkDeclaredDependencies(isolatedRoot, packageRoot, manifest) {
|
|
89
|
-
for (const dependencyName of declaredDependencyNames(manifest)) {
|
|
90
|
-
const resolved = await resolveDeclaredDependency(packageRoot, manifest, dependencyName);
|
|
91
|
-
if (!resolved) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
const targetPath = dependencyLinkPath(isolatedRoot, dependencyName);
|
|
95
|
-
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
96
|
-
await symlink(resolved, targetPath, "junction");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
async function linkHarnessPackage(isolatedRoot) {
|
|
100
|
-
const targetPath = dependencyLinkPath(isolatedRoot, HARNESS_PACKAGE_NAME);
|
|
101
|
-
if (existsSync(targetPath)) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
105
|
-
await symlink(HARNESS_PACKAGE_ROOT, targetPath, "junction");
|
|
106
|
-
}
|
|
107
|
-
async function resolveHarnessOwnedDependency(dependencyName) {
|
|
108
|
-
try {
|
|
109
|
-
const requireFromHarness = createRequire(path.join(HARNESS_PACKAGE_ROOT, "package.json"));
|
|
110
|
-
return dependencyPackageRoot(requireFromHarness.resolve(`${dependencyName}/package.json`));
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
async function linkHarnessToolAuthoringDependencies(isolatedRoot) {
|
|
117
|
-
for (const dependencyName of HARNESS_TOOL_AUTHORING_DEPENDENCIES) {
|
|
118
|
-
const targetPath = dependencyLinkPath(isolatedRoot, dependencyName);
|
|
119
|
-
if (existsSync(targetPath)) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
const resolved = await resolveHarnessOwnedDependency(dependencyName);
|
|
123
|
-
if (!resolved) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
127
|
-
await symlink(resolved, targetPath, "junction");
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async function buildIsolatedResourceRoot(packageRoot) {
|
|
131
|
-
const packageJsonPath = resourcePackageManifestPath(packageRoot);
|
|
132
|
-
const manifest = existsSync(packageJsonPath)
|
|
133
|
-
? JSON.parse(await readFile(packageJsonPath, "utf8"))
|
|
134
|
-
: {};
|
|
135
|
-
const isolatedRoot = createIsolatedSnapshotDir(packageRoot);
|
|
136
|
-
await mkdir(path.dirname(isolatedRoot), { recursive: true });
|
|
137
|
-
await cp(packageRoot, isolatedRoot, {
|
|
138
|
-
recursive: true,
|
|
139
|
-
force: true,
|
|
140
|
-
filter: (source) => path.basename(source) !== "node_modules",
|
|
141
|
-
});
|
|
142
|
-
if (!existsSync(path.join(isolatedRoot, "package.json"))) {
|
|
143
|
-
await cp(path.join(HARNESS_PACKAGE_ROOT, "resources", "package.json"), path.join(isolatedRoot, "package.json"));
|
|
144
|
-
}
|
|
145
|
-
await mkdir(path.join(isolatedRoot, "node_modules"), { recursive: true });
|
|
146
|
-
await linkDeclaredDependencies(isolatedRoot, packageRoot, manifest);
|
|
147
|
-
await linkHarnessPackage(isolatedRoot);
|
|
148
|
-
await linkHarnessToolAuthoringDependencies(isolatedRoot);
|
|
149
|
-
return isolatedRoot;
|
|
150
|
-
}
|
|
151
|
-
async function readResourcePackageManifest(packageRoot) {
|
|
152
|
-
const packageJsonPath = resourcePackageManifestPath(packageRoot);
|
|
153
|
-
if (!existsSync(packageJsonPath)) {
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
return JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
157
|
-
}
|
|
158
|
-
async function validateInstalledResourcePackage(packageRoot) {
|
|
159
|
-
const manifest = await readResourcePackageManifest(packageRoot);
|
|
160
|
-
if (!manifest) {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
const dependencyNames = declaredDependencyNames(manifest);
|
|
164
|
-
if (dependencyNames.length === 0) {
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
const missingDependencies = [];
|
|
168
|
-
for (const dependencyName of dependencyNames) {
|
|
169
|
-
const resolved = await resolveDeclaredDependency(packageRoot, manifest, dependencyName);
|
|
170
|
-
if (!resolved) {
|
|
171
|
-
missingDependencies.push(dependencyName);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if (missingDependencies.length > 0) {
|
|
175
|
-
const packageLabel = manifest.name ? `${manifest.name} ` : "";
|
|
176
|
-
throw new Error(`Resource package ${packageLabel}at ${packageRoot} is missing installed dependencies: ${missingDependencies.join(", ")}. Run npm install in ${packageRoot}.`);
|
|
177
|
-
}
|
|
178
|
-
return true;
|
|
179
|
-
}
|
|
180
|
-
async function rebuildIsolatedResourcePackageRoot(packageRoot) {
|
|
181
|
-
const existingBuild = isolatedResourceRootBuilds.get(packageRoot);
|
|
182
|
-
if (existingBuild) {
|
|
183
|
-
return existingBuild;
|
|
184
|
-
}
|
|
185
|
-
let loading;
|
|
186
|
-
loading = buildIsolatedResourceRoot(packageRoot)
|
|
187
|
-
.then((isolatedRoot) => {
|
|
188
|
-
isolatedResourceRootCache.set(packageRoot, Promise.resolve(isolatedRoot));
|
|
189
|
-
return isolatedRoot;
|
|
190
|
-
})
|
|
191
|
-
.catch((error) => {
|
|
192
|
-
if (isolatedResourceRootCache.get(packageRoot) === loading) {
|
|
193
|
-
isolatedResourceRootCache.delete(packageRoot);
|
|
194
|
-
}
|
|
195
|
-
throw error;
|
|
196
|
-
})
|
|
197
|
-
.finally(() => {
|
|
198
|
-
isolatedResourceRootBuilds.delete(packageRoot);
|
|
199
|
-
});
|
|
200
|
-
isolatedResourceRootCache.set(packageRoot, loading);
|
|
201
|
-
isolatedResourceRootBuilds.set(packageRoot, loading);
|
|
202
|
-
return loading;
|
|
203
|
-
}
|
|
204
|
-
export async function ensureIsolatedResourcePackageRoot(packageRoot) {
|
|
205
|
-
const cached = isolatedResourceRootCache.get(packageRoot);
|
|
206
|
-
if (cached) {
|
|
207
|
-
return cached;
|
|
208
|
-
}
|
|
209
|
-
return rebuildIsolatedResourcePackageRoot(packageRoot);
|
|
210
|
-
}
|
|
211
|
-
export async function resolveIsolatedResourceModulePath(packageRoot, sourcePath) {
|
|
212
|
-
if (hasResourcePackageManifest(packageRoot) && hasInstalledNodeModules(packageRoot) && await validateInstalledResourcePackage(packageRoot)) {
|
|
213
|
-
return sourcePath;
|
|
214
|
-
}
|
|
215
|
-
const relativeSourcePath = path.relative(packageRoot, sourcePath);
|
|
216
|
-
let isolatedRoot = await ensureIsolatedResourcePackageRoot(packageRoot);
|
|
217
|
-
let isolatedSourcePath = path.join(isolatedRoot, relativeSourcePath);
|
|
218
|
-
if (await isIsolatedModuleSnapshotCurrent(sourcePath, isolatedSourcePath)) {
|
|
219
|
-
return isolatedSourcePath;
|
|
220
|
-
}
|
|
221
|
-
isolatedRoot = await rebuildIsolatedResourcePackageRoot(packageRoot);
|
|
222
|
-
isolatedSourcePath = path.join(isolatedRoot, relativeSourcePath);
|
|
223
|
-
if (await isIsolatedModuleSnapshotCurrent(sourcePath, isolatedSourcePath)) {
|
|
224
|
-
return isolatedSourcePath;
|
|
225
|
-
}
|
|
226
|
-
throw new Error(`Isolated resource module ${relativeSourcePath} is missing from ${isolatedRoot}. Rebuild completed but the source package snapshot is still incomplete.`);
|
|
227
|
-
}
|
|
228
|
-
async function isIsolatedModuleSnapshotCurrent(sourcePath, isolatedSourcePath) {
|
|
229
|
-
if (!existsSync(isolatedSourcePath)) {
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
const [sourceStat, isolatedStat] = await Promise.all([
|
|
233
|
-
stat(sourcePath),
|
|
234
|
-
stat(isolatedSourcePath),
|
|
235
|
-
]);
|
|
236
|
-
return isolatedStat.size === sourceStat.size && isolatedStat.mtimeMs >= sourceStat.mtimeMs;
|
|
237
|
-
}
|
|
1
|
+
import{createRequire as w}from"node:module";import k from"node:os";import i from"node:path";import{createHash as E,randomUUID as I}from"node:crypto";import{existsSync as o}from"node:fs";import{cp as j,mkdir as c,readFile as y,realpath as g,stat as v,symlink as l}from"node:fs/promises";const _="@botbotgo/agent-harness",d=i.resolve(import.meta.dirname,"..",".."),A=["@langchain/core","zod"],u=new Map,f=new Map;function M(){return i.join(k.tmpdir(),"agent-harness-resource-isolation")}function N(e){const n=E("sha256").update(e).digest("hex").slice(0,16);return i.join(M(),`${i.basename(e)}-${n}`)}function O(e){return`${N(e)}-${Date.now().toString(36)}-${I()}`}function P(e){return Array.from(new Set([...Object.keys(e.dependencies??{}),...Object.keys(e.optionalDependencies??{}),...Object.keys(e.peerDependencies??{})])).sort()}function m(e,n){return i.join(e,"node_modules",...n.split("/"))}function p(e){return i.join(e,"package.json")}function H(e){return o(p(e))}function x(e){return o(i.join(e,"node_modules"))}async function h(e){return g(i.dirname(e)).catch(()=>i.dirname(e))}function C(e,n){return e.dependencies?.[n]??e.optionalDependencies?.[n]??e.peerDependencies?.[n]??null}function F(e,n){if(!n.startsWith("file:"))return null;const r=n.slice(5).trim();if(!r)return null;const t=i.resolve(e,r),s=t.endsWith("package.json")?t:i.join(t,"package.json");return o(s)?i.dirname(s):null}async function D(e,n,r){const t=i.join(e,"node_modules",...r.split("/"),"package.json");if(o(t))return h(t);const s=C(n,r),a=s?F(e,s):null;if(a)return g(a).catch(()=>a);try{const b=w(i.join(e,"package.json"));return h(b.resolve(`${r}/package.json`))}catch{return null}}async function J(e,n,r){for(const t of P(r)){const s=await D(n,r,t);if(!s)continue;const a=m(e,t);await c(i.dirname(a),{recursive:!0}),await l(s,a,"junction")}}async function R(e){const n=m(e,_);o(n)||(await c(i.dirname(n),{recursive:!0}),await l(d,n,"junction"))}async function T(e){try{const n=w(i.join(d,"package.json"));return h(n.resolve(`${e}/package.json`))}catch{return null}}async function q(e){for(const n of A){const r=m(e,n);if(o(r))continue;const t=await T(n);t&&(await c(i.dirname(r),{recursive:!0}),await l(t,r,"junction"))}}async function z(e){const n=p(e),r=o(n)?JSON.parse(await y(n,"utf8")):{},t=O(e);return await c(i.dirname(t),{recursive:!0}),await j(e,t,{recursive:!0,force:!0,filter:s=>i.basename(s)!=="node_modules"}),o(i.join(t,"package.json"))||await j(i.join(d,"resources","package.json"),i.join(t,"package.json")),await c(i.join(t,"node_modules"),{recursive:!0}),await J(t,e,r),await R(t),await q(t),t}async function G(e){const n=p(e);return o(n)?JSON.parse(await y(n,"utf8")):null}async function L(e){const n=await G(e);if(!n)return!1;const r=P(n);if(r.length===0)return!0;const t=[];for(const s of r)await D(e,n,s)||t.push(s);if(t.length>0){const s=n.name?`${n.name} `:"";throw new Error(`Resource package ${s}at ${e} is missing installed dependencies: ${t.join(", ")}. Run npm install in ${e}.`)}return!0}async function S(e){const n=f.get(e);if(n)return n;let r;return r=z(e).then(t=>(u.set(e,Promise.resolve(t)),t)).catch(t=>{throw u.get(e)===r&&u.delete(e),t}).finally(()=>{f.delete(e)}),u.set(e,r),f.set(e,r),r}async function U(e){const n=u.get(e);return n||S(e)}async function Y(e,n){if(H(e)&&x(e)&&await L(e))return n;const r=i.relative(e,n);let t=await U(e),s=i.join(t,r);if(await $(n,s)||(t=await S(e),s=i.join(t,r),await $(n,s)))return s;throw new Error(`Isolated resource module ${r} is missing from ${t}. Rebuild completed but the source package snapshot is still incomplete.`)}async function $(e,n){if(!o(n))return!1;const[r,t]=await Promise.all([v(e),v(n)]);return t.size===r.size&&t.mtimeMs>=r.mtimeMs}export{U as ensureIsolatedResourcePackageRoot,Y as resolveIsolatedResourceModulePath};
|