@yansirplus/cli 0.5.17 → 0.5.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -6
- package/agent-catalog/agentOS/SKILL.md +22 -0
- package/agent-catalog/agentOS/references/agent/decision-graph.json +530 -0
- package/agent-catalog/agentOS/references/agent/errors.json +497 -0
- package/agent-catalog/agentOS/references/agent/invariant-matrix.json +337 -0
- package/agent-catalog/agentOS/references/agent/primitives.json +989 -0
- package/agent-catalog/agentOS/references/agent/recipes.json +109 -0
- package/agent-catalog/agentOS/references/agent/start-here.md +25 -0
- package/agent-catalog/agentOS/references/package-map.md +72 -0
- package/agent-catalog/agentOS/references/provenance.json +251 -0
- package/agent-catalog/agentOS/references/public-api/cli.md +20 -0
- package/agent-catalog/agentOS/references/public-api/client.md +88 -0
- package/agent-catalog/agentOS/references/public-api/core.md +1817 -0
- package/agent-catalog/agentOS/references/public-api/runtime.md +794 -0
- package/dist/build/agent-authoring/config.d.ts +20 -5
- package/dist/build/agent-authoring/config.js +132 -32
- package/dist/build/agent-authoring/manifest-compiler.d.ts +131 -2
- package/dist/build/agent-authoring/manifest-compiler.js +630 -8
- package/dist/build/agent-authoring/shared.d.ts +2 -0
- package/dist/build/agent-authoring/shared.js +2 -0
- package/dist/build/agent-authoring/static-target.d.ts +6 -3
- package/dist/build/agent-authoring/static-target.js +1807 -286
- package/dist/build/agent-authoring.d.ts +3 -3
- package/dist/build/agent-authoring.js +1 -1
- package/dist/build/build-cli.d.ts +1 -1
- package/dist/build/build-cli.js +1614 -26
- package/dist/check/algorithmic/client-boundary-checks.mjs +3 -34
- package/dist/check/algorithmic/convergence-smoke-checks.mjs +652 -6
- package/dist/check/algorithmic/distribution-checks.mjs +8 -7
- package/dist/check/algorithmic/package-boundary-checks.mjs +3 -2
- package/dist/check/algorithmic/repo-surface-checks.mjs +55 -1
- package/dist/check/algorithmic/static-target-checks.mjs +83 -5
- package/dist/check/algorithmic-checks.mjs +10 -17
- package/dist/check/default-gate.mjs +3 -3
- package/dist/check/effect-scan-gate.mjs +121 -0
- package/dist/check/package-graph.mjs +2 -32
- package/dist/consumer-overlay.mjs +802 -0
- package/dist/lib/public-api-model.mjs +19 -0
- package/dist/lib/repo-source-files.mjs +26 -0
- package/dist/lib/ts-module-loader.mjs +44 -0
- package/dist/lib/workspace-manifest.mjs +77 -0
- package/dist/main.mjs +151 -21
- package/package.json +8 -4
- package/dist/check/check-coverage.mjs +0 -231
- package/dist/generate/generate-agent-docs.mjs +0 -435
- package/dist/generate/generate-carrier-reference.mjs +0 -514
- package/dist/generate/generate-docs.mjs +0 -345
- package/dist/generate/generate-effect-skill-manifests.mjs +0 -193
- package/dist/generate/project-docs-site.mjs +0 -190
- package/dist/lib/boundary-rules.mjs +0 -63
- package/dist/lib/capability-routes.mjs +0 -354
- package/dist/lib/projection-sink.mjs +0 -113
|
@@ -1,6 +1,6 @@
|
|
|
1
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";
|
|
2
|
+
import { digestText, GENERATED_LOAD_SKILL_TOOL_NAME, GENERATED_READ_SKILL_FILE_TOOL_NAME, isWorkspaceToolName, } from "./shared.js";
|
|
3
|
+
import { AGENTOS_CONFIG_CLIENT, AGENTOS_CONFIG_LLM_ROUTE, AGENTOS_CONFIG_PROFILE, AGENTOS_CONFIG_TARGET, llmMaterialEnvBindings, llmMaterialEnvBindingsForRoutes, } from "./config.js";
|
|
4
4
|
const generatedPath = (path, text) => ({
|
|
5
5
|
path,
|
|
6
6
|
text,
|
|
@@ -18,7 +18,91 @@ const stableJsonValue = (value) => {
|
|
|
18
18
|
};
|
|
19
19
|
const stableJson = (value) => `${JSON.stringify(stableJsonValue(value), null, 2)}\n`;
|
|
20
20
|
const jsString = (value) => JSON.stringify(value);
|
|
21
|
+
const identifierSuffix = (value) => value.replace(/[^A-Za-z0-9_$]+/g, "_").replace(/^[^A-Za-z_$]+/u, "_$&");
|
|
22
|
+
const routeEntries = (routes) => Object.entries(routes).sort(([left], [right]) => left.localeCompare(right));
|
|
23
|
+
const uniqueLlmMaterialEnvBindings = (routes) => {
|
|
24
|
+
const bindings = new Map();
|
|
25
|
+
for (const binding of llmMaterialEnvBindingsForRoutes(routes)) {
|
|
26
|
+
bindings.set(`${binding.kind}:${binding.ref}`, binding);
|
|
27
|
+
}
|
|
28
|
+
return [...bindings.values()].sort((left, right) => `${left.kind}:${left.ref}`.localeCompare(`${right.kind}:${right.ref}`));
|
|
29
|
+
};
|
|
30
|
+
const renderMaterialValueFunction = (routes) => {
|
|
31
|
+
const bindings = uniqueLlmMaterialEnvBindings(routes);
|
|
32
|
+
const cases = bindings
|
|
33
|
+
.map((binding) => ` if (ref.kind === ${jsString(binding.kind)} && ref.ref === ${jsString(binding.ref)}) {
|
|
34
|
+
return materialEnvValue(env, ${jsString(binding.envName)});
|
|
35
|
+
}`)
|
|
36
|
+
.join("\n");
|
|
37
|
+
return `const materialValue = (
|
|
38
|
+
env: AgentOSTargetEnv,
|
|
39
|
+
ref: { readonly kind: string; readonly ref: string },
|
|
40
|
+
): NonNullable<unknown> | null => {
|
|
41
|
+
${cases}
|
|
42
|
+
return null;
|
|
43
|
+
};`;
|
|
44
|
+
};
|
|
45
|
+
const renderGeneratedProviderPreflight = (routes) => {
|
|
46
|
+
const diagnostics = routeEntries(routes)
|
|
47
|
+
.map(([bindingRef, route]) => ` ...preflightOpenAiCompatibleProviderMaterial({
|
|
48
|
+
route: {
|
|
49
|
+
kind: ${jsString(route.route)},
|
|
50
|
+
endpointRef: ${jsString(route.endpointRef)},
|
|
51
|
+
credentialRef: ${jsString(route.credentialRef)},
|
|
52
|
+
modelId: typeof materialValue(env, { kind: "model", ref: ${jsString(route.modelRef)} }) === "string"
|
|
53
|
+
? materialValue(env, { kind: "model", ref: ${jsString(route.modelRef)} }) as string
|
|
54
|
+
: "",
|
|
55
|
+
},
|
|
56
|
+
refResolver: { material: (ref) => materialValue(env, ref) },
|
|
57
|
+
routeBindingRef: ${jsString(bindingRef)},
|
|
58
|
+
modelMaterial: {
|
|
59
|
+
ref: ${jsString(route.modelRef)},
|
|
60
|
+
value: materialValue(env, { kind: "model", ref: ${jsString(route.modelRef)} }),
|
|
61
|
+
},
|
|
62
|
+
}),`)
|
|
63
|
+
.join("\n");
|
|
64
|
+
return `const generatedProviderPreflightDiagnosticsFor = (
|
|
65
|
+
env: AgentOSTargetEnv,
|
|
66
|
+
): ReturnType<typeof preflightOpenAiCompatibleProviderMaterial> => [
|
|
67
|
+
${diagnostics}
|
|
68
|
+
];`;
|
|
69
|
+
};
|
|
70
|
+
const renderGeneratedLlmRoutesFor = (routes) => {
|
|
71
|
+
const checks = routeEntries(routes)
|
|
72
|
+
.map(([bindingRef, route]) => {
|
|
73
|
+
const suffix = identifierSuffix(bindingRef);
|
|
74
|
+
return ` const modelId_${suffix} = requiredStringMaterial(
|
|
75
|
+
"model",
|
|
76
|
+
${jsString(route.modelRef)},
|
|
77
|
+
materialValue(env, { kind: "model", ref: ${jsString(route.modelRef)} }),
|
|
78
|
+
);
|
|
79
|
+
if (!modelId_${suffix}.ok) return modelId_${suffix};`;
|
|
80
|
+
})
|
|
81
|
+
.join("\n");
|
|
82
|
+
const entries = routeEntries(routes)
|
|
83
|
+
.map(([bindingRef, route]) => ` ${jsString(bindingRef)}: {
|
|
84
|
+
kind: ${jsString(route.route)},
|
|
85
|
+
endpointRef: ${jsString(route.endpointRef)},
|
|
86
|
+
credentialRef: ${jsString(route.credentialRef)},
|
|
87
|
+
modelId: modelId_${identifierSuffix(bindingRef)}.value,
|
|
88
|
+
},`)
|
|
89
|
+
.join("\n");
|
|
90
|
+
return `const generatedLlmRoutesFor = (
|
|
91
|
+
env: AgentOSTargetEnv,
|
|
92
|
+
): GeneratedTargetResult<NonNullable<AgentSubmitBindings["llmRoutes"]>> => {
|
|
93
|
+
${checks}
|
|
94
|
+
return {
|
|
95
|
+
ok: true,
|
|
96
|
+
value: {
|
|
97
|
+
${entries}
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};`;
|
|
101
|
+
};
|
|
21
102
|
const importToolPath = (toolName) => `../../agent/tools/${toolName}`;
|
|
103
|
+
const importChannelPath = (path) => `../../${path.replace(/\.ts$/u, "")}`;
|
|
104
|
+
const importSchedulePath = (path) => `../../${path.replace(/\.ts$/u, "")}`;
|
|
105
|
+
const importDynamicResolverPath = (resolverPath) => `../../${resolverPath.replace(/\.ts$/u, "")}`;
|
|
22
106
|
const workspaceMutationToolNames = new Set(WORKSPACE_TOOL_EXPOSURE_PROFILES.mutation);
|
|
23
107
|
const workspaceShellToolNames = new Set(WORKSPACE_TOOL_EXPOSURE_PROFILES.shell);
|
|
24
108
|
const SOURCE_PACKAGE_SCOPE = "@agent-os";
|
|
@@ -28,13 +112,23 @@ const DEFAULT_STATIC_TARGET_PACKAGE_SCOPE = packageScopePattern.test(INJECTED_PU
|
|
|
28
112
|
? INJECTED_PUBLIC_PACKAGE_SCOPE
|
|
29
113
|
: SOURCE_PACKAGE_SCOPE;
|
|
30
114
|
const publicPackageSpecifier = (scope, name) => `${scope}/${name}`;
|
|
115
|
+
const cloudflareTargetFor = (target) => {
|
|
116
|
+
if (target.kind === AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1)
|
|
117
|
+
return target;
|
|
118
|
+
throw new TypeError(`cloudflare target renderer received ${target.kind}`);
|
|
119
|
+
};
|
|
31
120
|
const staticTargetModules = (scope) => ({
|
|
121
|
+
runtimeCapability: publicPackageSpecifier(scope, "runtime/capability"),
|
|
32
122
|
cloudflareDoRuntime: publicPackageSpecifier(scope, "runtime/cloudflare"),
|
|
33
|
-
|
|
123
|
+
localRuntime: publicPackageSpecifier(scope, "runtime/local"),
|
|
124
|
+
openAiCompatibleTransport: publicPackageSpecifier(scope, "runtime/llm-effect-ai/openai-compatible"),
|
|
34
125
|
workspaceAgentHost: publicPackageSpecifier(scope, "runtime/workspace-agent"),
|
|
35
126
|
workspaceAgentClient: publicPackageSpecifier(scope, "client/workspace-agent"),
|
|
36
127
|
workspaceBinding: publicPackageSpecifier(scope, "runtime/workspace-binding"),
|
|
37
128
|
workspaceEnvCloudflare: publicPackageSpecifier(scope, "runtime/cloudflare"),
|
|
129
|
+
runtimeChannel: publicPackageSpecifier(scope, "runtime/channel"),
|
|
130
|
+
runtimeSchedule: publicPackageSpecifier(scope, "runtime/schedule"),
|
|
131
|
+
runtimeRunProjector: publicPackageSpecifier(scope, "runtime/run-projector"),
|
|
38
132
|
clientCore: publicPackageSpecifier(scope, "client"),
|
|
39
133
|
clientSvelte: publicPackageSpecifier(scope, "client/svelte"),
|
|
40
134
|
runtimeProtocol: publicPackageSpecifier(scope, "core/runtime-protocol"),
|
|
@@ -53,7 +147,622 @@ const generatedToolImports = (toolNames) => toolNames.map((toolName, index) => (
|
|
|
53
147
|
source: importToolPath(toolName),
|
|
54
148
|
imports: [`default as tool_${index}`],
|
|
55
149
|
}));
|
|
150
|
+
const sortedSkills = (skills) => [...skills].sort((left, right) => left.name.localeCompare(right.name));
|
|
151
|
+
const sortedChannels = (channels) => [...channels].sort((left, right) => left.name.localeCompare(right.name));
|
|
152
|
+
const sortedSchedules = (schedules) => [...schedules].sort((left, right) => left.scheduleId.localeCompare(right.scheduleId));
|
|
153
|
+
const generatedChannelImports = (channels) => sortedChannels(channels).map((channel, index) => ({
|
|
154
|
+
kind: "authored-channel",
|
|
155
|
+
source: importChannelPath(channel.path),
|
|
156
|
+
imports: [`default as channel_${index}`],
|
|
157
|
+
}));
|
|
158
|
+
const generatedScheduleImports = (schedules) => sortedSchedules(schedules).map((schedule, index) => ({
|
|
159
|
+
kind: "authored-schedule",
|
|
160
|
+
source: importSchedulePath(schedule.path),
|
|
161
|
+
imports: [`default as schedule_${index}`],
|
|
162
|
+
}));
|
|
163
|
+
const sortedDynamicResolvers = (resolvers) => [...resolvers].sort((left, right) => left.slot.localeCompare(right.slot) || left.resolverId.localeCompare(right.resolverId));
|
|
164
|
+
const generatedDynamicResolverImports = (resolvers) => sortedDynamicResolvers(resolvers).map((resolver, index) => ({
|
|
165
|
+
kind: "authored-dynamic-resolver",
|
|
166
|
+
source: importDynamicResolverPath(resolver.path),
|
|
167
|
+
imports: [`default as dynamicResolver_${index}`],
|
|
168
|
+
}));
|
|
169
|
+
const renderChannelRegistry = (channels, modules) => {
|
|
170
|
+
const ordered = sortedChannels(channels);
|
|
171
|
+
const channelImports = ordered
|
|
172
|
+
.map((channel, index) => `import channel_${index} from ${jsString(importChannelPath(channel.path))};`)
|
|
173
|
+
.join("\n");
|
|
174
|
+
const entries = ordered.length === 0
|
|
175
|
+
? "[]"
|
|
176
|
+
: `[\n${ordered
|
|
177
|
+
.map((channel, index) => ` { name: ${jsString(channel.name)}, path: ${jsString(channel.path)}, channel: channel_${index} as DefinedChannel },`)
|
|
178
|
+
.join("\n")}\n]`;
|
|
179
|
+
return `${channelImports}
|
|
180
|
+
${renderNamedImport(["createChannelContext"], modules.runtimeChannel)}
|
|
181
|
+
${renderTypeImport(["ChannelMethod", "ChannelRequest", "ChannelRoute", "ChannelRuntime", "DefinedChannel"], modules.runtimeChannel)}
|
|
182
|
+
|
|
183
|
+
type GeneratedChannelDefinition = {
|
|
184
|
+
readonly name: string;
|
|
185
|
+
readonly path: string;
|
|
186
|
+
readonly channel: DefinedChannel;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
type GeneratedChannelRoute = ChannelRoute & {
|
|
190
|
+
readonly channelName: string;
|
|
191
|
+
readonly mountPath: string;
|
|
192
|
+
readonly channel: DefinedChannel;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
export const generatedChannels = ${entries} as const satisfies ReadonlyArray<GeneratedChannelDefinition>;
|
|
196
|
+
|
|
197
|
+
const mountedChannelPath = (channelName: string, routePath: string): string =>
|
|
198
|
+
routePath === "/" ? \`/channels/\${channelName}\` : \`/channels/\${channelName}\${routePath}\`;
|
|
199
|
+
|
|
200
|
+
const generatedRoutes = generatedChannels.flatMap((entry): ReadonlyArray<GeneratedChannelRoute> =>
|
|
201
|
+
entry.channel.routes.map((route) => ({
|
|
202
|
+
...route,
|
|
203
|
+
channelName: entry.name,
|
|
204
|
+
mountPath: mountedChannelPath(entry.name, route.path),
|
|
205
|
+
channel: entry.channel,
|
|
206
|
+
})),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const routeSegments = (path: string): ReadonlyArray<string> =>
|
|
210
|
+
path
|
|
211
|
+
.split("/")
|
|
212
|
+
.map((segment) => segment.trim())
|
|
213
|
+
.filter((segment) => segment.length > 0);
|
|
214
|
+
|
|
215
|
+
const isRouteParamSegment = (segment: string): boolean => segment.startsWith(":");
|
|
216
|
+
|
|
217
|
+
const routePatternsConflict = (left: string, right: string): boolean => {
|
|
218
|
+
const leftSegments = routeSegments(left);
|
|
219
|
+
const rightSegments = routeSegments(right);
|
|
220
|
+
if (leftSegments.length !== rightSegments.length) return false;
|
|
221
|
+
return leftSegments.every((leftSegment, index) => {
|
|
222
|
+
const rightSegment = rightSegments[index] ?? "";
|
|
223
|
+
return leftSegment === rightSegment || isRouteParamSegment(leftSegment) || isRouteParamSegment(rightSegment);
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const assertNoGeneratedChannelRouteConflicts = (routes: ReadonlyArray<GeneratedChannelRoute>): void => {
|
|
228
|
+
for (let leftIndex = 0; leftIndex < routes.length; leftIndex += 1) {
|
|
229
|
+
const left = routes[leftIndex];
|
|
230
|
+
if (left === undefined) continue;
|
|
231
|
+
for (let rightIndex = leftIndex + 1; rightIndex < routes.length; rightIndex += 1) {
|
|
232
|
+
const right = routes[rightIndex];
|
|
233
|
+
if (right === undefined || left.method !== right.method) continue;
|
|
234
|
+
if (!routePatternsConflict(left.mountPath, right.mountPath)) continue;
|
|
235
|
+
throw new Error(
|
|
236
|
+
\`generated channel route conflict: \${left.method} \${left.mountPath} conflicts with \${right.mountPath}\`,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
assertNoGeneratedChannelRouteConflicts(generatedRoutes);
|
|
243
|
+
|
|
244
|
+
export const generatedChannelNames = generatedChannels.map((entry) => entry.name);
|
|
245
|
+
export const generatedChannelRoutes = generatedRoutes;
|
|
246
|
+
|
|
247
|
+
const matchGeneratedChannelPath = (
|
|
248
|
+
pattern: string,
|
|
249
|
+
pathname: string,
|
|
250
|
+
): Readonly<Record<string, string>> | null => {
|
|
251
|
+
const patternSegments = routeSegments(pattern);
|
|
252
|
+
const pathSegments = routeSegments(pathname);
|
|
253
|
+
if (patternSegments.length !== pathSegments.length) return null;
|
|
254
|
+
const params: Record<string, string> = {};
|
|
255
|
+
for (let index = 0; index < patternSegments.length; index += 1) {
|
|
256
|
+
const patternSegment = patternSegments[index] ?? "";
|
|
257
|
+
const pathSegment = pathSegments[index] ?? "";
|
|
258
|
+
if (patternSegment.startsWith(":")) {
|
|
259
|
+
const paramName = patternSegment.slice(1);
|
|
260
|
+
if (paramName.length === 0) return null;
|
|
261
|
+
params[paramName] = decodeURIComponent(pathSegment);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (patternSegment !== pathSegment) return null;
|
|
265
|
+
}
|
|
266
|
+
return params;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export const dispatchGeneratedChannelRequest = async (
|
|
270
|
+
request: Request,
|
|
271
|
+
runtime: ChannelRuntime,
|
|
272
|
+
): Promise<Response | null> => {
|
|
273
|
+
const url = new URL(request.url);
|
|
274
|
+
const method = request.method.toUpperCase() as ChannelMethod;
|
|
275
|
+
for (const route of generatedChannelRoutes) {
|
|
276
|
+
if (route.method !== method) continue;
|
|
277
|
+
const params = matchGeneratedChannelPath(route.mountPath, url.pathname);
|
|
278
|
+
if (params === null) continue;
|
|
279
|
+
const channelRequest: ChannelRequest = {
|
|
280
|
+
method: route.method,
|
|
281
|
+
path: url.pathname,
|
|
282
|
+
params,
|
|
283
|
+
request,
|
|
284
|
+
url,
|
|
285
|
+
};
|
|
286
|
+
const principal = await route.channel.verify(channelRequest);
|
|
287
|
+
const context = createChannelContext(runtime, principal);
|
|
288
|
+
return route.handler(channelRequest, context);
|
|
289
|
+
}
|
|
290
|
+
return null;
|
|
291
|
+
};
|
|
292
|
+
`;
|
|
293
|
+
};
|
|
294
|
+
const renderScheduleRegistry = (schedules, modules) => {
|
|
295
|
+
const ordered = sortedSchedules(schedules);
|
|
296
|
+
const scheduleImports = ordered
|
|
297
|
+
.map((schedule, index) => `import schedule_${index} from ${jsString(importSchedulePath(schedule.path))};`)
|
|
298
|
+
.join("\n");
|
|
299
|
+
const entries = ordered.length === 0
|
|
300
|
+
? "[]"
|
|
301
|
+
: `[\n${ordered
|
|
302
|
+
.map((schedule, index) => ` { scheduleId: ${jsString(schedule.scheduleId)}, path: ${jsString(schedule.path)}, cron: ${jsString(schedule.cron)}, schedule: schedule_${index} as DefinedSchedule },`)
|
|
303
|
+
.join("\n")}\n]`;
|
|
304
|
+
return `${scheduleImports}
|
|
305
|
+
${renderNamedImport(["dispatchScheduleFire"], modules.runtimeSchedule)}
|
|
306
|
+
${renderTypeImport([
|
|
307
|
+
"DefinedSchedule",
|
|
308
|
+
"ScheduleDefinitionProjection",
|
|
309
|
+
"ScheduleFireDispatchResult",
|
|
310
|
+
"SchedulePrincipal",
|
|
311
|
+
"ScheduleRuntime",
|
|
312
|
+
], modules.runtimeSchedule)}
|
|
313
|
+
${renderTypeImport(["LedgerTruthIdentity"], modules.runtimeProtocol)}
|
|
314
|
+
|
|
315
|
+
type GeneratedScheduleDefinition = {
|
|
316
|
+
readonly scheduleId: string;
|
|
317
|
+
readonly path: string;
|
|
318
|
+
readonly cron: string;
|
|
319
|
+
readonly schedule: DefinedSchedule;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
export type GeneratedScheduleTriggerInput = {
|
|
323
|
+
readonly scheduleId: string;
|
|
324
|
+
readonly scheduledAt: string | number | Date;
|
|
325
|
+
readonly appPrincipal: SchedulePrincipal;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
export type GeneratedScheduleDispatchInput = GeneratedScheduleTriggerInput & {
|
|
329
|
+
readonly runtime: ScheduleRuntime;
|
|
330
|
+
readonly identity: LedgerTruthIdentity;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
export const generatedSchedules = ${entries} as const satisfies ReadonlyArray<GeneratedScheduleDefinition>;
|
|
334
|
+
export const generatedScheduleDefinitions = generatedSchedules.map(
|
|
335
|
+
({ scheduleId, path, cron }) => ({ scheduleId, path, cron }),
|
|
336
|
+
) satisfies ReadonlyArray<ScheduleDefinitionProjection>;
|
|
337
|
+
export const generatedScheduleIds = generatedScheduleDefinitions.map((entry) => entry.scheduleId);
|
|
338
|
+
export const generatedScheduleRegistry = new Map(
|
|
339
|
+
generatedSchedules.map((entry) => [entry.scheduleId, entry]),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
export const dispatchGeneratedSchedule = async (
|
|
343
|
+
input: GeneratedScheduleDispatchInput,
|
|
344
|
+
): Promise<ScheduleFireDispatchResult> => {
|
|
345
|
+
const entry = generatedScheduleRegistry.get(input.scheduleId);
|
|
346
|
+
if (entry === undefined) {
|
|
347
|
+
throw new Error(\`unknown generated schedule: \${input.scheduleId}\`);
|
|
348
|
+
}
|
|
349
|
+
return dispatchScheduleFire({
|
|
350
|
+
runtime: input.runtime,
|
|
351
|
+
schedule: entry.schedule,
|
|
352
|
+
scheduleId: entry.scheduleId,
|
|
353
|
+
appPrincipal: input.appPrincipal,
|
|
354
|
+
scheduledAt: input.scheduledAt,
|
|
355
|
+
scopeRef: input.identity.scopeRef,
|
|
356
|
+
effectAuthorityRef: input.identity.effectAuthorityRef,
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
`;
|
|
360
|
+
};
|
|
361
|
+
const renderSkillCatalog = (skills) => {
|
|
362
|
+
const entries = sortedSkills(skills).map((skill) => ` ${JSON.stringify(stableJsonValue({
|
|
363
|
+
description: skill.description,
|
|
364
|
+
digest: skill.digest,
|
|
365
|
+
files: skill.files.map((file) => ({
|
|
366
|
+
bytes: file.bytes,
|
|
367
|
+
digest: file.digest,
|
|
368
|
+
path: file.path,
|
|
369
|
+
text: file.text,
|
|
370
|
+
})),
|
|
371
|
+
name: skill.name,
|
|
372
|
+
path: skill.path,
|
|
373
|
+
text: skill.text,
|
|
374
|
+
}))}`);
|
|
375
|
+
return entries.length === 0 ? "[]" : `[\n${entries.join(",\n")}\n]`;
|
|
376
|
+
};
|
|
377
|
+
const renderInstructionFragments = (fragments) => {
|
|
378
|
+
const entries = [...fragments]
|
|
379
|
+
.sort((left, right) => left.fragmentId.localeCompare(right.fragmentId))
|
|
380
|
+
.map((fragment) => ` ${JSON.stringify(stableJsonValue({
|
|
381
|
+
digest: fragment.digest,
|
|
382
|
+
id: fragment.fragmentId,
|
|
383
|
+
text: fragment.text,
|
|
384
|
+
}))}`);
|
|
385
|
+
return entries.length === 0 ? "[]" : `[\n${entries.join(",\n")}\n]`;
|
|
386
|
+
};
|
|
387
|
+
const renderDynamicCapabilityCatalog = (normalized, toolNames, hasSkills) => {
|
|
388
|
+
const manifestTools = normalized.deployment.manifest.tools ?? {};
|
|
389
|
+
const dynamicToolNames = [
|
|
390
|
+
...toolNames,
|
|
391
|
+
...(hasSkills ? [GENERATED_LOAD_SKILL_TOOL_NAME, GENERATED_READ_SKILL_FILE_TOOL_NAME] : []),
|
|
392
|
+
];
|
|
393
|
+
return JSON.stringify(stableJsonValue({
|
|
394
|
+
instructions: normalized.instructionFragments.map((fragment) => ({
|
|
395
|
+
digest: fragment.digest,
|
|
396
|
+
id: fragment.fragmentId,
|
|
397
|
+
})),
|
|
398
|
+
skills: normalized.skills.map((skill) => ({
|
|
399
|
+
digest: skill.digest,
|
|
400
|
+
id: skill.name,
|
|
401
|
+
})),
|
|
402
|
+
tools: [...new Set(dynamicToolNames)].sort().map((toolName) => ({
|
|
403
|
+
id: toolName,
|
|
404
|
+
...(manifestTools[toolName]?.bindingRef === undefined
|
|
405
|
+
? {}
|
|
406
|
+
: { bindingRef: manifestTools[toolName]?.bindingRef }),
|
|
407
|
+
})),
|
|
408
|
+
}), null, 2);
|
|
409
|
+
};
|
|
410
|
+
const renderDynamicResolverImportStatements = (resolvers) => sortedDynamicResolvers(resolvers)
|
|
411
|
+
.map((resolver, index) => `import dynamicResolver_${index} from ${jsString(importDynamicResolverPath(resolver.path))};`)
|
|
412
|
+
.join("\n");
|
|
413
|
+
const renderDynamicCapabilitySupport = (normalized, toolNames, hasSkills) => {
|
|
414
|
+
const resolvers = sortedDynamicResolvers(normalized.dynamicResolvers);
|
|
415
|
+
const resolverEntries = resolvers.length === 0
|
|
416
|
+
? "[]"
|
|
417
|
+
: `[\n${resolvers
|
|
418
|
+
.map((resolver, index) => ` {
|
|
419
|
+
resolverId: ${jsString(resolver.resolverId)},
|
|
420
|
+
slot: ${jsString(resolver.slot)},
|
|
421
|
+
resolve: dynamicResolver_${index},
|
|
422
|
+
},`)
|
|
423
|
+
.join("\n")}\n]`;
|
|
424
|
+
return `${renderDynamicResolverImportStatements(resolvers)}
|
|
425
|
+
|
|
426
|
+
const generatedDynamicCapabilityCatalog = ${renderDynamicCapabilityCatalog(normalized, toolNames, hasSkills)} satisfies DynamicCapabilityCompiledCatalog;
|
|
427
|
+
|
|
428
|
+
const generatedInstructionFragments = ${renderInstructionFragments(normalized.instructionFragments)} satisfies ReadonlyArray<SubmitInstructionFragment>;
|
|
429
|
+
|
|
430
|
+
const generatedDynamicCapabilityResolvers = ${resolverEntries} satisfies ReadonlyArray<DynamicCapabilityResolverDefinition>;
|
|
431
|
+
|
|
432
|
+
const generatedDynamicCapabilityTurnEvent = (
|
|
433
|
+
refs: { readonly sessionRef?: string; readonly turnRef?: string } = {},
|
|
434
|
+
): DynamicCapabilityEventRef => ({
|
|
435
|
+
name: DYNAMIC_CAPABILITY_EVENT.TURN_STARTED,
|
|
436
|
+
...(refs.sessionRef === undefined ? {} : { sessionRef: refs.sessionRef }),
|
|
437
|
+
...(refs.turnRef === undefined ? {} : { turnRef: refs.turnRef }),
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
const generatedDynamicSubmitBindingsFor = async (
|
|
441
|
+
event: DynamicCapabilityEventRef,
|
|
442
|
+
): Promise<GeneratedTargetResult<Pick<AgentSubmitBindings, "dynamicCapabilityProjection" | "instructionFragments">>> => {
|
|
443
|
+
const projection = await runDynamicCapabilityResolvers({
|
|
444
|
+
event,
|
|
445
|
+
catalog: generatedDynamicCapabilityCatalog,
|
|
446
|
+
resolvers: generatedDynamicCapabilityResolvers,
|
|
447
|
+
materials: semanticManifest.materials ?? {},
|
|
448
|
+
});
|
|
449
|
+
if (!projection.ok) {
|
|
450
|
+
return targetFailure(\`dynamic capability resolver failed: \${JSON.stringify(projection.issues)}\`);
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
ok: true,
|
|
454
|
+
value: {
|
|
455
|
+
dynamicCapabilityProjection: projection.projection,
|
|
456
|
+
instructionFragments: generatedInstructionFragments,
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
};`;
|
|
460
|
+
};
|
|
461
|
+
const renderSkillSupport = (skills) => {
|
|
462
|
+
if (skills.length === 0)
|
|
463
|
+
return "";
|
|
464
|
+
return `
|
|
465
|
+
type GeneratedSkill = {
|
|
466
|
+
readonly name: string;
|
|
467
|
+
readonly description: string;
|
|
468
|
+
readonly path: string;
|
|
469
|
+
readonly digest: string;
|
|
470
|
+
readonly text: string;
|
|
471
|
+
readonly files: ReadonlyArray<{
|
|
472
|
+
readonly path: string;
|
|
473
|
+
readonly digest: string;
|
|
474
|
+
readonly bytes: number;
|
|
475
|
+
readonly text: string;
|
|
476
|
+
}>;
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
type GeneratedSkillFile = GeneratedSkill["files"][number];
|
|
480
|
+
|
|
481
|
+
type LoadedGeneratedSkill = Omit<GeneratedSkill, "files"> & {
|
|
482
|
+
readonly files: ReadonlyArray<Omit<GeneratedSkillFile, "text">>;
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
const generatedSkillCatalog = ${renderSkillCatalog(skills)} satisfies ReadonlyArray<GeneratedSkill>;
|
|
486
|
+
const generatedSkillNames = generatedSkillCatalog.map((skill) => skill.name);
|
|
487
|
+
const generatedSkillByName = Object.fromEntries(
|
|
488
|
+
generatedSkillCatalog.map((skill) => [skill.name, skill]),
|
|
489
|
+
) as Readonly<Record<string, GeneratedSkill>>;
|
|
490
|
+
const generatedSkillFilePathCatalog = generatedSkillCatalog.flatMap((skill) =>
|
|
491
|
+
skill.files.map((file) => ({ name: skill.name, path: file.path })),
|
|
492
|
+
);
|
|
493
|
+
const generatedVisibleSkillCatalogFor = (
|
|
494
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
495
|
+
): ReadonlyArray<GeneratedSkill> => {
|
|
496
|
+
if (projection === undefined) return generatedSkillCatalog;
|
|
497
|
+
const visible = new Set(
|
|
498
|
+
projection.skills.filter((skill) => skill.visible).map((skill) => skill.id),
|
|
499
|
+
);
|
|
500
|
+
return generatedSkillCatalog.filter((skill) => visible.has(skill.name));
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
const generatedSkillsSystemAdvert = (
|
|
504
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
505
|
+
): string => [
|
|
506
|
+
"Available agent skills are not loaded by default.",
|
|
507
|
+
...generatedVisibleSkillCatalogFor(projection).map((skill) => \`- \${skill.name}: \${skill.description}\`),
|
|
508
|
+
"Do not assume a skill's full instructions until ${GENERATED_LOAD_SKILL_TOOL_NAME} returns it.",
|
|
509
|
+
].join("\\n");
|
|
510
|
+
|
|
511
|
+
const generatedSystemPrompt = (
|
|
512
|
+
system: string | undefined,
|
|
513
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
514
|
+
): string =>
|
|
515
|
+
system === undefined || system.length === 0
|
|
516
|
+
? generatedSkillsSystemAdvert(projection)
|
|
517
|
+
: \`\${system}\\n\\n\${generatedSkillsSystemAdvert(projection)}\`;
|
|
518
|
+
|
|
519
|
+
const generatedLoadedSkill = (skill: GeneratedSkill): LoadedGeneratedSkill => ({
|
|
520
|
+
name: skill.name,
|
|
521
|
+
description: skill.description,
|
|
522
|
+
path: skill.path,
|
|
523
|
+
digest: skill.digest,
|
|
524
|
+
text: skill.text,
|
|
525
|
+
files: skill.files.map((file) => ({
|
|
526
|
+
path: file.path,
|
|
527
|
+
digest: file.digest,
|
|
528
|
+
bytes: file.bytes,
|
|
529
|
+
})),
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
const generatedFrameworkToolsFor = (
|
|
533
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
534
|
+
): Readonly<Record<string, Tool>> => {
|
|
535
|
+
const visibleSkillNames = new Set(
|
|
536
|
+
generatedVisibleSkillCatalogFor(projection).map((skill) => skill.name),
|
|
537
|
+
);
|
|
538
|
+
if (visibleSkillNames.size === 0) return {};
|
|
539
|
+
const visibleSkill = (name: string): GeneratedSkill | null => {
|
|
540
|
+
if (!visibleSkillNames.has(name)) return null;
|
|
541
|
+
return generatedSkillByName[name] ?? null;
|
|
542
|
+
};
|
|
543
|
+
const generatedLoadSkillTool = defineProductTool({
|
|
544
|
+
name: ${jsString(GENERATED_LOAD_SKILL_TOOL_NAME)},
|
|
545
|
+
description: "Load the full text of a CLI-authored agent skill by name.",
|
|
546
|
+
args: Schema.Struct({ name: Schema.String }),
|
|
547
|
+
authority: "agentos.generated.skills",
|
|
548
|
+
authorityId: "agentos.generated.skills.load_skill",
|
|
549
|
+
admit: ({ name }) => Effect.succeed({ ok: visibleSkillNames.has(name) } as const),
|
|
550
|
+
execute: ({ name }) => {
|
|
551
|
+
const skill = visibleSkill(name);
|
|
552
|
+
if (skill === null) return Effect.fail(Error(\`unknown skill \${name}\`));
|
|
553
|
+
return Effect.succeed(generatedLoadedSkill(skill));
|
|
554
|
+
},
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
const generatedReadSkillFileTool = defineProductTool({
|
|
558
|
+
name: ${jsString(GENERATED_READ_SKILL_FILE_TOOL_NAME)},
|
|
559
|
+
description: "Read one declared supporting file from a CLI-authored agent skill package.",
|
|
560
|
+
args: Schema.Struct({
|
|
561
|
+
name: Schema.String,
|
|
562
|
+
path: Schema.String,
|
|
563
|
+
}),
|
|
564
|
+
authority: "agentos.generated.skills",
|
|
565
|
+
authorityId: "agentos.generated.skills.read_skill_file",
|
|
566
|
+
admit: ({ name, path }) =>
|
|
567
|
+
Effect.succeed({
|
|
568
|
+
ok:
|
|
569
|
+
visibleSkillNames.has(name) &&
|
|
570
|
+
generatedSkillFilePathCatalog.some((file) => file.name === name && file.path === path),
|
|
571
|
+
} as const),
|
|
572
|
+
execute: ({ name, path }) => {
|
|
573
|
+
const skill = visibleSkill(name);
|
|
574
|
+
const file = skill?.files.find((candidate) => candidate.path === path);
|
|
575
|
+
if (skill === null || file === undefined) {
|
|
576
|
+
return Effect.fail(Error(\`unknown skill file \${name}/\${path}\`));
|
|
577
|
+
}
|
|
578
|
+
return Effect.succeed({
|
|
579
|
+
name,
|
|
580
|
+
path: file.path,
|
|
581
|
+
digest: file.digest,
|
|
582
|
+
text: file.text,
|
|
583
|
+
});
|
|
584
|
+
},
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
return {
|
|
588
|
+
${jsString(GENERATED_LOAD_SKILL_TOOL_NAME)}: generatedLoadSkillTool,
|
|
589
|
+
${jsString(GENERATED_READ_SKILL_FILE_TOOL_NAME)}: generatedReadSkillFileTool,
|
|
590
|
+
} satisfies Readonly<Record<string, Tool>>;
|
|
591
|
+
};
|
|
592
|
+
`;
|
|
593
|
+
};
|
|
594
|
+
const renderSubmitSpecFromRunInput = (hasSkills) => `const submitSpecFromRunInput = (
|
|
595
|
+
input: SubmitRunInput,
|
|
596
|
+
dynamicCapabilityProjection: DynamicCapabilityProjection | undefined,
|
|
597
|
+
): AgentSubmitSpec => ({
|
|
598
|
+
input,
|
|
599
|
+
intent: input.intent,
|
|
600
|
+
context: input.context,
|
|
601
|
+
${hasSkills ? "system: generatedSystemPrompt(input.system, dynamicCapabilityProjection)," : "...(input.system === undefined ? {} : { system: input.system }),"}
|
|
602
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
603
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
604
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
605
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
606
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
607
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
608
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
609
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
610
|
+
});`;
|
|
611
|
+
const renderProductApiHelpers = () => `export interface AgentSessionSubmitTurnInput extends SubmitRunInput {
|
|
612
|
+
readonly sessionRef: string;
|
|
613
|
+
readonly turnRef: string;
|
|
614
|
+
readonly idempotencyKey?: string;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export interface AgentWorkflowRunInput extends SubmitRunInput {
|
|
618
|
+
readonly workflowId: string;
|
|
619
|
+
readonly workflowRunId: string;
|
|
620
|
+
readonly idempotencyKey?: string;
|
|
621
|
+
readonly inputDigest?: string;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
export interface AgentWorkflowRunRef {
|
|
625
|
+
readonly workflowId: string;
|
|
626
|
+
readonly workflowRunId: string;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const submitRunInputFields = (input: SubmitRunInput): SubmitRunInput => ({
|
|
630
|
+
intent: input.intent,
|
|
631
|
+
context: input.context,
|
|
632
|
+
...(input.system === undefined ? {} : { system: input.system }),
|
|
633
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
634
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
635
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
636
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
637
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
638
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
639
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
640
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
const submitRunInputFromWorkflowRun = (
|
|
644
|
+
input: AgentWorkflowRunInput,
|
|
645
|
+
): SubmitRunInput => submitRunInputFields(input);
|
|
646
|
+
|
|
647
|
+
const submitRunInputFromSessionTurn = (
|
|
648
|
+
input: AgentSessionSubmitTurnInput,
|
|
649
|
+
): SubmitRunInput => submitRunInputFields(input);`;
|
|
650
|
+
const renderProductApiDurableObjectMethods = () => `
|
|
651
|
+
submitSessionTurn(input: AgentSessionSubmitTurnInput): Promise<SubmitResult> {
|
|
652
|
+
return generatedSubmitBindingsFor(
|
|
653
|
+
this.targetEnv,
|
|
654
|
+
generatedDynamicCapabilityTurnEvent({
|
|
655
|
+
sessionRef: input.sessionRef,
|
|
656
|
+
turnRef: input.turnRef,
|
|
657
|
+
}),
|
|
658
|
+
).then((bindings) =>
|
|
659
|
+
bindings.ok
|
|
660
|
+
? this.submitWithBindingsAndProductLink(
|
|
661
|
+
submitSpecFromRunInput(
|
|
662
|
+
submitRunInputFromSessionTurn(input),
|
|
663
|
+
bindings.value.dynamicCapabilityProjection,
|
|
664
|
+
),
|
|
665
|
+
bindings.value,
|
|
666
|
+
{
|
|
667
|
+
kind: "session_turn",
|
|
668
|
+
sessionRef: input.sessionRef,
|
|
669
|
+
turnRef: input.turnRef,
|
|
670
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
671
|
+
},
|
|
672
|
+
)
|
|
673
|
+
: rejectTargetFailure(bindings),
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
inspectSession(input: { readonly sessionRef: string }): Promise<AgentSessionProjection> {
|
|
678
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
679
|
+
projectAgentSession(events, input.sessionRef),
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
listSessions(): Promise<AgentSessionListProjection> {
|
|
684
|
+
return this.events(semanticTruthIdentity).then((events) => projectAgentSessions(events));
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
runWorkflow(input: AgentWorkflowRunInput): Promise<SubmitResult> {
|
|
688
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
689
|
+
bindings.ok
|
|
690
|
+
? this.submitWithBindingsAndProductLink(
|
|
691
|
+
submitSpecFromRunInput(
|
|
692
|
+
submitRunInputFromWorkflowRun(input),
|
|
693
|
+
bindings.value.dynamicCapabilityProjection,
|
|
694
|
+
),
|
|
695
|
+
bindings.value,
|
|
696
|
+
{
|
|
697
|
+
kind: "workflow_run",
|
|
698
|
+
workflowId: input.workflowId,
|
|
699
|
+
workflowRunId: input.workflowRunId,
|
|
700
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
701
|
+
...(input.inputDigest === undefined ? {} : { inputDigest: input.inputDigest }),
|
|
702
|
+
},
|
|
703
|
+
)
|
|
704
|
+
: rejectTargetFailure(bindings),
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
inspectWorkflowRun(input: AgentWorkflowRunRef): Promise<WorkflowRunProjection | null> {
|
|
709
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
710
|
+
projectWorkflowRun(events, input.workflowId, input.workflowRunId),
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
listWorkflowRuns(input: { readonly workflowId: string }): Promise<WorkflowRunListProjection> {
|
|
715
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
716
|
+
projectWorkflowRuns(events, input.workflowId),
|
|
717
|
+
);
|
|
718
|
+
}`;
|
|
719
|
+
const renderScheduleDurableObjectHelpers = () => `
|
|
720
|
+
const generatedScheduleRuntimeFor = (target: {
|
|
721
|
+
readonly submitSessionTurn: (input: AgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
722
|
+
readonly runWorkflow: (input: AgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
723
|
+
}) =>
|
|
724
|
+
Object.freeze({
|
|
725
|
+
sessions: Object.freeze({
|
|
726
|
+
submitTurn: (input: AgentSessionSubmitTurnInput) => target.submitSessionTurn(input),
|
|
727
|
+
}),
|
|
728
|
+
workflows: Object.freeze({
|
|
729
|
+
run: (input: AgentWorkflowRunInput) => target.runWorkflow(input),
|
|
730
|
+
}),
|
|
731
|
+
});`;
|
|
732
|
+
const renderScheduleDurableObjectMethod = () => `
|
|
733
|
+
dispatchSchedule(input: GeneratedScheduleTriggerInput): Promise<unknown> {
|
|
734
|
+
return dispatchGeneratedSchedule({
|
|
735
|
+
...input,
|
|
736
|
+
identity: semanticTruthIdentity,
|
|
737
|
+
runtime: generatedScheduleRuntimeFor(this),
|
|
738
|
+
}).then((result) => this.commitScheduleFireDispatchFull(result));
|
|
739
|
+
}
|
|
740
|
+
`;
|
|
741
|
+
const renderGeneratedWorkspaceOperations = (workspaceToolArray, usesMutationTools, usesShellTools) => `const generatedWorkspaceToolNames = ${workspaceToolArray};
|
|
742
|
+
|
|
743
|
+
const generatedWorkspaceToolInteractionFor = (
|
|
744
|
+
name: (typeof generatedWorkspaceToolNames)[number],
|
|
745
|
+
): "never" | "approval" => {
|
|
746
|
+
const interaction = semanticManifest.tools?.[name]?.interaction;
|
|
747
|
+
if (interaction === "never" || interaction === "approval") return interaction;
|
|
748
|
+
throw Error(\`invalid workspace tool interaction for \${name}: \${String(interaction)}\`);
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
const generatedWorkspaceToolInteractions = Object.fromEntries(
|
|
752
|
+
generatedWorkspaceToolNames.map((name) => [name, generatedWorkspaceToolInteractionFor(name)]),
|
|
753
|
+
) as Readonly<Partial<Record<(typeof generatedWorkspaceToolNames)[number], "never" | "approval">>>;
|
|
754
|
+
|
|
755
|
+
const generatedWorkspaceOperations = {
|
|
756
|
+
toolNames: generatedWorkspaceToolNames,
|
|
757
|
+
mutationPolicy: ${usesMutationTools ? '"receipt-backed"' : '"disabled"'},
|
|
758
|
+
shellPolicy: ${usesShellTools ? '"receipt-backed"' : '"disabled"'},
|
|
759
|
+
toolInteractions: generatedWorkspaceToolInteractions,
|
|
760
|
+
} as const;`;
|
|
56
761
|
const renderWorkspaceStaticTarget = (normalized, toolNames, modules) => {
|
|
762
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
763
|
+
const hasSkills = normalized.skills.length > 0;
|
|
764
|
+
const hasDynamicCapability = true;
|
|
765
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
57
766
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
58
767
|
const workspaceToolList = toolNames.filter((toolName) => isWorkspaceToolName(toolName) && !authoredToolNames.has(toolName));
|
|
59
768
|
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
@@ -71,23 +780,54 @@ const renderWorkspaceStaticTarget = (normalized, toolNames, modules) => {
|
|
|
71
780
|
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
72
781
|
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
73
782
|
.join("\n")}\n}`;
|
|
74
|
-
const
|
|
75
|
-
const generatedLlmEnvFields =
|
|
76
|
-
.map((
|
|
783
|
+
const llmEnvBindings = uniqueLlmMaterialEnvBindings(normalized.llmRoutes);
|
|
784
|
+
const generatedLlmEnvFields = llmEnvBindings
|
|
785
|
+
.map((binding) => ` readonly ${binding.envName}?: string;`)
|
|
77
786
|
.join("\n");
|
|
78
787
|
const imports = [
|
|
79
788
|
`import semanticDeclarations from "./manifest.json";`,
|
|
80
789
|
`import deploymentProvenance from "./deployment.json";`,
|
|
81
|
-
renderNamedImport(["
|
|
82
|
-
renderNamedImport(["
|
|
790
|
+
...(hasSchedules ? [renderNamedImport(["dispatchGeneratedSchedule"], "./schedules")] : []),
|
|
791
|
+
renderNamedImport(["createAgentDurableObject"], modules.cloudflareDoRuntime),
|
|
792
|
+
renderNamedImport([
|
|
793
|
+
"WORKSPACE_OPERATION_HOST_FACT",
|
|
794
|
+
"defineHost",
|
|
795
|
+
"resolveRuntimeInstallGraph",
|
|
796
|
+
...(hasDynamicCapability ? ["runDynamicCapabilityResolvers"] : []),
|
|
797
|
+
"workspaceOperations",
|
|
798
|
+
], modules.runtimeCapability),
|
|
799
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
800
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
801
|
+
renderNamedImport(["projectAgentSession", "projectAgentSessions", "projectWorkflowRun", "projectWorkflowRuns"], modules.runtimeRunProjector),
|
|
83
802
|
renderNamedImport(["defineWorkspaceAgentMount", "WORKSPACE_AGENT_PROJECTION"], modules.workspaceAgentHost),
|
|
84
|
-
renderNamedImport(["bindWorkspaceToolsForRuntime"], modules.workspaceBinding),
|
|
85
803
|
renderNamedImport(["makeCloudflareWorkspaceEnv"], modules.workspaceEnvCloudflare),
|
|
86
804
|
renderNamedImport(["getSandbox"], modules.cloudflareSandbox),
|
|
87
|
-
renderNamedImport([
|
|
88
|
-
|
|
805
|
+
renderNamedImport([
|
|
806
|
+
"deterministicToolInvocation",
|
|
807
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
808
|
+
"unsafeRunToolByName",
|
|
809
|
+
], modules.coreTools),
|
|
810
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
89
811
|
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
812
|
+
...(hasDynamicCapability
|
|
813
|
+
? [
|
|
814
|
+
renderTypeImport([
|
|
815
|
+
"DynamicCapabilityCompiledCatalog",
|
|
816
|
+
"DynamicCapabilityEventRef",
|
|
817
|
+
"DynamicCapabilityProjection",
|
|
818
|
+
"SubmitInstructionFragment",
|
|
819
|
+
], modules.runtimeProtocol),
|
|
820
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
821
|
+
]
|
|
822
|
+
: []),
|
|
823
|
+
renderTypeImport([
|
|
824
|
+
"AgentSessionListProjection",
|
|
825
|
+
"AgentSessionProjection",
|
|
826
|
+
"WorkflowRunListProjection",
|
|
827
|
+
"WorkflowRunProjection",
|
|
828
|
+
], modules.runtimeRunProjector),
|
|
90
829
|
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
830
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
91
831
|
renderTypeImport([
|
|
92
832
|
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
93
833
|
"WorkspaceAgentCustomCommandInput",
|
|
@@ -109,6 +849,7 @@ export const targetDeclarations = semanticDeclarations;
|
|
|
109
849
|
export const targetDeployment = deploymentProvenance;
|
|
110
850
|
|
|
111
851
|
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
852
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
112
853
|
const generatedHandler = () => undefined;
|
|
113
854
|
|
|
114
855
|
type AgentOSTargetEnv = {
|
|
@@ -120,33 +861,36 @@ ${generatedLlmEnvFields}
|
|
|
120
861
|
type GeneratedTargetFailure = {
|
|
121
862
|
readonly ok: false;
|
|
122
863
|
readonly message: string;
|
|
864
|
+
readonly diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
123
865
|
};
|
|
124
866
|
|
|
125
867
|
type GeneratedTargetResult<Value> =
|
|
126
868
|
| { readonly ok: true; readonly value: Value }
|
|
127
869
|
| GeneratedTargetFailure;
|
|
128
870
|
|
|
129
|
-
const targetFailure = (
|
|
871
|
+
const targetFailure = (
|
|
872
|
+
message: string,
|
|
873
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>,
|
|
874
|
+
): GeneratedTargetFailure => ({
|
|
875
|
+
ok: false,
|
|
876
|
+
message,
|
|
877
|
+
...(diagnostics === undefined || diagnostics.length === 0 ? {} : { diagnostics }),
|
|
878
|
+
});
|
|
130
879
|
|
|
131
|
-
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
132
|
-
|
|
880
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> => {
|
|
881
|
+
const error = Error(failure.message) as Error & {
|
|
882
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
883
|
+
};
|
|
884
|
+
if (failure.diagnostics !== undefined) error.diagnostics = failure.diagnostics;
|
|
885
|
+
return Promise.reject(error);
|
|
886
|
+
};
|
|
133
887
|
|
|
134
|
-
|
|
888
|
+
${renderGeneratedWorkspaceOperations(workspaceToolArray, usesMutationTools, usesShellTools)}
|
|
135
889
|
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
890
|
+
${hasDynamicCapability ? renderDynamicCapabilitySupport(normalized, toolNames, hasSkills) : ""}
|
|
891
|
+
${renderSkillSupport(normalized.skills)}
|
|
136
892
|
const generatedWorkspaceSandboxId = ${jsString(normalized.workspace.cloudflareSandboxId)};
|
|
137
893
|
|
|
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
894
|
const workspaceNamespaceFor = (env: AgentOSTargetEnv): DurableObjectNamespace<Sandbox> =>
|
|
151
895
|
env[${jsString(normalized.workspace.binding)}] as DurableObjectNamespace<Sandbox>;
|
|
152
896
|
|
|
@@ -221,36 +965,46 @@ const workspaceEnvFor = (env: AgentOSTargetEnv) =>
|
|
|
221
965
|
workspaceRef: ${jsString(normalized.workspace.providerResourceId)},
|
|
222
966
|
});
|
|
223
967
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
968
|
+
const generatedHostProfileFor = (env: AgentOSTargetEnv) => defineHost({
|
|
969
|
+
target: "cloudflare-do@1",
|
|
970
|
+
provides: [
|
|
971
|
+
"storage.ledger",
|
|
972
|
+
"durability.do",
|
|
973
|
+
WORKSPACE_OPERATION_HOST_FACT,
|
|
974
|
+
"timer.durable",
|
|
975
|
+
"network.outbound",
|
|
976
|
+
"secrets.store",
|
|
977
|
+
"eventLoop.durable",
|
|
978
|
+
"llm.openai",
|
|
979
|
+
],
|
|
980
|
+
materialize: () => ({
|
|
981
|
+
[WORKSPACE_OPERATION_HOST_FACT]: () => workspaceEnvFor(env),
|
|
982
|
+
}),
|
|
983
|
+
});
|
|
228
984
|
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
985
|
+
const generatedCapabilityInstallGraphFor = (env: AgentOSTargetEnv) => {
|
|
986
|
+
const graph = resolveRuntimeInstallGraph(
|
|
987
|
+
generatedHostProfileFor(env),
|
|
988
|
+
[workspaceOperations(generatedWorkspaceOperations)],
|
|
989
|
+
{ identity: semanticManifest.agentId },
|
|
990
|
+
);
|
|
991
|
+
if (!graph.ok) {
|
|
992
|
+
throw Error(
|
|
993
|
+
graph.diagnostics
|
|
994
|
+
.map((diagnostic) => diagnostic.reason)
|
|
995
|
+
.join("; ") || "capability install graph failed",
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
return graph.resolved;
|
|
999
|
+
};
|
|
233
1000
|
|
|
234
1001
|
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
235
1002
|
const value = env[name];
|
|
236
1003
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
237
1004
|
};
|
|
238
1005
|
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
};
|
|
1006
|
+
${renderMaterialValueFunction(normalized.llmRoutes)}
|
|
1007
|
+
${renderGeneratedProviderPreflight(normalized.llmRoutes)}
|
|
254
1008
|
|
|
255
1009
|
const requiredStringMaterial = (
|
|
256
1010
|
kind: string,
|
|
@@ -261,70 +1015,44 @@ const requiredStringMaterial = (
|
|
|
261
1015
|
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
262
1016
|
};
|
|
263
1017
|
|
|
264
|
-
|
|
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
|
-
};
|
|
1018
|
+
${renderGeneratedLlmRoutesFor(normalized.llmRoutes)}
|
|
281
1019
|
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
1020
|
+
const generatedSubmitBindingsFor = async (
|
|
1021
|
+
env: AgentOSTargetEnv,
|
|
1022
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1023
|
+
): Promise<GeneratedTargetResult<AgentSubmitBindings>> => {
|
|
1024
|
+
const preflightDiagnostics = generatedProviderPreflightDiagnosticsFor(env);
|
|
1025
|
+
if (preflightDiagnostics.length > 0) {
|
|
1026
|
+
return targetFailure(
|
|
1027
|
+
"OpenAI-compatible provider material preflight failed",
|
|
1028
|
+
preflightDiagnostics,
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
const capabilityGraph = generatedCapabilityInstallGraphFor(env);
|
|
1032
|
+
const routes = generatedLlmRoutesFor(env);
|
|
1033
|
+
if (!routes.ok) return routes;
|
|
1034
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event);
|
|
1035
|
+
if (!dynamicBindings.ok) return dynamicBindings;
|
|
1036
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
299
1037
|
return {
|
|
300
1038
|
ok: true,
|
|
301
1039
|
value: {
|
|
302
|
-
...
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
},
|
|
1040
|
+
...capabilityGraph.bindings,
|
|
1041
|
+
...dynamicBindings.value,
|
|
1042
|
+
llmRoutes: routes.value,
|
|
306
1043
|
tools: {
|
|
307
|
-
...(
|
|
1044
|
+
...(capabilityGraph.bindings.tools ?? {}),
|
|
308
1045
|
...generatedCustomTools,
|
|
1046
|
+
${hasSkills ? "...generatedFrameworkToolsFor(dynamicCapabilityProjection)," : ""}
|
|
309
1047
|
},
|
|
310
1048
|
},
|
|
311
1049
|
};
|
|
312
1050
|
};
|
|
313
1051
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
-
});
|
|
1052
|
+
${renderSubmitSpecFromRunInput(hasSkills)}
|
|
1053
|
+
|
|
1054
|
+
${renderProductApiHelpers()}
|
|
1055
|
+
${hasSchedules ? renderScheduleDurableObjectHelpers() : ""}
|
|
328
1056
|
|
|
329
1057
|
export const workspaceMount = defineWorkspaceAgentMount({
|
|
330
1058
|
driver: { kind: "driver_mount", client: undefined as never },
|
|
@@ -337,22 +1065,24 @@ export const workspaceMount = defineWorkspaceAgentMount({
|
|
|
337
1065
|
],
|
|
338
1066
|
});
|
|
339
1067
|
|
|
340
|
-
const Base${
|
|
1068
|
+
const Base${target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
341
1069
|
manifest: semanticManifest,
|
|
342
|
-
agentBindings: {
|
|
1070
|
+
agentBindings: (env) => ({
|
|
343
1071
|
handlers: ${handlerRecord},
|
|
344
|
-
|
|
1072
|
+
...generatedCapabilityInstallGraphFor(env).agentBindings,
|
|
1073
|
+
}),
|
|
345
1074
|
refResolver: (env) => ({
|
|
346
1075
|
material: (ref) => materialValue(env, ref),
|
|
347
1076
|
}),
|
|
348
1077
|
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
349
|
-
extensions: (env) =>
|
|
350
|
-
declaredIntents: (env) =>
|
|
351
|
-
projections: (env) =>
|
|
352
|
-
|
|
1078
|
+
extensions: (env) => generatedCapabilityInstallGraphFor(env).extensions,
|
|
1079
|
+
declaredIntents: (env) => generatedCapabilityInstallGraphFor(env).declaredIntents,
|
|
1080
|
+
projections: (env) => generatedCapabilityInstallGraphFor(env).projections,
|
|
1081
|
+
graphStatus: (env) => generatedCapabilityInstallGraphFor(env).graphStatus,
|
|
1082
|
+
eventHandlers: (context, env) => generatedCapabilityInstallGraphFor(env).handlers(context),
|
|
353
1083
|
});
|
|
354
1084
|
|
|
355
|
-
export class ${
|
|
1085
|
+
export class ${target.durableObject.className} extends Base${target.durableObject.className} {
|
|
356
1086
|
private readonly targetEnv: AgentOSTargetEnv;
|
|
357
1087
|
|
|
358
1088
|
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
@@ -361,31 +1091,39 @@ export class ${normalized.target.durableObject.className} extends Base${normaliz
|
|
|
361
1091
|
}
|
|
362
1092
|
|
|
363
1093
|
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
: rejectTargetFailure(bindings);
|
|
1094
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1095
|
+
bindings.ok ? this.submitWithBindings(spec, bindings.value) : rejectTargetFailure(bindings),
|
|
1096
|
+
);
|
|
368
1097
|
}
|
|
369
1098
|
|
|
370
1099
|
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
1100
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1101
|
+
bindings.ok
|
|
1102
|
+
? this.submitWithBindings(
|
|
1103
|
+
submitSpecFromRunInput(input, bindings.value.dynamicCapabilityProjection),
|
|
1104
|
+
bindings.value,
|
|
1105
|
+
)
|
|
1106
|
+
: rejectTargetFailure(bindings),
|
|
1107
|
+
);
|
|
375
1108
|
}
|
|
376
1109
|
|
|
1110
|
+
${renderProductApiDurableObjectMethods()}
|
|
1111
|
+
${hasSchedules ? renderScheduleDurableObjectMethod() : ""}
|
|
1112
|
+
|
|
377
1113
|
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
1114
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1115
|
+
bindings.ok
|
|
1116
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
1117
|
+
: rejectTargetFailure(bindings),
|
|
1118
|
+
);
|
|
382
1119
|
}
|
|
383
1120
|
|
|
384
1121
|
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1122
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1123
|
+
bindings.ok
|
|
1124
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
1125
|
+
: rejectTargetFailure(bindings),
|
|
1126
|
+
);
|
|
389
1127
|
}
|
|
390
1128
|
|
|
391
1129
|
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
@@ -452,8 +1190,246 @@ export class ${normalized.target.durableObject.className} extends Base${normaliz
|
|
|
452
1190
|
}
|
|
453
1191
|
`;
|
|
454
1192
|
};
|
|
455
|
-
const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
1193
|
+
const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
1194
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1195
|
+
const hasSkills = normalized.skills.length > 0;
|
|
1196
|
+
const hasDynamicCapability = true;
|
|
1197
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
1198
|
+
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1199
|
+
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
1200
|
+
const toolImports = customToolNames
|
|
1201
|
+
.map((toolName, index) => `import tool_${index} from ${jsString(importToolPath(toolName))};`)
|
|
1202
|
+
.join("\n");
|
|
1203
|
+
const customToolRecord = customToolNames.length === 0
|
|
1204
|
+
? "{}"
|
|
1205
|
+
: `{\n${customToolNames
|
|
1206
|
+
.map((toolName, index) => ` ${jsString(toolName)}: tool_${index},`)
|
|
1207
|
+
.join("\n")}\n}`;
|
|
1208
|
+
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
1209
|
+
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
1210
|
+
.join("\n")}\n}`;
|
|
1211
|
+
const llmEnvBindings = uniqueLlmMaterialEnvBindings(normalized.llmRoutes);
|
|
1212
|
+
const generatedLlmEnvFields = llmEnvBindings
|
|
1213
|
+
.map((binding) => ` readonly ${binding.envName}?: string;`)
|
|
1214
|
+
.join("\n");
|
|
1215
|
+
const imports = [
|
|
1216
|
+
`import semanticDeclarations from "./manifest.json";`,
|
|
1217
|
+
`import deploymentProvenance from "./deployment.json";`,
|
|
1218
|
+
...(hasSchedules ? [renderNamedImport(["dispatchGeneratedSchedule"], "./schedules")] : []),
|
|
1219
|
+
renderNamedImport(["createAgentDurableObject"], modules.cloudflareDoRuntime),
|
|
1220
|
+
renderNamedImport(["runDynamicCapabilityResolvers"], modules.runtimeCapability),
|
|
1221
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
1222
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
1223
|
+
renderNamedImport(["projectAgentSession", "projectAgentSessions", "projectWorkflowRun", "projectWorkflowRuns"], modules.runtimeRunProjector),
|
|
1224
|
+
renderNamedImport([
|
|
1225
|
+
"deterministicToolInvocation",
|
|
1226
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
1227
|
+
"unsafeRunToolByName",
|
|
1228
|
+
], modules.coreTools),
|
|
1229
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
1230
|
+
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
1231
|
+
...(hasDynamicCapability
|
|
1232
|
+
? [
|
|
1233
|
+
renderTypeImport([
|
|
1234
|
+
"DynamicCapabilityCompiledCatalog",
|
|
1235
|
+
"DynamicCapabilityEventRef",
|
|
1236
|
+
"DynamicCapabilityProjection",
|
|
1237
|
+
"SubmitInstructionFragment",
|
|
1238
|
+
], modules.runtimeProtocol),
|
|
1239
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
1240
|
+
]
|
|
1241
|
+
: []),
|
|
1242
|
+
renderTypeImport([
|
|
1243
|
+
"AgentSessionListProjection",
|
|
1244
|
+
"AgentSessionProjection",
|
|
1245
|
+
"WorkflowRunListProjection",
|
|
1246
|
+
"WorkflowRunProjection",
|
|
1247
|
+
], modules.runtimeRunProjector),
|
|
1248
|
+
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
1249
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
1250
|
+
renderTypeImport([
|
|
1251
|
+
"WorkspaceAgentCustomCommandInput",
|
|
1252
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
1253
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
1254
|
+
], modules.workspaceAgentHost),
|
|
1255
|
+
renderTypeImport(["Tool"], modules.coreTools),
|
|
1256
|
+
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
1257
|
+
].join("\n");
|
|
1258
|
+
return `${imports}
|
|
1259
|
+
|
|
1260
|
+
export const targetDeclarations = semanticDeclarations;
|
|
1261
|
+
export const targetDeployment = deploymentProvenance;
|
|
1262
|
+
|
|
1263
|
+
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
1264
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
1265
|
+
const generatedHandler = () => undefined;
|
|
1266
|
+
|
|
1267
|
+
type AgentOSTargetEnv = {
|
|
1268
|
+
readonly [binding: string]: unknown;
|
|
1269
|
+
${generatedLlmEnvFields}
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
type GeneratedTargetFailure = {
|
|
1273
|
+
readonly ok: false;
|
|
1274
|
+
readonly message: string;
|
|
1275
|
+
readonly diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
1276
|
+
};
|
|
1277
|
+
|
|
1278
|
+
type GeneratedTargetResult<Value> =
|
|
1279
|
+
| { readonly ok: true; readonly value: Value }
|
|
1280
|
+
| GeneratedTargetFailure;
|
|
1281
|
+
|
|
1282
|
+
const targetFailure = (
|
|
1283
|
+
message: string,
|
|
1284
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>,
|
|
1285
|
+
): GeneratedTargetFailure => ({
|
|
1286
|
+
ok: false,
|
|
1287
|
+
message,
|
|
1288
|
+
...(diagnostics === undefined || diagnostics.length === 0 ? {} : { diagnostics }),
|
|
1289
|
+
});
|
|
1290
|
+
|
|
1291
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> => {
|
|
1292
|
+
const error = Error(failure.message) as Error & {
|
|
1293
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
1294
|
+
};
|
|
1295
|
+
if (failure.diagnostics !== undefined) error.diagnostics = failure.diagnostics;
|
|
1296
|
+
return Promise.reject(error);
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
1300
|
+
${renderDynamicCapabilitySupport(normalized, toolNames, hasSkills)}
|
|
1301
|
+
${renderSkillSupport(normalized.skills)}
|
|
1302
|
+
|
|
1303
|
+
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
1304
|
+
const value = env[name];
|
|
1305
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
${renderMaterialValueFunction(normalized.llmRoutes)}
|
|
1309
|
+
${renderGeneratedProviderPreflight(normalized.llmRoutes)}
|
|
1310
|
+
|
|
1311
|
+
const requiredStringMaterial = (
|
|
1312
|
+
kind: string,
|
|
1313
|
+
ref: string,
|
|
1314
|
+
value: NonNullable<unknown> | null,
|
|
1315
|
+
): GeneratedTargetResult<string> => {
|
|
1316
|
+
if (typeof value === "string" && value.length > 0) return { ok: true, value };
|
|
1317
|
+
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
1318
|
+
};
|
|
1319
|
+
|
|
1320
|
+
${renderGeneratedLlmRoutesFor(normalized.llmRoutes)}
|
|
1321
|
+
|
|
1322
|
+
const generatedSubmitBindingsFor = async (
|
|
1323
|
+
env: AgentOSTargetEnv,
|
|
1324
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1325
|
+
): Promise<GeneratedTargetResult<AgentSubmitBindings>> => {
|
|
1326
|
+
const preflightDiagnostics = generatedProviderPreflightDiagnosticsFor(env);
|
|
1327
|
+
if (preflightDiagnostics.length > 0) {
|
|
1328
|
+
return targetFailure(
|
|
1329
|
+
"OpenAI-compatible provider material preflight failed",
|
|
1330
|
+
preflightDiagnostics,
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
const routes = generatedLlmRoutesFor(env);
|
|
1334
|
+
if (!routes.ok) return routes;
|
|
1335
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event);
|
|
1336
|
+
if (!dynamicBindings.ok) return dynamicBindings;
|
|
1337
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
1338
|
+
return {
|
|
1339
|
+
ok: true,
|
|
1340
|
+
value: {
|
|
1341
|
+
...dynamicBindings.value,
|
|
1342
|
+
llmRoutes: routes.value,
|
|
1343
|
+
tools: ${hasSkills
|
|
1344
|
+
? `{
|
|
1345
|
+
...generatedCustomTools,
|
|
1346
|
+
...generatedFrameworkToolsFor(dynamicCapabilityProjection),
|
|
1347
|
+
}`
|
|
1348
|
+
: "generatedCustomTools"},
|
|
1349
|
+
},
|
|
1350
|
+
};
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
${renderSubmitSpecFromRunInput(hasSkills)}
|
|
1354
|
+
|
|
1355
|
+
${renderProductApiHelpers()}
|
|
1356
|
+
${hasSchedules ? renderScheduleDurableObjectHelpers() : ""}
|
|
1357
|
+
|
|
1358
|
+
const Base${target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
1359
|
+
manifest: semanticManifest,
|
|
1360
|
+
agentBindings: {
|
|
1361
|
+
handlers: ${handlerRecord},
|
|
1362
|
+
},
|
|
1363
|
+
refResolver: (env) => ({
|
|
1364
|
+
material: (ref) => materialValue(env, ref),
|
|
1365
|
+
}),
|
|
1366
|
+
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
1367
|
+
});
|
|
1368
|
+
|
|
1369
|
+
export class ${target.durableObject.className} extends Base${target.durableObject.className} {
|
|
1370
|
+
private readonly targetEnv: AgentOSTargetEnv;
|
|
1371
|
+
|
|
1372
|
+
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
1373
|
+
super(ctx, env);
|
|
1374
|
+
this.targetEnv = env;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
1378
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1379
|
+
bindings.ok ? this.submitWithBindings(spec, bindings.value) : rejectTargetFailure(bindings),
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
1384
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1385
|
+
bindings.ok
|
|
1386
|
+
? this.submitWithBindings(
|
|
1387
|
+
submitSpecFromRunInput(input, bindings.value.dynamicCapabilityProjection),
|
|
1388
|
+
bindings.value,
|
|
1389
|
+
)
|
|
1390
|
+
: rejectTargetFailure(bindings),
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
${renderProductApiDurableObjectMethods()}
|
|
1395
|
+
${hasSchedules ? renderScheduleDurableObjectMethod() : ""}
|
|
1396
|
+
|
|
1397
|
+
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
1398
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1399
|
+
bindings.ok
|
|
1400
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
1401
|
+
: rejectTargetFailure(bindings),
|
|
1402
|
+
);
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
1406
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1407
|
+
bindings.ok
|
|
1408
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
1409
|
+
: rejectTargetFailure(bindings),
|
|
1410
|
+
);
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
1414
|
+
return Effect.runPromise(
|
|
1415
|
+
unsafeRunToolByName(
|
|
1416
|
+
generatedCustomTools,
|
|
1417
|
+
deterministicToolInvocation(input.method, input.input),
|
|
1418
|
+
),
|
|
1419
|
+
);
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
`;
|
|
1423
|
+
};
|
|
1424
|
+
const renderLocalAgentApp = (normalized, toolNames, modules) => {
|
|
1425
|
+
if (normalized.target.kind !== AGENTOS_CONFIG_TARGET.NODE_V1) {
|
|
1426
|
+
throw new TypeError(`local agent app renderer received ${normalized.target.kind}`);
|
|
1427
|
+
}
|
|
1428
|
+
const hasChannels = normalized.channels.length > 0;
|
|
1429
|
+
const hasSkills = normalized.skills.length > 0;
|
|
1430
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
456
1431
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1432
|
+
const workspaceToolList = toolNames.filter((toolName) => isWorkspaceToolName(toolName) && !authoredToolNames.has(toolName));
|
|
457
1433
|
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
458
1434
|
const toolImports = customToolNames
|
|
459
1435
|
.map((toolName, index) => `import tool_${index} from ${jsString(importToolPath(toolName))};`)
|
|
@@ -463,42 +1439,69 @@ const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
|
463
1439
|
: `{\n${customToolNames
|
|
464
1440
|
.map((toolName, index) => ` ${jsString(toolName)}: tool_${index},`)
|
|
465
1441
|
.join("\n")}\n}`;
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
1442
|
+
const workspaceToolArray = `[${workspaceToolList.map(jsString).join(", ")}] as const`;
|
|
1443
|
+
const usesMutationTools = workspaceToolList.some((toolName) => workspaceMutationToolNames.has(toolName));
|
|
1444
|
+
const usesShellTools = workspaceToolList.some((toolName) => workspaceShellToolNames.has(toolName));
|
|
469
1445
|
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
1446
|
const imports = [
|
|
474
1447
|
`import semanticDeclarations from "./manifest.json";`,
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
1448
|
+
...(hasChannels ? [renderNamedImport(["dispatchGeneratedChannelRequest"], "./channels")] : []),
|
|
1449
|
+
...(hasChannels ? [renderTypeImport(["ChannelRuntime"], modules.runtimeChannel)] : []),
|
|
1450
|
+
...(hasSchedules
|
|
1451
|
+
? [
|
|
1452
|
+
renderNamedImport(["dispatchGeneratedSchedule", "generatedScheduleDefinitions", "generatedScheduleIds"], "./schedules"),
|
|
1453
|
+
]
|
|
1454
|
+
: []),
|
|
1455
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
1456
|
+
renderNamedImport(["lowerLocalAgentRuntime"], modules.localRuntime),
|
|
1457
|
+
renderNamedImport(["runDynamicCapabilityResolvers"], modules.runtimeCapability),
|
|
1458
|
+
...(hasSchedules
|
|
1459
|
+
? [renderNamedImport(["projectScheduleFireHistory"], modules.runtimeSchedule)]
|
|
1460
|
+
: []),
|
|
1461
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
1462
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
1463
|
+
renderNamedImport(["projectAgentSession", "projectAgentSessions", "projectWorkflowRun", "projectWorkflowRuns"], modules.runtimeRunProjector),
|
|
1464
|
+
renderTypeImport(["AgentManifest", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
482
1465
|
renderTypeImport([
|
|
483
|
-
"
|
|
484
|
-
"
|
|
485
|
-
"
|
|
486
|
-
|
|
1466
|
+
"AgentSubmitBindings",
|
|
1467
|
+
"DynamicCapabilityCompiledCatalog",
|
|
1468
|
+
"DynamicCapabilityEventRef",
|
|
1469
|
+
"DynamicCapabilityProjection",
|
|
1470
|
+
"SubmitInstructionFragment",
|
|
1471
|
+
], modules.runtimeProtocol),
|
|
1472
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
1473
|
+
...(hasSchedules
|
|
1474
|
+
? [
|
|
1475
|
+
renderTypeImport([
|
|
1476
|
+
"ScheduleDefinitionProjection",
|
|
1477
|
+
"ScheduleFireHistoryProjection",
|
|
1478
|
+
"ScheduleFireProjection",
|
|
1479
|
+
], modules.runtimeSchedule),
|
|
1480
|
+
]
|
|
1481
|
+
: []),
|
|
1482
|
+
renderTypeImport([
|
|
1483
|
+
"AgentSessionListProjection",
|
|
1484
|
+
"AgentSessionProjection",
|
|
1485
|
+
"WorkflowRunListProjection",
|
|
1486
|
+
"WorkflowRunProjection",
|
|
1487
|
+
], modules.runtimeRunProjector),
|
|
1488
|
+
renderTypeImport(["CreateLocalAgentRuntimeOptions", "LocalAgentRuntime", "LocalAgentSubmitInput"], modules.localRuntime),
|
|
1489
|
+
renderTypeImport(["WorkspaceAgentCustomCommandInput"], modules.workspaceAgentHost),
|
|
1490
|
+
renderNamedImport([
|
|
1491
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
1492
|
+
"deterministicToolInvocation",
|
|
1493
|
+
"unsafeRunToolByName",
|
|
1494
|
+
], modules.coreTools),
|
|
1495
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
487
1496
|
renderTypeImport(["Tool"], modules.coreTools),
|
|
488
1497
|
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
489
1498
|
].join("\n");
|
|
490
1499
|
return `${imports}
|
|
491
1500
|
|
|
492
|
-
export const targetDeclarations = semanticDeclarations;
|
|
493
|
-
export const targetDeployment = deploymentProvenance;
|
|
494
|
-
|
|
495
1501
|
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
496
|
-
const
|
|
1502
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
497
1503
|
|
|
498
|
-
type AgentOSTargetEnv =
|
|
499
|
-
readonly [binding: string]: unknown;
|
|
500
|
-
${generatedLlmEnvFields}
|
|
501
|
-
};
|
|
1504
|
+
type AgentOSTargetEnv = Readonly<Record<string, string | undefined>>;
|
|
502
1505
|
|
|
503
1506
|
type GeneratedTargetFailure = {
|
|
504
1507
|
readonly ok: false;
|
|
@@ -509,12 +1512,33 @@ type GeneratedTargetResult<Value> =
|
|
|
509
1512
|
| { readonly ok: true; readonly value: Value }
|
|
510
1513
|
| GeneratedTargetFailure;
|
|
511
1514
|
|
|
512
|
-
const targetFailure = (message: string): GeneratedTargetFailure => ({
|
|
1515
|
+
const targetFailure = (message: string): GeneratedTargetFailure => ({
|
|
1516
|
+
ok: false,
|
|
1517
|
+
message,
|
|
1518
|
+
});
|
|
513
1519
|
|
|
514
1520
|
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
515
1521
|
Promise.reject(Error(failure.message));
|
|
516
1522
|
|
|
1523
|
+
${renderGeneratedWorkspaceOperations(workspaceToolArray, usesMutationTools, usesShellTools)}
|
|
517
1524
|
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
1525
|
+
${renderDynamicCapabilitySupport(normalized, toolNames, hasSkills)}
|
|
1526
|
+
${renderSkillSupport(normalized.skills)}
|
|
1527
|
+
|
|
1528
|
+
const cleanEnv = (source: AgentOSTargetEnv): Record<string, string> => {
|
|
1529
|
+
const env: Record<string, string> = {};
|
|
1530
|
+
for (const [key, value] of Object.entries(source)) {
|
|
1531
|
+
if (value !== undefined) env[key] = value;
|
|
1532
|
+
}
|
|
1533
|
+
return env;
|
|
1534
|
+
};
|
|
1535
|
+
|
|
1536
|
+
const generatedTargetEnvFor = (
|
|
1537
|
+
options: Pick<CreateLocalAgentAppOptions, "env" | "inheritEnv">,
|
|
1538
|
+
): AgentOSTargetEnv => ({
|
|
1539
|
+
...(options.inheritEnv === true ? cleanEnv(process.env) : {}),
|
|
1540
|
+
...(options.env === undefined ? {} : cleanEnv(options.env)),
|
|
1541
|
+
});
|
|
518
1542
|
|
|
519
1543
|
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
520
1544
|
const value = env[name];
|
|
@@ -537,124 +1561,209 @@ const materialValue = (
|
|
|
537
1561
|
return null;
|
|
538
1562
|
};
|
|
539
1563
|
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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;
|
|
1564
|
+
const generatedLocalLlmFor = (
|
|
1565
|
+
env: AgentOSTargetEnv,
|
|
1566
|
+
): NonNullable<CreateLocalAgentRuntimeOptions["llm"]> => {
|
|
1567
|
+
const modelValue = materialValue(env, { kind: "model", ref: ${jsString(normalized.llm.modelRef)} });
|
|
556
1568
|
return {
|
|
557
|
-
|
|
558
|
-
|
|
1569
|
+
kind: "transport",
|
|
1570
|
+
transport: OpenAiCompatibleLlmTransportLive,
|
|
1571
|
+
route: {
|
|
559
1572
|
kind: "openai-chat-compatible",
|
|
560
1573
|
endpointRef: ${jsString(normalized.llm.endpointRef)},
|
|
561
1574
|
credentialRef: ${jsString(normalized.llm.credentialRef)},
|
|
562
|
-
modelId:
|
|
1575
|
+
modelId: typeof modelValue === "string" ? modelValue : "",
|
|
563
1576
|
},
|
|
1577
|
+
refResolver: {
|
|
1578
|
+
material: (ref) => materialValue(env, ref),
|
|
1579
|
+
},
|
|
1580
|
+
preflight: preflightOpenAiCompatibleProviderMaterial,
|
|
564
1581
|
};
|
|
565
1582
|
};
|
|
566
1583
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
1584
|
+
${renderProductApiHelpers()}
|
|
1585
|
+
|
|
1586
|
+
const generatedLocalSubmitInputFromRunInput = async (
|
|
1587
|
+
input: SubmitRunInput,
|
|
1588
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1589
|
+
): Promise<LocalAgentSubmitInput> => {
|
|
1590
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event);
|
|
1591
|
+
if (!dynamicBindings.ok) return rejectTargetFailure(dynamicBindings);
|
|
1592
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
570
1593
|
return {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
1594
|
+
...input,
|
|
1595
|
+
...(input.context === undefined ? {} : { context: input.context }),
|
|
1596
|
+
...(input.system === undefined && !${hasSkills} ? {} : {
|
|
1597
|
+
system: ${hasSkills ? "generatedSystemPrompt(input.system, dynamicCapabilityProjection)" : "input.system"},
|
|
1598
|
+
}),
|
|
1599
|
+
dynamicCapabilityProjection,
|
|
1600
|
+
instructionFragments: dynamicBindings.value.instructionFragments,
|
|
1601
|
+
tools: ${hasSkills
|
|
1602
|
+
? `{
|
|
1603
|
+
...generatedCustomTools,
|
|
1604
|
+
...generatedFrameworkToolsFor(dynamicCapabilityProjection),
|
|
1605
|
+
}`
|
|
1606
|
+
: "generatedCustomTools"},
|
|
578
1607
|
};
|
|
579
1608
|
};
|
|
580
1609
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
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
|
-
}
|
|
1610
|
+
export interface LocalAgentApp {
|
|
1611
|
+
readonly runtime: LocalAgentRuntime;
|
|
1612
|
+
readonly sessions: {
|
|
1613
|
+
readonly submitTurn: (input: AgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
1614
|
+
readonly inspect: (sessionRef: string) => AgentSessionProjection;
|
|
1615
|
+
readonly list: () => AgentSessionListProjection;
|
|
1616
|
+
};
|
|
1617
|
+
readonly workflows: {
|
|
1618
|
+
readonly run: (input: AgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
1619
|
+
readonly inspectRun: (
|
|
1620
|
+
workflowId: string,
|
|
1621
|
+
workflowRunId: string,
|
|
1622
|
+
) => WorkflowRunProjection | null;
|
|
1623
|
+
readonly listRuns: (workflowId: string) => WorkflowRunListProjection;
|
|
1624
|
+
};
|
|
1625
|
+
${hasChannels
|
|
1626
|
+
? `readonly channels: {
|
|
1627
|
+
readonly handle: (request: Request) => Promise<Response | null>;
|
|
1628
|
+
};`
|
|
1629
|
+
: ""}
|
|
1630
|
+
readonly customCommand: (input: WorkspaceAgentCustomCommandInput) => Promise<unknown>;
|
|
1631
|
+
${hasSchedules
|
|
1632
|
+
? `readonly schedules: {
|
|
1633
|
+
readonly ids: ReadonlyArray<string>;
|
|
1634
|
+
readonly list: () => ReadonlyArray<ScheduleDefinitionProjection>;
|
|
1635
|
+
readonly trigger: (input: GeneratedScheduleTriggerInput) => Promise<ScheduleFireProjection>;
|
|
1636
|
+
readonly history: (input?: { readonly scheduleId?: string }) => ScheduleFireHistoryProjection;
|
|
1637
|
+
};`
|
|
1638
|
+
: ""}
|
|
1639
|
+
}
|
|
635
1640
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
1641
|
+
${hasChannels
|
|
1642
|
+
? `export const handleLocalAgentChannelRequest = (
|
|
1643
|
+
request: Request,
|
|
1644
|
+
runtime: ChannelRuntime,
|
|
1645
|
+
): Promise<Response | null> => dispatchGeneratedChannelRequest(request, runtime);`
|
|
1646
|
+
: ""}
|
|
1647
|
+
|
|
1648
|
+
export interface CreateLocalAgentAppOptions {
|
|
1649
|
+
readonly cwd?: string;
|
|
1650
|
+
readonly env?: CreateLocalAgentRuntimeOptions["env"];
|
|
1651
|
+
readonly inheritEnv?: CreateLocalAgentRuntimeOptions["inheritEnv"];
|
|
1652
|
+
readonly llm?: CreateLocalAgentRuntimeOptions["llm"];
|
|
1653
|
+
}
|
|
642
1654
|
|
|
643
|
-
|
|
644
|
-
|
|
1655
|
+
export const createLocalAgentApp = async (
|
|
1656
|
+
options: CreateLocalAgentAppOptions = {},
|
|
1657
|
+
): Promise<LocalAgentApp> => {
|
|
1658
|
+
const targetEnv = generatedTargetEnvFor(options);
|
|
1659
|
+
const lowered = await lowerLocalAgentRuntime({
|
|
1660
|
+
target: "node@1",
|
|
1661
|
+
identity: semanticManifest.agentId,
|
|
1662
|
+
truthIdentity: semanticTruthIdentity,
|
|
1663
|
+
cwd: options.cwd ?? process.cwd(),
|
|
1664
|
+
...(options.env === undefined ? {} : { env: options.env }),
|
|
1665
|
+
...(options.inheritEnv === undefined ? {} : { inheritEnv: options.inheritEnv }),
|
|
1666
|
+
llm: options.llm ?? generatedLocalLlmFor(targetEnv),
|
|
1667
|
+
workspaceOperations: generatedWorkspaceOperations,
|
|
1668
|
+
});
|
|
1669
|
+
const sessions = {
|
|
1670
|
+
submitTurn: (input: AgentSessionSubmitTurnInput) =>
|
|
1671
|
+
generatedLocalSubmitInputFromRunInput(
|
|
1672
|
+
submitRunInputFromSessionTurn(input),
|
|
1673
|
+
generatedDynamicCapabilityTurnEvent({
|
|
1674
|
+
sessionRef: input.sessionRef,
|
|
1675
|
+
turnRef: input.turnRef,
|
|
1676
|
+
}),
|
|
1677
|
+
).then((submitInput) =>
|
|
1678
|
+
lowered.submitWithProductLink(submitInput, {
|
|
1679
|
+
kind: "session_turn",
|
|
1680
|
+
sessionRef: input.sessionRef,
|
|
1681
|
+
turnRef: input.turnRef,
|
|
1682
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
1683
|
+
}),
|
|
1684
|
+
),
|
|
1685
|
+
inspect: (sessionRef: string) => projectAgentSession(lowered.runtime.events(), sessionRef),
|
|
1686
|
+
list: () => projectAgentSessions(lowered.runtime.events()),
|
|
1687
|
+
};
|
|
1688
|
+
const workflows = {
|
|
1689
|
+
run: (input: AgentWorkflowRunInput) =>
|
|
1690
|
+
generatedLocalSubmitInputFromRunInput(submitRunInputFromWorkflowRun(input)).then(
|
|
1691
|
+
(submitInput) =>
|
|
1692
|
+
lowered.submitWithProductLink(submitInput, {
|
|
1693
|
+
kind: "workflow_run",
|
|
1694
|
+
workflowId: input.workflowId,
|
|
1695
|
+
workflowRunId: input.workflowRunId,
|
|
1696
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
1697
|
+
...(input.inputDigest === undefined ? {} : { inputDigest: input.inputDigest }),
|
|
1698
|
+
}),
|
|
1699
|
+
),
|
|
1700
|
+
inspectRun: (workflowId: string, workflowRunId: string) =>
|
|
1701
|
+
projectWorkflowRun(lowered.runtime.events(), workflowId, workflowRunId),
|
|
1702
|
+
listRuns: (workflowId: string) => projectWorkflowRuns(lowered.runtime.events(), workflowId),
|
|
1703
|
+
};
|
|
1704
|
+
${hasChannels
|
|
1705
|
+
? `const channelRuntime: ChannelRuntime = {
|
|
1706
|
+
submit: (input) => lowered.runtime.submit(input),
|
|
1707
|
+
dispatch: async () => {
|
|
1708
|
+
throw new Error("local node channel dispatch is unavailable");
|
|
1709
|
+
},
|
|
1710
|
+
};
|
|
1711
|
+
const channels = {
|
|
1712
|
+
handle: (request: Request) => handleLocalAgentChannelRequest(request, channelRuntime),
|
|
1713
|
+
};`
|
|
1714
|
+
: ""}
|
|
1715
|
+
const customCommand = (input: WorkspaceAgentCustomCommandInput): Promise<unknown> =>
|
|
1716
|
+
Effect.runPromise(
|
|
645
1717
|
unsafeRunToolByName(
|
|
646
1718
|
generatedCustomTools,
|
|
647
1719
|
deterministicToolInvocation(input.method, input.input),
|
|
648
1720
|
),
|
|
649
1721
|
);
|
|
650
|
-
|
|
651
|
-
|
|
1722
|
+
${hasSchedules
|
|
1723
|
+
? `const scheduleHistory = (
|
|
1724
|
+
input: { readonly scheduleId?: string } = {},
|
|
1725
|
+
): ScheduleFireHistoryProjection => projectScheduleFireHistory(lowered.runtime.events(), input);
|
|
1726
|
+
const triggerSchedule = async (
|
|
1727
|
+
input: GeneratedScheduleTriggerInput,
|
|
1728
|
+
): Promise<ScheduleFireProjection> => {
|
|
1729
|
+
const result = await dispatchGeneratedSchedule({
|
|
1730
|
+
...input,
|
|
1731
|
+
identity: semanticTruthIdentity,
|
|
1732
|
+
runtime: { sessions, workflows },
|
|
1733
|
+
});
|
|
1734
|
+
await lowered.commitScheduleFireDispatch(result);
|
|
1735
|
+
const projected = scheduleHistory({ scheduleId: input.scheduleId }).fires.find(
|
|
1736
|
+
(fire) => fire.fireId === result.fireId,
|
|
1737
|
+
);
|
|
1738
|
+
if (projected === undefined) {
|
|
1739
|
+
throw new Error(\`schedule fire projection missing after commit: \${result.fireId}\`);
|
|
1740
|
+
}
|
|
1741
|
+
return projected;
|
|
1742
|
+
};`
|
|
1743
|
+
: ""}
|
|
1744
|
+
return {
|
|
1745
|
+
runtime: lowered.runtime,
|
|
1746
|
+
sessions,
|
|
1747
|
+
workflows,
|
|
1748
|
+
${hasChannels ? "channels,\n " : ""}customCommand,
|
|
1749
|
+
${hasSchedules
|
|
1750
|
+
? `schedules: {
|
|
1751
|
+
ids: generatedScheduleIds,
|
|
1752
|
+
list: () => generatedScheduleDefinitions,
|
|
1753
|
+
trigger: triggerSchedule,
|
|
1754
|
+
history: scheduleHistory,
|
|
1755
|
+
},`
|
|
1756
|
+
: ""}
|
|
1757
|
+
};
|
|
1758
|
+
};
|
|
652
1759
|
`;
|
|
653
1760
|
};
|
|
654
1761
|
const renderStaticTarget = (normalized, toolNames, modules) => normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
655
1762
|
? renderWorkspaceStaticTarget(normalized, toolNames, modules)
|
|
656
1763
|
: renderChatStaticTarget(normalized, toolNames, modules);
|
|
657
|
-
const renderCloudflareScopeHelper = (normalized, modules) =>
|
|
1764
|
+
const renderCloudflareScopeHelper = (normalized, modules) => {
|
|
1765
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1766
|
+
return `${renderNamedImport(["durableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
658
1767
|
${renderNamedImport(["manifestTruthIdentity"], modules.runtimeProtocol)}
|
|
659
1768
|
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
660
1769
|
${renderTypeImport(["DurableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
@@ -667,7 +1776,7 @@ export type AgentOSTargetEnv = {
|
|
|
667
1776
|
|
|
668
1777
|
export const agentOSTruthIdentity = manifestTruthIdentity(manifest as AgentManifest);
|
|
669
1778
|
export const agentOSScopeId = agentOSTruthIdentity.scopeRef.scopeId;
|
|
670
|
-
export const agentOSDurableObjectBinding = ${jsString(
|
|
1779
|
+
export const agentOSDurableObjectBinding = ${jsString(target.durableObject.binding)};
|
|
671
1780
|
|
|
672
1781
|
export const agentOSDurableObjectNamespace = (
|
|
673
1782
|
env: AgentOSTargetEnv,
|
|
@@ -681,18 +1790,79 @@ export const agentOSRpcClient = <
|
|
|
681
1790
|
scopeId: string = agentOSScopeId,
|
|
682
1791
|
): DurableObjectRpcClient<Rpc> => durableObjectRpcClient<Rpc>(agentOSDurableObjectNamespace(env), scopeId);
|
|
683
1792
|
`;
|
|
684
|
-
|
|
685
|
-
|
|
1793
|
+
};
|
|
1794
|
+
const renderCloudflareWorkerEntry = (normalized, modules) => {
|
|
1795
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1796
|
+
const hasChannels = normalized.channels.length > 0;
|
|
1797
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
1798
|
+
const cloudflareScopeImports = [
|
|
1799
|
+
...(hasChannels || hasSchedules ? ["agentOSRpcClient"] : []),
|
|
1800
|
+
...(hasSchedules ? ["agentOSScopeId"] : []),
|
|
1801
|
+
];
|
|
1802
|
+
return `${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? `${renderNamedImport(["Sandbox"], modules.cloudflareSandbox)}\n` : ""}${renderNamedImport([target.durableObject.className], "./target")}
|
|
1803
|
+
${hasChannels ? `${renderNamedImport(["dispatchGeneratedChannelRequest"], "./channels")}\n${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}\n${renderTypeImport(["ChannelRuntime"], modules.runtimeChannel)}\n` : ""}${hasSchedules ? `${renderNamedImport(["generatedSchedules"], "./schedules")}\n${renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")}\n` : ""}${cloudflareScopeImports.length === 0 ? "" : `${renderNamedImport(cloudflareScopeImports, "./cloudflare-scope")}\n`}${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
1804
|
+
|
|
1805
|
+
export { ${target.durableObject.className}${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? ", Sandbox" : ""} };
|
|
1806
|
+
|
|
1807
|
+
${hasChannels
|
|
1808
|
+
? `type AgentOSChannelRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
1809
|
+
readonly submitRunInput: ChannelRuntime["submit"];
|
|
1810
|
+
readonly dispatchToScope: ChannelRuntime["dispatch"];
|
|
1811
|
+
};
|
|
1812
|
+
|
|
1813
|
+
const generatedChannelRuntimeFor = (env: AgentOSTargetEnv): ChannelRuntime => {
|
|
1814
|
+
const runtime = agentOSRpcClient<AgentOSChannelRpc>(env);
|
|
1815
|
+
return Object.freeze({
|
|
1816
|
+
submit: (input) => runtime.submitRunInput(input),
|
|
1817
|
+
dispatch: (spec) => runtime.dispatchToScope(spec),
|
|
1818
|
+
});
|
|
1819
|
+
};
|
|
1820
|
+
`
|
|
1821
|
+
: ""}
|
|
1822
|
+
${hasSchedules
|
|
1823
|
+
? `type AgentOSScheduleRpc = {
|
|
1824
|
+
readonly dispatchSchedule: (input: GeneratedScheduleTriggerInput) => Promise<unknown>;
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
const generatedScheduleAppPrincipal: GeneratedScheduleTriggerInput["appPrincipal"] = {
|
|
1828
|
+
authority: "agentos.app",
|
|
1829
|
+
subject: agentOSScopeId,
|
|
1830
|
+
};
|
|
686
1831
|
|
|
687
|
-
|
|
1832
|
+
const generatedScheduleInputsFor = (
|
|
1833
|
+
controller: ScheduledController,
|
|
1834
|
+
): ReadonlyArray<GeneratedScheduleTriggerInput> =>
|
|
1835
|
+
generatedSchedules
|
|
1836
|
+
.filter((entry) => entry.cron === controller.cron)
|
|
1837
|
+
.map((entry) => ({
|
|
1838
|
+
scheduleId: entry.scheduleId,
|
|
1839
|
+
scheduledAt: controller.scheduledTime,
|
|
1840
|
+
appPrincipal: generatedScheduleAppPrincipal,
|
|
1841
|
+
}));
|
|
1842
|
+
`
|
|
1843
|
+
: ""}
|
|
688
1844
|
|
|
689
1845
|
export default {
|
|
690
|
-
fetch(): Response {
|
|
1846
|
+
async fetch(request: Request, env: AgentOSTargetEnv): Promise<Response> {
|
|
1847
|
+
${hasChannels
|
|
1848
|
+
? `const channelResponse = await dispatchGeneratedChannelRequest(request, generatedChannelRuntimeFor(env));
|
|
1849
|
+
if (channelResponse !== null) return channelResponse;`
|
|
1850
|
+
: ""}
|
|
691
1851
|
return new Response("agentOS Cloudflare target", { status: 404 });
|
|
692
1852
|
},
|
|
1853
|
+
${hasSchedules
|
|
1854
|
+
? `scheduled(controller: ScheduledController, env: AgentOSTargetEnv, ctx: ExecutionContext): void {
|
|
1855
|
+
const runtime = agentOSRpcClient<AgentOSScheduleRpc>(env);
|
|
1856
|
+
for (const input of generatedScheduleInputsFor(controller)) {
|
|
1857
|
+
ctx.waitUntil(runtime.dispatchSchedule(input));
|
|
1858
|
+
}
|
|
1859
|
+
},`
|
|
1860
|
+
: ""}
|
|
693
1861
|
} satisfies ExportedHandler<AgentOSTargetEnv>;
|
|
694
1862
|
`;
|
|
1863
|
+
};
|
|
695
1864
|
const renderCloudflareWranglerConfig = (normalized) => {
|
|
1865
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
696
1866
|
const workspaceConfig = normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
697
1867
|
? {
|
|
698
1868
|
vars: {
|
|
@@ -713,15 +1883,15 @@ const renderCloudflareWranglerConfig = (normalized) => {
|
|
|
713
1883
|
name: normalized.workspace.binding,
|
|
714
1884
|
},
|
|
715
1885
|
{
|
|
716
|
-
class_name:
|
|
717
|
-
name:
|
|
1886
|
+
class_name: target.durableObject.className,
|
|
1887
|
+
name: target.durableObject.binding,
|
|
718
1888
|
},
|
|
719
1889
|
],
|
|
720
1890
|
},
|
|
721
1891
|
migrations: [
|
|
722
1892
|
{
|
|
723
1893
|
tag: "v1",
|
|
724
|
-
new_sqlite_classes: ["Sandbox",
|
|
1894
|
+
new_sqlite_classes: ["Sandbox", target.durableObject.className],
|
|
725
1895
|
},
|
|
726
1896
|
],
|
|
727
1897
|
}
|
|
@@ -729,15 +1899,15 @@ const renderCloudflareWranglerConfig = (normalized) => {
|
|
|
729
1899
|
durable_objects: {
|
|
730
1900
|
bindings: [
|
|
731
1901
|
{
|
|
732
|
-
class_name:
|
|
733
|
-
name:
|
|
1902
|
+
class_name: target.durableObject.className,
|
|
1903
|
+
name: target.durableObject.binding,
|
|
734
1904
|
},
|
|
735
1905
|
],
|
|
736
1906
|
},
|
|
737
1907
|
migrations: [
|
|
738
1908
|
{
|
|
739
1909
|
tag: "v1",
|
|
740
|
-
new_sqlite_classes: [
|
|
1910
|
+
new_sqlite_classes: [target.durableObject.className],
|
|
741
1911
|
},
|
|
742
1912
|
],
|
|
743
1913
|
};
|
|
@@ -759,6 +1929,11 @@ const generatedClientModuleImports = (normalized, modules) => [
|
|
|
759
1929
|
"createWorkspaceAgentClientBridge",
|
|
760
1930
|
"CreateWorkspaceAgentClientOptions",
|
|
761
1931
|
"WorkspaceAgentClientBridge",
|
|
1932
|
+
"WorkspaceAgentProductClient",
|
|
1933
|
+
"WorkspaceAgentProductCommandMap",
|
|
1934
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
1935
|
+
"WorkspaceAgentProductCommandOutputByName",
|
|
1936
|
+
"WORKSPACE_AGENT_PRODUCT_COMMAND",
|
|
762
1937
|
]
|
|
763
1938
|
: [
|
|
764
1939
|
"WORKSPACE_AGENT_COMMAND",
|
|
@@ -807,11 +1982,18 @@ const renderWorkspaceSvelteKitRemote = (normalized, modules) => `${renderNamedIm
|
|
|
807
1982
|
${renderNamedImport(["decodeSseHttpEvents", "responseToSseHttpChunks"], modules.sseHttp)}
|
|
808
1983
|
${renderNamedImport(["Result", "Schema"], modules.effect)}
|
|
809
1984
|
${renderNamedImport(["WORKSPACE_AGENT_COMMAND"], modules.workspaceAgentHost)}
|
|
1985
|
+
${renderNamedImport(["WORKSPACE_AGENT_PRODUCT_COMMAND"], modules.workspaceAgentClient)}
|
|
810
1986
|
${renderNamedImport(["decodeRuntimeLedgerEvent", "isInputRequestRef", "parseInputRequestResumePayload"], modules.runtimeProtocol)}
|
|
811
1987
|
${renderNamedImport(["agentOSRpcClient", "agentOSTruthIdentity"], "./cloudflare-scope")}
|
|
812
1988
|
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
813
1989
|
${renderTypeImport(["SseHttpEvent"], modules.sseHttp)}
|
|
814
1990
|
${renderTypeImport(["RuntimeLedgerEvent", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol)}
|
|
1991
|
+
${renderTypeImport([
|
|
1992
|
+
"AgentSessionListProjection",
|
|
1993
|
+
"AgentSessionProjection",
|
|
1994
|
+
"WorkflowRunListProjection",
|
|
1995
|
+
"WorkflowRunProjection",
|
|
1996
|
+
], modules.runtimeRunProjector)}
|
|
815
1997
|
${renderTypeImport([
|
|
816
1998
|
"WorkspaceAgentCustomCommandInput",
|
|
817
1999
|
"WorkspaceAgentDestroyCommandInput",
|
|
@@ -822,10 +2004,28 @@ ${renderTypeImport([
|
|
|
822
2004
|
"WorkspaceAgentReadStateCommandInput",
|
|
823
2005
|
"WorkspaceAgentResetCommandInput",
|
|
824
2006
|
], modules.workspaceAgentHost)}
|
|
2007
|
+
${renderTypeImport([
|
|
2008
|
+
"WorkspaceAgentSessionSubmitTurnInput",
|
|
2009
|
+
"WorkspaceAgentWorkflowRunInput",
|
|
2010
|
+
"WorkspaceAgentWorkflowRunRef",
|
|
2011
|
+
"WorkspaceAgentWorkflowRunsInput",
|
|
2012
|
+
], modules.workspaceAgentClient)}
|
|
825
2013
|
${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
826
2014
|
|
|
827
2015
|
type AgentOSRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
828
2016
|
readonly submitRunInput: (input: SubmitRunInput) => Promise<SubmitResult>;
|
|
2017
|
+
readonly submitSessionTurn: (input: WorkspaceAgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
2018
|
+
readonly inspectSession: (
|
|
2019
|
+
input: { readonly sessionRef: string },
|
|
2020
|
+
) => Promise<AgentSessionProjection>;
|
|
2021
|
+
readonly listSessions: () => Promise<AgentSessionListProjection>;
|
|
2022
|
+
readonly runWorkflow: (input: WorkspaceAgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
2023
|
+
readonly inspectWorkflowRun: (
|
|
2024
|
+
input: WorkspaceAgentWorkflowRunRef,
|
|
2025
|
+
) => Promise<WorkflowRunProjection | null>;
|
|
2026
|
+
readonly listWorkflowRuns: (
|
|
2027
|
+
input: WorkspaceAgentWorkflowRunsInput,
|
|
2028
|
+
) => Promise<WorkflowRunListProjection>;
|
|
829
2029
|
readonly resumeInputRequest: (
|
|
830
2030
|
input: WorkspaceAgentResumeInputRequestCommandInput,
|
|
831
2031
|
) => Promise<SubmitResult>;
|
|
@@ -908,6 +2108,78 @@ const submitInputFromUnknown = (
|
|
|
908
2108
|
return { ok: true, value: { input: value.input as unknown as AgentOSSubmitRunInput } };
|
|
909
2109
|
};
|
|
910
2110
|
|
|
2111
|
+
const productSubmitInputFromUnknown = (
|
|
2112
|
+
value: unknown,
|
|
2113
|
+
label: string,
|
|
2114
|
+
): GeneratedResult<AgentOSSubmitRunInput> => {
|
|
2115
|
+
if (!isRecord(value)) return fail(400, \`invalid \${label} command input\`);
|
|
2116
|
+
if (typeof value.intent !== "string" || !isRecord(value.context)) {
|
|
2117
|
+
return fail(400, \`invalid \${label} submit run input\`);
|
|
2118
|
+
}
|
|
2119
|
+
return { ok: true, value: value as unknown as AgentOSSubmitRunInput };
|
|
2120
|
+
};
|
|
2121
|
+
|
|
2122
|
+
const sessionTurnInputFromUnknown = (
|
|
2123
|
+
value: unknown,
|
|
2124
|
+
): GeneratedResult<WorkspaceAgentSessionSubmitTurnInput> => {
|
|
2125
|
+
const submitInput = productSubmitInputFromUnknown(value, "submitSessionTurn");
|
|
2126
|
+
if (!submitInput.ok) return submitInput;
|
|
2127
|
+
if (!isRecord(value)) return fail(400, "invalid submitSessionTurn command input");
|
|
2128
|
+
if (typeof value.sessionRef !== "string" || typeof value.turnRef !== "string") {
|
|
2129
|
+
return fail(400, "invalid session turn identity");
|
|
2130
|
+
}
|
|
2131
|
+
return { ok: true, value: value as unknown as WorkspaceAgentSessionSubmitTurnInput };
|
|
2132
|
+
};
|
|
2133
|
+
|
|
2134
|
+
const sessionInspectInputFromUnknown = (
|
|
2135
|
+
value: unknown,
|
|
2136
|
+
): GeneratedResult<{ readonly sessionRef: string }> => {
|
|
2137
|
+
if (!isRecord(value) || typeof value.sessionRef !== "string") {
|
|
2138
|
+
return fail(400, "invalid inspectSession command input");
|
|
2139
|
+
}
|
|
2140
|
+
return { ok: true, value: { sessionRef: value.sessionRef } };
|
|
2141
|
+
};
|
|
2142
|
+
|
|
2143
|
+
const workflowRunInputFromUnknown = (
|
|
2144
|
+
value: unknown,
|
|
2145
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunInput> => {
|
|
2146
|
+
const submitInput = productSubmitInputFromUnknown(value, "runWorkflow");
|
|
2147
|
+
if (!submitInput.ok) return submitInput;
|
|
2148
|
+
if (!isRecord(value)) return fail(400, "invalid runWorkflow command input");
|
|
2149
|
+
if (typeof value.workflowId !== "string" || typeof value.workflowRunId !== "string") {
|
|
2150
|
+
return fail(400, "invalid workflow run identity");
|
|
2151
|
+
}
|
|
2152
|
+
if (value.idempotencyKey !== undefined && typeof value.idempotencyKey !== "string") {
|
|
2153
|
+
return fail(400, "invalid workflow run idempotencyKey");
|
|
2154
|
+
}
|
|
2155
|
+
if (value.inputDigest !== undefined && typeof value.inputDigest !== "string") {
|
|
2156
|
+
return fail(400, "invalid workflow run inputDigest");
|
|
2157
|
+
}
|
|
2158
|
+
return { ok: true, value: value as unknown as WorkspaceAgentWorkflowRunInput };
|
|
2159
|
+
};
|
|
2160
|
+
|
|
2161
|
+
const workflowRunRefFromUnknown = (
|
|
2162
|
+
value: unknown,
|
|
2163
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunRef> => {
|
|
2164
|
+
if (!isRecord(value)) return fail(400, "invalid inspectWorkflowRun command input");
|
|
2165
|
+
if (typeof value.workflowId !== "string" || typeof value.workflowRunId !== "string") {
|
|
2166
|
+
return fail(400, "invalid workflow run identity");
|
|
2167
|
+
}
|
|
2168
|
+
return {
|
|
2169
|
+
ok: true,
|
|
2170
|
+
value: { workflowId: value.workflowId, workflowRunId: value.workflowRunId },
|
|
2171
|
+
};
|
|
2172
|
+
};
|
|
2173
|
+
|
|
2174
|
+
const workflowRunsInputFromUnknown = (
|
|
2175
|
+
value: unknown,
|
|
2176
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunsInput> => {
|
|
2177
|
+
if (!isRecord(value) || typeof value.workflowId !== "string") {
|
|
2178
|
+
return fail(400, "invalid listWorkflowRuns command input");
|
|
2179
|
+
}
|
|
2180
|
+
return { ok: true, value: { workflowId: value.workflowId } };
|
|
2181
|
+
};
|
|
2182
|
+
|
|
911
2183
|
const resumeInputRequestFromUnknown = (
|
|
912
2184
|
value: unknown,
|
|
913
2185
|
): GeneratedResult<WorkspaceAgentResumeInputRequestCommandInput> => {
|
|
@@ -1142,6 +2414,33 @@ export const invokeAgentCommand = command(commandInput, ({ name, input }): Promi
|
|
|
1142
2414
|
? runtime.submitRunInput(submitInput.value.input)
|
|
1143
2415
|
: rejectFailure(submitInput);
|
|
1144
2416
|
}
|
|
2417
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.SUBMIT_SESSION_TURN) {
|
|
2418
|
+
const sessionInput = sessionTurnInputFromUnknown(input);
|
|
2419
|
+
return sessionInput.ok ? runtime.submitSessionTurn(sessionInput.value) : rejectFailure(sessionInput);
|
|
2420
|
+
}
|
|
2421
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.INSPECT_SESSION) {
|
|
2422
|
+
const sessionInput = sessionInspectInputFromUnknown(input);
|
|
2423
|
+
return sessionInput.ok ? runtime.inspectSession(sessionInput.value) : rejectFailure(sessionInput);
|
|
2424
|
+
}
|
|
2425
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.LIST_SESSIONS) {
|
|
2426
|
+
return runtime.listSessions();
|
|
2427
|
+
}
|
|
2428
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.RUN_WORKFLOW) {
|
|
2429
|
+
const workflowInput = workflowRunInputFromUnknown(input);
|
|
2430
|
+
return workflowInput.ok ? runtime.runWorkflow(workflowInput.value) : rejectFailure(workflowInput);
|
|
2431
|
+
}
|
|
2432
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.INSPECT_WORKFLOW_RUN) {
|
|
2433
|
+
const workflowInput = workflowRunRefFromUnknown(input);
|
|
2434
|
+
return workflowInput.ok
|
|
2435
|
+
? runtime.inspectWorkflowRun(workflowInput.value)
|
|
2436
|
+
: rejectFailure(workflowInput);
|
|
2437
|
+
}
|
|
2438
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.LIST_WORKFLOW_RUNS) {
|
|
2439
|
+
const workflowInput = workflowRunsInputFromUnknown(input);
|
|
2440
|
+
return workflowInput.ok
|
|
2441
|
+
? runtime.listWorkflowRuns(workflowInput.value)
|
|
2442
|
+
: rejectFailure(workflowInput);
|
|
2443
|
+
}
|
|
1145
2444
|
if (name === WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST) {
|
|
1146
2445
|
const resumeInput = resumeInputRequestFromUnknown(input);
|
|
1147
2446
|
return resumeInput.ok
|
|
@@ -1500,10 +2799,29 @@ const renderSvelteKitRemote = (normalized, modules) => normalized.profile === AG
|
|
|
1500
2799
|
const renderWorkspaceStaticClient = (normalized, modules) => {
|
|
1501
2800
|
if (normalized.client.kind === AGENTOS_CONFIG_CLIENT.BROWSER_DIRECT_V1) {
|
|
1502
2801
|
return `${renderNamedImport(["createWorkspaceAgentClientBridge"], modules.workspaceAgentClient)}
|
|
1503
|
-
${renderTypeImport([
|
|
2802
|
+
${renderTypeImport([
|
|
2803
|
+
"AgentSessionListProjection",
|
|
2804
|
+
"AgentSessionProjection",
|
|
2805
|
+
"WorkflowRunListProjection",
|
|
2806
|
+
"WorkflowRunProjection",
|
|
2807
|
+
], modules.runtimeRunProjector)}
|
|
2808
|
+
${renderTypeImport([
|
|
2809
|
+
"CreateWorkspaceAgentClientOptions",
|
|
2810
|
+
"WorkspaceAgentClientBridge",
|
|
2811
|
+
"WorkspaceAgentProductCommandMap",
|
|
2812
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
2813
|
+
], modules.workspaceAgentClient)}
|
|
2814
|
+
|
|
2815
|
+
export interface GeneratedAgentClientProductProjections extends WorkspaceAgentProductProjectionTypes {
|
|
2816
|
+
readonly session: AgentSessionProjection;
|
|
2817
|
+
readonly sessionList: AgentSessionListProjection;
|
|
2818
|
+
readonly workflowRun: WorkflowRunProjection;
|
|
2819
|
+
readonly workflowRunList: WorkflowRunListProjection;
|
|
2820
|
+
}
|
|
1504
2821
|
|
|
1505
|
-
export type GeneratedAgentClientOptions =
|
|
1506
|
-
|
|
2822
|
+
export type GeneratedAgentClientOptions =
|
|
2823
|
+
CreateWorkspaceAgentClientOptions<WorkspaceAgentProductCommandMap<GeneratedAgentClientProductProjections>>;
|
|
2824
|
+
export type GeneratedAgentClient = WorkspaceAgentClientBridge<GeneratedAgentClientProductProjections>;
|
|
1507
2825
|
|
|
1508
2826
|
export const createAgentOSClient = (
|
|
1509
2827
|
options: GeneratedAgentClientOptions = {},
|
|
@@ -1514,17 +2832,33 @@ export const createAgentOSClient = (
|
|
|
1514
2832
|
import { invokeAgentCommand, runEventStream } from "./sveltekit.remote";
|
|
1515
2833
|
${renderNamedImport(["clientReadable", "selectClientReadable"], modules.clientSvelte)}
|
|
1516
2834
|
${renderTypeImport(["AgentClientSnapshot"], modules.clientCore)}
|
|
2835
|
+
${renderTypeImport([
|
|
2836
|
+
"AgentSessionListProjection",
|
|
2837
|
+
"AgentSessionProjection",
|
|
2838
|
+
"WorkflowRunListProjection",
|
|
2839
|
+
"WorkflowRunProjection",
|
|
2840
|
+
], modules.runtimeRunProjector)}
|
|
1517
2841
|
${renderTypeImport([
|
|
1518
2842
|
"CreateWorkspaceAgentClientOptions",
|
|
1519
|
-
"WorkspaceAgentClient",
|
|
1520
2843
|
"WorkspaceAgentClientBridge",
|
|
1521
|
-
"
|
|
2844
|
+
"WorkspaceAgentProductClient",
|
|
2845
|
+
"WorkspaceAgentProductCommandMap",
|
|
2846
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
1522
2847
|
], modules.workspaceAgentClient)}
|
|
1523
2848
|
${renderTypeImport(["Readable"], modules.svelteStore)}
|
|
1524
2849
|
|
|
1525
|
-
export
|
|
2850
|
+
export interface GeneratedAgentClientProductProjections extends WorkspaceAgentProductProjectionTypes {
|
|
2851
|
+
readonly session: AgentSessionProjection;
|
|
2852
|
+
readonly sessionList: AgentSessionListProjection;
|
|
2853
|
+
readonly workflowRun: WorkflowRunProjection;
|
|
2854
|
+
readonly workflowRunList: WorkflowRunListProjection;
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
export type GeneratedAgentClientOptions =
|
|
2858
|
+
CreateWorkspaceAgentClientOptions<WorkspaceAgentProductCommandMap<GeneratedAgentClientProductProjections>>;
|
|
1526
2859
|
|
|
1527
|
-
export interface GeneratedAgentClient
|
|
2860
|
+
export interface GeneratedAgentClient
|
|
2861
|
+
extends WorkspaceAgentClientBridge<GeneratedAgentClientProductProjections> {
|
|
1528
2862
|
readonly snapshot: Readable<AgentClientSnapshot>;
|
|
1529
2863
|
readonly events: Readable<AgentClientSnapshot["events"]>;
|
|
1530
2864
|
readonly connection: Readable<AgentClientSnapshot["connection"]>;
|
|
@@ -1539,8 +2873,10 @@ const generatedStreamSource: NonNullable<GeneratedAgentClientOptions["streamSour
|
|
|
1539
2873
|
}),
|
|
1540
2874
|
};
|
|
1541
2875
|
|
|
1542
|
-
const generatedRpcInvoker
|
|
1543
|
-
invokeAgentCommand({ name, input }) as
|
|
2876
|
+
const generatedRpcInvoker = ((name, input) =>
|
|
2877
|
+
invokeAgentCommand({ name, input })) as WorkspaceAgentProductClient<
|
|
2878
|
+
GeneratedAgentClientProductProjections
|
|
2879
|
+
>["invoke"];
|
|
1544
2880
|
|
|
1545
2881
|
export const createAgentOSClient = (
|
|
1546
2882
|
options: GeneratedAgentClientOptions = {},
|
|
@@ -1696,12 +3032,6 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1696
3032
|
};
|
|
1697
3033
|
}
|
|
1698
3034
|
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
3035
|
if (normalized.llm.route !== AGENTOS_CONFIG_LLM_ROUTE.OPENAI_CHAT_COMPATIBLE) {
|
|
1706
3036
|
return {
|
|
1707
3037
|
ok: false,
|
|
@@ -1709,6 +3039,138 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1709
3039
|
};
|
|
1710
3040
|
}
|
|
1711
3041
|
const toolNames = Object.keys(normalized.deployment.manifest.tools ?? {}).sort();
|
|
3042
|
+
const hasChannels = normalized.channels.length > 0;
|
|
3043
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
3044
|
+
if (normalized.target.kind === AGENTOS_CONFIG_TARGET.NODE_V1) {
|
|
3045
|
+
if (normalized.profile !== AGENTOS_CONFIG_PROFILE.WORKSPACE_V1) {
|
|
3046
|
+
return {
|
|
3047
|
+
ok: false,
|
|
3048
|
+
issues: [{ kind: "unsupported_static_target", target: normalized.target.kind }],
|
|
3049
|
+
};
|
|
3050
|
+
}
|
|
3051
|
+
const authoredManifestToolNames = toolNames.filter((toolName) => normalized.authoredToolNames.includes(toolName));
|
|
3052
|
+
const deploymentJson = {
|
|
3053
|
+
deploymentId: normalized.deployment.deploymentId,
|
|
3054
|
+
backend: normalized.deployment.backend,
|
|
3055
|
+
adapter: normalized.deployment.adapter,
|
|
3056
|
+
codec: normalized.deployment.codec,
|
|
3057
|
+
...(normalized.deployment.providerStrategy === undefined
|
|
3058
|
+
? {}
|
|
3059
|
+
: { providerStrategy: normalized.deployment.providerStrategy }),
|
|
3060
|
+
workspace: {
|
|
3061
|
+
binding: normalized.workspace.binding,
|
|
3062
|
+
bindingRef: normalized.workspace.bindingRef,
|
|
3063
|
+
root: normalized.workspace.root,
|
|
3064
|
+
topology: normalized.workspace.topology,
|
|
3065
|
+
providerResourceId: normalized.workspace.providerResourceId,
|
|
3066
|
+
},
|
|
3067
|
+
};
|
|
3068
|
+
const moduleGraph = [
|
|
3069
|
+
{ kind: "semantic-json", source: "./manifest.json", imports: ["default as declarations"] },
|
|
3070
|
+
{ kind: "semantic-json", source: "./deployment.json", imports: ["default as deployment"] },
|
|
3071
|
+
{
|
|
3072
|
+
kind: "local-runtime",
|
|
3073
|
+
source: modules.localRuntime,
|
|
3074
|
+
imports: ["lowerLocalAgentRuntime"],
|
|
3075
|
+
},
|
|
3076
|
+
{
|
|
3077
|
+
kind: "capability-runtime",
|
|
3078
|
+
source: modules.runtimeCapability,
|
|
3079
|
+
imports: ["runDynamicCapabilityResolvers"],
|
|
3080
|
+
},
|
|
3081
|
+
{
|
|
3082
|
+
kind: "workspace-host",
|
|
3083
|
+
source: modules.workspaceAgentHost,
|
|
3084
|
+
imports: ["WorkspaceAgentCustomCommandInput"],
|
|
3085
|
+
},
|
|
3086
|
+
...generatedToolImports(authoredManifestToolNames),
|
|
3087
|
+
...generatedDynamicResolverImports(normalized.dynamicResolvers),
|
|
3088
|
+
...(hasChannels
|
|
3089
|
+
? [
|
|
3090
|
+
{
|
|
3091
|
+
kind: "channel-runtime",
|
|
3092
|
+
source: modules.runtimeChannel,
|
|
3093
|
+
imports: ["DefinedChannel"],
|
|
3094
|
+
},
|
|
3095
|
+
...generatedChannelImports(normalized.channels),
|
|
3096
|
+
{
|
|
3097
|
+
kind: "channel-registry",
|
|
3098
|
+
source: "./channels",
|
|
3099
|
+
imports: ["dispatchGeneratedChannelRequest", "generatedChannels"],
|
|
3100
|
+
},
|
|
3101
|
+
]
|
|
3102
|
+
: []),
|
|
3103
|
+
...(hasSchedules
|
|
3104
|
+
? [
|
|
3105
|
+
{
|
|
3106
|
+
kind: "schedule-runtime",
|
|
3107
|
+
source: modules.runtimeSchedule,
|
|
3108
|
+
imports: ["DefinedSchedule"],
|
|
3109
|
+
},
|
|
3110
|
+
...generatedScheduleImports(normalized.schedules),
|
|
3111
|
+
{
|
|
3112
|
+
kind: "schedule-registry",
|
|
3113
|
+
source: "./schedules",
|
|
3114
|
+
imports: [
|
|
3115
|
+
"dispatchGeneratedSchedule",
|
|
3116
|
+
"generatedScheduleDefinitions",
|
|
3117
|
+
"generatedSchedules",
|
|
3118
|
+
],
|
|
3119
|
+
},
|
|
3120
|
+
]
|
|
3121
|
+
: []),
|
|
3122
|
+
];
|
|
3123
|
+
return {
|
|
3124
|
+
ok: true,
|
|
3125
|
+
value: {
|
|
3126
|
+
files: [
|
|
3127
|
+
generatedPath(".agentos/generated/manifest.json", stableJson(normalized.deployment.manifest)),
|
|
3128
|
+
generatedPath(".agentos/generated/deployment.json", stableJson(deploymentJson)),
|
|
3129
|
+
generatedPath(".agentos/generated/provenance.json", stableJson(normalized.provenance)),
|
|
3130
|
+
generatedPath(".agentos/generated/fingerprints.json", stableJson({
|
|
3131
|
+
deployment: digestText(stableJson(deploymentJson)),
|
|
3132
|
+
manifest: digestText(stableJson(normalized.deployment.manifest)),
|
|
3133
|
+
targetModuleGraph: digestText(stableJson(moduleGraph)),
|
|
3134
|
+
})),
|
|
3135
|
+
...(hasChannels
|
|
3136
|
+
? [
|
|
3137
|
+
generatedPath(".agentos/generated/channels.ts", renderChannelRegistry(normalized.channels, modules)),
|
|
3138
|
+
]
|
|
3139
|
+
: []),
|
|
3140
|
+
...(hasSchedules
|
|
3141
|
+
? [
|
|
3142
|
+
generatedPath(".agentos/generated/schedules.ts", renderScheduleRegistry(normalized.schedules, modules)),
|
|
3143
|
+
]
|
|
3144
|
+
: []),
|
|
3145
|
+
generatedPath(".agentos/generated/local.ts", renderLocalAgentApp(normalized, toolNames, modules)),
|
|
3146
|
+
],
|
|
3147
|
+
moduleGraph,
|
|
3148
|
+
canonicalDeployment: {
|
|
3149
|
+
profile: normalized.profile,
|
|
3150
|
+
target: normalized.target.kind,
|
|
3151
|
+
llmRoute: normalized.llm.route,
|
|
3152
|
+
client: normalized.client.kind,
|
|
3153
|
+
workspaceTopology: normalized.workspace.topology,
|
|
3154
|
+
toolNames,
|
|
3155
|
+
},
|
|
3156
|
+
mount: {
|
|
3157
|
+
driver: {
|
|
3158
|
+
kind: "local-node",
|
|
3159
|
+
target: AGENTOS_CONFIG_TARGET.NODE_V1,
|
|
3160
|
+
},
|
|
3161
|
+
projectionSinks: [
|
|
3162
|
+
"agent.info",
|
|
3163
|
+
"workspace.state",
|
|
3164
|
+
"workspace.files",
|
|
3165
|
+
"runtime.events",
|
|
3166
|
+
"runtime.input_requests",
|
|
3167
|
+
],
|
|
3168
|
+
providerResourceId: normalized.workspace.providerResourceId,
|
|
3169
|
+
},
|
|
3170
|
+
},
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1712
3174
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1713
3175
|
const authoredManifestToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
1714
3176
|
const deploymentJson = {
|
|
@@ -1738,10 +3200,63 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1738
3200
|
{
|
|
1739
3201
|
kind: "target-runtime",
|
|
1740
3202
|
source: modules.cloudflareDoRuntime,
|
|
1741
|
-
imports:
|
|
1742
|
-
? ["createAgentDurableObject", "installCloudflareWorkspaceOperationProvider"]
|
|
1743
|
-
: ["createAgentDurableObject"],
|
|
3203
|
+
imports: ["createAgentDurableObject"],
|
|
1744
3204
|
},
|
|
3205
|
+
...(hasChannels
|
|
3206
|
+
? [
|
|
3207
|
+
{
|
|
3208
|
+
kind: "channel-runtime",
|
|
3209
|
+
source: modules.runtimeChannel,
|
|
3210
|
+
imports: ["DefinedChannel"],
|
|
3211
|
+
},
|
|
3212
|
+
...generatedChannelImports(normalized.channels),
|
|
3213
|
+
{
|
|
3214
|
+
kind: "channel-registry",
|
|
3215
|
+
source: "./channels",
|
|
3216
|
+
imports: ["dispatchGeneratedChannelRequest", "generatedChannels"],
|
|
3217
|
+
},
|
|
3218
|
+
]
|
|
3219
|
+
: []),
|
|
3220
|
+
...(hasSchedules
|
|
3221
|
+
? [
|
|
3222
|
+
{
|
|
3223
|
+
kind: "schedule-runtime",
|
|
3224
|
+
source: modules.runtimeSchedule,
|
|
3225
|
+
imports: ["DefinedSchedule"],
|
|
3226
|
+
},
|
|
3227
|
+
...generatedScheduleImports(normalized.schedules),
|
|
3228
|
+
{
|
|
3229
|
+
kind: "schedule-registry",
|
|
3230
|
+
source: "./schedules",
|
|
3231
|
+
imports: [
|
|
3232
|
+
"dispatchGeneratedSchedule",
|
|
3233
|
+
"generatedScheduleDefinitions",
|
|
3234
|
+
"generatedSchedules",
|
|
3235
|
+
],
|
|
3236
|
+
},
|
|
3237
|
+
]
|
|
3238
|
+
: []),
|
|
3239
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
3240
|
+
? [
|
|
3241
|
+
{
|
|
3242
|
+
kind: "capability-runtime",
|
|
3243
|
+
source: modules.runtimeCapability,
|
|
3244
|
+
imports: [
|
|
3245
|
+
"WORKSPACE_OPERATION_HOST_FACT",
|
|
3246
|
+
"defineHost",
|
|
3247
|
+
"resolveRuntimeInstallGraph",
|
|
3248
|
+
"runDynamicCapabilityResolvers",
|
|
3249
|
+
"workspaceOperations",
|
|
3250
|
+
],
|
|
3251
|
+
},
|
|
3252
|
+
]
|
|
3253
|
+
: [
|
|
3254
|
+
{
|
|
3255
|
+
kind: "capability-runtime",
|
|
3256
|
+
source: modules.runtimeCapability,
|
|
3257
|
+
imports: ["runDynamicCapabilityResolvers"],
|
|
3258
|
+
},
|
|
3259
|
+
]),
|
|
1745
3260
|
{
|
|
1746
3261
|
kind: "provider-runtime",
|
|
1747
3262
|
source: modules.openAiCompatibleTransport,
|
|
@@ -1755,13 +3270,9 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1755
3270
|
: ["WORKSPACE_AGENT_COMMAND"],
|
|
1756
3271
|
},
|
|
1757
3272
|
...generatedToolImports(authoredManifestToolNames),
|
|
3273
|
+
...generatedDynamicResolverImports(normalized.dynamicResolvers),
|
|
1758
3274
|
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1759
3275
|
? [
|
|
1760
|
-
{
|
|
1761
|
-
kind: "workspace-binding",
|
|
1762
|
-
source: modules.workspaceBinding,
|
|
1763
|
-
imports: ["bindWorkspaceToolsForRuntime"],
|
|
1764
|
-
},
|
|
1765
3276
|
{
|
|
1766
3277
|
kind: "execution-domain-runtime",
|
|
1767
3278
|
source: modules.workspaceEnvCloudflare,
|
|
@@ -1788,8 +3299,8 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1788
3299
|
kind: "target-worker",
|
|
1789
3300
|
source: "./worker",
|
|
1790
3301
|
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1791
|
-
? [
|
|
1792
|
-
: [
|
|
3302
|
+
? [target.durableObject.className, "Sandbox"]
|
|
3303
|
+
: [target.durableObject.className],
|
|
1793
3304
|
},
|
|
1794
3305
|
{
|
|
1795
3306
|
kind: "target-config",
|
|
@@ -1810,6 +3321,16 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1810
3321
|
manifest: digestText(stableJson(normalized.deployment.manifest)),
|
|
1811
3322
|
targetModuleGraph: digestText(stableJson(moduleGraph)),
|
|
1812
3323
|
})),
|
|
3324
|
+
...(hasChannels
|
|
3325
|
+
? [
|
|
3326
|
+
generatedPath(".agentos/generated/channels.ts", renderChannelRegistry(normalized.channels, modules)),
|
|
3327
|
+
]
|
|
3328
|
+
: []),
|
|
3329
|
+
...(hasSchedules
|
|
3330
|
+
? [
|
|
3331
|
+
generatedPath(".agentos/generated/schedules.ts", renderScheduleRegistry(normalized.schedules, modules)),
|
|
3332
|
+
]
|
|
3333
|
+
: []),
|
|
1813
3334
|
generatedPath(".agentos/generated/target.ts", renderStaticTarget(normalized, toolNames, modules)),
|
|
1814
3335
|
generatedPath(".agentos/generated/cloudflare-scope.ts", renderCloudflareScopeHelper(normalized, modules)),
|
|
1815
3336
|
generatedPath(".agentos/generated/worker.ts", renderCloudflareWorkerEntry(normalized, modules)),
|
|
@@ -1836,8 +3357,8 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1836
3357
|
mount: {
|
|
1837
3358
|
driver: {
|
|
1838
3359
|
kind: "cloudflare-do",
|
|
1839
|
-
className:
|
|
1840
|
-
binding:
|
|
3360
|
+
className: target.durableObject.className,
|
|
3361
|
+
binding: target.durableObject.binding,
|
|
1841
3362
|
},
|
|
1842
3363
|
projectionSinks: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1843
3364
|
? [
|