@yansirplus/cli 0.5.17
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/PUBLIC_API.md +22 -0
- package/README.md +34 -0
- package/dist/build/agent-authoring/config.d.ts +177 -0
- package/dist/build/agent-authoring/config.js +607 -0
- package/dist/build/agent-authoring/manifest-compiler.d.ts +159 -0
- package/dist/build/agent-authoring/manifest-compiler.js +737 -0
- package/dist/build/agent-authoring/shared.d.ts +10 -0
- package/dist/build/agent-authoring/shared.js +57 -0
- package/dist/build/agent-authoring/static-target.d.ts +59 -0
- package/dist/build/agent-authoring/static-target.js +1857 -0
- package/dist/build/agent-authoring.d.ts +9 -0
- package/dist/build/agent-authoring.js +5 -0
- package/dist/build/build-cli.d.ts +2 -0
- package/dist/build/build-cli.js +264 -0
- package/dist/check/algorithmic/architecture-checks.mjs +971 -0
- package/dist/check/algorithmic/client-boundary-checks.mjs +337 -0
- package/dist/check/algorithmic/convergence-smoke-checks.mjs +608 -0
- package/dist/check/algorithmic/distribution-checks.mjs +919 -0
- package/dist/check/algorithmic/owner-checks.mjs +647 -0
- package/dist/check/algorithmic/package-boundary-checks.mjs +985 -0
- package/dist/check/algorithmic/projection-boundary-checks.mjs +302 -0
- package/dist/check/algorithmic/repo-surface-checks.mjs +267 -0
- package/dist/check/algorithmic/runtime-structural-checks.mjs +264 -0
- package/dist/check/algorithmic/source-alias-checks.mjs +106 -0
- package/dist/check/algorithmic/static-target-checks.mjs +447 -0
- package/dist/check/algorithmic-checks.mjs +482 -0
- package/dist/check/check-coverage.mjs +231 -0
- package/dist/check/command-runner.mjs +22 -0
- package/dist/check/default-gate.mjs +51 -0
- package/dist/check/gate-selector.mjs +305 -0
- package/dist/check/manifest-rules.mjs +223 -0
- package/dist/check/package-graph.mjs +464 -0
- package/dist/generate/generate-agent-docs.mjs +435 -0
- package/dist/generate/generate-carrier-reference.mjs +514 -0
- package/dist/generate/generate-docs.mjs +345 -0
- package/dist/generate/generate-effect-skill-manifests.mjs +193 -0
- package/dist/generate/project-docs-site.mjs +190 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +25 -0
- package/dist/lib/agent-docs-model.mjs +888 -0
- package/dist/lib/boundary-rules.mjs +63 -0
- package/dist/lib/capability-routes.mjs +354 -0
- package/dist/lib/projection-sink.mjs +113 -0
- package/dist/lib/public-api-model.mjs +306 -0
- package/dist/main.mjs +233 -0
- package/dist/runner.mjs +127 -0
- package/package.json +32 -0
|
@@ -0,0 +1,1857 @@
|
|
|
1
|
+
import { WORKSPACE_TOOL_EXPOSURE_PROFILES } from "@yansirplus/runtime";
|
|
2
|
+
import { digestText, isWorkspaceToolName } from "./shared.js";
|
|
3
|
+
import { AGENTOS_CONFIG_CLIENT, AGENTOS_CONFIG_LLM_ROUTE, AGENTOS_CONFIG_PROFILE, AGENTOS_CONFIG_TARGET, llmMaterialEnvBindings, } from "./config.js";
|
|
4
|
+
const generatedPath = (path, text) => ({
|
|
5
|
+
path,
|
|
6
|
+
text,
|
|
7
|
+
});
|
|
8
|
+
const stableJsonValue = (value) => {
|
|
9
|
+
if (value === null || typeof value !== "object")
|
|
10
|
+
return value;
|
|
11
|
+
if (Array.isArray(value))
|
|
12
|
+
return value.map(stableJsonValue);
|
|
13
|
+
const record = value;
|
|
14
|
+
const sorted = {};
|
|
15
|
+
for (const key of Object.keys(record).sort())
|
|
16
|
+
sorted[key] = stableJsonValue(record[key]);
|
|
17
|
+
return sorted;
|
|
18
|
+
};
|
|
19
|
+
const stableJson = (value) => `${JSON.stringify(stableJsonValue(value), null, 2)}\n`;
|
|
20
|
+
const jsString = (value) => JSON.stringify(value);
|
|
21
|
+
const importToolPath = (toolName) => `../../agent/tools/${toolName}`;
|
|
22
|
+
const workspaceMutationToolNames = new Set(WORKSPACE_TOOL_EXPOSURE_PROFILES.mutation);
|
|
23
|
+
const workspaceShellToolNames = new Set(WORKSPACE_TOOL_EXPOSURE_PROFILES.shell);
|
|
24
|
+
const SOURCE_PACKAGE_SCOPE = "@agent-os";
|
|
25
|
+
const INJECTED_PUBLIC_PACKAGE_SCOPE = "@yansirplus";
|
|
26
|
+
const packageScopePattern = /^@[a-z0-9][a-z0-9._-]*$/u;
|
|
27
|
+
const DEFAULT_STATIC_TARGET_PACKAGE_SCOPE = packageScopePattern.test(INJECTED_PUBLIC_PACKAGE_SCOPE)
|
|
28
|
+
? INJECTED_PUBLIC_PACKAGE_SCOPE
|
|
29
|
+
: SOURCE_PACKAGE_SCOPE;
|
|
30
|
+
const publicPackageSpecifier = (scope, name) => `${scope}/${name}`;
|
|
31
|
+
const staticTargetModules = (scope) => ({
|
|
32
|
+
cloudflareDoRuntime: publicPackageSpecifier(scope, "runtime/cloudflare"),
|
|
33
|
+
openAiCompatibleTransport: publicPackageSpecifier(scope, "runtime/llm-effect-ai"),
|
|
34
|
+
workspaceAgentHost: publicPackageSpecifier(scope, "runtime/workspace-agent"),
|
|
35
|
+
workspaceAgentClient: publicPackageSpecifier(scope, "client/workspace-agent"),
|
|
36
|
+
workspaceBinding: publicPackageSpecifier(scope, "runtime/workspace-binding"),
|
|
37
|
+
workspaceEnvCloudflare: publicPackageSpecifier(scope, "runtime/cloudflare"),
|
|
38
|
+
clientCore: publicPackageSpecifier(scope, "client"),
|
|
39
|
+
clientSvelte: publicPackageSpecifier(scope, "client/svelte"),
|
|
40
|
+
runtimeProtocol: publicPackageSpecifier(scope, "core/runtime-protocol"),
|
|
41
|
+
coreTools: publicPackageSpecifier(scope, "core/tools"),
|
|
42
|
+
sseHttp: publicPackageSpecifier(scope, "runtime/sse-http"),
|
|
43
|
+
cloudflareSandbox: "@cloudflare/sandbox",
|
|
44
|
+
svelteKitServer: "$app/server",
|
|
45
|
+
svelteKitKit: "@sveltejs/kit",
|
|
46
|
+
effect: "effect",
|
|
47
|
+
svelteStore: "svelte/store",
|
|
48
|
+
});
|
|
49
|
+
const renderNamedImport = (names, source) => `import { ${names.join(", ")} } ${"from"} ${jsString(source)};`;
|
|
50
|
+
const renderTypeImport = (names, source) => `import type { ${names.join(", ")} } ${"from"} ${jsString(source)};`;
|
|
51
|
+
const generatedToolImports = (toolNames) => toolNames.map((toolName, index) => ({
|
|
52
|
+
kind: "authored-tool",
|
|
53
|
+
source: importToolPath(toolName),
|
|
54
|
+
imports: [`default as tool_${index}`],
|
|
55
|
+
}));
|
|
56
|
+
const renderWorkspaceStaticTarget = (normalized, toolNames, modules) => {
|
|
57
|
+
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
58
|
+
const workspaceToolList = toolNames.filter((toolName) => isWorkspaceToolName(toolName) && !authoredToolNames.has(toolName));
|
|
59
|
+
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
60
|
+
const toolImports = customToolNames
|
|
61
|
+
.map((toolName, index) => `import tool_${index} from ${jsString(importToolPath(toolName))};`)
|
|
62
|
+
.join("\n");
|
|
63
|
+
const customToolRecord = customToolNames.length === 0
|
|
64
|
+
? "{}"
|
|
65
|
+
: `{\n${customToolNames
|
|
66
|
+
.map((toolName, index) => ` ${jsString(toolName)}: tool_${index},`)
|
|
67
|
+
.join("\n")}\n}`;
|
|
68
|
+
const workspaceToolArray = `[${workspaceToolList.map(jsString).join(", ")}] as const`;
|
|
69
|
+
const usesMutationTools = workspaceToolList.some((toolName) => workspaceMutationToolNames.has(toolName));
|
|
70
|
+
const usesShellTools = workspaceToolList.some((toolName) => workspaceShellToolNames.has(toolName));
|
|
71
|
+
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
72
|
+
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
73
|
+
.join("\n")}\n}`;
|
|
74
|
+
const llmEnvByKind = Object.fromEntries(llmMaterialEnvBindings(normalized.llm).map((binding) => [binding.kind, binding.envName]));
|
|
75
|
+
const generatedLlmEnvFields = Object.values(llmEnvByKind)
|
|
76
|
+
.map((envName) => ` readonly ${envName}?: string;`)
|
|
77
|
+
.join("\n");
|
|
78
|
+
const imports = [
|
|
79
|
+
`import semanticDeclarations from "./manifest.json";`,
|
|
80
|
+
`import deploymentProvenance from "./deployment.json";`,
|
|
81
|
+
renderNamedImport(["createAgentDurableObject", "installCloudflareWorkspaceOperationProvider"], modules.cloudflareDoRuntime),
|
|
82
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive"], modules.openAiCompatibleTransport),
|
|
83
|
+
renderNamedImport(["defineWorkspaceAgentMount", "WORKSPACE_AGENT_PROJECTION"], modules.workspaceAgentHost),
|
|
84
|
+
renderNamedImport(["bindWorkspaceToolsForRuntime"], modules.workspaceBinding),
|
|
85
|
+
renderNamedImport(["makeCloudflareWorkspaceEnv"], modules.workspaceEnvCloudflare),
|
|
86
|
+
renderNamedImport(["getSandbox"], modules.cloudflareSandbox),
|
|
87
|
+
renderNamedImport(["deterministicToolInvocation", "unsafeRunToolByName"], modules.coreTools),
|
|
88
|
+
renderNamedImport(["Effect"], modules.effect),
|
|
89
|
+
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
90
|
+
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
91
|
+
renderTypeImport([
|
|
92
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
93
|
+
"WorkspaceAgentCustomCommandInput",
|
|
94
|
+
"WorkspaceAgentFileEntry",
|
|
95
|
+
"WorkspaceAgentMutationCommandOutput",
|
|
96
|
+
"WorkspaceAgentReadStateCommandInput",
|
|
97
|
+
"WorkspaceAgentReadStateCommandOutput",
|
|
98
|
+
"WorkspaceAgentReadFileCommandInput",
|
|
99
|
+
"WorkspaceAgentReadFileCommandOutput",
|
|
100
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
101
|
+
], modules.workspaceAgentHost),
|
|
102
|
+
renderTypeImport(["Tool"], modules.coreTools),
|
|
103
|
+
renderTypeImport(["Sandbox", "SandboxTransport"], modules.cloudflareSandbox),
|
|
104
|
+
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
105
|
+
].join("\n");
|
|
106
|
+
return `${imports}
|
|
107
|
+
|
|
108
|
+
export const targetDeclarations = semanticDeclarations;
|
|
109
|
+
export const targetDeployment = deploymentProvenance;
|
|
110
|
+
|
|
111
|
+
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
112
|
+
const generatedHandler = () => undefined;
|
|
113
|
+
|
|
114
|
+
type AgentOSTargetEnv = {
|
|
115
|
+
readonly [binding: string]: unknown;
|
|
116
|
+
readonly SANDBOX_TRANSPORT?: SandboxTransport;
|
|
117
|
+
${generatedLlmEnvFields}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type GeneratedTargetFailure = {
|
|
121
|
+
readonly ok: false;
|
|
122
|
+
readonly message: string;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
type GeneratedTargetResult<Value> =
|
|
126
|
+
| { readonly ok: true; readonly value: Value }
|
|
127
|
+
| GeneratedTargetFailure;
|
|
128
|
+
|
|
129
|
+
const targetFailure = (message: string): GeneratedTargetFailure => ({ ok: false, message });
|
|
130
|
+
|
|
131
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
132
|
+
Promise.reject(Error(failure.message));
|
|
133
|
+
|
|
134
|
+
const generatedWorkspaceToolNames = ${workspaceToolArray};
|
|
135
|
+
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
136
|
+
const generatedWorkspaceSandboxId = ${jsString(normalized.workspace.cloudflareSandboxId)};
|
|
137
|
+
|
|
138
|
+
const generatedWorkspaceToolInteractionFor = (
|
|
139
|
+
name: (typeof generatedWorkspaceToolNames)[number],
|
|
140
|
+
): "never" | "approval" => {
|
|
141
|
+
const interaction = semanticManifest.tools?.[name]?.interaction;
|
|
142
|
+
if (interaction === "never" || interaction === "approval") return interaction;
|
|
143
|
+
throw Error(\`invalid workspace tool interaction for \${name}: \${String(interaction)}\`);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const generatedWorkspaceToolInteractions = Object.fromEntries(
|
|
147
|
+
generatedWorkspaceToolNames.map((name) => [name, generatedWorkspaceToolInteractionFor(name)]),
|
|
148
|
+
) as Readonly<Partial<Record<(typeof generatedWorkspaceToolNames)[number], "never" | "approval">>>;
|
|
149
|
+
|
|
150
|
+
const workspaceNamespaceFor = (env: AgentOSTargetEnv): DurableObjectNamespace<Sandbox> =>
|
|
151
|
+
env[${jsString(normalized.workspace.binding)}] as DurableObjectNamespace<Sandbox>;
|
|
152
|
+
|
|
153
|
+
const workspaceSandboxFor = (env: AgentOSTargetEnv): Sandbox =>
|
|
154
|
+
getSandbox(workspaceNamespaceFor(env), generatedWorkspaceSandboxId, {
|
|
155
|
+
normalizeId: true,
|
|
156
|
+
sleepAfter: "10m",
|
|
157
|
+
transport: env.SANDBOX_TRANSPORT ?? "rpc",
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
type WorkspacePathResult =
|
|
161
|
+
| { readonly ok: true; readonly path: string }
|
|
162
|
+
| { readonly ok: false; readonly message: string };
|
|
163
|
+
|
|
164
|
+
const workspacePathFor = (path: string): WorkspacePathResult => {
|
|
165
|
+
const parts = path
|
|
166
|
+
.split("/")
|
|
167
|
+
.map((part) => part.trim())
|
|
168
|
+
.filter((part) => part.length > 0);
|
|
169
|
+
if (parts.some((part) => part === "." || part === "..")) {
|
|
170
|
+
return { ok: false, message: "path escapes workspace" };
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
ok: true,
|
|
174
|
+
path: parts.length === 0 ? ${jsString(normalized.workspace.root)} : ${jsString(`${normalized.workspace.root}/`)} + parts.join("/"),
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const relativeWorkspacePath = (path: string): string =>
|
|
179
|
+
path.startsWith(${jsString(`${normalized.workspace.root}/`)})
|
|
180
|
+
? path.slice(${normalized.workspace.root.length + 1})
|
|
181
|
+
: path;
|
|
182
|
+
|
|
183
|
+
type WorkspaceListFile = {
|
|
184
|
+
readonly type?: string;
|
|
185
|
+
readonly relativePath?: string;
|
|
186
|
+
readonly absolutePath?: string;
|
|
187
|
+
readonly size?: number;
|
|
188
|
+
readonly mtimeMs?: number;
|
|
189
|
+
readonly sha256?: string;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const workspaceFileKind = (type: string | undefined): WorkspaceAgentFileEntry["kind"] =>
|
|
193
|
+
type === "file" || type === "directory" ? type : "other";
|
|
194
|
+
|
|
195
|
+
const workspaceFileEntryFor = (value: unknown): WorkspaceAgentFileEntry | null => {
|
|
196
|
+
if (typeof value === "string") {
|
|
197
|
+
return { path: relativeWorkspacePath(value), kind: "file" };
|
|
198
|
+
}
|
|
199
|
+
if (value === null || typeof value !== "object") return null;
|
|
200
|
+
const file = value as WorkspaceListFile;
|
|
201
|
+
const path =
|
|
202
|
+
typeof file.relativePath === "string" && file.relativePath.length > 0
|
|
203
|
+
? file.relativePath
|
|
204
|
+
: typeof file.absolutePath === "string" && file.absolutePath.length > 0
|
|
205
|
+
? relativeWorkspacePath(file.absolutePath)
|
|
206
|
+
: "";
|
|
207
|
+
if (path.length === 0) return null;
|
|
208
|
+
return {
|
|
209
|
+
path,
|
|
210
|
+
kind: workspaceFileKind(file.type),
|
|
211
|
+
...(typeof file.size === "number" ? { size: file.size } : {}),
|
|
212
|
+
...(typeof file.mtimeMs === "number" ? { mtimeMs: file.mtimeMs } : {}),
|
|
213
|
+
...(typeof file.sha256 === "string" ? { sha256: file.sha256 } : {}),
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const workspaceEnvFor = (env: AgentOSTargetEnv) =>
|
|
218
|
+
makeCloudflareWorkspaceEnv({
|
|
219
|
+
client: workspaceSandboxFor(env),
|
|
220
|
+
cwd: ${jsString(normalized.workspace.root)},
|
|
221
|
+
workspaceRef: ${jsString(normalized.workspace.providerResourceId)},
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const allowWorkspaceTool = () =>
|
|
225
|
+
Effect.succeed({ ok: true as const }).pipe(
|
|
226
|
+
Effect.withSpan("agentos.generated.workspace.allow_tool"),
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const workspaceOperationInstallFor = (env: AgentOSTargetEnv) =>
|
|
230
|
+
installCloudflareWorkspaceOperationProvider({
|
|
231
|
+
env: workspaceEnvFor(env),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
235
|
+
const value = env[name];
|
|
236
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const materialValue = (
|
|
240
|
+
env: AgentOSTargetEnv,
|
|
241
|
+
ref: { readonly kind: string; readonly ref: string },
|
|
242
|
+
): NonNullable<unknown> | null => {
|
|
243
|
+
if (ref.kind === "endpoint" && ref.ref === ${jsString(normalized.llm.endpointRef)}) {
|
|
244
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.endpoint)});
|
|
245
|
+
}
|
|
246
|
+
if (ref.kind === "credential" && ref.ref === ${jsString(normalized.llm.credentialRef)}) {
|
|
247
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.credential)});
|
|
248
|
+
}
|
|
249
|
+
if (ref.kind === "model" && ref.ref === ${jsString(normalized.llm.modelRef)}) {
|
|
250
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.model)});
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const requiredStringMaterial = (
|
|
256
|
+
kind: string,
|
|
257
|
+
ref: string,
|
|
258
|
+
value: NonNullable<unknown> | null,
|
|
259
|
+
): GeneratedTargetResult<string> => {
|
|
260
|
+
if (typeof value === "string" && value.length > 0) return { ok: true, value };
|
|
261
|
+
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const generatedLlmRouteFor = (env: AgentOSTargetEnv): GeneratedTargetResult<NonNullable<AgentSubmitBindings["llmRoutes"]>["default"]> => {
|
|
265
|
+
const modelId = requiredStringMaterial(
|
|
266
|
+
"model",
|
|
267
|
+
${jsString(normalized.llm.modelRef)},
|
|
268
|
+
materialValue(env, { kind: "model", ref: ${jsString(normalized.llm.modelRef)} }),
|
|
269
|
+
);
|
|
270
|
+
if (!modelId.ok) return modelId;
|
|
271
|
+
return {
|
|
272
|
+
ok: true,
|
|
273
|
+
value: {
|
|
274
|
+
kind: "openai-chat-compatible",
|
|
275
|
+
endpointRef: ${jsString(normalized.llm.endpointRef)},
|
|
276
|
+
credentialRef: ${jsString(normalized.llm.credentialRef)},
|
|
277
|
+
modelId: modelId.value,
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
const generatedWorkspaceBindingsFor = (env: AgentOSTargetEnv): AgentSubmitBindings =>
|
|
283
|
+
generatedWorkspaceToolNames.length === 0
|
|
284
|
+
? {}
|
|
285
|
+
: bindWorkspaceToolsForRuntime({
|
|
286
|
+
env: workspaceEnvFor(env),
|
|
287
|
+
authority: "agentos.workspace.static-target",
|
|
288
|
+
admit: allowWorkspaceTool,
|
|
289
|
+
toolNames: generatedWorkspaceToolNames,
|
|
290
|
+
mutationPolicy: ${usesMutationTools ? '"receipt-backed"' : '"disabled"'},
|
|
291
|
+
shellPolicy: ${usesShellTools ? '"receipt-backed"' : '"disabled"'},
|
|
292
|
+
toolInteractions: generatedWorkspaceToolInteractions,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const generatedSubmitBindingsFor = (env: AgentOSTargetEnv): GeneratedTargetResult<AgentSubmitBindings> => {
|
|
296
|
+
const workspaceBindings = generatedWorkspaceBindingsFor(env);
|
|
297
|
+
const route = generatedLlmRouteFor(env);
|
|
298
|
+
if (!route.ok) return route;
|
|
299
|
+
return {
|
|
300
|
+
ok: true,
|
|
301
|
+
value: {
|
|
302
|
+
...workspaceBindings,
|
|
303
|
+
llmRoutes: {
|
|
304
|
+
default: route.value,
|
|
305
|
+
},
|
|
306
|
+
tools: {
|
|
307
|
+
...(workspaceBindings.tools ?? {}),
|
|
308
|
+
...generatedCustomTools,
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const submitSpecFromRunInput = (input: SubmitRunInput): AgentSubmitSpec => ({
|
|
315
|
+
input,
|
|
316
|
+
intent: input.intent,
|
|
317
|
+
context: input.context,
|
|
318
|
+
...(input.system === undefined ? {} : { system: input.system }),
|
|
319
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
320
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
321
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
322
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
323
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
324
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
325
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
326
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
export const workspaceMount = defineWorkspaceAgentMount({
|
|
330
|
+
driver: { kind: "driver_mount", client: undefined as never },
|
|
331
|
+
projectionSinks: [
|
|
332
|
+
{ kind: "projection_sink", name: WORKSPACE_AGENT_PROJECTION.AGENT_INFO },
|
|
333
|
+
{ kind: "projection_sink", name: WORKSPACE_AGENT_PROJECTION.STATE },
|
|
334
|
+
{ kind: "projection_sink", name: WORKSPACE_AGENT_PROJECTION.FILES },
|
|
335
|
+
{ kind: "projection_sink", name: WORKSPACE_AGENT_PROJECTION.RUN_EVENTS },
|
|
336
|
+
{ kind: "projection_sink", name: WORKSPACE_AGENT_PROJECTION.INPUT_REQUESTS },
|
|
337
|
+
],
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
const Base${normalized.target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
341
|
+
manifest: semanticManifest,
|
|
342
|
+
agentBindings: {
|
|
343
|
+
handlers: ${handlerRecord},
|
|
344
|
+
},
|
|
345
|
+
refResolver: (env) => ({
|
|
346
|
+
material: (ref) => materialValue(env, ref),
|
|
347
|
+
}),
|
|
348
|
+
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
349
|
+
extensions: (env) => workspaceOperationInstallFor(env).extensions,
|
|
350
|
+
declaredIntents: (env) => workspaceOperationInstallFor(env).declaredIntents,
|
|
351
|
+
projections: (env) => workspaceOperationInstallFor(env).projections,
|
|
352
|
+
eventHandlers: (context, env) => workspaceOperationInstallFor(env).eventHandlers(context),
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
export class ${normalized.target.durableObject.className} extends Base${normalized.target.durableObject.className} {
|
|
356
|
+
private readonly targetEnv: AgentOSTargetEnv;
|
|
357
|
+
|
|
358
|
+
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
359
|
+
super(ctx, env);
|
|
360
|
+
this.targetEnv = env;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
364
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
365
|
+
return bindings.ok
|
|
366
|
+
? this.submitWithBindings(spec, bindings.value)
|
|
367
|
+
: rejectTargetFailure(bindings);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
371
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
372
|
+
return bindings.ok
|
|
373
|
+
? this.submitWithBindings(submitSpecFromRunInput(input), bindings.value)
|
|
374
|
+
: rejectTargetFailure(bindings);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
378
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
379
|
+
return bindings.ok
|
|
380
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
381
|
+
: rejectTargetFailure(bindings);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
385
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
386
|
+
return bindings.ok
|
|
387
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
388
|
+
: rejectTargetFailure(bindings);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
392
|
+
return Effect.runPromise(
|
|
393
|
+
unsafeRunToolByName(
|
|
394
|
+
generatedCustomTools,
|
|
395
|
+
deterministicToolInvocation(input.method, input.input),
|
|
396
|
+
),
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
readWorkspaceState(
|
|
401
|
+
input: WorkspaceAgentReadStateCommandInput = {},
|
|
402
|
+
): Promise<WorkspaceAgentReadStateCommandOutput> {
|
|
403
|
+
const sandbox = workspaceSandboxFor(this.targetEnv);
|
|
404
|
+
return sandbox
|
|
405
|
+
.mkdir(${jsString(normalized.workspace.root)}, { recursive: true })
|
|
406
|
+
.then(() =>
|
|
407
|
+
sandbox.listFiles(${jsString(normalized.workspace.root)}, {
|
|
408
|
+
recursive: true,
|
|
409
|
+
includeHidden: input.includeHidden ?? true,
|
|
410
|
+
}),
|
|
411
|
+
)
|
|
412
|
+
.then((listed) => ({
|
|
413
|
+
workspaceRef: ${jsString(normalized.workspace.providerResourceId)},
|
|
414
|
+
files: listed.files
|
|
415
|
+
.map(workspaceFileEntryFor)
|
|
416
|
+
.filter((file): file is WorkspaceAgentFileEntry => file !== null)
|
|
417
|
+
.sort((left, right) => left.path.localeCompare(right.path)),
|
|
418
|
+
}));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
readWorkspaceFile(
|
|
422
|
+
input: WorkspaceAgentReadFileCommandInput,
|
|
423
|
+
): Promise<WorkspaceAgentReadFileCommandOutput> {
|
|
424
|
+
const path = workspacePathFor(input.path);
|
|
425
|
+
if (!path.ok) return Promise.reject(new TypeError(path.message));
|
|
426
|
+
return workspaceSandboxFor(this.targetEnv)
|
|
427
|
+
.readFile(path.path, {
|
|
428
|
+
encoding: input.encoding ?? "utf-8",
|
|
429
|
+
})
|
|
430
|
+
.then((file) => ({
|
|
431
|
+
path: relativeWorkspacePath(path.path),
|
|
432
|
+
content: file.content,
|
|
433
|
+
}));
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
resetWorkspace(): Promise<WorkspaceAgentMutationCommandOutput> {
|
|
437
|
+
return workspaceSandboxFor(this.targetEnv)
|
|
438
|
+
.destroy()
|
|
439
|
+
.then(() =>
|
|
440
|
+
workspaceSandboxFor(this.targetEnv).mkdir(${jsString(normalized.workspace.root)}, {
|
|
441
|
+
recursive: true,
|
|
442
|
+
}),
|
|
443
|
+
)
|
|
444
|
+
.then(() => ({ ok: true as const }));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
destroyWorkspace(): Promise<WorkspaceAgentMutationCommandOutput> {
|
|
448
|
+
return workspaceSandboxFor(this.targetEnv)
|
|
449
|
+
.destroy()
|
|
450
|
+
.then(() => ({ ok: true as const }));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
`;
|
|
454
|
+
};
|
|
455
|
+
const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
456
|
+
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
457
|
+
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
458
|
+
const toolImports = customToolNames
|
|
459
|
+
.map((toolName, index) => `import tool_${index} from ${jsString(importToolPath(toolName))};`)
|
|
460
|
+
.join("\n");
|
|
461
|
+
const customToolRecord = customToolNames.length === 0
|
|
462
|
+
? "{}"
|
|
463
|
+
: `{\n${customToolNames
|
|
464
|
+
.map((toolName, index) => ` ${jsString(toolName)}: tool_${index},`)
|
|
465
|
+
.join("\n")}\n}`;
|
|
466
|
+
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
467
|
+
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
468
|
+
.join("\n")}\n}`;
|
|
469
|
+
const llmEnvByKind = Object.fromEntries(llmMaterialEnvBindings(normalized.llm).map((binding) => [binding.kind, binding.envName]));
|
|
470
|
+
const generatedLlmEnvFields = Object.values(llmEnvByKind)
|
|
471
|
+
.map((envName) => ` readonly ${envName}?: string;`)
|
|
472
|
+
.join("\n");
|
|
473
|
+
const imports = [
|
|
474
|
+
`import semanticDeclarations from "./manifest.json";`,
|
|
475
|
+
`import deploymentProvenance from "./deployment.json";`,
|
|
476
|
+
renderNamedImport(["createAgentDurableObject"], modules.cloudflareDoRuntime),
|
|
477
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive"], modules.openAiCompatibleTransport),
|
|
478
|
+
renderNamedImport(["deterministicToolInvocation", "unsafeRunToolByName"], modules.coreTools),
|
|
479
|
+
renderNamedImport(["Effect"], modules.effect),
|
|
480
|
+
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
481
|
+
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
482
|
+
renderTypeImport([
|
|
483
|
+
"WorkspaceAgentCustomCommandInput",
|
|
484
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
485
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
486
|
+
], modules.workspaceAgentHost),
|
|
487
|
+
renderTypeImport(["Tool"], modules.coreTools),
|
|
488
|
+
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
489
|
+
].join("\n");
|
|
490
|
+
return `${imports}
|
|
491
|
+
|
|
492
|
+
export const targetDeclarations = semanticDeclarations;
|
|
493
|
+
export const targetDeployment = deploymentProvenance;
|
|
494
|
+
|
|
495
|
+
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
496
|
+
const generatedHandler = () => undefined;
|
|
497
|
+
|
|
498
|
+
type AgentOSTargetEnv = {
|
|
499
|
+
readonly [binding: string]: unknown;
|
|
500
|
+
${generatedLlmEnvFields}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
type GeneratedTargetFailure = {
|
|
504
|
+
readonly ok: false;
|
|
505
|
+
readonly message: string;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
type GeneratedTargetResult<Value> =
|
|
509
|
+
| { readonly ok: true; readonly value: Value }
|
|
510
|
+
| GeneratedTargetFailure;
|
|
511
|
+
|
|
512
|
+
const targetFailure = (message: string): GeneratedTargetFailure => ({ ok: false, message });
|
|
513
|
+
|
|
514
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
515
|
+
Promise.reject(Error(failure.message));
|
|
516
|
+
|
|
517
|
+
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
518
|
+
|
|
519
|
+
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
520
|
+
const value = env[name];
|
|
521
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
const materialValue = (
|
|
525
|
+
env: AgentOSTargetEnv,
|
|
526
|
+
ref: { readonly kind: string; readonly ref: string },
|
|
527
|
+
): NonNullable<unknown> | null => {
|
|
528
|
+
if (ref.kind === "endpoint" && ref.ref === ${jsString(normalized.llm.endpointRef)}) {
|
|
529
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.endpoint)});
|
|
530
|
+
}
|
|
531
|
+
if (ref.kind === "credential" && ref.ref === ${jsString(normalized.llm.credentialRef)}) {
|
|
532
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.credential)});
|
|
533
|
+
}
|
|
534
|
+
if (ref.kind === "model" && ref.ref === ${jsString(normalized.llm.modelRef)}) {
|
|
535
|
+
return materialEnvValue(env, ${jsString(llmEnvByKind.model)});
|
|
536
|
+
}
|
|
537
|
+
return null;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const requiredStringMaterial = (
|
|
541
|
+
kind: string,
|
|
542
|
+
ref: string,
|
|
543
|
+
value: NonNullable<unknown> | null,
|
|
544
|
+
): GeneratedTargetResult<string> => {
|
|
545
|
+
if (typeof value === "string" && value.length > 0) return { ok: true, value };
|
|
546
|
+
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
const generatedLlmRouteFor = (env: AgentOSTargetEnv): GeneratedTargetResult<NonNullable<AgentSubmitBindings["llmRoutes"]>["default"]> => {
|
|
550
|
+
const modelId = requiredStringMaterial(
|
|
551
|
+
"model",
|
|
552
|
+
${jsString(normalized.llm.modelRef)},
|
|
553
|
+
materialValue(env, { kind: "model", ref: ${jsString(normalized.llm.modelRef)} }),
|
|
554
|
+
);
|
|
555
|
+
if (!modelId.ok) return modelId;
|
|
556
|
+
return {
|
|
557
|
+
ok: true,
|
|
558
|
+
value: {
|
|
559
|
+
kind: "openai-chat-compatible",
|
|
560
|
+
endpointRef: ${jsString(normalized.llm.endpointRef)},
|
|
561
|
+
credentialRef: ${jsString(normalized.llm.credentialRef)},
|
|
562
|
+
modelId: modelId.value,
|
|
563
|
+
},
|
|
564
|
+
};
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
const generatedSubmitBindingsFor = (env: AgentOSTargetEnv): GeneratedTargetResult<AgentSubmitBindings> => {
|
|
568
|
+
const route = generatedLlmRouteFor(env);
|
|
569
|
+
if (!route.ok) return route;
|
|
570
|
+
return {
|
|
571
|
+
ok: true,
|
|
572
|
+
value: {
|
|
573
|
+
llmRoutes: {
|
|
574
|
+
default: route.value,
|
|
575
|
+
},
|
|
576
|
+
tools: generatedCustomTools,
|
|
577
|
+
},
|
|
578
|
+
};
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
const submitSpecFromRunInput = (input: SubmitRunInput): AgentSubmitSpec => ({
|
|
582
|
+
input,
|
|
583
|
+
intent: input.intent,
|
|
584
|
+
context: input.context,
|
|
585
|
+
...(input.system === undefined ? {} : { system: input.system }),
|
|
586
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
587
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
588
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
589
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
590
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
591
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
592
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
593
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
const Base${normalized.target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
597
|
+
manifest: semanticManifest,
|
|
598
|
+
agentBindings: {
|
|
599
|
+
handlers: ${handlerRecord},
|
|
600
|
+
},
|
|
601
|
+
refResolver: (env) => ({
|
|
602
|
+
material: (ref) => materialValue(env, ref),
|
|
603
|
+
}),
|
|
604
|
+
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
export class ${normalized.target.durableObject.className} extends Base${normalized.target.durableObject.className} {
|
|
608
|
+
private readonly targetEnv: AgentOSTargetEnv;
|
|
609
|
+
|
|
610
|
+
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
611
|
+
super(ctx, env);
|
|
612
|
+
this.targetEnv = env;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
616
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
617
|
+
return bindings.ok
|
|
618
|
+
? this.submitWithBindings(spec, bindings.value)
|
|
619
|
+
: rejectTargetFailure(bindings);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
623
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
624
|
+
return bindings.ok
|
|
625
|
+
? this.submitWithBindings(submitSpecFromRunInput(input), bindings.value)
|
|
626
|
+
: rejectTargetFailure(bindings);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
630
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
631
|
+
return bindings.ok
|
|
632
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
633
|
+
: rejectTargetFailure(bindings);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
637
|
+
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
638
|
+
return bindings.ok
|
|
639
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
640
|
+
: rejectTargetFailure(bindings);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
644
|
+
return Effect.runPromise(
|
|
645
|
+
unsafeRunToolByName(
|
|
646
|
+
generatedCustomTools,
|
|
647
|
+
deterministicToolInvocation(input.method, input.input),
|
|
648
|
+
),
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
`;
|
|
653
|
+
};
|
|
654
|
+
const renderStaticTarget = (normalized, toolNames, modules) => normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
655
|
+
? renderWorkspaceStaticTarget(normalized, toolNames, modules)
|
|
656
|
+
: renderChatStaticTarget(normalized, toolNames, modules);
|
|
657
|
+
const renderCloudflareScopeHelper = (normalized, modules) => `${renderNamedImport(["durableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
658
|
+
${renderNamedImport(["manifestTruthIdentity"], modules.runtimeProtocol)}
|
|
659
|
+
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
660
|
+
${renderTypeImport(["DurableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
661
|
+
${renderTypeImport(["AgentManifest"], modules.runtimeProtocol)}
|
|
662
|
+
import manifest from "./manifest.json";
|
|
663
|
+
|
|
664
|
+
export type AgentOSTargetEnv = {
|
|
665
|
+
readonly [binding: string]: unknown;
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
export const agentOSTruthIdentity = manifestTruthIdentity(manifest as AgentManifest);
|
|
669
|
+
export const agentOSScopeId = agentOSTruthIdentity.scopeRef.scopeId;
|
|
670
|
+
export const agentOSDurableObjectBinding = ${jsString(normalized.target.durableObject.binding)};
|
|
671
|
+
|
|
672
|
+
export const agentOSDurableObjectNamespace = (
|
|
673
|
+
env: AgentOSTargetEnv,
|
|
674
|
+
): DurableObjectNamespace =>
|
|
675
|
+
env[agentOSDurableObjectBinding] as DurableObjectNamespace;
|
|
676
|
+
|
|
677
|
+
export const agentOSRpcClient = <
|
|
678
|
+
Rpc extends Pick<AgentRuntimeClient, "events" | "streamEvents"> = AgentRuntimeClient,
|
|
679
|
+
>(
|
|
680
|
+
env: AgentOSTargetEnv,
|
|
681
|
+
scopeId: string = agentOSScopeId,
|
|
682
|
+
): DurableObjectRpcClient<Rpc> => durableObjectRpcClient<Rpc>(agentOSDurableObjectNamespace(env), scopeId);
|
|
683
|
+
`;
|
|
684
|
+
const renderCloudflareWorkerEntry = (normalized, modules) => `${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? `${renderNamedImport(["Sandbox"], modules.cloudflareSandbox)}\n` : ""}${renderNamedImport([normalized.target.durableObject.className], "./target")}
|
|
685
|
+
${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
686
|
+
|
|
687
|
+
export { ${normalized.target.durableObject.className}${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? ", Sandbox" : ""} };
|
|
688
|
+
|
|
689
|
+
export default {
|
|
690
|
+
fetch(): Response {
|
|
691
|
+
return new Response("agentOS Cloudflare target", { status: 404 });
|
|
692
|
+
},
|
|
693
|
+
} satisfies ExportedHandler<AgentOSTargetEnv>;
|
|
694
|
+
`;
|
|
695
|
+
const renderCloudflareWranglerConfig = (normalized) => {
|
|
696
|
+
const workspaceConfig = normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
697
|
+
? {
|
|
698
|
+
vars: {
|
|
699
|
+
SANDBOX_TRANSPORT: "rpc",
|
|
700
|
+
},
|
|
701
|
+
containers: [
|
|
702
|
+
{
|
|
703
|
+
class_name: "Sandbox",
|
|
704
|
+
image: "../../Dockerfile",
|
|
705
|
+
instance_type: "lite",
|
|
706
|
+
max_instances: 2,
|
|
707
|
+
},
|
|
708
|
+
],
|
|
709
|
+
durable_objects: {
|
|
710
|
+
bindings: [
|
|
711
|
+
{
|
|
712
|
+
class_name: "Sandbox",
|
|
713
|
+
name: normalized.workspace.binding,
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
class_name: normalized.target.durableObject.className,
|
|
717
|
+
name: normalized.target.durableObject.binding,
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
},
|
|
721
|
+
migrations: [
|
|
722
|
+
{
|
|
723
|
+
tag: "v1",
|
|
724
|
+
new_sqlite_classes: ["Sandbox", normalized.target.durableObject.className],
|
|
725
|
+
},
|
|
726
|
+
],
|
|
727
|
+
}
|
|
728
|
+
: {
|
|
729
|
+
durable_objects: {
|
|
730
|
+
bindings: [
|
|
731
|
+
{
|
|
732
|
+
class_name: normalized.target.durableObject.className,
|
|
733
|
+
name: normalized.target.durableObject.binding,
|
|
734
|
+
},
|
|
735
|
+
],
|
|
736
|
+
},
|
|
737
|
+
migrations: [
|
|
738
|
+
{
|
|
739
|
+
tag: "v1",
|
|
740
|
+
new_sqlite_classes: [normalized.target.durableObject.className],
|
|
741
|
+
},
|
|
742
|
+
],
|
|
743
|
+
};
|
|
744
|
+
return stableJson({
|
|
745
|
+
$schema: "node_modules/wrangler/config-schema.json",
|
|
746
|
+
name: normalized.deployment.deploymentId,
|
|
747
|
+
main: "./worker.ts",
|
|
748
|
+
compatibility_date: "2026-04-15",
|
|
749
|
+
compatibility_flags: ["nodejs_compat"],
|
|
750
|
+
...workspaceConfig,
|
|
751
|
+
});
|
|
752
|
+
};
|
|
753
|
+
const generatedClientModuleImports = (normalized, modules) => [
|
|
754
|
+
{
|
|
755
|
+
kind: "workspace-client",
|
|
756
|
+
source: modules.workspaceAgentClient,
|
|
757
|
+
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
758
|
+
? [
|
|
759
|
+
"createWorkspaceAgentClientBridge",
|
|
760
|
+
"CreateWorkspaceAgentClientOptions",
|
|
761
|
+
"WorkspaceAgentClientBridge",
|
|
762
|
+
]
|
|
763
|
+
: [
|
|
764
|
+
"WORKSPACE_AGENT_COMMAND",
|
|
765
|
+
"createWorkspaceAgentClient",
|
|
766
|
+
"CreateWorkspaceAgentClientOptions",
|
|
767
|
+
"WorkspaceAgentClient",
|
|
768
|
+
"WorkspaceAgentCommandOutputByName",
|
|
769
|
+
],
|
|
770
|
+
},
|
|
771
|
+
...(normalized.client.kind === AGENTOS_CONFIG_CLIENT.SVELTE_KIT_REMOTE_V1
|
|
772
|
+
? [
|
|
773
|
+
{
|
|
774
|
+
kind: "client-transport",
|
|
775
|
+
source: "./sveltekit.remote",
|
|
776
|
+
imports: ["invokeAgentCommand", "runEventStream"],
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
kind: "client-transport",
|
|
780
|
+
source: modules.svelteKitServer,
|
|
781
|
+
imports: ["command", "getRequestEvent", "query"],
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
kind: "client-transport",
|
|
785
|
+
source: modules.sseHttp,
|
|
786
|
+
imports: ["decodeSseHttpEvents", "responseToSseHttpChunks"],
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
kind: "client-core",
|
|
790
|
+
source: modules.clientCore,
|
|
791
|
+
imports: ["AgentClientSnapshot"],
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
kind: "client-framework",
|
|
795
|
+
source: modules.clientSvelte,
|
|
796
|
+
imports: ["clientReadable", "selectClientReadable"],
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
kind: "client-framework",
|
|
800
|
+
source: modules.svelteStore,
|
|
801
|
+
imports: ["Readable"],
|
|
802
|
+
},
|
|
803
|
+
]
|
|
804
|
+
: []),
|
|
805
|
+
];
|
|
806
|
+
const renderWorkspaceSvelteKitRemote = (normalized, modules) => `${renderNamedImport(["command", "getRequestEvent", "query"], modules.svelteKitServer)}
|
|
807
|
+
${renderNamedImport(["decodeSseHttpEvents", "responseToSseHttpChunks"], modules.sseHttp)}
|
|
808
|
+
${renderNamedImport(["Result", "Schema"], modules.effect)}
|
|
809
|
+
${renderNamedImport(["WORKSPACE_AGENT_COMMAND"], modules.workspaceAgentHost)}
|
|
810
|
+
${renderNamedImport(["decodeRuntimeLedgerEvent", "isInputRequestRef", "parseInputRequestResumePayload"], modules.runtimeProtocol)}
|
|
811
|
+
${renderNamedImport(["agentOSRpcClient", "agentOSTruthIdentity"], "./cloudflare-scope")}
|
|
812
|
+
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
813
|
+
${renderTypeImport(["SseHttpEvent"], modules.sseHttp)}
|
|
814
|
+
${renderTypeImport(["RuntimeLedgerEvent", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol)}
|
|
815
|
+
${renderTypeImport([
|
|
816
|
+
"WorkspaceAgentCustomCommandInput",
|
|
817
|
+
"WorkspaceAgentDestroyCommandInput",
|
|
818
|
+
"WorkspaceAgentCommandOutputByName",
|
|
819
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
820
|
+
"WorkspaceAgentReadFileCommandInput",
|
|
821
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
822
|
+
"WorkspaceAgentReadStateCommandInput",
|
|
823
|
+
"WorkspaceAgentResetCommandInput",
|
|
824
|
+
], modules.workspaceAgentHost)}
|
|
825
|
+
${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
826
|
+
|
|
827
|
+
type AgentOSRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
828
|
+
readonly submitRunInput: (input: SubmitRunInput) => Promise<SubmitResult>;
|
|
829
|
+
readonly resumeInputRequest: (
|
|
830
|
+
input: WorkspaceAgentResumeInputRequestCommandInput,
|
|
831
|
+
) => Promise<SubmitResult>;
|
|
832
|
+
readonly decideInputRequest: (
|
|
833
|
+
input: WorkspaceAgentDecideInputRequestCommandInput,
|
|
834
|
+
) => Promise<SubmitResult>;
|
|
835
|
+
readonly customCommand: (
|
|
836
|
+
input: WorkspaceAgentCustomCommandInput,
|
|
837
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.CUSTOM]>;
|
|
838
|
+
readonly readWorkspaceFile: (
|
|
839
|
+
input: WorkspaceAgentReadFileCommandInput,
|
|
840
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.READ_FILE]>;
|
|
841
|
+
readonly readWorkspaceState: (
|
|
842
|
+
input?: WorkspaceAgentReadStateCommandInput,
|
|
843
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.READ_STATE]>;
|
|
844
|
+
readonly resetWorkspace: (
|
|
845
|
+
input?: WorkspaceAgentResetCommandInput,
|
|
846
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.RESET]>;
|
|
847
|
+
readonly destroyWorkspace: (
|
|
848
|
+
input?: WorkspaceAgentDestroyCommandInput,
|
|
849
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.DESTROY]>;
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const optionalAfterIdInput = Schema.toStandardSchemaV1(
|
|
853
|
+
Schema.Struct({ afterId: Schema.optional(Schema.Number) }),
|
|
854
|
+
);
|
|
855
|
+
const commandInput = Schema.toStandardSchemaV1(
|
|
856
|
+
Schema.Struct({
|
|
857
|
+
name: Schema.String,
|
|
858
|
+
input: Schema.Unknown,
|
|
859
|
+
}),
|
|
860
|
+
);
|
|
861
|
+
|
|
862
|
+
type GeneratedFailure = {
|
|
863
|
+
readonly ok: false;
|
|
864
|
+
readonly status: number;
|
|
865
|
+
readonly message: string;
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
type GeneratedResult<Value> =
|
|
869
|
+
| { readonly ok: true; readonly value: Value }
|
|
870
|
+
| GeneratedFailure;
|
|
871
|
+
|
|
872
|
+
const fail = (status: number, message: string): GeneratedFailure => ({
|
|
873
|
+
ok: false,
|
|
874
|
+
status,
|
|
875
|
+
message,
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
const rejectFailure = (failure: GeneratedFailure): Promise<never> =>
|
|
879
|
+
Promise.reject(
|
|
880
|
+
Object.assign(Error(failure.message), {
|
|
881
|
+
status: failure.status,
|
|
882
|
+
body: { message: failure.message },
|
|
883
|
+
}),
|
|
884
|
+
);
|
|
885
|
+
|
|
886
|
+
const env = (): GeneratedResult<AgentOSTargetEnv> => {
|
|
887
|
+
const platformEnv = getRequestEvent().platform?.env;
|
|
888
|
+
if (platformEnv === undefined) return fail(500, "Cloudflare platform env missing");
|
|
889
|
+
return { ok: true, value: platformEnv as AgentOSTargetEnv };
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
const agentOS = (platformEnv: AgentOSTargetEnv) =>
|
|
893
|
+
agentOSRpcClient<AgentOSRpc>(platformEnv);
|
|
894
|
+
|
|
895
|
+
type AgentOSRemote = ReturnType<typeof agentOS>;
|
|
896
|
+
type AgentOSSubmitRunInput = Parameters<AgentOSRemote["submitRunInput"]>[0];
|
|
897
|
+
|
|
898
|
+
const isRecord = (value: unknown): value is Readonly<Record<string, unknown>> =>
|
|
899
|
+
value !== null && typeof value === "object" && !Array.isArray(value);
|
|
900
|
+
|
|
901
|
+
const submitInputFromUnknown = (
|
|
902
|
+
value: unknown,
|
|
903
|
+
): GeneratedResult<{ readonly input: AgentOSSubmitRunInput }> => {
|
|
904
|
+
if (!isRecord(value) || !isRecord(value.input)) return fail(400, "invalid submit command input");
|
|
905
|
+
if (typeof value.input.intent !== "string" || !isRecord(value.input.context)) {
|
|
906
|
+
return fail(400, "invalid submit run input");
|
|
907
|
+
}
|
|
908
|
+
return { ok: true, value: { input: value.input as unknown as AgentOSSubmitRunInput } };
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
const resumeInputRequestFromUnknown = (
|
|
912
|
+
value: unknown,
|
|
913
|
+
): GeneratedResult<WorkspaceAgentResumeInputRequestCommandInput> => {
|
|
914
|
+
if (!isRecord(value)) return fail(400, "invalid resumeInputRequest command input");
|
|
915
|
+
if (!isInputRequestRef(value.ref)) return fail(400, "invalid resumeInputRequest ref");
|
|
916
|
+
const ref = value.ref;
|
|
917
|
+
if (typeof value.decidedBy !== "string" || value.decidedBy.length === 0) {
|
|
918
|
+
return fail(400, "invalid resumeInputRequest decidedBy");
|
|
919
|
+
}
|
|
920
|
+
if (!isRecord(value.answer) || typeof value.answer.decisionRef !== "string") {
|
|
921
|
+
return fail(400, "invalid resumeInputRequest answer");
|
|
922
|
+
}
|
|
923
|
+
const parsed = parseInputRequestResumePayload(ref.requestKind, value.answer.resume);
|
|
924
|
+
if (!parsed.ok) return fail(400, parsed.reason);
|
|
925
|
+
return {
|
|
926
|
+
ok: true,
|
|
927
|
+
value: {
|
|
928
|
+
ref,
|
|
929
|
+
decidedBy: value.decidedBy,
|
|
930
|
+
answer: {
|
|
931
|
+
decisionRef: value.answer.decisionRef,
|
|
932
|
+
resume: parsed.resume,
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
};
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
const decideInputRequestFromUnknown = (
|
|
939
|
+
value: unknown,
|
|
940
|
+
): GeneratedResult<WorkspaceAgentDecideInputRequestCommandInput> => {
|
|
941
|
+
if (!isRecord(value)) return fail(400, "invalid decideInputRequest command input");
|
|
942
|
+
if (!isInputRequestRef(value.ref)) return fail(400, "invalid decideInputRequest ref");
|
|
943
|
+
if (!isRecord(value.decision) || typeof value.decision.kind !== "string") {
|
|
944
|
+
return fail(400, "invalid decideInputRequest decision");
|
|
945
|
+
}
|
|
946
|
+
const ref = value.ref;
|
|
947
|
+
const decision = value.decision;
|
|
948
|
+
if (decision.kind === "approved") {
|
|
949
|
+
if (typeof decision.decidedBy !== "string" || decision.decidedBy.length === 0) {
|
|
950
|
+
return fail(400, "invalid decideInputRequest decidedBy");
|
|
951
|
+
}
|
|
952
|
+
if (!isRecord(decision.answer) || typeof decision.answer.decisionRef !== "string") {
|
|
953
|
+
return fail(400, "invalid decideInputRequest answer");
|
|
954
|
+
}
|
|
955
|
+
const parsed = parseInputRequestResumePayload(ref.requestKind, decision.answer.resume);
|
|
956
|
+
if (!parsed.ok) return fail(400, parsed.reason);
|
|
957
|
+
return {
|
|
958
|
+
ok: true,
|
|
959
|
+
value: {
|
|
960
|
+
ref,
|
|
961
|
+
decision: {
|
|
962
|
+
kind: "approved",
|
|
963
|
+
decidedBy: decision.decidedBy,
|
|
964
|
+
answer: {
|
|
965
|
+
decisionRef: decision.answer.decisionRef,
|
|
966
|
+
resume: parsed.resume,
|
|
967
|
+
},
|
|
968
|
+
},
|
|
969
|
+
},
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
if (decision.kind === "rejected") {
|
|
973
|
+
if (typeof decision.decisionRef !== "string" || decision.decisionRef.length === 0) {
|
|
974
|
+
return fail(400, "invalid decideInputRequest decisionRef");
|
|
975
|
+
}
|
|
976
|
+
if (typeof decision.decidedBy !== "string" || decision.decidedBy.length === 0) {
|
|
977
|
+
return fail(400, "invalid decideInputRequest decidedBy");
|
|
978
|
+
}
|
|
979
|
+
return {
|
|
980
|
+
ok: true,
|
|
981
|
+
value: {
|
|
982
|
+
ref,
|
|
983
|
+
decision: {
|
|
984
|
+
kind: "rejected",
|
|
985
|
+
decisionRef: decision.decisionRef,
|
|
986
|
+
decidedBy: decision.decidedBy,
|
|
987
|
+
...(typeof decision.reason === "string" ? { reason: decision.reason } : {}),
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
if (decision.kind === "cancelled" || decision.kind === "expired") {
|
|
993
|
+
if (typeof decision.closeRef !== "string" || decision.closeRef.length === 0) {
|
|
994
|
+
return fail(400, "invalid decideInputRequest closeRef");
|
|
995
|
+
}
|
|
996
|
+
return {
|
|
997
|
+
ok: true,
|
|
998
|
+
value: {
|
|
999
|
+
ref,
|
|
1000
|
+
decision: {
|
|
1001
|
+
kind: decision.kind,
|
|
1002
|
+
closeRef: decision.closeRef,
|
|
1003
|
+
...(typeof decision.reason === "string" ? { reason: decision.reason } : {}),
|
|
1004
|
+
},
|
|
1005
|
+
},
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
return fail(400, "unsupported decideInputRequest decision");
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
const customInputFromUnknown = (
|
|
1012
|
+
value: unknown,
|
|
1013
|
+
): GeneratedResult<WorkspaceAgentCustomCommandInput> => {
|
|
1014
|
+
if (!isRecord(value) || typeof value.method !== "string" || value.method.length === 0) {
|
|
1015
|
+
return fail(400, "invalid custom command input");
|
|
1016
|
+
}
|
|
1017
|
+
return { ok: true, value: { method: value.method, input: value.input } };
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
const readStateInputFromUnknown = (
|
|
1021
|
+
value: unknown,
|
|
1022
|
+
): GeneratedResult<WorkspaceAgentReadStateCommandInput> => {
|
|
1023
|
+
if (value === undefined) return { ok: true, value: {} };
|
|
1024
|
+
if (!isRecord(value)) return fail(400, "invalid readState command input");
|
|
1025
|
+
if (value.includeHidden !== undefined && typeof value.includeHidden !== "boolean") {
|
|
1026
|
+
return fail(400, "invalid readState includeHidden");
|
|
1027
|
+
}
|
|
1028
|
+
return {
|
|
1029
|
+
ok: true,
|
|
1030
|
+
value:
|
|
1031
|
+
value.includeHidden === undefined
|
|
1032
|
+
? {}
|
|
1033
|
+
: { includeHidden: value.includeHidden },
|
|
1034
|
+
};
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
const readFileInputFromUnknown = (
|
|
1038
|
+
value: unknown,
|
|
1039
|
+
): GeneratedResult<WorkspaceAgentReadFileCommandInput> => {
|
|
1040
|
+
if (!isRecord(value) || typeof value.path !== "string") {
|
|
1041
|
+
return fail(400, "invalid readFile command input");
|
|
1042
|
+
}
|
|
1043
|
+
if (value.encoding !== undefined && value.encoding !== "utf-8") {
|
|
1044
|
+
return fail(400, "unsupported readFile encoding");
|
|
1045
|
+
}
|
|
1046
|
+
return {
|
|
1047
|
+
ok: true,
|
|
1048
|
+
value: {
|
|
1049
|
+
path: value.path,
|
|
1050
|
+
...(value.encoding === undefined ? {} : { encoding: value.encoding }),
|
|
1051
|
+
},
|
|
1052
|
+
};
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
const resetInputFromUnknown = (value: unknown): GeneratedResult<WorkspaceAgentResetCommandInput> => {
|
|
1056
|
+
if (value === undefined) return { ok: true, value: {} };
|
|
1057
|
+
if (!isRecord(value)) return fail(400, "invalid reset command input");
|
|
1058
|
+
return { ok: true, value: typeof value.reason === "string" ? { reason: value.reason } : {} };
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
const destroyInputFromUnknown = (
|
|
1062
|
+
value: unknown,
|
|
1063
|
+
): GeneratedResult<WorkspaceAgentDestroyCommandInput> => {
|
|
1064
|
+
if (value === undefined) return { ok: true, value: {} };
|
|
1065
|
+
if (!isRecord(value)) return fail(400, "invalid destroy command input");
|
|
1066
|
+
return { ok: true, value: typeof value.reason === "string" ? { reason: value.reason } : {} };
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
const runtimeEventFromLedger = (
|
|
1070
|
+
event: Parameters<typeof decodeRuntimeLedgerEvent>[0],
|
|
1071
|
+
): RuntimeLedgerEvent | null => {
|
|
1072
|
+
const decoded = decodeRuntimeLedgerEvent(event);
|
|
1073
|
+
return decoded._tag === "runtime" ? decoded.event : null;
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
const jsonValueFromString = (data: string): GeneratedResult<unknown> =>
|
|
1077
|
+
Result.match(
|
|
1078
|
+
Result.try({
|
|
1079
|
+
try: () => JSON.parse(data) as unknown,
|
|
1080
|
+
catch: () => "invalid ledger stream event: malformed JSON",
|
|
1081
|
+
}),
|
|
1082
|
+
{
|
|
1083
|
+
onFailure: (message) => fail(502, message),
|
|
1084
|
+
onSuccess: (value) => ({ ok: true, value }),
|
|
1085
|
+
},
|
|
1086
|
+
);
|
|
1087
|
+
|
|
1088
|
+
const ledgerEventFromSse = (
|
|
1089
|
+
event: SseHttpEvent,
|
|
1090
|
+
): GeneratedResult<Parameters<typeof decodeRuntimeLedgerEvent>[0] | null> => {
|
|
1091
|
+
if (event.event !== "ledger") return { ok: true, value: null };
|
|
1092
|
+
if (event.data.trim().length === 0) {
|
|
1093
|
+
return fail(502, "invalid ledger stream event: empty data");
|
|
1094
|
+
}
|
|
1095
|
+
const parsed = jsonValueFromString(event.data);
|
|
1096
|
+
return parsed.ok
|
|
1097
|
+
? { ok: true, value: parsed.value as Parameters<typeof decodeRuntimeLedgerEvent>[0] }
|
|
1098
|
+
: parsed;
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
const emptyRuntimeEvents = (): AsyncIterable<RuntimeLedgerEvent> => ({
|
|
1102
|
+
[Symbol.asyncIterator]() {
|
|
1103
|
+
return {
|
|
1104
|
+
next: () => Promise.resolve({ done: true as const, value: undefined }),
|
|
1105
|
+
};
|
|
1106
|
+
},
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
const runtimeEventsFromSse = (response: Response): AsyncIterable<RuntimeLedgerEvent> => {
|
|
1110
|
+
if (response.body === null) return emptyRuntimeEvents();
|
|
1111
|
+
const source = decodeSseHttpEvents(responseToSseHttpChunks(response));
|
|
1112
|
+
return {
|
|
1113
|
+
[Symbol.asyncIterator]() {
|
|
1114
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
1115
|
+
const next = (): Promise<IteratorResult<RuntimeLedgerEvent>> =>
|
|
1116
|
+
iterator.next().then((result) => {
|
|
1117
|
+
if (result.done === true) return { done: true, value: undefined };
|
|
1118
|
+
const ledgerEvent = ledgerEventFromSse(result.value);
|
|
1119
|
+
if (!ledgerEvent.ok) return rejectFailure(ledgerEvent);
|
|
1120
|
+
if (ledgerEvent.value === null) return next();
|
|
1121
|
+
const runtimeEvent = runtimeEventFromLedger(ledgerEvent.value);
|
|
1122
|
+
return runtimeEvent === null ? next() : { done: false, value: runtimeEvent };
|
|
1123
|
+
});
|
|
1124
|
+
return {
|
|
1125
|
+
next,
|
|
1126
|
+
return: () =>
|
|
1127
|
+
iterator.return === undefined
|
|
1128
|
+
? Promise.resolve({ done: true, value: undefined })
|
|
1129
|
+
: iterator.return(undefined).then(() => ({ done: true, value: undefined })),
|
|
1130
|
+
};
|
|
1131
|
+
},
|
|
1132
|
+
};
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
export const invokeAgentCommand = command(commandInput, ({ name, input }): Promise<unknown> => {
|
|
1136
|
+
const platformEnv = env();
|
|
1137
|
+
if (!platformEnv.ok) return rejectFailure(platformEnv);
|
|
1138
|
+
const runtime = agentOS(platformEnv.value);
|
|
1139
|
+
if (name === WORKSPACE_AGENT_COMMAND.SUBMIT) {
|
|
1140
|
+
const submitInput = submitInputFromUnknown(input);
|
|
1141
|
+
return submitInput.ok
|
|
1142
|
+
? runtime.submitRunInput(submitInput.value.input)
|
|
1143
|
+
: rejectFailure(submitInput);
|
|
1144
|
+
}
|
|
1145
|
+
if (name === WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST) {
|
|
1146
|
+
const resumeInput = resumeInputRequestFromUnknown(input);
|
|
1147
|
+
return resumeInput.ok
|
|
1148
|
+
? runtime.resumeInputRequest(resumeInput.value)
|
|
1149
|
+
: rejectFailure(resumeInput);
|
|
1150
|
+
}
|
|
1151
|
+
if (name === WORKSPACE_AGENT_COMMAND.DECIDE_INPUT_REQUEST) {
|
|
1152
|
+
const decideInput = decideInputRequestFromUnknown(input);
|
|
1153
|
+
return decideInput.ok
|
|
1154
|
+
? runtime.decideInputRequest(decideInput.value)
|
|
1155
|
+
: rejectFailure(decideInput);
|
|
1156
|
+
}
|
|
1157
|
+
if (name === WORKSPACE_AGENT_COMMAND.CUSTOM) {
|
|
1158
|
+
const customInput = customInputFromUnknown(input);
|
|
1159
|
+
return customInput.ok ? runtime.customCommand(customInput.value) : rejectFailure(customInput);
|
|
1160
|
+
}
|
|
1161
|
+
if (name === WORKSPACE_AGENT_COMMAND.READ_STATE) {
|
|
1162
|
+
const readStateInput = readStateInputFromUnknown(input);
|
|
1163
|
+
return readStateInput.ok
|
|
1164
|
+
? runtime.readWorkspaceState(readStateInput.value)
|
|
1165
|
+
: rejectFailure(readStateInput);
|
|
1166
|
+
}
|
|
1167
|
+
if (name === WORKSPACE_AGENT_COMMAND.READ_FILE) {
|
|
1168
|
+
const readFileInput = readFileInputFromUnknown(input);
|
|
1169
|
+
return readFileInput.ok
|
|
1170
|
+
? runtime.readWorkspaceFile(readFileInput.value)
|
|
1171
|
+
: rejectFailure(readFileInput);
|
|
1172
|
+
}
|
|
1173
|
+
if (name === WORKSPACE_AGENT_COMMAND.RESET) {
|
|
1174
|
+
const resetInput = resetInputFromUnknown(input);
|
|
1175
|
+
return resetInput.ok ? runtime.resetWorkspace(resetInput.value) : rejectFailure(resetInput);
|
|
1176
|
+
}
|
|
1177
|
+
if (name === WORKSPACE_AGENT_COMMAND.DESTROY) {
|
|
1178
|
+
const destroyInput = destroyInputFromUnknown(input);
|
|
1179
|
+
return destroyInput.ok
|
|
1180
|
+
? runtime.destroyWorkspace(destroyInput.value)
|
|
1181
|
+
: rejectFailure(destroyInput);
|
|
1182
|
+
}
|
|
1183
|
+
return rejectFailure(fail(501, \`unsupported generated workspace command \${name}\`));
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
export const runEventStream = query.live(optionalAfterIdInput, (input) => {
|
|
1187
|
+
const afterId = input.afterId ?? 0;
|
|
1188
|
+
const platformEnv = env();
|
|
1189
|
+
if (!platformEnv.ok) return rejectFailure(platformEnv);
|
|
1190
|
+
return agentOS(platformEnv.value)
|
|
1191
|
+
.streamEvents(agentOSTruthIdentity, afterId > 0 ? { afterId } : {})
|
|
1192
|
+
.then(runtimeEventsFromSse);
|
|
1193
|
+
});
|
|
1194
|
+
`;
|
|
1195
|
+
const renderChatSvelteKitRemote = (normalized, modules) => `${renderNamedImport(["command", "getRequestEvent", "query"], modules.svelteKitServer)}
|
|
1196
|
+
${renderNamedImport(["decodeSseHttpEvents", "responseToSseHttpChunks"], modules.sseHttp)}
|
|
1197
|
+
${renderNamedImport(["Result", "Schema"], modules.effect)}
|
|
1198
|
+
${renderNamedImport(["WORKSPACE_AGENT_COMMAND"], modules.workspaceAgentHost)}
|
|
1199
|
+
${renderNamedImport(["decodeRuntimeLedgerEvent", "isInputRequestRef", "parseInputRequestResumePayload"], modules.runtimeProtocol)}
|
|
1200
|
+
${renderNamedImport(["agentOSRpcClient", "agentOSTruthIdentity"], "./cloudflare-scope")}
|
|
1201
|
+
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
1202
|
+
${renderTypeImport(["SseHttpEvent"], modules.sseHttp)}
|
|
1203
|
+
${renderTypeImport(["RuntimeLedgerEvent", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol)}
|
|
1204
|
+
${renderTypeImport([
|
|
1205
|
+
"WorkspaceAgentCommandOutputByName",
|
|
1206
|
+
"WorkspaceAgentCustomCommandInput",
|
|
1207
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
1208
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
1209
|
+
], modules.workspaceAgentHost)}
|
|
1210
|
+
${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
1211
|
+
|
|
1212
|
+
type AgentOSRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
1213
|
+
readonly submitRunInput: (input: SubmitRunInput) => Promise<SubmitResult>;
|
|
1214
|
+
readonly resumeInputRequest: (
|
|
1215
|
+
input: WorkspaceAgentResumeInputRequestCommandInput,
|
|
1216
|
+
) => Promise<SubmitResult>;
|
|
1217
|
+
readonly decideInputRequest: (
|
|
1218
|
+
input: WorkspaceAgentDecideInputRequestCommandInput,
|
|
1219
|
+
) => Promise<SubmitResult>;
|
|
1220
|
+
readonly customCommand: (
|
|
1221
|
+
input: WorkspaceAgentCustomCommandInput,
|
|
1222
|
+
) => Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.CUSTOM]>;
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
const optionalAfterIdInput = Schema.toStandardSchemaV1(
|
|
1226
|
+
Schema.Struct({ afterId: Schema.optional(Schema.Number) }),
|
|
1227
|
+
);
|
|
1228
|
+
const commandInput = Schema.toStandardSchemaV1(
|
|
1229
|
+
Schema.Struct({
|
|
1230
|
+
name: Schema.String,
|
|
1231
|
+
input: Schema.Unknown,
|
|
1232
|
+
}),
|
|
1233
|
+
);
|
|
1234
|
+
|
|
1235
|
+
type GeneratedFailure = {
|
|
1236
|
+
readonly ok: false;
|
|
1237
|
+
readonly status: number;
|
|
1238
|
+
readonly message: string;
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
type GeneratedResult<Value> =
|
|
1242
|
+
| { readonly ok: true; readonly value: Value }
|
|
1243
|
+
| GeneratedFailure;
|
|
1244
|
+
|
|
1245
|
+
const fail = (status: number, message: string): GeneratedFailure => ({
|
|
1246
|
+
ok: false,
|
|
1247
|
+
status,
|
|
1248
|
+
message,
|
|
1249
|
+
});
|
|
1250
|
+
|
|
1251
|
+
const rejectFailure = (failure: GeneratedFailure): Promise<never> =>
|
|
1252
|
+
Promise.reject(
|
|
1253
|
+
Object.assign(Error(failure.message), {
|
|
1254
|
+
status: failure.status,
|
|
1255
|
+
body: { message: failure.message },
|
|
1256
|
+
}),
|
|
1257
|
+
);
|
|
1258
|
+
|
|
1259
|
+
const env = (): GeneratedResult<AgentOSTargetEnv> => {
|
|
1260
|
+
const platformEnv = getRequestEvent().platform?.env;
|
|
1261
|
+
if (platformEnv === undefined) return fail(500, "Cloudflare platform env missing");
|
|
1262
|
+
return { ok: true, value: platformEnv as AgentOSTargetEnv };
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
const agentOS = (platformEnv: AgentOSTargetEnv) =>
|
|
1266
|
+
agentOSRpcClient<AgentOSRpc>(platformEnv);
|
|
1267
|
+
|
|
1268
|
+
type AgentOSRemote = ReturnType<typeof agentOS>;
|
|
1269
|
+
type AgentOSSubmitRunInput = Parameters<AgentOSRemote["submitRunInput"]>[0];
|
|
1270
|
+
|
|
1271
|
+
const isRecord = (value: unknown): value is Readonly<Record<string, unknown>> =>
|
|
1272
|
+
value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1273
|
+
|
|
1274
|
+
const submitInputFromUnknown = (
|
|
1275
|
+
value: unknown,
|
|
1276
|
+
): GeneratedResult<{ readonly input: AgentOSSubmitRunInput }> => {
|
|
1277
|
+
if (!isRecord(value) || !isRecord(value.input)) return fail(400, "invalid submit command input");
|
|
1278
|
+
if (typeof value.input.intent !== "string" || !isRecord(value.input.context)) {
|
|
1279
|
+
return fail(400, "invalid submit run input");
|
|
1280
|
+
}
|
|
1281
|
+
return { ok: true, value: { input: value.input as unknown as AgentOSSubmitRunInput } };
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
const resumeInputRequestFromUnknown = (
|
|
1285
|
+
value: unknown,
|
|
1286
|
+
): GeneratedResult<WorkspaceAgentResumeInputRequestCommandInput> => {
|
|
1287
|
+
if (!isRecord(value)) return fail(400, "invalid resumeInputRequest command input");
|
|
1288
|
+
if (!isInputRequestRef(value.ref)) return fail(400, "invalid resumeInputRequest ref");
|
|
1289
|
+
const ref = value.ref;
|
|
1290
|
+
if (typeof value.decidedBy !== "string" || value.decidedBy.length === 0) {
|
|
1291
|
+
return fail(400, "invalid resumeInputRequest decidedBy");
|
|
1292
|
+
}
|
|
1293
|
+
if (!isRecord(value.answer) || typeof value.answer.decisionRef !== "string") {
|
|
1294
|
+
return fail(400, "invalid resumeInputRequest answer");
|
|
1295
|
+
}
|
|
1296
|
+
const parsed = parseInputRequestResumePayload(ref.requestKind, value.answer.resume);
|
|
1297
|
+
if (!parsed.ok) return fail(400, parsed.reason);
|
|
1298
|
+
return {
|
|
1299
|
+
ok: true,
|
|
1300
|
+
value: {
|
|
1301
|
+
ref,
|
|
1302
|
+
decidedBy: value.decidedBy,
|
|
1303
|
+
answer: {
|
|
1304
|
+
decisionRef: value.answer.decisionRef,
|
|
1305
|
+
resume: parsed.resume,
|
|
1306
|
+
},
|
|
1307
|
+
},
|
|
1308
|
+
};
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1311
|
+
const decideInputRequestFromUnknown = (
|
|
1312
|
+
value: unknown,
|
|
1313
|
+
): GeneratedResult<WorkspaceAgentDecideInputRequestCommandInput> => {
|
|
1314
|
+
if (!isRecord(value)) return fail(400, "invalid decideInputRequest command input");
|
|
1315
|
+
if (!isInputRequestRef(value.ref)) return fail(400, "invalid decideInputRequest ref");
|
|
1316
|
+
if (!isRecord(value.decision) || typeof value.decision.kind !== "string") {
|
|
1317
|
+
return fail(400, "invalid decideInputRequest decision");
|
|
1318
|
+
}
|
|
1319
|
+
const ref = value.ref;
|
|
1320
|
+
const decision = value.decision;
|
|
1321
|
+
if (decision.kind === "approved") {
|
|
1322
|
+
if (typeof decision.decidedBy !== "string" || decision.decidedBy.length === 0) {
|
|
1323
|
+
return fail(400, "invalid decideInputRequest decidedBy");
|
|
1324
|
+
}
|
|
1325
|
+
if (!isRecord(decision.answer) || typeof decision.answer.decisionRef !== "string") {
|
|
1326
|
+
return fail(400, "invalid decideInputRequest answer");
|
|
1327
|
+
}
|
|
1328
|
+
const parsed = parseInputRequestResumePayload(ref.requestKind, decision.answer.resume);
|
|
1329
|
+
if (!parsed.ok) return fail(400, parsed.reason);
|
|
1330
|
+
return {
|
|
1331
|
+
ok: true,
|
|
1332
|
+
value: {
|
|
1333
|
+
ref,
|
|
1334
|
+
decision: {
|
|
1335
|
+
kind: "approved",
|
|
1336
|
+
decidedBy: decision.decidedBy,
|
|
1337
|
+
answer: {
|
|
1338
|
+
decisionRef: decision.answer.decisionRef,
|
|
1339
|
+
resume: parsed.resume,
|
|
1340
|
+
},
|
|
1341
|
+
},
|
|
1342
|
+
},
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
if (decision.kind === "rejected") {
|
|
1346
|
+
if (typeof decision.decisionRef !== "string" || decision.decisionRef.length === 0) {
|
|
1347
|
+
return fail(400, "invalid decideInputRequest decisionRef");
|
|
1348
|
+
}
|
|
1349
|
+
if (typeof decision.decidedBy !== "string" || decision.decidedBy.length === 0) {
|
|
1350
|
+
return fail(400, "invalid decideInputRequest decidedBy");
|
|
1351
|
+
}
|
|
1352
|
+
return {
|
|
1353
|
+
ok: true,
|
|
1354
|
+
value: {
|
|
1355
|
+
ref,
|
|
1356
|
+
decision: {
|
|
1357
|
+
kind: "rejected",
|
|
1358
|
+
decisionRef: decision.decisionRef,
|
|
1359
|
+
decidedBy: decision.decidedBy,
|
|
1360
|
+
...(typeof decision.reason === "string" ? { reason: decision.reason } : {}),
|
|
1361
|
+
},
|
|
1362
|
+
},
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
if (decision.kind === "cancelled" || decision.kind === "expired") {
|
|
1366
|
+
if (typeof decision.closeRef !== "string" || decision.closeRef.length === 0) {
|
|
1367
|
+
return fail(400, "invalid decideInputRequest closeRef");
|
|
1368
|
+
}
|
|
1369
|
+
return {
|
|
1370
|
+
ok: true,
|
|
1371
|
+
value: {
|
|
1372
|
+
ref,
|
|
1373
|
+
decision: {
|
|
1374
|
+
kind: decision.kind,
|
|
1375
|
+
closeRef: decision.closeRef,
|
|
1376
|
+
...(typeof decision.reason === "string" ? { reason: decision.reason } : {}),
|
|
1377
|
+
},
|
|
1378
|
+
},
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
return fail(400, "unsupported decideInputRequest decision");
|
|
1382
|
+
};
|
|
1383
|
+
|
|
1384
|
+
const customInputFromUnknown = (
|
|
1385
|
+
value: unknown,
|
|
1386
|
+
): GeneratedResult<WorkspaceAgentCustomCommandInput> => {
|
|
1387
|
+
if (!isRecord(value) || typeof value.method !== "string" || value.method.length === 0) {
|
|
1388
|
+
return fail(400, "invalid custom command input");
|
|
1389
|
+
}
|
|
1390
|
+
return { ok: true, value: { method: value.method, input: value.input } };
|
|
1391
|
+
};
|
|
1392
|
+
|
|
1393
|
+
const runtimeEventFromLedger = (
|
|
1394
|
+
event: Parameters<typeof decodeRuntimeLedgerEvent>[0],
|
|
1395
|
+
): RuntimeLedgerEvent | null => {
|
|
1396
|
+
const decoded = decodeRuntimeLedgerEvent(event);
|
|
1397
|
+
return decoded._tag === "runtime" ? decoded.event : null;
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
const jsonValueFromString = (data: string): GeneratedResult<unknown> =>
|
|
1401
|
+
Result.match(
|
|
1402
|
+
Result.try({
|
|
1403
|
+
try: () => JSON.parse(data) as unknown,
|
|
1404
|
+
catch: () => "invalid ledger stream event: malformed JSON",
|
|
1405
|
+
}),
|
|
1406
|
+
{
|
|
1407
|
+
onFailure: (message) => fail(502, message),
|
|
1408
|
+
onSuccess: (value) => ({ ok: true, value }),
|
|
1409
|
+
},
|
|
1410
|
+
);
|
|
1411
|
+
|
|
1412
|
+
const ledgerEventFromSse = (
|
|
1413
|
+
event: SseHttpEvent,
|
|
1414
|
+
): GeneratedResult<Parameters<typeof decodeRuntimeLedgerEvent>[0] | null> => {
|
|
1415
|
+
if (event.event !== "ledger") return { ok: true, value: null };
|
|
1416
|
+
if (event.data.trim().length === 0) {
|
|
1417
|
+
return fail(502, "invalid ledger stream event: empty data");
|
|
1418
|
+
}
|
|
1419
|
+
const parsed = jsonValueFromString(event.data);
|
|
1420
|
+
return parsed.ok
|
|
1421
|
+
? { ok: true, value: parsed.value as Parameters<typeof decodeRuntimeLedgerEvent>[0] }
|
|
1422
|
+
: parsed;
|
|
1423
|
+
};
|
|
1424
|
+
|
|
1425
|
+
const emptyRuntimeEvents = (): AsyncIterable<RuntimeLedgerEvent> => ({
|
|
1426
|
+
[Symbol.asyncIterator]() {
|
|
1427
|
+
return {
|
|
1428
|
+
next: () => Promise.resolve({ done: true as const, value: undefined }),
|
|
1429
|
+
};
|
|
1430
|
+
},
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
const runtimeEventsFromSse = (response: Response): AsyncIterable<RuntimeLedgerEvent> => {
|
|
1434
|
+
if (response.body === null) return emptyRuntimeEvents();
|
|
1435
|
+
const source = decodeSseHttpEvents(responseToSseHttpChunks(response));
|
|
1436
|
+
return {
|
|
1437
|
+
[Symbol.asyncIterator]() {
|
|
1438
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
1439
|
+
const next = (): Promise<IteratorResult<RuntimeLedgerEvent>> =>
|
|
1440
|
+
iterator.next().then((result) => {
|
|
1441
|
+
if (result.done === true) return { done: true, value: undefined };
|
|
1442
|
+
const ledgerEvent = ledgerEventFromSse(result.value);
|
|
1443
|
+
if (!ledgerEvent.ok) return rejectFailure(ledgerEvent);
|
|
1444
|
+
if (ledgerEvent.value === null) return next();
|
|
1445
|
+
const runtimeEvent = runtimeEventFromLedger(ledgerEvent.value);
|
|
1446
|
+
return runtimeEvent === null ? next() : { done: false, value: runtimeEvent };
|
|
1447
|
+
});
|
|
1448
|
+
return {
|
|
1449
|
+
next,
|
|
1450
|
+
return: () =>
|
|
1451
|
+
iterator.return === undefined
|
|
1452
|
+
? Promise.resolve({ done: true, value: undefined })
|
|
1453
|
+
: iterator.return(undefined).then(() => ({ done: true, value: undefined })),
|
|
1454
|
+
};
|
|
1455
|
+
},
|
|
1456
|
+
};
|
|
1457
|
+
};
|
|
1458
|
+
|
|
1459
|
+
export const invokeAgentCommand = command(commandInput, ({ name, input }): Promise<unknown> => {
|
|
1460
|
+
const platformEnv = env();
|
|
1461
|
+
if (!platformEnv.ok) return rejectFailure(platformEnv);
|
|
1462
|
+
const runtime = agentOS(platformEnv.value);
|
|
1463
|
+
if (name === WORKSPACE_AGENT_COMMAND.SUBMIT) {
|
|
1464
|
+
const submitInput = submitInputFromUnknown(input);
|
|
1465
|
+
return submitInput.ok
|
|
1466
|
+
? runtime.submitRunInput(submitInput.value.input)
|
|
1467
|
+
: rejectFailure(submitInput);
|
|
1468
|
+
}
|
|
1469
|
+
if (name === WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST) {
|
|
1470
|
+
const resumeInput = resumeInputRequestFromUnknown(input);
|
|
1471
|
+
return resumeInput.ok
|
|
1472
|
+
? runtime.resumeInputRequest(resumeInput.value)
|
|
1473
|
+
: rejectFailure(resumeInput);
|
|
1474
|
+
}
|
|
1475
|
+
if (name === WORKSPACE_AGENT_COMMAND.DECIDE_INPUT_REQUEST) {
|
|
1476
|
+
const decideInput = decideInputRequestFromUnknown(input);
|
|
1477
|
+
return decideInput.ok
|
|
1478
|
+
? runtime.decideInputRequest(decideInput.value)
|
|
1479
|
+
: rejectFailure(decideInput);
|
|
1480
|
+
}
|
|
1481
|
+
if (name === WORKSPACE_AGENT_COMMAND.CUSTOM) {
|
|
1482
|
+
const customInput = customInputFromUnknown(input);
|
|
1483
|
+
return customInput.ok ? runtime.customCommand(customInput.value) : rejectFailure(customInput);
|
|
1484
|
+
}
|
|
1485
|
+
return rejectFailure(fail(501, \`unsupported generated chat command \${name}\`));
|
|
1486
|
+
});
|
|
1487
|
+
|
|
1488
|
+
export const runEventStream = query.live(optionalAfterIdInput, (input) => {
|
|
1489
|
+
const afterId = input.afterId ?? 0;
|
|
1490
|
+
const platformEnv = env();
|
|
1491
|
+
if (!platformEnv.ok) return rejectFailure(platformEnv);
|
|
1492
|
+
return agentOS(platformEnv.value)
|
|
1493
|
+
.streamEvents(agentOSTruthIdentity, afterId > 0 ? { afterId } : {})
|
|
1494
|
+
.then(runtimeEventsFromSse);
|
|
1495
|
+
});
|
|
1496
|
+
`;
|
|
1497
|
+
const renderSvelteKitRemote = (normalized, modules) => normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1498
|
+
? renderWorkspaceSvelteKitRemote(normalized, modules)
|
|
1499
|
+
: renderChatSvelteKitRemote(normalized, modules);
|
|
1500
|
+
const renderWorkspaceStaticClient = (normalized, modules) => {
|
|
1501
|
+
if (normalized.client.kind === AGENTOS_CONFIG_CLIENT.BROWSER_DIRECT_V1) {
|
|
1502
|
+
return `${renderNamedImport(["createWorkspaceAgentClientBridge"], modules.workspaceAgentClient)}
|
|
1503
|
+
${renderTypeImport(["CreateWorkspaceAgentClientOptions", "WorkspaceAgentClientBridge"], modules.workspaceAgentClient)}
|
|
1504
|
+
|
|
1505
|
+
export type GeneratedAgentClientOptions = CreateWorkspaceAgentClientOptions;
|
|
1506
|
+
export type GeneratedAgentClient = WorkspaceAgentClientBridge;
|
|
1507
|
+
|
|
1508
|
+
export const createAgentOSClient = (
|
|
1509
|
+
options: GeneratedAgentClientOptions = {},
|
|
1510
|
+
): GeneratedAgentClient => createWorkspaceAgentClientBridge(options);
|
|
1511
|
+
`;
|
|
1512
|
+
}
|
|
1513
|
+
return `${renderNamedImport(["createWorkspaceAgentClientBridge"], modules.workspaceAgentClient)}
|
|
1514
|
+
import { invokeAgentCommand, runEventStream } from "./sveltekit.remote";
|
|
1515
|
+
${renderNamedImport(["clientReadable", "selectClientReadable"], modules.clientSvelte)}
|
|
1516
|
+
${renderTypeImport(["AgentClientSnapshot"], modules.clientCore)}
|
|
1517
|
+
${renderTypeImport([
|
|
1518
|
+
"CreateWorkspaceAgentClientOptions",
|
|
1519
|
+
"WorkspaceAgentClient",
|
|
1520
|
+
"WorkspaceAgentClientBridge",
|
|
1521
|
+
"WorkspaceAgentCommandOutputByName",
|
|
1522
|
+
], modules.workspaceAgentClient)}
|
|
1523
|
+
${renderTypeImport(["Readable"], modules.svelteStore)}
|
|
1524
|
+
|
|
1525
|
+
export type GeneratedAgentClientOptions = CreateWorkspaceAgentClientOptions;
|
|
1526
|
+
|
|
1527
|
+
export interface GeneratedAgentClient extends WorkspaceAgentClientBridge {
|
|
1528
|
+
readonly snapshot: Readable<AgentClientSnapshot>;
|
|
1529
|
+
readonly events: Readable<AgentClientSnapshot["events"]>;
|
|
1530
|
+
readonly connection: Readable<AgentClientSnapshot["connection"]>;
|
|
1531
|
+
readonly run: Readable<AgentClientSnapshot["run"]>;
|
|
1532
|
+
readonly inputRequests: Readable<AgentClientSnapshot["run"]["inputRequests"]>;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
const generatedStreamSource: NonNullable<GeneratedAgentClientOptions["streamSource"]> = {
|
|
1536
|
+
open: (cursor) =>
|
|
1537
|
+
runEventStream({
|
|
1538
|
+
...(cursor.afterEventId === undefined ? {} : { afterId: cursor.afterEventId }),
|
|
1539
|
+
}),
|
|
1540
|
+
};
|
|
1541
|
+
|
|
1542
|
+
const generatedRpcInvoker: WorkspaceAgentClient["invoke"] = (name, input) =>
|
|
1543
|
+
invokeAgentCommand({ name, input }) as Promise<WorkspaceAgentCommandOutputByName[typeof name]>;
|
|
1544
|
+
|
|
1545
|
+
export const createAgentOSClient = (
|
|
1546
|
+
options: GeneratedAgentClientOptions = {},
|
|
1547
|
+
): GeneratedAgentClient => {
|
|
1548
|
+
const bridge = createWorkspaceAgentClientBridge({
|
|
1549
|
+
...options,
|
|
1550
|
+
streamSource: options.streamSource ?? generatedStreamSource,
|
|
1551
|
+
rpcInvoker: options.rpcInvoker ?? generatedRpcInvoker,
|
|
1552
|
+
});
|
|
1553
|
+
return {
|
|
1554
|
+
...bridge,
|
|
1555
|
+
snapshot: clientReadable(bridge.client),
|
|
1556
|
+
events: selectClientReadable(bridge.client, (snapshot) => snapshot.events),
|
|
1557
|
+
connection: selectClientReadable(bridge.client, (snapshot) => snapshot.connection),
|
|
1558
|
+
run: selectClientReadable(bridge.client, (snapshot) => snapshot.run),
|
|
1559
|
+
inputRequests: selectClientReadable(bridge.client, (snapshot) => snapshot.run.inputRequests),
|
|
1560
|
+
};
|
|
1561
|
+
};
|
|
1562
|
+
`;
|
|
1563
|
+
};
|
|
1564
|
+
const renderChatStaticClient = (normalized, modules) => {
|
|
1565
|
+
const commonImports = `${renderNamedImport(["WORKSPACE_AGENT_COMMAND", "createWorkspaceAgentClient"], modules.workspaceAgentClient)}
|
|
1566
|
+
${renderTypeImport(["SubmitRunInput"], modules.runtimeProtocol)}
|
|
1567
|
+
${renderTypeImport(["AgentClientCommandOptions", "AgentClientSnapshot"], modules.clientCore)}
|
|
1568
|
+
${renderTypeImport([
|
|
1569
|
+
"CreateWorkspaceAgentClientOptions",
|
|
1570
|
+
"WorkspaceAgentClient",
|
|
1571
|
+
"WorkspaceAgentCommandOutputByName",
|
|
1572
|
+
"WorkspaceAgentCustomCommandInput",
|
|
1573
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
1574
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
1575
|
+
], modules.workspaceAgentClient)}`;
|
|
1576
|
+
const commonTypes = `
|
|
1577
|
+
export type GeneratedAgentClientOptions = CreateWorkspaceAgentClientOptions;
|
|
1578
|
+
|
|
1579
|
+
export interface GeneratedAgentClient {
|
|
1580
|
+
readonly client: WorkspaceAgentClient;
|
|
1581
|
+
submit(
|
|
1582
|
+
input: SubmitRunInput,
|
|
1583
|
+
options?: AgentClientCommandOptions,
|
|
1584
|
+
): Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.SUBMIT]>;
|
|
1585
|
+
resumeInputRequest(
|
|
1586
|
+
input: WorkspaceAgentResumeInputRequestCommandInput,
|
|
1587
|
+
options?: AgentClientCommandOptions,
|
|
1588
|
+
): Promise<
|
|
1589
|
+
WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST]
|
|
1590
|
+
>;
|
|
1591
|
+
decideInputRequest(
|
|
1592
|
+
input: WorkspaceAgentDecideInputRequestCommandInput,
|
|
1593
|
+
options?: AgentClientCommandOptions,
|
|
1594
|
+
): Promise<
|
|
1595
|
+
WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.DECIDE_INPUT_REQUEST]
|
|
1596
|
+
>;
|
|
1597
|
+
custom(
|
|
1598
|
+
input: WorkspaceAgentCustomCommandInput,
|
|
1599
|
+
options?: AgentClientCommandOptions,
|
|
1600
|
+
): Promise<WorkspaceAgentCommandOutputByName[typeof WORKSPACE_AGENT_COMMAND.CUSTOM]>;
|
|
1601
|
+
`;
|
|
1602
|
+
const commonMethods = `
|
|
1603
|
+
client,
|
|
1604
|
+
submit(input, commandOptions) {
|
|
1605
|
+
return client.invoke(WORKSPACE_AGENT_COMMAND.SUBMIT, { input }, commandOptions);
|
|
1606
|
+
},
|
|
1607
|
+
resumeInputRequest(input, commandOptions) {
|
|
1608
|
+
return client.invoke(WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST, input, commandOptions);
|
|
1609
|
+
},
|
|
1610
|
+
decideInputRequest(input, commandOptions) {
|
|
1611
|
+
return client.invoke(WORKSPACE_AGENT_COMMAND.DECIDE_INPUT_REQUEST, input, commandOptions);
|
|
1612
|
+
},
|
|
1613
|
+
custom(input, commandOptions) {
|
|
1614
|
+
return client.invoke(WORKSPACE_AGENT_COMMAND.CUSTOM, input, commandOptions);
|
|
1615
|
+
},`;
|
|
1616
|
+
if (normalized.client.kind === AGENTOS_CONFIG_CLIENT.BROWSER_DIRECT_V1) {
|
|
1617
|
+
return `${commonImports}
|
|
1618
|
+
${commonTypes}
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
export const createAgentOSClient = (
|
|
1622
|
+
options: GeneratedAgentClientOptions = {},
|
|
1623
|
+
): GeneratedAgentClient => {
|
|
1624
|
+
const client = createWorkspaceAgentClient(options);
|
|
1625
|
+
return {${commonMethods}
|
|
1626
|
+
};
|
|
1627
|
+
};
|
|
1628
|
+
`;
|
|
1629
|
+
}
|
|
1630
|
+
return `${commonImports}
|
|
1631
|
+
import { invokeAgentCommand, runEventStream } from "./sveltekit.remote";
|
|
1632
|
+
${renderNamedImport(["clientReadable", "selectClientReadable"], modules.clientSvelte)}
|
|
1633
|
+
${renderTypeImport(["Readable"], modules.svelteStore)}
|
|
1634
|
+
${commonTypes}
|
|
1635
|
+
readonly snapshot: Readable<AgentClientSnapshot>;
|
|
1636
|
+
readonly events: Readable<AgentClientSnapshot["events"]>;
|
|
1637
|
+
readonly connection: Readable<AgentClientSnapshot["connection"]>;
|
|
1638
|
+
readonly run: Readable<AgentClientSnapshot["run"]>;
|
|
1639
|
+
readonly inputRequests: Readable<AgentClientSnapshot["run"]["inputRequests"]>;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
const generatedStreamSource: NonNullable<GeneratedAgentClientOptions["streamSource"]> = {
|
|
1643
|
+
open: (cursor) =>
|
|
1644
|
+
runEventStream({
|
|
1645
|
+
...(cursor.afterEventId === undefined ? {} : { afterId: cursor.afterEventId }),
|
|
1646
|
+
}),
|
|
1647
|
+
};
|
|
1648
|
+
|
|
1649
|
+
const generatedRpcInvoker: WorkspaceAgentClient["invoke"] = (name, input) =>
|
|
1650
|
+
invokeAgentCommand({ name, input }) as Promise<WorkspaceAgentCommandOutputByName[typeof name]>;
|
|
1651
|
+
|
|
1652
|
+
export const createAgentOSClient = (
|
|
1653
|
+
options: GeneratedAgentClientOptions = {},
|
|
1654
|
+
): GeneratedAgentClient => {
|
|
1655
|
+
const client = createWorkspaceAgentClient({
|
|
1656
|
+
...options,
|
|
1657
|
+
streamSource: options.streamSource ?? generatedStreamSource,
|
|
1658
|
+
rpcInvoker: options.rpcInvoker ?? generatedRpcInvoker,
|
|
1659
|
+
});
|
|
1660
|
+
return {${commonMethods}
|
|
1661
|
+
snapshot: clientReadable(client),
|
|
1662
|
+
events: selectClientReadable(client, (snapshot) => snapshot.events),
|
|
1663
|
+
connection: selectClientReadable(client, (snapshot) => snapshot.connection),
|
|
1664
|
+
run: selectClientReadable(client, (snapshot) => snapshot.run),
|
|
1665
|
+
inputRequests: selectClientReadable(client, (snapshot) => snapshot.run.inputRequests),
|
|
1666
|
+
};
|
|
1667
|
+
};
|
|
1668
|
+
`;
|
|
1669
|
+
};
|
|
1670
|
+
const renderStaticClient = (normalized, modules) => normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1671
|
+
? renderWorkspaceStaticClient(normalized, modules)
|
|
1672
|
+
: renderChatStaticClient(normalized, modules);
|
|
1673
|
+
const renderStaticClientTypes = () => `export type {
|
|
1674
|
+
GeneratedAgentClient,
|
|
1675
|
+
GeneratedAgentClientOptions,
|
|
1676
|
+
} from "./client";
|
|
1677
|
+
|
|
1678
|
+
export { createAgentOSClient } from "./client";
|
|
1679
|
+
`;
|
|
1680
|
+
/**
|
|
1681
|
+
* Link normalized workspace authoring intent to a closed-target residual
|
|
1682
|
+
* program. Implementation wiring is static imports and factory composition;
|
|
1683
|
+
* manifest and deployment JSON remain semantic/provenance data only.
|
|
1684
|
+
*
|
|
1685
|
+
* @agentosPrimitive primitive.agent-authoring.linkWorkspaceStaticTarget
|
|
1686
|
+
* @agentosInvariant invariant.docs.agent-projection
|
|
1687
|
+
* @agentosInvariant invariant.algebra.single-code-source
|
|
1688
|
+
* @agentosDocs docs/guides/build-natural-language-workspace-agent.md
|
|
1689
|
+
*/
|
|
1690
|
+
export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
1691
|
+
const packageScope = options.packageScope ?? DEFAULT_STATIC_TARGET_PACKAGE_SCOPE;
|
|
1692
|
+
if (!packageScopePattern.test(packageScope)) {
|
|
1693
|
+
return {
|
|
1694
|
+
ok: false,
|
|
1695
|
+
issues: [{ kind: "invalid_static_package_scope", scope: packageScope }],
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
const modules = staticTargetModules(packageScope);
|
|
1699
|
+
if (normalized.target.kind !== AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1) {
|
|
1700
|
+
return {
|
|
1701
|
+
ok: false,
|
|
1702
|
+
issues: [{ kind: "unsupported_static_target", target: normalized.target.kind }],
|
|
1703
|
+
};
|
|
1704
|
+
}
|
|
1705
|
+
if (normalized.llm.route !== AGENTOS_CONFIG_LLM_ROUTE.OPENAI_CHAT_COMPATIBLE) {
|
|
1706
|
+
return {
|
|
1707
|
+
ok: false,
|
|
1708
|
+
issues: [{ kind: "unsupported_static_llm_route", route: normalized.llm.route }],
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
const toolNames = Object.keys(normalized.deployment.manifest.tools ?? {}).sort();
|
|
1712
|
+
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1713
|
+
const authoredManifestToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
1714
|
+
const deploymentJson = {
|
|
1715
|
+
deploymentId: normalized.deployment.deploymentId,
|
|
1716
|
+
backend: normalized.deployment.backend,
|
|
1717
|
+
adapter: normalized.deployment.adapter,
|
|
1718
|
+
codec: normalized.deployment.codec,
|
|
1719
|
+
...(normalized.deployment.providerStrategy === undefined
|
|
1720
|
+
? {}
|
|
1721
|
+
: { providerStrategy: normalized.deployment.providerStrategy }),
|
|
1722
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1723
|
+
? {
|
|
1724
|
+
workspace: {
|
|
1725
|
+
binding: normalized.workspace.binding,
|
|
1726
|
+
bindingRef: normalized.workspace.bindingRef,
|
|
1727
|
+
root: normalized.workspace.root,
|
|
1728
|
+
topology: normalized.workspace.topology,
|
|
1729
|
+
providerResourceId: normalized.workspace.providerResourceId,
|
|
1730
|
+
cloudflareSandboxId: normalized.workspace.cloudflareSandboxId,
|
|
1731
|
+
},
|
|
1732
|
+
}
|
|
1733
|
+
: {}),
|
|
1734
|
+
};
|
|
1735
|
+
const moduleGraph = [
|
|
1736
|
+
{ kind: "semantic-json", source: "./manifest.json", imports: ["default as declarations"] },
|
|
1737
|
+
{ kind: "semantic-json", source: "./deployment.json", imports: ["default as deployment"] },
|
|
1738
|
+
{
|
|
1739
|
+
kind: "target-runtime",
|
|
1740
|
+
source: modules.cloudflareDoRuntime,
|
|
1741
|
+
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1742
|
+
? ["createAgentDurableObject", "installCloudflareWorkspaceOperationProvider"]
|
|
1743
|
+
: ["createAgentDurableObject"],
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
kind: "provider-runtime",
|
|
1747
|
+
source: modules.openAiCompatibleTransport,
|
|
1748
|
+
imports: ["OpenAiCompatibleLlmTransportLive"],
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
kind: "workspace-host",
|
|
1752
|
+
source: modules.workspaceAgentHost,
|
|
1753
|
+
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1754
|
+
? ["defineWorkspaceAgentMount", "WORKSPACE_AGENT_PROJECTION"]
|
|
1755
|
+
: ["WORKSPACE_AGENT_COMMAND"],
|
|
1756
|
+
},
|
|
1757
|
+
...generatedToolImports(authoredManifestToolNames),
|
|
1758
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1759
|
+
? [
|
|
1760
|
+
{
|
|
1761
|
+
kind: "workspace-binding",
|
|
1762
|
+
source: modules.workspaceBinding,
|
|
1763
|
+
imports: ["bindWorkspaceToolsForRuntime"],
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
kind: "execution-domain-runtime",
|
|
1767
|
+
source: modules.workspaceEnvCloudflare,
|
|
1768
|
+
imports: ["makeCloudflareWorkspaceEnv"],
|
|
1769
|
+
},
|
|
1770
|
+
{
|
|
1771
|
+
kind: "platform-runtime",
|
|
1772
|
+
source: modules.cloudflareSandbox,
|
|
1773
|
+
imports: ["getSandbox", "Sandbox", "SandboxTransport"],
|
|
1774
|
+
},
|
|
1775
|
+
]
|
|
1776
|
+
: []),
|
|
1777
|
+
{
|
|
1778
|
+
kind: "effect-runtime",
|
|
1779
|
+
source: modules.effect,
|
|
1780
|
+
imports: ["Effect"],
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
kind: "target-scope-helper",
|
|
1784
|
+
source: "./cloudflare-scope",
|
|
1785
|
+
imports: ["agentOSRpcClient", "AgentOSTargetEnv"],
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
kind: "target-worker",
|
|
1789
|
+
source: "./worker",
|
|
1790
|
+
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1791
|
+
? [normalized.target.durableObject.className, "Sandbox"]
|
|
1792
|
+
: [normalized.target.durableObject.className],
|
|
1793
|
+
},
|
|
1794
|
+
{
|
|
1795
|
+
kind: "target-config",
|
|
1796
|
+
source: "./wrangler.jsonc",
|
|
1797
|
+
imports: [],
|
|
1798
|
+
},
|
|
1799
|
+
...generatedClientModuleImports(normalized, modules),
|
|
1800
|
+
];
|
|
1801
|
+
return {
|
|
1802
|
+
ok: true,
|
|
1803
|
+
value: {
|
|
1804
|
+
files: [
|
|
1805
|
+
generatedPath(".agentos/generated/manifest.json", stableJson(normalized.deployment.manifest)),
|
|
1806
|
+
generatedPath(".agentos/generated/deployment.json", stableJson(deploymentJson)),
|
|
1807
|
+
generatedPath(".agentos/generated/provenance.json", stableJson(normalized.provenance)),
|
|
1808
|
+
generatedPath(".agentos/generated/fingerprints.json", stableJson({
|
|
1809
|
+
deployment: digestText(stableJson(deploymentJson)),
|
|
1810
|
+
manifest: digestText(stableJson(normalized.deployment.manifest)),
|
|
1811
|
+
targetModuleGraph: digestText(stableJson(moduleGraph)),
|
|
1812
|
+
})),
|
|
1813
|
+
generatedPath(".agentos/generated/target.ts", renderStaticTarget(normalized, toolNames, modules)),
|
|
1814
|
+
generatedPath(".agentos/generated/cloudflare-scope.ts", renderCloudflareScopeHelper(normalized, modules)),
|
|
1815
|
+
generatedPath(".agentos/generated/worker.ts", renderCloudflareWorkerEntry(normalized, modules)),
|
|
1816
|
+
generatedPath(".agentos/generated/wrangler.jsonc", renderCloudflareWranglerConfig(normalized)),
|
|
1817
|
+
...(normalized.client.kind === AGENTOS_CONFIG_CLIENT.SVELTE_KIT_REMOTE_V1
|
|
1818
|
+
? [
|
|
1819
|
+
generatedPath(".agentos/generated/sveltekit.remote.ts", renderSvelteKitRemote(normalized, modules)),
|
|
1820
|
+
]
|
|
1821
|
+
: []),
|
|
1822
|
+
generatedPath(".agentos/generated/client.ts", renderStaticClient(normalized, modules)),
|
|
1823
|
+
generatedPath(".agentos/generated/client.d.ts", renderStaticClientTypes()),
|
|
1824
|
+
],
|
|
1825
|
+
moduleGraph,
|
|
1826
|
+
canonicalDeployment: {
|
|
1827
|
+
profile: normalized.profile,
|
|
1828
|
+
target: normalized.target.kind,
|
|
1829
|
+
llmRoute: normalized.llm.route,
|
|
1830
|
+
client: normalized.client.kind,
|
|
1831
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1832
|
+
? { workspaceTopology: normalized.workspace.topology }
|
|
1833
|
+
: {}),
|
|
1834
|
+
toolNames,
|
|
1835
|
+
},
|
|
1836
|
+
mount: {
|
|
1837
|
+
driver: {
|
|
1838
|
+
kind: "cloudflare-do",
|
|
1839
|
+
className: normalized.target.durableObject.className,
|
|
1840
|
+
binding: normalized.target.durableObject.binding,
|
|
1841
|
+
},
|
|
1842
|
+
projectionSinks: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1843
|
+
? [
|
|
1844
|
+
"agent.info",
|
|
1845
|
+
"workspace.state",
|
|
1846
|
+
"workspace.files",
|
|
1847
|
+
"runtime.events",
|
|
1848
|
+
"runtime.input_requests",
|
|
1849
|
+
]
|
|
1850
|
+
: ["agent.info", "runtime.events", "runtime.input_requests"],
|
|
1851
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1852
|
+
? { providerResourceId: normalized.workspace.providerResourceId }
|
|
1853
|
+
: {}),
|
|
1854
|
+
},
|
|
1855
|
+
},
|
|
1856
|
+
};
|
|
1857
|
+
};
|