@yansirplus/cli 0.5.17 → 0.5.19
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 +73 -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 +90 -0
- package/agent-catalog/agentOS/references/public-api/core.md +1907 -0
- package/agent-catalog/agentOS/references/public-api/runtime.md +843 -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 +1900 -281
- 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 +1629 -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 +1281 -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 +171 -21
- package/dist/release-status.mjs +515 -0
- 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,659 @@ 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", "dispatchScheduleFireDelivery"], modules.runtimeSchedule)}
|
|
306
|
+
${renderTypeImport([
|
|
307
|
+
"DefinedSchedule",
|
|
308
|
+
"ScheduleDefinitionProjection",
|
|
309
|
+
"ScheduleFireDeliveryDispatchInput",
|
|
310
|
+
"ScheduleFireDeliveryDispatchResult",
|
|
311
|
+
"ScheduleFireDispatchResult",
|
|
312
|
+
"SchedulePrincipal",
|
|
313
|
+
"ScheduleRuntime",
|
|
314
|
+
], modules.runtimeSchedule)}
|
|
315
|
+
${renderTypeImport(["LedgerTruthIdentity"], modules.runtimeProtocol)}
|
|
316
|
+
|
|
317
|
+
type GeneratedScheduleDefinition = {
|
|
318
|
+
readonly scheduleId: string;
|
|
319
|
+
readonly path: string;
|
|
320
|
+
readonly cron: string;
|
|
321
|
+
readonly schedule: DefinedSchedule;
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
export type GeneratedScheduleTriggerInput = {
|
|
325
|
+
readonly scheduleId: string;
|
|
326
|
+
readonly scheduledAt: string | number | Date;
|
|
327
|
+
readonly appPrincipal: SchedulePrincipal;
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
export type GeneratedScheduleDispatchInput = GeneratedScheduleTriggerInput & {
|
|
331
|
+
readonly runtime: ScheduleRuntime;
|
|
332
|
+
readonly identity: LedgerTruthIdentity;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
export type GeneratedScheduleDeliveryDispatchInput = GeneratedScheduleDispatchInput & {
|
|
336
|
+
readonly history: ScheduleFireDeliveryDispatchInput["history"];
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export const generatedSchedules = ${entries} as const satisfies ReadonlyArray<GeneratedScheduleDefinition>;
|
|
340
|
+
export const generatedScheduleDefinitions = generatedSchedules.map(
|
|
341
|
+
({ scheduleId, path, cron }) => ({ scheduleId, path, cron }),
|
|
342
|
+
) satisfies ReadonlyArray<ScheduleDefinitionProjection>;
|
|
343
|
+
export const generatedScheduleIds = generatedScheduleDefinitions.map((entry) => entry.scheduleId);
|
|
344
|
+
export const generatedScheduleRegistry = new Map(
|
|
345
|
+
generatedSchedules.map((entry) => [entry.scheduleId, entry]),
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
export const dispatchGeneratedSchedule = async (
|
|
349
|
+
input: GeneratedScheduleDispatchInput,
|
|
350
|
+
): Promise<ScheduleFireDispatchResult> => {
|
|
351
|
+
const entry = generatedScheduleRegistry.get(input.scheduleId);
|
|
352
|
+
if (entry === undefined) {
|
|
353
|
+
throw new Error(\`unknown generated schedule: \${input.scheduleId}\`);
|
|
354
|
+
}
|
|
355
|
+
return dispatchScheduleFire({
|
|
356
|
+
runtime: input.runtime,
|
|
357
|
+
schedule: entry.schedule,
|
|
358
|
+
scheduleId: entry.scheduleId,
|
|
359
|
+
appPrincipal: input.appPrincipal,
|
|
360
|
+
scheduledAt: input.scheduledAt,
|
|
361
|
+
scopeRef: input.identity.scopeRef,
|
|
362
|
+
effectAuthorityRef: input.identity.effectAuthorityRef,
|
|
363
|
+
});
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
export const dispatchGeneratedScheduleDelivery = async (
|
|
367
|
+
input: GeneratedScheduleDeliveryDispatchInput,
|
|
368
|
+
): Promise<ScheduleFireDeliveryDispatchResult> => {
|
|
369
|
+
const entry = generatedScheduleRegistry.get(input.scheduleId);
|
|
370
|
+
if (entry === undefined) {
|
|
371
|
+
throw new Error(\`unknown generated schedule: \${input.scheduleId}\`);
|
|
372
|
+
}
|
|
373
|
+
return dispatchScheduleFireDelivery({
|
|
374
|
+
history: input.history,
|
|
375
|
+
runtime: input.runtime,
|
|
376
|
+
schedule: entry.schedule,
|
|
377
|
+
scheduleId: entry.scheduleId,
|
|
378
|
+
appPrincipal: input.appPrincipal,
|
|
379
|
+
scheduledAt: input.scheduledAt,
|
|
380
|
+
scopeRef: input.identity.scopeRef,
|
|
381
|
+
effectAuthorityRef: input.identity.effectAuthorityRef,
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
`;
|
|
385
|
+
};
|
|
386
|
+
const renderSkillCatalog = (skills) => {
|
|
387
|
+
const entries = sortedSkills(skills).map((skill) => ` ${JSON.stringify(stableJsonValue({
|
|
388
|
+
description: skill.description,
|
|
389
|
+
digest: skill.digest,
|
|
390
|
+
files: skill.files.map((file) => ({
|
|
391
|
+
bytes: file.bytes,
|
|
392
|
+
digest: file.digest,
|
|
393
|
+
path: file.path,
|
|
394
|
+
text: file.text,
|
|
395
|
+
})),
|
|
396
|
+
name: skill.name,
|
|
397
|
+
path: skill.path,
|
|
398
|
+
text: skill.text,
|
|
399
|
+
}))}`);
|
|
400
|
+
return entries.length === 0 ? "[]" : `[\n${entries.join(",\n")}\n]`;
|
|
401
|
+
};
|
|
402
|
+
const renderInstructionFragments = (fragments) => {
|
|
403
|
+
const entries = [...fragments]
|
|
404
|
+
.sort((left, right) => left.fragmentId.localeCompare(right.fragmentId))
|
|
405
|
+
.map((fragment) => ` ${JSON.stringify(stableJsonValue({
|
|
406
|
+
digest: fragment.digest,
|
|
407
|
+
id: fragment.fragmentId,
|
|
408
|
+
text: fragment.text,
|
|
409
|
+
}))}`);
|
|
410
|
+
return entries.length === 0 ? "[]" : `[\n${entries.join(",\n")}\n]`;
|
|
411
|
+
};
|
|
412
|
+
const renderDynamicCapabilityCatalog = (normalized, toolNames, hasSkills) => {
|
|
413
|
+
const manifestTools = normalized.deployment.manifest.tools ?? {};
|
|
414
|
+
const dynamicToolNames = [
|
|
415
|
+
...toolNames,
|
|
416
|
+
...(hasSkills ? [GENERATED_LOAD_SKILL_TOOL_NAME, GENERATED_READ_SKILL_FILE_TOOL_NAME] : []),
|
|
417
|
+
];
|
|
418
|
+
return JSON.stringify(stableJsonValue({
|
|
419
|
+
instructions: normalized.instructionFragments.map((fragment) => ({
|
|
420
|
+
digest: fragment.digest,
|
|
421
|
+
id: fragment.fragmentId,
|
|
422
|
+
})),
|
|
423
|
+
skills: normalized.skills.map((skill) => ({
|
|
424
|
+
digest: skill.digest,
|
|
425
|
+
id: skill.name,
|
|
426
|
+
})),
|
|
427
|
+
tools: [...new Set(dynamicToolNames)].sort().map((toolName) => ({
|
|
428
|
+
id: toolName,
|
|
429
|
+
...(manifestTools[toolName]?.bindingRef === undefined
|
|
430
|
+
? {}
|
|
431
|
+
: { bindingRef: manifestTools[toolName]?.bindingRef }),
|
|
432
|
+
})),
|
|
433
|
+
}), null, 2);
|
|
434
|
+
};
|
|
435
|
+
const renderDynamicResolverImportStatements = (resolvers) => sortedDynamicResolvers(resolvers)
|
|
436
|
+
.map((resolver, index) => `import dynamicResolver_${index} from ${jsString(importDynamicResolverPath(resolver.path))};`)
|
|
437
|
+
.join("\n");
|
|
438
|
+
const renderDynamicCapabilitySupport = (normalized, toolNames, hasSkills) => {
|
|
439
|
+
const resolvers = sortedDynamicResolvers(normalized.dynamicResolvers);
|
|
440
|
+
const resolverEntries = resolvers.length === 0
|
|
441
|
+
? "[]"
|
|
442
|
+
: `[\n${resolvers
|
|
443
|
+
.map((resolver, index) => ` {
|
|
444
|
+
resolverId: ${jsString(resolver.resolverId)},
|
|
445
|
+
slot: ${jsString(resolver.slot)},
|
|
446
|
+
resolve: dynamicResolver_${index},
|
|
447
|
+
},`)
|
|
448
|
+
.join("\n")}\n]`;
|
|
449
|
+
return `${renderDynamicResolverImportStatements(resolvers)}
|
|
450
|
+
|
|
451
|
+
const generatedDynamicCapabilityCatalog = ${renderDynamicCapabilityCatalog(normalized, toolNames, hasSkills)} satisfies DynamicCapabilityCompiledCatalog;
|
|
452
|
+
|
|
453
|
+
const generatedInstructionFragments = ${renderInstructionFragments(normalized.instructionFragments)} satisfies ReadonlyArray<SubmitInstructionFragment>;
|
|
454
|
+
|
|
455
|
+
const generatedDynamicCapabilityResolvers = ${resolverEntries} satisfies ReadonlyArray<DynamicCapabilityResolverDefinition>;
|
|
456
|
+
|
|
457
|
+
const generatedDynamicCapabilityTurnEvent = (
|
|
458
|
+
refs: { readonly sessionRef?: string; readonly turnRef?: string } = {},
|
|
459
|
+
): DynamicCapabilityEventRef => ({
|
|
460
|
+
name: DYNAMIC_CAPABILITY_EVENT.TURN_STARTED,
|
|
461
|
+
...(refs.sessionRef === undefined ? {} : { sessionRef: refs.sessionRef }),
|
|
462
|
+
...(refs.turnRef === undefined ? {} : { turnRef: refs.turnRef }),
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
const generatedDynamicSubmitBindingsFor = async (
|
|
466
|
+
event: DynamicCapabilityEventRef,
|
|
467
|
+
input: DynamicCapabilityRunInput | undefined = undefined,
|
|
468
|
+
): Promise<GeneratedTargetResult<Pick<AgentSubmitBindings, "dynamicCapabilityProjection" | "instructionFragments">>> => {
|
|
469
|
+
const projection = await runDynamicCapabilityResolvers({
|
|
470
|
+
event,
|
|
471
|
+
catalog: generatedDynamicCapabilityCatalog,
|
|
472
|
+
resolvers: generatedDynamicCapabilityResolvers,
|
|
473
|
+
input,
|
|
474
|
+
materials: semanticManifest.materials ?? {},
|
|
475
|
+
});
|
|
476
|
+
if (!projection.ok) {
|
|
477
|
+
return targetFailure(\`dynamic capability resolver failed: \${JSON.stringify(projection.issues)}\`);
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
ok: true,
|
|
481
|
+
value: {
|
|
482
|
+
dynamicCapabilityProjection: projection.projection,
|
|
483
|
+
instructionFragments: generatedInstructionFragments,
|
|
484
|
+
},
|
|
485
|
+
};
|
|
486
|
+
};`;
|
|
487
|
+
};
|
|
488
|
+
const renderSkillSupport = (skills) => {
|
|
489
|
+
if (skills.length === 0)
|
|
490
|
+
return "";
|
|
491
|
+
return `
|
|
492
|
+
type GeneratedSkill = {
|
|
493
|
+
readonly name: string;
|
|
494
|
+
readonly description: string;
|
|
495
|
+
readonly path: string;
|
|
496
|
+
readonly digest: string;
|
|
497
|
+
readonly text: string;
|
|
498
|
+
readonly files: ReadonlyArray<{
|
|
499
|
+
readonly path: string;
|
|
500
|
+
readonly digest: string;
|
|
501
|
+
readonly bytes: number;
|
|
502
|
+
readonly text: string;
|
|
503
|
+
}>;
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
type GeneratedSkillFile = GeneratedSkill["files"][number];
|
|
507
|
+
|
|
508
|
+
type LoadedGeneratedSkill = Omit<GeneratedSkill, "files"> & {
|
|
509
|
+
readonly files: ReadonlyArray<Omit<GeneratedSkillFile, "text">>;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
const generatedSkillCatalog = ${renderSkillCatalog(skills)} satisfies ReadonlyArray<GeneratedSkill>;
|
|
513
|
+
const generatedSkillNames = generatedSkillCatalog.map((skill) => skill.name);
|
|
514
|
+
const generatedSkillByName = Object.fromEntries(
|
|
515
|
+
generatedSkillCatalog.map((skill) => [skill.name, skill]),
|
|
516
|
+
) as Readonly<Record<string, GeneratedSkill>>;
|
|
517
|
+
const generatedSkillFilePathCatalog = generatedSkillCatalog.flatMap((skill) =>
|
|
518
|
+
skill.files.map((file) => ({ name: skill.name, path: file.path })),
|
|
519
|
+
);
|
|
520
|
+
const generatedVisibleSkillCatalogFor = (
|
|
521
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
522
|
+
): ReadonlyArray<GeneratedSkill> => {
|
|
523
|
+
if (projection === undefined) return generatedSkillCatalog;
|
|
524
|
+
const visible = new Set(
|
|
525
|
+
projection.skills.filter((skill) => skill.visible).map((skill) => skill.id),
|
|
526
|
+
);
|
|
527
|
+
return generatedSkillCatalog.filter((skill) => visible.has(skill.name));
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
const generatedSkillsSystemAdvert = (
|
|
531
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
532
|
+
): string => [
|
|
533
|
+
"Available agent skills are not loaded by default.",
|
|
534
|
+
...generatedVisibleSkillCatalogFor(projection).map((skill) => \`- \${skill.name}: \${skill.description}\`),
|
|
535
|
+
"Do not assume a skill's full instructions until ${GENERATED_LOAD_SKILL_TOOL_NAME} returns it.",
|
|
536
|
+
].join("\\n");
|
|
537
|
+
|
|
538
|
+
const generatedSystemPrompt = (
|
|
539
|
+
system: string | undefined,
|
|
540
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
541
|
+
): string =>
|
|
542
|
+
system === undefined || system.length === 0
|
|
543
|
+
? generatedSkillsSystemAdvert(projection)
|
|
544
|
+
: \`\${system}\\n\\n\${generatedSkillsSystemAdvert(projection)}\`;
|
|
545
|
+
|
|
546
|
+
const generatedLoadedSkill = (skill: GeneratedSkill): LoadedGeneratedSkill => ({
|
|
547
|
+
name: skill.name,
|
|
548
|
+
description: skill.description,
|
|
549
|
+
path: skill.path,
|
|
550
|
+
digest: skill.digest,
|
|
551
|
+
text: skill.text,
|
|
552
|
+
files: skill.files.map((file) => ({
|
|
553
|
+
path: file.path,
|
|
554
|
+
digest: file.digest,
|
|
555
|
+
bytes: file.bytes,
|
|
556
|
+
})),
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
const generatedFrameworkToolsFor = (
|
|
560
|
+
projection: DynamicCapabilityProjection | undefined,
|
|
561
|
+
): Readonly<Record<string, Tool>> => {
|
|
562
|
+
const visibleSkillNames = new Set(
|
|
563
|
+
generatedVisibleSkillCatalogFor(projection).map((skill) => skill.name),
|
|
564
|
+
);
|
|
565
|
+
if (visibleSkillNames.size === 0) return {};
|
|
566
|
+
const visibleSkill = (name: string): GeneratedSkill | null => {
|
|
567
|
+
if (!visibleSkillNames.has(name)) return null;
|
|
568
|
+
return generatedSkillByName[name] ?? null;
|
|
569
|
+
};
|
|
570
|
+
const generatedLoadSkillTool = defineProductTool({
|
|
571
|
+
name: ${jsString(GENERATED_LOAD_SKILL_TOOL_NAME)},
|
|
572
|
+
description: "Load the full text of a CLI-authored agent skill by name.",
|
|
573
|
+
args: Schema.Struct({ name: Schema.String }),
|
|
574
|
+
authority: "agentos.generated.skills",
|
|
575
|
+
authorityId: "agentos.generated.skills.load_skill",
|
|
576
|
+
admit: ({ name }) => Effect.succeed({ ok: visibleSkillNames.has(name) } as const),
|
|
577
|
+
execute: ({ name }) => {
|
|
578
|
+
const skill = visibleSkill(name);
|
|
579
|
+
if (skill === null) return Effect.fail(Error(\`unknown skill \${name}\`));
|
|
580
|
+
return Effect.succeed(generatedLoadedSkill(skill));
|
|
581
|
+
},
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
const generatedReadSkillFileTool = defineProductTool({
|
|
585
|
+
name: ${jsString(GENERATED_READ_SKILL_FILE_TOOL_NAME)},
|
|
586
|
+
description: "Read one declared supporting file from a CLI-authored agent skill package.",
|
|
587
|
+
args: Schema.Struct({
|
|
588
|
+
name: Schema.String,
|
|
589
|
+
path: Schema.String,
|
|
590
|
+
}),
|
|
591
|
+
authority: "agentos.generated.skills",
|
|
592
|
+
authorityId: "agentos.generated.skills.read_skill_file",
|
|
593
|
+
admit: ({ name, path }) =>
|
|
594
|
+
Effect.succeed({
|
|
595
|
+
ok:
|
|
596
|
+
visibleSkillNames.has(name) &&
|
|
597
|
+
generatedSkillFilePathCatalog.some((file) => file.name === name && file.path === path),
|
|
598
|
+
} as const),
|
|
599
|
+
execute: ({ name, path }) => {
|
|
600
|
+
const skill = visibleSkill(name);
|
|
601
|
+
const file = skill?.files.find((candidate) => candidate.path === path);
|
|
602
|
+
if (skill === null || file === undefined) {
|
|
603
|
+
return Effect.fail(Error(\`unknown skill file \${name}/\${path}\`));
|
|
604
|
+
}
|
|
605
|
+
return Effect.succeed({
|
|
606
|
+
name,
|
|
607
|
+
path: file.path,
|
|
608
|
+
digest: file.digest,
|
|
609
|
+
text: file.text,
|
|
610
|
+
});
|
|
611
|
+
},
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
${jsString(GENERATED_LOAD_SKILL_TOOL_NAME)}: generatedLoadSkillTool,
|
|
616
|
+
${jsString(GENERATED_READ_SKILL_FILE_TOOL_NAME)}: generatedReadSkillFileTool,
|
|
617
|
+
} satisfies Readonly<Record<string, Tool>>;
|
|
618
|
+
};
|
|
619
|
+
`;
|
|
620
|
+
};
|
|
621
|
+
const renderSubmitSpecFromRunInput = (hasSkills) => `const submitSpecFromRunInput = (
|
|
622
|
+
input: SubmitRunInput,
|
|
623
|
+
dynamicCapabilityProjection: DynamicCapabilityProjection | undefined,
|
|
624
|
+
): AgentSubmitSpec => ({
|
|
625
|
+
input,
|
|
626
|
+
intent: input.intent,
|
|
627
|
+
context: input.context,
|
|
628
|
+
${hasSkills ? "system: generatedSystemPrompt(input.system, dynamicCapabilityProjection)," : "...(input.system === undefined ? {} : { system: input.system }),"}
|
|
629
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
630
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
631
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
632
|
+
...(input.dynamicCapability === undefined ? {} : { dynamicCapability: input.dynamicCapability }),
|
|
633
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
634
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
635
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
636
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
637
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
638
|
+
});`;
|
|
639
|
+
const renderProductApiHelpers = () => `export interface AgentSessionSubmitTurnInput extends SubmitRunInput {
|
|
640
|
+
readonly sessionRef: string;
|
|
641
|
+
readonly turnRef: string;
|
|
642
|
+
readonly idempotencyKey?: string;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
export interface AgentWorkflowRunInput extends SubmitRunInput {
|
|
646
|
+
readonly workflowId: string;
|
|
647
|
+
readonly workflowRunId: string;
|
|
648
|
+
readonly idempotencyKey?: string;
|
|
649
|
+
readonly inputDigest?: string;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
export interface AgentWorkflowRunRef {
|
|
653
|
+
readonly workflowId: string;
|
|
654
|
+
readonly workflowRunId: string;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const submitRunInputFields = (input: SubmitRunInput): SubmitRunInput => ({
|
|
658
|
+
intent: input.intent,
|
|
659
|
+
context: input.context,
|
|
660
|
+
...(input.system === undefined ? {} : { system: input.system }),
|
|
661
|
+
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
662
|
+
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
663
|
+
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
664
|
+
...(input.dynamicCapability === undefined ? {} : { dynamicCapability: input.dynamicCapability }),
|
|
665
|
+
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
666
|
+
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
667
|
+
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
668
|
+
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
669
|
+
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
const submitRunInputFromWorkflowRun = (
|
|
673
|
+
input: AgentWorkflowRunInput,
|
|
674
|
+
): SubmitRunInput => submitRunInputFields(input);
|
|
675
|
+
|
|
676
|
+
const submitRunInputFromSessionTurn = (
|
|
677
|
+
input: AgentSessionSubmitTurnInput,
|
|
678
|
+
): SubmitRunInput => submitRunInputFields(input);`;
|
|
679
|
+
const renderProductApiDurableObjectMethods = () => `
|
|
680
|
+
submitSessionTurn(input: AgentSessionSubmitTurnInput): Promise<SubmitResult> {
|
|
681
|
+
return generatedSubmitBindingsFor(
|
|
682
|
+
this.targetEnv,
|
|
683
|
+
generatedDynamicCapabilityTurnEvent({
|
|
684
|
+
sessionRef: input.sessionRef,
|
|
685
|
+
turnRef: input.turnRef,
|
|
686
|
+
}),
|
|
687
|
+
input.dynamicCapability,
|
|
688
|
+
).then((bindings) =>
|
|
689
|
+
bindings.ok
|
|
690
|
+
? this.submitWithBindingsAndProductLink(
|
|
691
|
+
submitSpecFromRunInput(
|
|
692
|
+
submitRunInputFromSessionTurn(input),
|
|
693
|
+
bindings.value.dynamicCapabilityProjection,
|
|
694
|
+
),
|
|
695
|
+
bindings.value,
|
|
696
|
+
{
|
|
697
|
+
kind: "session_turn",
|
|
698
|
+
sessionRef: input.sessionRef,
|
|
699
|
+
turnRef: input.turnRef,
|
|
700
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
701
|
+
},
|
|
702
|
+
)
|
|
703
|
+
: rejectTargetFailure(bindings),
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
inspectSession(input: { readonly sessionRef: string }): Promise<AgentSessionProjection> {
|
|
708
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
709
|
+
projectAgentSession(events, input.sessionRef),
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
listSessions(): Promise<AgentSessionListProjection> {
|
|
714
|
+
return this.events(semanticTruthIdentity).then((events) => projectAgentSessions(events));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
runWorkflow(input: AgentWorkflowRunInput): Promise<SubmitResult> {
|
|
718
|
+
return generatedSubmitBindingsFor(
|
|
719
|
+
this.targetEnv,
|
|
720
|
+
generatedDynamicCapabilityTurnEvent(),
|
|
721
|
+
input.dynamicCapability,
|
|
722
|
+
).then((bindings) =>
|
|
723
|
+
bindings.ok
|
|
724
|
+
? this.submitWithBindingsAndProductLink(
|
|
725
|
+
submitSpecFromRunInput(
|
|
726
|
+
submitRunInputFromWorkflowRun(input),
|
|
727
|
+
bindings.value.dynamicCapabilityProjection,
|
|
728
|
+
),
|
|
729
|
+
bindings.value,
|
|
730
|
+
{
|
|
731
|
+
kind: "workflow_run",
|
|
732
|
+
workflowId: input.workflowId,
|
|
733
|
+
workflowRunId: input.workflowRunId,
|
|
734
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
735
|
+
...(input.inputDigest === undefined ? {} : { inputDigest: input.inputDigest }),
|
|
736
|
+
},
|
|
737
|
+
)
|
|
738
|
+
: rejectTargetFailure(bindings),
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
inspectWorkflowRun(input: AgentWorkflowRunRef): Promise<WorkflowRunProjection | null> {
|
|
743
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
744
|
+
projectWorkflowRun(events, input.workflowId, input.workflowRunId),
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
listWorkflowRuns(input: { readonly workflowId: string }): Promise<WorkflowRunListProjection> {
|
|
749
|
+
return this.events(semanticTruthIdentity).then((events) =>
|
|
750
|
+
projectWorkflowRuns(events, input.workflowId),
|
|
751
|
+
);
|
|
752
|
+
}`;
|
|
753
|
+
const renderScheduleDurableObjectHelpers = () => `
|
|
754
|
+
const generatedScheduleRuntimeFor = (target: {
|
|
755
|
+
readonly submitSessionTurn: (input: AgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
756
|
+
readonly runWorkflow: (input: AgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
757
|
+
}) =>
|
|
758
|
+
Object.freeze({
|
|
759
|
+
sessions: Object.freeze({
|
|
760
|
+
submitTurn: (input: AgentSessionSubmitTurnInput) => target.submitSessionTurn(input),
|
|
761
|
+
}),
|
|
762
|
+
workflows: Object.freeze({
|
|
763
|
+
run: (input: AgentWorkflowRunInput) => target.runWorkflow(input),
|
|
764
|
+
}),
|
|
765
|
+
});`;
|
|
766
|
+
const renderScheduleDurableObjectMethod = () => `
|
|
767
|
+
dispatchSchedule(input: GeneratedScheduleTriggerInput): Promise<unknown> {
|
|
768
|
+
return this.events(semanticTruthIdentity).then((history) =>
|
|
769
|
+
dispatchGeneratedScheduleDelivery({
|
|
770
|
+
...input,
|
|
771
|
+
history,
|
|
772
|
+
identity: semanticTruthIdentity,
|
|
773
|
+
runtime: generatedScheduleRuntimeFor(this),
|
|
774
|
+
}).then((result) => this.commitScheduleFireDispatchFullWithDelivery(result)),
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
`;
|
|
778
|
+
const renderGeneratedWorkspaceOperations = (workspaceToolArray, usesMutationTools, usesShellTools) => `const generatedWorkspaceToolNames = ${workspaceToolArray};
|
|
779
|
+
|
|
780
|
+
const generatedWorkspaceToolInteractionFor = (
|
|
781
|
+
name: (typeof generatedWorkspaceToolNames)[number],
|
|
782
|
+
): "never" | "approval" => {
|
|
783
|
+
const interaction = semanticManifest.tools?.[name]?.interaction;
|
|
784
|
+
if (interaction === "never" || interaction === "approval") return interaction;
|
|
785
|
+
throw Error(\`invalid workspace tool interaction for \${name}: \${String(interaction)}\`);
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
const generatedWorkspaceToolInteractions = Object.fromEntries(
|
|
789
|
+
generatedWorkspaceToolNames.map((name) => [name, generatedWorkspaceToolInteractionFor(name)]),
|
|
790
|
+
) as Readonly<Partial<Record<(typeof generatedWorkspaceToolNames)[number], "never" | "approval">>>;
|
|
791
|
+
|
|
792
|
+
const generatedWorkspaceOperations = {
|
|
793
|
+
toolNames: generatedWorkspaceToolNames,
|
|
794
|
+
mutationPolicy: ${usesMutationTools ? '"receipt-backed"' : '"disabled"'},
|
|
795
|
+
shellPolicy: ${usesShellTools ? '"receipt-backed"' : '"disabled"'},
|
|
796
|
+
toolInteractions: generatedWorkspaceToolInteractions,
|
|
797
|
+
} as const;`;
|
|
56
798
|
const renderWorkspaceStaticTarget = (normalized, toolNames, modules) => {
|
|
799
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
800
|
+
const hasSkills = normalized.skills.length > 0;
|
|
801
|
+
const hasDynamicCapability = true;
|
|
802
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
57
803
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
58
804
|
const workspaceToolList = toolNames.filter((toolName) => isWorkspaceToolName(toolName) && !authoredToolNames.has(toolName));
|
|
59
805
|
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
@@ -71,23 +817,57 @@ const renderWorkspaceStaticTarget = (normalized, toolNames, modules) => {
|
|
|
71
817
|
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
72
818
|
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
73
819
|
.join("\n")}\n}`;
|
|
74
|
-
const
|
|
75
|
-
const generatedLlmEnvFields =
|
|
76
|
-
.map((
|
|
820
|
+
const llmEnvBindings = uniqueLlmMaterialEnvBindings(normalized.llmRoutes);
|
|
821
|
+
const generatedLlmEnvFields = llmEnvBindings
|
|
822
|
+
.map((binding) => ` readonly ${binding.envName}?: string;`)
|
|
77
823
|
.join("\n");
|
|
78
824
|
const imports = [
|
|
79
825
|
`import semanticDeclarations from "./manifest.json";`,
|
|
80
826
|
`import deploymentProvenance from "./deployment.json";`,
|
|
81
|
-
|
|
82
|
-
|
|
827
|
+
...(hasSchedules
|
|
828
|
+
? [renderNamedImport(["dispatchGeneratedScheduleDelivery"], "./schedules")]
|
|
829
|
+
: []),
|
|
830
|
+
renderNamedImport(["createAgentDurableObject"], modules.cloudflareDoRuntime),
|
|
831
|
+
renderNamedImport([
|
|
832
|
+
"WORKSPACE_OPERATION_HOST_FACT",
|
|
833
|
+
"defineHost",
|
|
834
|
+
"resolveRuntimeInstallGraph",
|
|
835
|
+
...(hasDynamicCapability ? ["runDynamicCapabilityResolvers"] : []),
|
|
836
|
+
"workspaceOperations",
|
|
837
|
+
], modules.runtimeCapability),
|
|
838
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
839
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
840
|
+
renderNamedImport(["projectAgentSession", "projectAgentSessions", "projectWorkflowRun", "projectWorkflowRuns"], modules.runtimeRunProjector),
|
|
83
841
|
renderNamedImport(["defineWorkspaceAgentMount", "WORKSPACE_AGENT_PROJECTION"], modules.workspaceAgentHost),
|
|
84
|
-
renderNamedImport(["bindWorkspaceToolsForRuntime"], modules.workspaceBinding),
|
|
85
842
|
renderNamedImport(["makeCloudflareWorkspaceEnv"], modules.workspaceEnvCloudflare),
|
|
86
843
|
renderNamedImport(["getSandbox"], modules.cloudflareSandbox),
|
|
87
|
-
renderNamedImport([
|
|
88
|
-
|
|
844
|
+
renderNamedImport([
|
|
845
|
+
"deterministicToolInvocation",
|
|
846
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
847
|
+
"unsafeRunToolByName",
|
|
848
|
+
], modules.coreTools),
|
|
849
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
89
850
|
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
851
|
+
...(hasDynamicCapability
|
|
852
|
+
? [
|
|
853
|
+
renderTypeImport([
|
|
854
|
+
"DynamicCapabilityCompiledCatalog",
|
|
855
|
+
"DynamicCapabilityEventRef",
|
|
856
|
+
"DynamicCapabilityProjection",
|
|
857
|
+
"DynamicCapabilityRunInput",
|
|
858
|
+
"SubmitInstructionFragment",
|
|
859
|
+
], modules.runtimeProtocol),
|
|
860
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
861
|
+
]
|
|
862
|
+
: []),
|
|
863
|
+
renderTypeImport([
|
|
864
|
+
"AgentSessionListProjection",
|
|
865
|
+
"AgentSessionProjection",
|
|
866
|
+
"WorkflowRunListProjection",
|
|
867
|
+
"WorkflowRunProjection",
|
|
868
|
+
], modules.runtimeRunProjector),
|
|
90
869
|
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
870
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
91
871
|
renderTypeImport([
|
|
92
872
|
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
93
873
|
"WorkspaceAgentCustomCommandInput",
|
|
@@ -109,6 +889,7 @@ export const targetDeclarations = semanticDeclarations;
|
|
|
109
889
|
export const targetDeployment = deploymentProvenance;
|
|
110
890
|
|
|
111
891
|
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
892
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
112
893
|
const generatedHandler = () => undefined;
|
|
113
894
|
|
|
114
895
|
type AgentOSTargetEnv = {
|
|
@@ -120,33 +901,36 @@ ${generatedLlmEnvFields}
|
|
|
120
901
|
type GeneratedTargetFailure = {
|
|
121
902
|
readonly ok: false;
|
|
122
903
|
readonly message: string;
|
|
904
|
+
readonly diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
123
905
|
};
|
|
124
906
|
|
|
125
907
|
type GeneratedTargetResult<Value> =
|
|
126
908
|
| { readonly ok: true; readonly value: Value }
|
|
127
909
|
| GeneratedTargetFailure;
|
|
128
910
|
|
|
129
|
-
const targetFailure = (
|
|
911
|
+
const targetFailure = (
|
|
912
|
+
message: string,
|
|
913
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>,
|
|
914
|
+
): GeneratedTargetFailure => ({
|
|
915
|
+
ok: false,
|
|
916
|
+
message,
|
|
917
|
+
...(diagnostics === undefined || diagnostics.length === 0 ? {} : { diagnostics }),
|
|
918
|
+
});
|
|
130
919
|
|
|
131
|
-
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
132
|
-
|
|
920
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> => {
|
|
921
|
+
const error = Error(failure.message) as Error & {
|
|
922
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
923
|
+
};
|
|
924
|
+
if (failure.diagnostics !== undefined) error.diagnostics = failure.diagnostics;
|
|
925
|
+
return Promise.reject(error);
|
|
926
|
+
};
|
|
133
927
|
|
|
134
|
-
|
|
928
|
+
${renderGeneratedWorkspaceOperations(workspaceToolArray, usesMutationTools, usesShellTools)}
|
|
135
929
|
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
930
|
+
${hasDynamicCapability ? renderDynamicCapabilitySupport(normalized, toolNames, hasSkills) : ""}
|
|
931
|
+
${renderSkillSupport(normalized.skills)}
|
|
136
932
|
const generatedWorkspaceSandboxId = ${jsString(normalized.workspace.cloudflareSandboxId)};
|
|
137
933
|
|
|
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
934
|
const workspaceNamespaceFor = (env: AgentOSTargetEnv): DurableObjectNamespace<Sandbox> =>
|
|
151
935
|
env[${jsString(normalized.workspace.binding)}] as DurableObjectNamespace<Sandbox>;
|
|
152
936
|
|
|
@@ -221,36 +1005,46 @@ const workspaceEnvFor = (env: AgentOSTargetEnv) =>
|
|
|
221
1005
|
workspaceRef: ${jsString(normalized.workspace.providerResourceId)},
|
|
222
1006
|
});
|
|
223
1007
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
1008
|
+
const generatedHostProfileFor = (env: AgentOSTargetEnv) => defineHost({
|
|
1009
|
+
target: "cloudflare-do@1",
|
|
1010
|
+
provides: [
|
|
1011
|
+
"storage.ledger",
|
|
1012
|
+
"durability.do",
|
|
1013
|
+
WORKSPACE_OPERATION_HOST_FACT,
|
|
1014
|
+
"timer.durable",
|
|
1015
|
+
"network.outbound",
|
|
1016
|
+
"secrets.store",
|
|
1017
|
+
"eventLoop.durable",
|
|
1018
|
+
"llm.openai",
|
|
1019
|
+
],
|
|
1020
|
+
materialize: () => ({
|
|
1021
|
+
[WORKSPACE_OPERATION_HOST_FACT]: () => workspaceEnvFor(env),
|
|
1022
|
+
}),
|
|
1023
|
+
});
|
|
228
1024
|
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
1025
|
+
const generatedCapabilityInstallGraphFor = (env: AgentOSTargetEnv) => {
|
|
1026
|
+
const graph = resolveRuntimeInstallGraph(
|
|
1027
|
+
generatedHostProfileFor(env),
|
|
1028
|
+
[workspaceOperations(generatedWorkspaceOperations)],
|
|
1029
|
+
{ identity: semanticManifest.agentId },
|
|
1030
|
+
);
|
|
1031
|
+
if (!graph.ok) {
|
|
1032
|
+
throw Error(
|
|
1033
|
+
graph.diagnostics
|
|
1034
|
+
.map((diagnostic) => diagnostic.reason)
|
|
1035
|
+
.join("; ") || "capability install graph failed",
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
return graph.resolved;
|
|
1039
|
+
};
|
|
233
1040
|
|
|
234
1041
|
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
235
1042
|
const value = env[name];
|
|
236
1043
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
237
1044
|
};
|
|
238
1045
|
|
|
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
|
-
};
|
|
1046
|
+
${renderMaterialValueFunction(normalized.llmRoutes)}
|
|
1047
|
+
${renderGeneratedProviderPreflight(normalized.llmRoutes)}
|
|
254
1048
|
|
|
255
1049
|
const requiredStringMaterial = (
|
|
256
1050
|
kind: string,
|
|
@@ -261,70 +1055,45 @@ const requiredStringMaterial = (
|
|
|
261
1055
|
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
262
1056
|
};
|
|
263
1057
|
|
|
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
|
-
};
|
|
1058
|
+
${renderGeneratedLlmRoutesFor(normalized.llmRoutes)}
|
|
281
1059
|
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
if (!
|
|
1060
|
+
const generatedSubmitBindingsFor = async (
|
|
1061
|
+
env: AgentOSTargetEnv,
|
|
1062
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1063
|
+
dynamicCapability: DynamicCapabilityRunInput | undefined = undefined,
|
|
1064
|
+
): Promise<GeneratedTargetResult<AgentSubmitBindings>> => {
|
|
1065
|
+
const preflightDiagnostics = generatedProviderPreflightDiagnosticsFor(env);
|
|
1066
|
+
if (preflightDiagnostics.length > 0) {
|
|
1067
|
+
return targetFailure(
|
|
1068
|
+
"OpenAI-compatible provider material preflight failed",
|
|
1069
|
+
preflightDiagnostics,
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
const capabilityGraph = generatedCapabilityInstallGraphFor(env);
|
|
1073
|
+
const routes = generatedLlmRoutesFor(env);
|
|
1074
|
+
if (!routes.ok) return routes;
|
|
1075
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event, dynamicCapability);
|
|
1076
|
+
if (!dynamicBindings.ok) return dynamicBindings;
|
|
1077
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
299
1078
|
return {
|
|
300
1079
|
ok: true,
|
|
301
1080
|
value: {
|
|
302
|
-
...
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
},
|
|
1081
|
+
...capabilityGraph.bindings,
|
|
1082
|
+
...dynamicBindings.value,
|
|
1083
|
+
llmRoutes: routes.value,
|
|
306
1084
|
tools: {
|
|
307
|
-
...(
|
|
1085
|
+
...(capabilityGraph.bindings.tools ?? {}),
|
|
308
1086
|
...generatedCustomTools,
|
|
1087
|
+
${hasSkills ? "...generatedFrameworkToolsFor(dynamicCapabilityProjection)," : ""}
|
|
309
1088
|
},
|
|
310
1089
|
},
|
|
311
1090
|
};
|
|
312
1091
|
};
|
|
313
1092
|
|
|
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
|
-
});
|
|
1093
|
+
${renderSubmitSpecFromRunInput(hasSkills)}
|
|
1094
|
+
|
|
1095
|
+
${renderProductApiHelpers()}
|
|
1096
|
+
${hasSchedules ? renderScheduleDurableObjectHelpers() : ""}
|
|
328
1097
|
|
|
329
1098
|
export const workspaceMount = defineWorkspaceAgentMount({
|
|
330
1099
|
driver: { kind: "driver_mount", client: undefined as never },
|
|
@@ -337,22 +1106,24 @@ export const workspaceMount = defineWorkspaceAgentMount({
|
|
|
337
1106
|
],
|
|
338
1107
|
});
|
|
339
1108
|
|
|
340
|
-
const Base${
|
|
1109
|
+
const Base${target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
341
1110
|
manifest: semanticManifest,
|
|
342
|
-
agentBindings: {
|
|
1111
|
+
agentBindings: (env) => ({
|
|
343
1112
|
handlers: ${handlerRecord},
|
|
344
|
-
|
|
1113
|
+
...generatedCapabilityInstallGraphFor(env).agentBindings,
|
|
1114
|
+
}),
|
|
345
1115
|
refResolver: (env) => ({
|
|
346
1116
|
material: (ref) => materialValue(env, ref),
|
|
347
1117
|
}),
|
|
348
1118
|
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
349
|
-
extensions: (env) =>
|
|
350
|
-
declaredIntents: (env) =>
|
|
351
|
-
projections: (env) =>
|
|
352
|
-
|
|
1119
|
+
extensions: (env) => generatedCapabilityInstallGraphFor(env).extensions,
|
|
1120
|
+
declaredIntents: (env) => generatedCapabilityInstallGraphFor(env).declaredIntents,
|
|
1121
|
+
projections: (env) => generatedCapabilityInstallGraphFor(env).projections,
|
|
1122
|
+
graphStatus: (env) => generatedCapabilityInstallGraphFor(env).graphStatus,
|
|
1123
|
+
eventHandlers: (context, env) => generatedCapabilityInstallGraphFor(env).handlers(context),
|
|
353
1124
|
});
|
|
354
1125
|
|
|
355
|
-
export class ${
|
|
1126
|
+
export class ${target.durableObject.className} extends Base${target.durableObject.className} {
|
|
356
1127
|
private readonly targetEnv: AgentOSTargetEnv;
|
|
357
1128
|
|
|
358
1129
|
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
@@ -361,31 +1132,47 @@ export class ${normalized.target.durableObject.className} extends Base${normaliz
|
|
|
361
1132
|
}
|
|
362
1133
|
|
|
363
1134
|
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
1135
|
+
return generatedSubmitBindingsFor(
|
|
1136
|
+
this.targetEnv,
|
|
1137
|
+
generatedDynamicCapabilityTurnEvent(),
|
|
1138
|
+
spec.dynamicCapability,
|
|
1139
|
+
).then((bindings) =>
|
|
1140
|
+
bindings.ok ? this.submitWithBindings(spec, bindings.value) : rejectTargetFailure(bindings),
|
|
1141
|
+
);
|
|
368
1142
|
}
|
|
369
1143
|
|
|
370
1144
|
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
1145
|
+
return generatedSubmitBindingsFor(
|
|
1146
|
+
this.targetEnv,
|
|
1147
|
+
generatedDynamicCapabilityTurnEvent(),
|
|
1148
|
+
input.dynamicCapability,
|
|
1149
|
+
).then((bindings) =>
|
|
1150
|
+
bindings.ok
|
|
1151
|
+
? this.submitWithBindings(
|
|
1152
|
+
submitSpecFromRunInput(input, bindings.value.dynamicCapabilityProjection),
|
|
1153
|
+
bindings.value,
|
|
1154
|
+
)
|
|
1155
|
+
: rejectTargetFailure(bindings),
|
|
1156
|
+
);
|
|
375
1157
|
}
|
|
376
1158
|
|
|
1159
|
+
${renderProductApiDurableObjectMethods()}
|
|
1160
|
+
${hasSchedules ? renderScheduleDurableObjectMethod() : ""}
|
|
1161
|
+
|
|
377
1162
|
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
1163
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1164
|
+
bindings.ok
|
|
1165
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
1166
|
+
: rejectTargetFailure(bindings),
|
|
1167
|
+
);
|
|
382
1168
|
}
|
|
383
1169
|
|
|
384
1170
|
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1171
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1172
|
+
bindings.ok
|
|
1173
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
1174
|
+
: rejectTargetFailure(bindings),
|
|
1175
|
+
);
|
|
389
1176
|
}
|
|
390
1177
|
|
|
391
1178
|
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
@@ -453,6 +1240,10 @@ export class ${normalized.target.durableObject.className} extends Base${normaliz
|
|
|
453
1240
|
`;
|
|
454
1241
|
};
|
|
455
1242
|
const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
1243
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1244
|
+
const hasSkills = normalized.skills.length > 0;
|
|
1245
|
+
const hasDynamicCapability = true;
|
|
1246
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
456
1247
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
457
1248
|
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
458
1249
|
const toolImports = customToolNames
|
|
@@ -466,39 +1257,324 @@ const renderChatStaticTarget = (normalized, toolNames, modules) => {
|
|
|
466
1257
|
const handlerRecord = `{\n${normalized.deployment.manifest.handlers
|
|
467
1258
|
.map((handler) => ` ${jsString(handler)}: generatedHandler,`)
|
|
468
1259
|
.join("\n")}\n}`;
|
|
1260
|
+
const llmEnvBindings = uniqueLlmMaterialEnvBindings(normalized.llmRoutes);
|
|
1261
|
+
const generatedLlmEnvFields = llmEnvBindings
|
|
1262
|
+
.map((binding) => ` readonly ${binding.envName}?: string;`)
|
|
1263
|
+
.join("\n");
|
|
1264
|
+
const imports = [
|
|
1265
|
+
`import semanticDeclarations from "./manifest.json";`,
|
|
1266
|
+
`import deploymentProvenance from "./deployment.json";`,
|
|
1267
|
+
...(hasSchedules
|
|
1268
|
+
? [renderNamedImport(["dispatchGeneratedScheduleDelivery"], "./schedules")]
|
|
1269
|
+
: []),
|
|
1270
|
+
renderNamedImport(["createAgentDurableObject"], modules.cloudflareDoRuntime),
|
|
1271
|
+
renderNamedImport(["runDynamicCapabilityResolvers"], modules.runtimeCapability),
|
|
1272
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
1273
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
1274
|
+
renderNamedImport(["projectAgentSession", "projectAgentSessions", "projectWorkflowRun", "projectWorkflowRuns"], modules.runtimeRunProjector),
|
|
1275
|
+
renderNamedImport([
|
|
1276
|
+
"deterministicToolInvocation",
|
|
1277
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
1278
|
+
"unsafeRunToolByName",
|
|
1279
|
+
], modules.coreTools),
|
|
1280
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
1281
|
+
renderTypeImport(["AgentManifest", "AgentSubmitBindings", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
1282
|
+
...(hasDynamicCapability
|
|
1283
|
+
? [
|
|
1284
|
+
renderTypeImport([
|
|
1285
|
+
"DynamicCapabilityCompiledCatalog",
|
|
1286
|
+
"DynamicCapabilityEventRef",
|
|
1287
|
+
"DynamicCapabilityProjection",
|
|
1288
|
+
"DynamicCapabilityRunInput",
|
|
1289
|
+
"SubmitInstructionFragment",
|
|
1290
|
+
], modules.runtimeProtocol),
|
|
1291
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
1292
|
+
]
|
|
1293
|
+
: []),
|
|
1294
|
+
renderTypeImport([
|
|
1295
|
+
"AgentSessionListProjection",
|
|
1296
|
+
"AgentSessionProjection",
|
|
1297
|
+
"WorkflowRunListProjection",
|
|
1298
|
+
"WorkflowRunProjection",
|
|
1299
|
+
], modules.runtimeRunProjector),
|
|
1300
|
+
renderTypeImport(["AgentSubmitSpec"], modules.cloudflareDoRuntime),
|
|
1301
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
1302
|
+
renderTypeImport([
|
|
1303
|
+
"WorkspaceAgentCustomCommandInput",
|
|
1304
|
+
"WorkspaceAgentDecideInputRequestCommandInput",
|
|
1305
|
+
"WorkspaceAgentResumeInputRequestCommandInput",
|
|
1306
|
+
], modules.workspaceAgentHost),
|
|
1307
|
+
renderTypeImport(["Tool"], modules.coreTools),
|
|
1308
|
+
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
1309
|
+
].join("\n");
|
|
1310
|
+
return `${imports}
|
|
1311
|
+
|
|
1312
|
+
export const targetDeclarations = semanticDeclarations;
|
|
1313
|
+
export const targetDeployment = deploymentProvenance;
|
|
1314
|
+
|
|
1315
|
+
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
1316
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
1317
|
+
const generatedHandler = () => undefined;
|
|
1318
|
+
|
|
1319
|
+
type AgentOSTargetEnv = {
|
|
1320
|
+
readonly [binding: string]: unknown;
|
|
1321
|
+
${generatedLlmEnvFields}
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
type GeneratedTargetFailure = {
|
|
1325
|
+
readonly ok: false;
|
|
1326
|
+
readonly message: string;
|
|
1327
|
+
readonly diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
type GeneratedTargetResult<Value> =
|
|
1331
|
+
| { readonly ok: true; readonly value: Value }
|
|
1332
|
+
| GeneratedTargetFailure;
|
|
1333
|
+
|
|
1334
|
+
const targetFailure = (
|
|
1335
|
+
message: string,
|
|
1336
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>,
|
|
1337
|
+
): GeneratedTargetFailure => ({
|
|
1338
|
+
ok: false,
|
|
1339
|
+
message,
|
|
1340
|
+
...(diagnostics === undefined || diagnostics.length === 0 ? {} : { diagnostics }),
|
|
1341
|
+
});
|
|
1342
|
+
|
|
1343
|
+
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> => {
|
|
1344
|
+
const error = Error(failure.message) as Error & {
|
|
1345
|
+
diagnostics?: ReturnType<typeof preflightOpenAiCompatibleProviderMaterial>;
|
|
1346
|
+
};
|
|
1347
|
+
if (failure.diagnostics !== undefined) error.diagnostics = failure.diagnostics;
|
|
1348
|
+
return Promise.reject(error);
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1351
|
+
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
1352
|
+
${renderDynamicCapabilitySupport(normalized, toolNames, hasSkills)}
|
|
1353
|
+
${renderSkillSupport(normalized.skills)}
|
|
1354
|
+
|
|
1355
|
+
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
1356
|
+
const value = env[name];
|
|
1357
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1358
|
+
};
|
|
1359
|
+
|
|
1360
|
+
${renderMaterialValueFunction(normalized.llmRoutes)}
|
|
1361
|
+
${renderGeneratedProviderPreflight(normalized.llmRoutes)}
|
|
1362
|
+
|
|
1363
|
+
const requiredStringMaterial = (
|
|
1364
|
+
kind: string,
|
|
1365
|
+
ref: string,
|
|
1366
|
+
value: NonNullable<unknown> | null,
|
|
1367
|
+
): GeneratedTargetResult<string> => {
|
|
1368
|
+
if (typeof value === "string" && value.length > 0) return { ok: true, value };
|
|
1369
|
+
return targetFailure(\`missing \${kind} material: \${ref}\`);
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1372
|
+
${renderGeneratedLlmRoutesFor(normalized.llmRoutes)}
|
|
1373
|
+
|
|
1374
|
+
const generatedSubmitBindingsFor = async (
|
|
1375
|
+
env: AgentOSTargetEnv,
|
|
1376
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1377
|
+
dynamicCapability: DynamicCapabilityRunInput | undefined = undefined,
|
|
1378
|
+
): Promise<GeneratedTargetResult<AgentSubmitBindings>> => {
|
|
1379
|
+
const preflightDiagnostics = generatedProviderPreflightDiagnosticsFor(env);
|
|
1380
|
+
if (preflightDiagnostics.length > 0) {
|
|
1381
|
+
return targetFailure(
|
|
1382
|
+
"OpenAI-compatible provider material preflight failed",
|
|
1383
|
+
preflightDiagnostics,
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
const routes = generatedLlmRoutesFor(env);
|
|
1387
|
+
if (!routes.ok) return routes;
|
|
1388
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event, dynamicCapability);
|
|
1389
|
+
if (!dynamicBindings.ok) return dynamicBindings;
|
|
1390
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
1391
|
+
return {
|
|
1392
|
+
ok: true,
|
|
1393
|
+
value: {
|
|
1394
|
+
...dynamicBindings.value,
|
|
1395
|
+
llmRoutes: routes.value,
|
|
1396
|
+
tools: ${hasSkills
|
|
1397
|
+
? `{
|
|
1398
|
+
...generatedCustomTools,
|
|
1399
|
+
...generatedFrameworkToolsFor(dynamicCapabilityProjection),
|
|
1400
|
+
}`
|
|
1401
|
+
: "generatedCustomTools"},
|
|
1402
|
+
},
|
|
1403
|
+
};
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
${renderSubmitSpecFromRunInput(hasSkills)}
|
|
1407
|
+
|
|
1408
|
+
${renderProductApiHelpers()}
|
|
1409
|
+
${hasSchedules ? renderScheduleDurableObjectHelpers() : ""}
|
|
1410
|
+
|
|
1411
|
+
const Base${target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
1412
|
+
manifest: semanticManifest,
|
|
1413
|
+
agentBindings: {
|
|
1414
|
+
handlers: ${handlerRecord},
|
|
1415
|
+
},
|
|
1416
|
+
refResolver: (env) => ({
|
|
1417
|
+
material: (ref) => materialValue(env, ref),
|
|
1418
|
+
}),
|
|
1419
|
+
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
1420
|
+
});
|
|
1421
|
+
|
|
1422
|
+
export class ${target.durableObject.className} extends Base${target.durableObject.className} {
|
|
1423
|
+
private readonly targetEnv: AgentOSTargetEnv;
|
|
1424
|
+
|
|
1425
|
+
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
1426
|
+
super(ctx, env);
|
|
1427
|
+
this.targetEnv = env;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
1431
|
+
return generatedSubmitBindingsFor(
|
|
1432
|
+
this.targetEnv,
|
|
1433
|
+
generatedDynamicCapabilityTurnEvent(),
|
|
1434
|
+
spec.dynamicCapability,
|
|
1435
|
+
).then((bindings) =>
|
|
1436
|
+
bindings.ok ? this.submitWithBindings(spec, bindings.value) : rejectTargetFailure(bindings),
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
1441
|
+
return generatedSubmitBindingsFor(
|
|
1442
|
+
this.targetEnv,
|
|
1443
|
+
generatedDynamicCapabilityTurnEvent(),
|
|
1444
|
+
input.dynamicCapability,
|
|
1445
|
+
).then((bindings) =>
|
|
1446
|
+
bindings.ok
|
|
1447
|
+
? this.submitWithBindings(
|
|
1448
|
+
submitSpecFromRunInput(input, bindings.value.dynamicCapabilityProjection),
|
|
1449
|
+
bindings.value,
|
|
1450
|
+
)
|
|
1451
|
+
: rejectTargetFailure(bindings),
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
${renderProductApiDurableObjectMethods()}
|
|
1456
|
+
${hasSchedules ? renderScheduleDurableObjectMethod() : ""}
|
|
1457
|
+
|
|
1458
|
+
resumeInputRequest(input: WorkspaceAgentResumeInputRequestCommandInput): Promise<SubmitResult> {
|
|
1459
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1460
|
+
bindings.ok
|
|
1461
|
+
? this.resumeInputRequestWithBindings(input, bindings.value)
|
|
1462
|
+
: rejectTargetFailure(bindings),
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
decideInputRequest(input: WorkspaceAgentDecideInputRequestCommandInput): Promise<SubmitResult> {
|
|
1467
|
+
return generatedSubmitBindingsFor(this.targetEnv).then((bindings) =>
|
|
1468
|
+
bindings.ok
|
|
1469
|
+
? this.decideInputRequestWithBindings(input, bindings.value)
|
|
1470
|
+
: rejectTargetFailure(bindings),
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
customCommand(input: WorkspaceAgentCustomCommandInput): Promise<unknown> {
|
|
1475
|
+
return Effect.runPromise(
|
|
1476
|
+
unsafeRunToolByName(
|
|
1477
|
+
generatedCustomTools,
|
|
1478
|
+
deterministicToolInvocation(input.method, input.input),
|
|
1479
|
+
),
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
`;
|
|
1484
|
+
};
|
|
1485
|
+
const renderLocalAgentApp = (normalized, toolNames, modules) => {
|
|
1486
|
+
if (normalized.target.kind !== AGENTOS_CONFIG_TARGET.NODE_V1) {
|
|
1487
|
+
throw new TypeError(`local agent app renderer received ${normalized.target.kind}`);
|
|
1488
|
+
}
|
|
1489
|
+
const hasChannels = normalized.channels.length > 0;
|
|
1490
|
+
const hasSkills = normalized.skills.length > 0;
|
|
1491
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
1492
|
+
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1493
|
+
const workspaceToolList = toolNames.filter((toolName) => isWorkspaceToolName(toolName) && !authoredToolNames.has(toolName));
|
|
1494
|
+
const customToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
1495
|
+
const toolImports = customToolNames
|
|
1496
|
+
.map((toolName, index) => `import tool_${index} from ${jsString(importToolPath(toolName))};`)
|
|
1497
|
+
.join("\n");
|
|
1498
|
+
const customToolRecord = customToolNames.length === 0
|
|
1499
|
+
? "{}"
|
|
1500
|
+
: `{\n${customToolNames
|
|
1501
|
+
.map((toolName, index) => ` ${jsString(toolName)}: tool_${index},`)
|
|
1502
|
+
.join("\n")}\n}`;
|
|
1503
|
+
const workspaceToolArray = `[${workspaceToolList.map(jsString).join(", ")}] as const`;
|
|
1504
|
+
const usesMutationTools = workspaceToolList.some((toolName) => workspaceMutationToolNames.has(toolName));
|
|
1505
|
+
const usesShellTools = workspaceToolList.some((toolName) => workspaceShellToolNames.has(toolName));
|
|
469
1506
|
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
1507
|
const imports = [
|
|
474
1508
|
`import semanticDeclarations from "./manifest.json";`,
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
1509
|
+
...(hasChannels ? [renderNamedImport(["dispatchGeneratedChannelRequest"], "./channels")] : []),
|
|
1510
|
+
...(hasChannels ? [renderTypeImport(["ChannelRuntime"], modules.runtimeChannel)] : []),
|
|
1511
|
+
...(hasSchedules
|
|
1512
|
+
? [
|
|
1513
|
+
renderNamedImport([
|
|
1514
|
+
"dispatchGeneratedScheduleDelivery",
|
|
1515
|
+
"generatedScheduleDefinitions",
|
|
1516
|
+
"generatedScheduleIds",
|
|
1517
|
+
], "./schedules"),
|
|
1518
|
+
]
|
|
1519
|
+
: []),
|
|
1520
|
+
...(hasSchedules ? [renderTypeImport(["GeneratedScheduleTriggerInput"], "./schedules")] : []),
|
|
1521
|
+
renderNamedImport(["lowerLocalAgentRuntime"], modules.localRuntime),
|
|
1522
|
+
renderNamedImport(["runDynamicCapabilityResolvers"], modules.runtimeCapability),
|
|
1523
|
+
...(hasSchedules
|
|
1524
|
+
? [renderNamedImport(["projectScheduleFireHistory"], modules.runtimeSchedule)]
|
|
1525
|
+
: []),
|
|
1526
|
+
renderNamedImport(["DYNAMIC_CAPABILITY_EVENT", "manifestTruthIdentity"], modules.runtimeProtocol),
|
|
1527
|
+
renderNamedImport(["OpenAiCompatibleLlmTransportLive", "preflightOpenAiCompatibleProviderMaterial"], modules.openAiCompatibleTransport),
|
|
1528
|
+
renderNamedImport([
|
|
1529
|
+
"projectAgentSession",
|
|
1530
|
+
"projectAgentSessions",
|
|
1531
|
+
"projectRunInspection",
|
|
1532
|
+
"projectWorkflowRun",
|
|
1533
|
+
"projectWorkflowRuns",
|
|
1534
|
+
], modules.runtimeRunProjector),
|
|
1535
|
+
renderTypeImport(["AgentManifest", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol),
|
|
482
1536
|
renderTypeImport([
|
|
483
|
-
"
|
|
484
|
-
"
|
|
485
|
-
"
|
|
486
|
-
|
|
1537
|
+
"AgentSubmitBindings",
|
|
1538
|
+
"DynamicCapabilityCompiledCatalog",
|
|
1539
|
+
"DynamicCapabilityEventRef",
|
|
1540
|
+
"DynamicCapabilityProjection",
|
|
1541
|
+
"DynamicCapabilityRunInput",
|
|
1542
|
+
"SubmitInstructionFragment",
|
|
1543
|
+
], modules.runtimeProtocol),
|
|
1544
|
+
renderTypeImport(["DynamicCapabilityResolverDefinition"], modules.runtimeCapability),
|
|
1545
|
+
...(hasSchedules
|
|
1546
|
+
? [
|
|
1547
|
+
renderTypeImport([
|
|
1548
|
+
"ScheduleDefinitionProjection",
|
|
1549
|
+
"ScheduleFireHistoryProjection",
|
|
1550
|
+
"ScheduleFireProjection",
|
|
1551
|
+
], modules.runtimeSchedule),
|
|
1552
|
+
]
|
|
1553
|
+
: []),
|
|
1554
|
+
renderTypeImport([
|
|
1555
|
+
"AgentSessionListProjection",
|
|
1556
|
+
"AgentSessionProjection",
|
|
1557
|
+
"RunInspection",
|
|
1558
|
+
"WorkflowRunListProjection",
|
|
1559
|
+
"WorkflowRunProjection",
|
|
1560
|
+
], modules.runtimeRunProjector),
|
|
1561
|
+
renderTypeImport(["CreateLocalAgentRuntimeOptions", "LocalAgentRuntime", "LocalAgentSubmitInput"], modules.localRuntime),
|
|
1562
|
+
renderTypeImport(["WorkspaceAgentCustomCommandInput"], modules.workspaceAgentHost),
|
|
1563
|
+
renderNamedImport([
|
|
1564
|
+
...(hasSkills ? ["defineProductTool"] : []),
|
|
1565
|
+
"deterministicToolInvocation",
|
|
1566
|
+
"unsafeRunToolByName",
|
|
1567
|
+
], modules.coreTools),
|
|
1568
|
+
renderNamedImport(hasSkills ? ["Effect", "Schema"] : ["Effect"], modules.effect),
|
|
487
1569
|
renderTypeImport(["Tool"], modules.coreTools),
|
|
488
1570
|
...(toolImports.length === 0 ? [] : [toolImports]),
|
|
489
1571
|
].join("\n");
|
|
490
1572
|
return `${imports}
|
|
491
1573
|
|
|
492
|
-
export const targetDeclarations = semanticDeclarations;
|
|
493
|
-
export const targetDeployment = deploymentProvenance;
|
|
494
|
-
|
|
495
1574
|
const semanticManifest = semanticDeclarations as AgentManifest;
|
|
496
|
-
const
|
|
1575
|
+
const semanticTruthIdentity = manifestTruthIdentity(semanticManifest);
|
|
497
1576
|
|
|
498
|
-
type AgentOSTargetEnv =
|
|
499
|
-
readonly [binding: string]: unknown;
|
|
500
|
-
${generatedLlmEnvFields}
|
|
501
|
-
};
|
|
1577
|
+
type AgentOSTargetEnv = Readonly<Record<string, string | undefined>>;
|
|
502
1578
|
|
|
503
1579
|
type GeneratedTargetFailure = {
|
|
504
1580
|
readonly ok: false;
|
|
@@ -509,12 +1585,33 @@ type GeneratedTargetResult<Value> =
|
|
|
509
1585
|
| { readonly ok: true; readonly value: Value }
|
|
510
1586
|
| GeneratedTargetFailure;
|
|
511
1587
|
|
|
512
|
-
const targetFailure = (message: string): GeneratedTargetFailure => ({
|
|
1588
|
+
const targetFailure = (message: string): GeneratedTargetFailure => ({
|
|
1589
|
+
ok: false,
|
|
1590
|
+
message,
|
|
1591
|
+
});
|
|
513
1592
|
|
|
514
1593
|
const rejectTargetFailure = (failure: GeneratedTargetFailure): Promise<never> =>
|
|
515
1594
|
Promise.reject(Error(failure.message));
|
|
516
1595
|
|
|
1596
|
+
${renderGeneratedWorkspaceOperations(workspaceToolArray, usesMutationTools, usesShellTools)}
|
|
517
1597
|
const generatedCustomTools = ${customToolRecord} satisfies Readonly<Record<string, Tool>>;
|
|
1598
|
+
${renderDynamicCapabilitySupport(normalized, toolNames, hasSkills)}
|
|
1599
|
+
${renderSkillSupport(normalized.skills)}
|
|
1600
|
+
|
|
1601
|
+
const cleanEnv = (source: AgentOSTargetEnv): Record<string, string> => {
|
|
1602
|
+
const env: Record<string, string> = {};
|
|
1603
|
+
for (const [key, value] of Object.entries(source)) {
|
|
1604
|
+
if (value !== undefined) env[key] = value;
|
|
1605
|
+
}
|
|
1606
|
+
return env;
|
|
1607
|
+
};
|
|
1608
|
+
|
|
1609
|
+
const generatedTargetEnvFor = (
|
|
1610
|
+
options: Pick<CreateLocalAgentAppOptions, "env" | "inheritEnv">,
|
|
1611
|
+
): AgentOSTargetEnv => ({
|
|
1612
|
+
...(options.inheritEnv === true ? cleanEnv(process.env) : {}),
|
|
1613
|
+
...(options.env === undefined ? {} : cleanEnv(options.env)),
|
|
1614
|
+
});
|
|
518
1615
|
|
|
519
1616
|
const materialEnvValue = (env: AgentOSTargetEnv, name: string): string | null => {
|
|
520
1617
|
const value = env[name];
|
|
@@ -537,124 +1634,221 @@ const materialValue = (
|
|
|
537
1634
|
return null;
|
|
538
1635
|
};
|
|
539
1636
|
|
|
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;
|
|
1637
|
+
const generatedLocalLlmFor = (
|
|
1638
|
+
env: AgentOSTargetEnv,
|
|
1639
|
+
): NonNullable<CreateLocalAgentRuntimeOptions["llm"]> => {
|
|
1640
|
+
const modelValue = materialValue(env, { kind: "model", ref: ${jsString(normalized.llm.modelRef)} });
|
|
556
1641
|
return {
|
|
557
|
-
|
|
558
|
-
|
|
1642
|
+
kind: "transport",
|
|
1643
|
+
transport: OpenAiCompatibleLlmTransportLive,
|
|
1644
|
+
route: {
|
|
559
1645
|
kind: "openai-chat-compatible",
|
|
560
1646
|
endpointRef: ${jsString(normalized.llm.endpointRef)},
|
|
561
1647
|
credentialRef: ${jsString(normalized.llm.credentialRef)},
|
|
562
|
-
modelId:
|
|
1648
|
+
modelId: typeof modelValue === "string" ? modelValue : "",
|
|
1649
|
+
},
|
|
1650
|
+
refResolver: {
|
|
1651
|
+
material: (ref) => materialValue(env, ref),
|
|
563
1652
|
},
|
|
1653
|
+
preflight: preflightOpenAiCompatibleProviderMaterial,
|
|
564
1654
|
};
|
|
565
1655
|
};
|
|
566
1656
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
1657
|
+
${renderProductApiHelpers()}
|
|
1658
|
+
|
|
1659
|
+
const generatedLocalSubmitInputFromRunInput = async (
|
|
1660
|
+
input: SubmitRunInput,
|
|
1661
|
+
event: DynamicCapabilityEventRef = generatedDynamicCapabilityTurnEvent(),
|
|
1662
|
+
): Promise<LocalAgentSubmitInput> => {
|
|
1663
|
+
const dynamicBindings = await generatedDynamicSubmitBindingsFor(event, input.dynamicCapability);
|
|
1664
|
+
if (!dynamicBindings.ok) return rejectTargetFailure(dynamicBindings);
|
|
1665
|
+
const dynamicCapabilityProjection = dynamicBindings.value.dynamicCapabilityProjection;
|
|
570
1666
|
return {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
1667
|
+
...input,
|
|
1668
|
+
...(input.context === undefined ? {} : { context: input.context }),
|
|
1669
|
+
...(input.system === undefined && !${hasSkills} ? {} : {
|
|
1670
|
+
system: ${hasSkills ? "generatedSystemPrompt(input.system, dynamicCapabilityProjection)" : "input.system"},
|
|
1671
|
+
}),
|
|
1672
|
+
dynamicCapabilityProjection,
|
|
1673
|
+
instructionFragments: dynamicBindings.value.instructionFragments,
|
|
1674
|
+
tools: ${hasSkills
|
|
1675
|
+
? `{
|
|
1676
|
+
...generatedCustomTools,
|
|
1677
|
+
...generatedFrameworkToolsFor(dynamicCapabilityProjection),
|
|
1678
|
+
}`
|
|
1679
|
+
: "generatedCustomTools"},
|
|
578
1680
|
};
|
|
579
1681
|
};
|
|
580
1682
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
context: input.context,
|
|
585
|
-
...(input.system === undefined ? {} : { system: input.system }),
|
|
586
|
-
...(input.budget === undefined ? {} : { budget: input.budget }),
|
|
587
|
-
...(input.outputSchema === undefined ? {} : { outputSchema: input.outputSchema }),
|
|
588
|
-
...(input.traceContext === undefined ? {} : { traceContext: input.traceContext }),
|
|
589
|
-
...(input.materials === undefined ? {} : { materials: input.materials }),
|
|
590
|
-
...(input.toolContext === undefined ? {} : { toolContext: input.toolContext }),
|
|
591
|
-
...(input.toolPolicy === undefined ? {} : { toolPolicy: input.toolPolicy }),
|
|
592
|
-
...(input.decisionInterrupts === undefined ? {} : { decisionInterrupts: input.decisionInterrupts }),
|
|
593
|
-
...(input.resume === undefined ? {} : { resume: input.resume }),
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
const Base${normalized.target.durableObject.className} = createAgentDurableObject<AgentOSTargetEnv>({
|
|
597
|
-
manifest: semanticManifest,
|
|
598
|
-
agentBindings: {
|
|
599
|
-
handlers: ${handlerRecord},
|
|
600
|
-
},
|
|
601
|
-
refResolver: (env) => ({
|
|
602
|
-
material: (ref) => materialValue(env, ref),
|
|
603
|
-
}),
|
|
604
|
-
llmTransport: () => OpenAiCompatibleLlmTransportLive,
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
export class ${normalized.target.durableObject.className} extends Base${normalized.target.durableObject.className} {
|
|
608
|
-
private readonly targetEnv: AgentOSTargetEnv;
|
|
609
|
-
|
|
610
|
-
constructor(ctx: DurableObjectState, env: AgentOSTargetEnv) {
|
|
611
|
-
super(ctx, env);
|
|
612
|
-
this.targetEnv = env;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
override submit(spec: AgentSubmitSpec): Promise<SubmitResult> {
|
|
616
|
-
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
617
|
-
return bindings.ok
|
|
618
|
-
? this.submitWithBindings(spec, bindings.value)
|
|
619
|
-
: rejectTargetFailure(bindings);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
submitRunInput(input: SubmitRunInput): Promise<SubmitResult> {
|
|
623
|
-
const bindings = generatedSubmitBindingsFor(this.targetEnv);
|
|
624
|
-
return bindings.ok
|
|
625
|
-
? this.submitWithBindings(submitSpecFromRunInput(input), bindings.value)
|
|
626
|
-
: rejectTargetFailure(bindings);
|
|
627
|
-
}
|
|
1683
|
+
export interface LocalAgentAppRuntime extends LocalAgentRuntime {
|
|
1684
|
+
readonly inspectRun: (runId: number | string) => RunInspection;
|
|
1685
|
+
}
|
|
628
1686
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
1687
|
+
export interface LocalAgentApp {
|
|
1688
|
+
readonly runtime: LocalAgentAppRuntime;
|
|
1689
|
+
readonly sessions: {
|
|
1690
|
+
readonly submitTurn: (input: AgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
1691
|
+
readonly inspect: (sessionRef: string) => AgentSessionProjection;
|
|
1692
|
+
readonly list: () => AgentSessionListProjection;
|
|
1693
|
+
};
|
|
1694
|
+
readonly workflows: {
|
|
1695
|
+
readonly run: (input: AgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
1696
|
+
readonly inspectRun: (
|
|
1697
|
+
workflowId: string,
|
|
1698
|
+
workflowRunId: string,
|
|
1699
|
+
) => WorkflowRunProjection | null;
|
|
1700
|
+
readonly listRuns: (workflowId: string) => WorkflowRunListProjection;
|
|
1701
|
+
};
|
|
1702
|
+
${hasChannels
|
|
1703
|
+
? `readonly channels: {
|
|
1704
|
+
readonly handle: (request: Request) => Promise<Response | null>;
|
|
1705
|
+
};`
|
|
1706
|
+
: ""}
|
|
1707
|
+
readonly customCommand: (input: WorkspaceAgentCustomCommandInput) => Promise<unknown>;
|
|
1708
|
+
${hasSchedules
|
|
1709
|
+
? `readonly schedules: {
|
|
1710
|
+
readonly ids: ReadonlyArray<string>;
|
|
1711
|
+
readonly list: () => ReadonlyArray<ScheduleDefinitionProjection>;
|
|
1712
|
+
readonly trigger: (input: GeneratedScheduleTriggerInput) => Promise<ScheduleFireProjection>;
|
|
1713
|
+
readonly history: (input?: { readonly scheduleId?: string }) => ScheduleFireHistoryProjection;
|
|
1714
|
+
};`
|
|
1715
|
+
: ""}
|
|
1716
|
+
}
|
|
635
1717
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
1718
|
+
${hasChannels
|
|
1719
|
+
? `export const handleLocalAgentChannelRequest = (
|
|
1720
|
+
request: Request,
|
|
1721
|
+
runtime: ChannelRuntime,
|
|
1722
|
+
): Promise<Response | null> => dispatchGeneratedChannelRequest(request, runtime);`
|
|
1723
|
+
: ""}
|
|
1724
|
+
|
|
1725
|
+
export interface CreateLocalAgentAppOptions {
|
|
1726
|
+
readonly cwd?: string;
|
|
1727
|
+
readonly env?: CreateLocalAgentRuntimeOptions["env"];
|
|
1728
|
+
readonly inheritEnv?: CreateLocalAgentRuntimeOptions["inheritEnv"];
|
|
1729
|
+
readonly llm?: CreateLocalAgentRuntimeOptions["llm"];
|
|
1730
|
+
}
|
|
642
1731
|
|
|
643
|
-
|
|
644
|
-
|
|
1732
|
+
export const createLocalAgentApp = async (
|
|
1733
|
+
options: CreateLocalAgentAppOptions = {},
|
|
1734
|
+
): Promise<LocalAgentApp> => {
|
|
1735
|
+
const targetEnv = generatedTargetEnvFor(options);
|
|
1736
|
+
const lowered = await lowerLocalAgentRuntime({
|
|
1737
|
+
target: "node@1",
|
|
1738
|
+
identity: semanticManifest.agentId,
|
|
1739
|
+
truthIdentity: semanticTruthIdentity,
|
|
1740
|
+
cwd: options.cwd ?? process.cwd(),
|
|
1741
|
+
...(options.env === undefined ? {} : { env: options.env }),
|
|
1742
|
+
...(options.inheritEnv === undefined ? {} : { inheritEnv: options.inheritEnv }),
|
|
1743
|
+
llm: options.llm ?? generatedLocalLlmFor(targetEnv),
|
|
1744
|
+
workspaceOperations: generatedWorkspaceOperations,
|
|
1745
|
+
});
|
|
1746
|
+
const sessions = {
|
|
1747
|
+
submitTurn: (input: AgentSessionSubmitTurnInput) =>
|
|
1748
|
+
generatedLocalSubmitInputFromRunInput(
|
|
1749
|
+
submitRunInputFromSessionTurn(input),
|
|
1750
|
+
generatedDynamicCapabilityTurnEvent({
|
|
1751
|
+
sessionRef: input.sessionRef,
|
|
1752
|
+
turnRef: input.turnRef,
|
|
1753
|
+
}),
|
|
1754
|
+
).then((submitInput) =>
|
|
1755
|
+
lowered.submitWithProductLink(submitInput, {
|
|
1756
|
+
kind: "session_turn",
|
|
1757
|
+
sessionRef: input.sessionRef,
|
|
1758
|
+
turnRef: input.turnRef,
|
|
1759
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
1760
|
+
}),
|
|
1761
|
+
),
|
|
1762
|
+
inspect: (sessionRef: string) => projectAgentSession(lowered.runtime.events(), sessionRef),
|
|
1763
|
+
list: () => projectAgentSessions(lowered.runtime.events()),
|
|
1764
|
+
};
|
|
1765
|
+
const workflows = {
|
|
1766
|
+
run: (input: AgentWorkflowRunInput) =>
|
|
1767
|
+
generatedLocalSubmitInputFromRunInput(submitRunInputFromWorkflowRun(input)).then(
|
|
1768
|
+
(submitInput) =>
|
|
1769
|
+
lowered.submitWithProductLink(submitInput, {
|
|
1770
|
+
kind: "workflow_run",
|
|
1771
|
+
workflowId: input.workflowId,
|
|
1772
|
+
workflowRunId: input.workflowRunId,
|
|
1773
|
+
...(input.idempotencyKey === undefined ? {} : { idempotencyKey: input.idempotencyKey }),
|
|
1774
|
+
...(input.inputDigest === undefined ? {} : { inputDigest: input.inputDigest }),
|
|
1775
|
+
}),
|
|
1776
|
+
),
|
|
1777
|
+
inspectRun: (workflowId: string, workflowRunId: string) =>
|
|
1778
|
+
projectWorkflowRun(lowered.runtime.events(), workflowId, workflowRunId),
|
|
1779
|
+
listRuns: (workflowId: string) => projectWorkflowRuns(lowered.runtime.events(), workflowId),
|
|
1780
|
+
};
|
|
1781
|
+
const runtime: LocalAgentAppRuntime = {
|
|
1782
|
+
...lowered.runtime,
|
|
1783
|
+
inspectRun: (runId) =>
|
|
1784
|
+
projectRunInspection(lowered.runtime.events(), runId, lowered.runtime.diagnostics()),
|
|
1785
|
+
};
|
|
1786
|
+
${hasChannels
|
|
1787
|
+
? `const channelRuntime: ChannelRuntime = {
|
|
1788
|
+
submit: (input) => lowered.runtime.submit(input),
|
|
1789
|
+
dispatch: async () => {
|
|
1790
|
+
throw new Error("local node channel dispatch is unavailable");
|
|
1791
|
+
},
|
|
1792
|
+
};
|
|
1793
|
+
const channels = {
|
|
1794
|
+
handle: (request: Request) => handleLocalAgentChannelRequest(request, channelRuntime),
|
|
1795
|
+
};`
|
|
1796
|
+
: ""}
|
|
1797
|
+
const customCommand = (input: WorkspaceAgentCustomCommandInput): Promise<unknown> =>
|
|
1798
|
+
Effect.runPromise(
|
|
645
1799
|
unsafeRunToolByName(
|
|
646
1800
|
generatedCustomTools,
|
|
647
1801
|
deterministicToolInvocation(input.method, input.input),
|
|
648
1802
|
),
|
|
649
1803
|
);
|
|
650
|
-
|
|
651
|
-
|
|
1804
|
+
${hasSchedules
|
|
1805
|
+
? `const scheduleHistory = (
|
|
1806
|
+
input: { readonly scheduleId?: string } = {},
|
|
1807
|
+
): ScheduleFireHistoryProjection => projectScheduleFireHistory(lowered.runtime.events(), input);
|
|
1808
|
+
const triggerSchedule = async (
|
|
1809
|
+
input: GeneratedScheduleTriggerInput,
|
|
1810
|
+
): Promise<ScheduleFireProjection> => {
|
|
1811
|
+
const result = await dispatchGeneratedScheduleDelivery({
|
|
1812
|
+
...input,
|
|
1813
|
+
history: lowered.runtime.events(),
|
|
1814
|
+
identity: semanticTruthIdentity,
|
|
1815
|
+
runtime: { sessions, workflows },
|
|
1816
|
+
});
|
|
1817
|
+
if (result.kind === "attempt") {
|
|
1818
|
+
await lowered.commitScheduleFireDispatchWithDelivery(result);
|
|
1819
|
+
}
|
|
1820
|
+
const projected = scheduleHistory({ scheduleId: input.scheduleId }).fires.find(
|
|
1821
|
+
(fire) => fire.fireId === result.fireId,
|
|
1822
|
+
);
|
|
1823
|
+
if (projected === undefined) {
|
|
1824
|
+
throw new Error(\`schedule fire projection missing after commit: \${result.fireId}\`);
|
|
1825
|
+
}
|
|
1826
|
+
return projected;
|
|
1827
|
+
};`
|
|
1828
|
+
: ""}
|
|
1829
|
+
return {
|
|
1830
|
+
runtime,
|
|
1831
|
+
sessions,
|
|
1832
|
+
workflows,
|
|
1833
|
+
${hasChannels ? "channels,\n " : ""}customCommand,
|
|
1834
|
+
${hasSchedules
|
|
1835
|
+
? `schedules: {
|
|
1836
|
+
ids: generatedScheduleIds,
|
|
1837
|
+
list: () => generatedScheduleDefinitions,
|
|
1838
|
+
trigger: triggerSchedule,
|
|
1839
|
+
history: scheduleHistory,
|
|
1840
|
+
},`
|
|
1841
|
+
: ""}
|
|
1842
|
+
};
|
|
1843
|
+
};
|
|
652
1844
|
`;
|
|
653
1845
|
};
|
|
654
1846
|
const renderStaticTarget = (normalized, toolNames, modules) => normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
655
1847
|
? renderWorkspaceStaticTarget(normalized, toolNames, modules)
|
|
656
1848
|
: renderChatStaticTarget(normalized, toolNames, modules);
|
|
657
|
-
const renderCloudflareScopeHelper = (normalized, modules) =>
|
|
1849
|
+
const renderCloudflareScopeHelper = (normalized, modules) => {
|
|
1850
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1851
|
+
return `${renderNamedImport(["durableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
658
1852
|
${renderNamedImport(["manifestTruthIdentity"], modules.runtimeProtocol)}
|
|
659
1853
|
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
660
1854
|
${renderTypeImport(["DurableObjectRpcClient"], `${modules.cloudflareDoRuntime}/do-rpc`)}
|
|
@@ -667,7 +1861,7 @@ export type AgentOSTargetEnv = {
|
|
|
667
1861
|
|
|
668
1862
|
export const agentOSTruthIdentity = manifestTruthIdentity(manifest as AgentManifest);
|
|
669
1863
|
export const agentOSScopeId = agentOSTruthIdentity.scopeRef.scopeId;
|
|
670
|
-
export const agentOSDurableObjectBinding = ${jsString(
|
|
1864
|
+
export const agentOSDurableObjectBinding = ${jsString(target.durableObject.binding)};
|
|
671
1865
|
|
|
672
1866
|
export const agentOSDurableObjectNamespace = (
|
|
673
1867
|
env: AgentOSTargetEnv,
|
|
@@ -681,18 +1875,79 @@ export const agentOSRpcClient = <
|
|
|
681
1875
|
scopeId: string = agentOSScopeId,
|
|
682
1876
|
): DurableObjectRpcClient<Rpc> => durableObjectRpcClient<Rpc>(agentOSDurableObjectNamespace(env), scopeId);
|
|
683
1877
|
`;
|
|
684
|
-
|
|
685
|
-
|
|
1878
|
+
};
|
|
1879
|
+
const renderCloudflareWorkerEntry = (normalized, modules) => {
|
|
1880
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1881
|
+
const hasChannels = normalized.channels.length > 0;
|
|
1882
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
1883
|
+
const cloudflareScopeImports = [
|
|
1884
|
+
...(hasChannels || hasSchedules ? ["agentOSRpcClient"] : []),
|
|
1885
|
+
...(hasSchedules ? ["agentOSScopeId"] : []),
|
|
1886
|
+
];
|
|
1887
|
+
return `${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? `${renderNamedImport(["Sandbox"], modules.cloudflareSandbox)}\n` : ""}${renderNamedImport([target.durableObject.className], "./target")}
|
|
1888
|
+
${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")}
|
|
1889
|
+
|
|
1890
|
+
export { ${target.durableObject.className}${normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 ? ", Sandbox" : ""} };
|
|
686
1891
|
|
|
687
|
-
|
|
1892
|
+
${hasChannels
|
|
1893
|
+
? `type AgentOSChannelRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
1894
|
+
readonly submitRunInput: ChannelRuntime["submit"];
|
|
1895
|
+
readonly dispatchToScope: ChannelRuntime["dispatch"];
|
|
1896
|
+
};
|
|
1897
|
+
|
|
1898
|
+
const generatedChannelRuntimeFor = (env: AgentOSTargetEnv): ChannelRuntime => {
|
|
1899
|
+
const runtime = agentOSRpcClient<AgentOSChannelRpc>(env);
|
|
1900
|
+
return Object.freeze({
|
|
1901
|
+
submit: (input) => runtime.submitRunInput(input),
|
|
1902
|
+
dispatch: (spec) => runtime.dispatchToScope(spec),
|
|
1903
|
+
});
|
|
1904
|
+
};
|
|
1905
|
+
`
|
|
1906
|
+
: ""}
|
|
1907
|
+
${hasSchedules
|
|
1908
|
+
? `type AgentOSScheduleRpc = {
|
|
1909
|
+
readonly dispatchSchedule: (input: GeneratedScheduleTriggerInput) => Promise<unknown>;
|
|
1910
|
+
};
|
|
1911
|
+
|
|
1912
|
+
const generatedScheduleAppPrincipal: GeneratedScheduleTriggerInput["appPrincipal"] = {
|
|
1913
|
+
authority: "agentos.app",
|
|
1914
|
+
subject: agentOSScopeId,
|
|
1915
|
+
};
|
|
1916
|
+
|
|
1917
|
+
const generatedScheduleInputsFor = (
|
|
1918
|
+
controller: ScheduledController,
|
|
1919
|
+
): ReadonlyArray<GeneratedScheduleTriggerInput> =>
|
|
1920
|
+
generatedSchedules
|
|
1921
|
+
.filter((entry) => entry.cron === controller.cron)
|
|
1922
|
+
.map((entry) => ({
|
|
1923
|
+
scheduleId: entry.scheduleId,
|
|
1924
|
+
scheduledAt: controller.scheduledTime,
|
|
1925
|
+
appPrincipal: generatedScheduleAppPrincipal,
|
|
1926
|
+
}));
|
|
1927
|
+
`
|
|
1928
|
+
: ""}
|
|
688
1929
|
|
|
689
1930
|
export default {
|
|
690
|
-
fetch(): Response {
|
|
1931
|
+
async fetch(request: Request, env: AgentOSTargetEnv): Promise<Response> {
|
|
1932
|
+
${hasChannels
|
|
1933
|
+
? `const channelResponse = await dispatchGeneratedChannelRequest(request, generatedChannelRuntimeFor(env));
|
|
1934
|
+
if (channelResponse !== null) return channelResponse;`
|
|
1935
|
+
: ""}
|
|
691
1936
|
return new Response("agentOS Cloudflare target", { status: 404 });
|
|
692
1937
|
},
|
|
1938
|
+
${hasSchedules
|
|
1939
|
+
? `scheduled(controller: ScheduledController, env: AgentOSTargetEnv, ctx: ExecutionContext): void {
|
|
1940
|
+
const runtime = agentOSRpcClient<AgentOSScheduleRpc>(env);
|
|
1941
|
+
for (const input of generatedScheduleInputsFor(controller)) {
|
|
1942
|
+
ctx.waitUntil(runtime.dispatchSchedule(input));
|
|
1943
|
+
}
|
|
1944
|
+
},`
|
|
1945
|
+
: ""}
|
|
693
1946
|
} satisfies ExportedHandler<AgentOSTargetEnv>;
|
|
694
1947
|
`;
|
|
1948
|
+
};
|
|
695
1949
|
const renderCloudflareWranglerConfig = (normalized) => {
|
|
1950
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
696
1951
|
const workspaceConfig = normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
697
1952
|
? {
|
|
698
1953
|
vars: {
|
|
@@ -713,15 +1968,15 @@ const renderCloudflareWranglerConfig = (normalized) => {
|
|
|
713
1968
|
name: normalized.workspace.binding,
|
|
714
1969
|
},
|
|
715
1970
|
{
|
|
716
|
-
class_name:
|
|
717
|
-
name:
|
|
1971
|
+
class_name: target.durableObject.className,
|
|
1972
|
+
name: target.durableObject.binding,
|
|
718
1973
|
},
|
|
719
1974
|
],
|
|
720
1975
|
},
|
|
721
1976
|
migrations: [
|
|
722
1977
|
{
|
|
723
1978
|
tag: "v1",
|
|
724
|
-
new_sqlite_classes: ["Sandbox",
|
|
1979
|
+
new_sqlite_classes: ["Sandbox", target.durableObject.className],
|
|
725
1980
|
},
|
|
726
1981
|
],
|
|
727
1982
|
}
|
|
@@ -729,15 +1984,15 @@ const renderCloudflareWranglerConfig = (normalized) => {
|
|
|
729
1984
|
durable_objects: {
|
|
730
1985
|
bindings: [
|
|
731
1986
|
{
|
|
732
|
-
class_name:
|
|
733
|
-
name:
|
|
1987
|
+
class_name: target.durableObject.className,
|
|
1988
|
+
name: target.durableObject.binding,
|
|
734
1989
|
},
|
|
735
1990
|
],
|
|
736
1991
|
},
|
|
737
1992
|
migrations: [
|
|
738
1993
|
{
|
|
739
1994
|
tag: "v1",
|
|
740
|
-
new_sqlite_classes: [
|
|
1995
|
+
new_sqlite_classes: [target.durableObject.className],
|
|
741
1996
|
},
|
|
742
1997
|
],
|
|
743
1998
|
};
|
|
@@ -759,6 +2014,11 @@ const generatedClientModuleImports = (normalized, modules) => [
|
|
|
759
2014
|
"createWorkspaceAgentClientBridge",
|
|
760
2015
|
"CreateWorkspaceAgentClientOptions",
|
|
761
2016
|
"WorkspaceAgentClientBridge",
|
|
2017
|
+
"WorkspaceAgentProductClient",
|
|
2018
|
+
"WorkspaceAgentProductCommandMap",
|
|
2019
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
2020
|
+
"WorkspaceAgentProductCommandOutputByName",
|
|
2021
|
+
"WORKSPACE_AGENT_PRODUCT_COMMAND",
|
|
762
2022
|
]
|
|
763
2023
|
: [
|
|
764
2024
|
"WORKSPACE_AGENT_COMMAND",
|
|
@@ -807,11 +2067,18 @@ const renderWorkspaceSvelteKitRemote = (normalized, modules) => `${renderNamedIm
|
|
|
807
2067
|
${renderNamedImport(["decodeSseHttpEvents", "responseToSseHttpChunks"], modules.sseHttp)}
|
|
808
2068
|
${renderNamedImport(["Result", "Schema"], modules.effect)}
|
|
809
2069
|
${renderNamedImport(["WORKSPACE_AGENT_COMMAND"], modules.workspaceAgentHost)}
|
|
2070
|
+
${renderNamedImport(["WORKSPACE_AGENT_PRODUCT_COMMAND"], modules.workspaceAgentClient)}
|
|
810
2071
|
${renderNamedImport(["decodeRuntimeLedgerEvent", "isInputRequestRef", "parseInputRequestResumePayload"], modules.runtimeProtocol)}
|
|
811
2072
|
${renderNamedImport(["agentOSRpcClient", "agentOSTruthIdentity"], "./cloudflare-scope")}
|
|
812
2073
|
${renderTypeImport(["AgentRuntimeClient"], modules.cloudflareDoRuntime)}
|
|
813
2074
|
${renderTypeImport(["SseHttpEvent"], modules.sseHttp)}
|
|
814
2075
|
${renderTypeImport(["RuntimeLedgerEvent", "SubmitResult", "SubmitRunInput"], modules.runtimeProtocol)}
|
|
2076
|
+
${renderTypeImport([
|
|
2077
|
+
"AgentSessionListProjection",
|
|
2078
|
+
"AgentSessionProjection",
|
|
2079
|
+
"WorkflowRunListProjection",
|
|
2080
|
+
"WorkflowRunProjection",
|
|
2081
|
+
], modules.runtimeRunProjector)}
|
|
815
2082
|
${renderTypeImport([
|
|
816
2083
|
"WorkspaceAgentCustomCommandInput",
|
|
817
2084
|
"WorkspaceAgentDestroyCommandInput",
|
|
@@ -822,10 +2089,28 @@ ${renderTypeImport([
|
|
|
822
2089
|
"WorkspaceAgentReadStateCommandInput",
|
|
823
2090
|
"WorkspaceAgentResetCommandInput",
|
|
824
2091
|
], modules.workspaceAgentHost)}
|
|
2092
|
+
${renderTypeImport([
|
|
2093
|
+
"WorkspaceAgentSessionSubmitTurnInput",
|
|
2094
|
+
"WorkspaceAgentWorkflowRunInput",
|
|
2095
|
+
"WorkspaceAgentWorkflowRunRef",
|
|
2096
|
+
"WorkspaceAgentWorkflowRunsInput",
|
|
2097
|
+
], modules.workspaceAgentClient)}
|
|
825
2098
|
${renderTypeImport(["AgentOSTargetEnv"], "./cloudflare-scope")}
|
|
826
2099
|
|
|
827
2100
|
type AgentOSRpc = Pick<AgentRuntimeClient, "events" | "streamEvents"> & {
|
|
828
2101
|
readonly submitRunInput: (input: SubmitRunInput) => Promise<SubmitResult>;
|
|
2102
|
+
readonly submitSessionTurn: (input: WorkspaceAgentSessionSubmitTurnInput) => Promise<SubmitResult>;
|
|
2103
|
+
readonly inspectSession: (
|
|
2104
|
+
input: { readonly sessionRef: string },
|
|
2105
|
+
) => Promise<AgentSessionProjection>;
|
|
2106
|
+
readonly listSessions: () => Promise<AgentSessionListProjection>;
|
|
2107
|
+
readonly runWorkflow: (input: WorkspaceAgentWorkflowRunInput) => Promise<SubmitResult>;
|
|
2108
|
+
readonly inspectWorkflowRun: (
|
|
2109
|
+
input: WorkspaceAgentWorkflowRunRef,
|
|
2110
|
+
) => Promise<WorkflowRunProjection | null>;
|
|
2111
|
+
readonly listWorkflowRuns: (
|
|
2112
|
+
input: WorkspaceAgentWorkflowRunsInput,
|
|
2113
|
+
) => Promise<WorkflowRunListProjection>;
|
|
829
2114
|
readonly resumeInputRequest: (
|
|
830
2115
|
input: WorkspaceAgentResumeInputRequestCommandInput,
|
|
831
2116
|
) => Promise<SubmitResult>;
|
|
@@ -908,6 +2193,78 @@ const submitInputFromUnknown = (
|
|
|
908
2193
|
return { ok: true, value: { input: value.input as unknown as AgentOSSubmitRunInput } };
|
|
909
2194
|
};
|
|
910
2195
|
|
|
2196
|
+
const productSubmitInputFromUnknown = (
|
|
2197
|
+
value: unknown,
|
|
2198
|
+
label: string,
|
|
2199
|
+
): GeneratedResult<AgentOSSubmitRunInput> => {
|
|
2200
|
+
if (!isRecord(value)) return fail(400, \`invalid \${label} command input\`);
|
|
2201
|
+
if (typeof value.intent !== "string" || !isRecord(value.context)) {
|
|
2202
|
+
return fail(400, \`invalid \${label} submit run input\`);
|
|
2203
|
+
}
|
|
2204
|
+
return { ok: true, value: value as unknown as AgentOSSubmitRunInput };
|
|
2205
|
+
};
|
|
2206
|
+
|
|
2207
|
+
const sessionTurnInputFromUnknown = (
|
|
2208
|
+
value: unknown,
|
|
2209
|
+
): GeneratedResult<WorkspaceAgentSessionSubmitTurnInput> => {
|
|
2210
|
+
const submitInput = productSubmitInputFromUnknown(value, "submitSessionTurn");
|
|
2211
|
+
if (!submitInput.ok) return submitInput;
|
|
2212
|
+
if (!isRecord(value)) return fail(400, "invalid submitSessionTurn command input");
|
|
2213
|
+
if (typeof value.sessionRef !== "string" || typeof value.turnRef !== "string") {
|
|
2214
|
+
return fail(400, "invalid session turn identity");
|
|
2215
|
+
}
|
|
2216
|
+
return { ok: true, value: value as unknown as WorkspaceAgentSessionSubmitTurnInput };
|
|
2217
|
+
};
|
|
2218
|
+
|
|
2219
|
+
const sessionInspectInputFromUnknown = (
|
|
2220
|
+
value: unknown,
|
|
2221
|
+
): GeneratedResult<{ readonly sessionRef: string }> => {
|
|
2222
|
+
if (!isRecord(value) || typeof value.sessionRef !== "string") {
|
|
2223
|
+
return fail(400, "invalid inspectSession command input");
|
|
2224
|
+
}
|
|
2225
|
+
return { ok: true, value: { sessionRef: value.sessionRef } };
|
|
2226
|
+
};
|
|
2227
|
+
|
|
2228
|
+
const workflowRunInputFromUnknown = (
|
|
2229
|
+
value: unknown,
|
|
2230
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunInput> => {
|
|
2231
|
+
const submitInput = productSubmitInputFromUnknown(value, "runWorkflow");
|
|
2232
|
+
if (!submitInput.ok) return submitInput;
|
|
2233
|
+
if (!isRecord(value)) return fail(400, "invalid runWorkflow command input");
|
|
2234
|
+
if (typeof value.workflowId !== "string" || typeof value.workflowRunId !== "string") {
|
|
2235
|
+
return fail(400, "invalid workflow run identity");
|
|
2236
|
+
}
|
|
2237
|
+
if (value.idempotencyKey !== undefined && typeof value.idempotencyKey !== "string") {
|
|
2238
|
+
return fail(400, "invalid workflow run idempotencyKey");
|
|
2239
|
+
}
|
|
2240
|
+
if (value.inputDigest !== undefined && typeof value.inputDigest !== "string") {
|
|
2241
|
+
return fail(400, "invalid workflow run inputDigest");
|
|
2242
|
+
}
|
|
2243
|
+
return { ok: true, value: value as unknown as WorkspaceAgentWorkflowRunInput };
|
|
2244
|
+
};
|
|
2245
|
+
|
|
2246
|
+
const workflowRunRefFromUnknown = (
|
|
2247
|
+
value: unknown,
|
|
2248
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunRef> => {
|
|
2249
|
+
if (!isRecord(value)) return fail(400, "invalid inspectWorkflowRun command input");
|
|
2250
|
+
if (typeof value.workflowId !== "string" || typeof value.workflowRunId !== "string") {
|
|
2251
|
+
return fail(400, "invalid workflow run identity");
|
|
2252
|
+
}
|
|
2253
|
+
return {
|
|
2254
|
+
ok: true,
|
|
2255
|
+
value: { workflowId: value.workflowId, workflowRunId: value.workflowRunId },
|
|
2256
|
+
};
|
|
2257
|
+
};
|
|
2258
|
+
|
|
2259
|
+
const workflowRunsInputFromUnknown = (
|
|
2260
|
+
value: unknown,
|
|
2261
|
+
): GeneratedResult<WorkspaceAgentWorkflowRunsInput> => {
|
|
2262
|
+
if (!isRecord(value) || typeof value.workflowId !== "string") {
|
|
2263
|
+
return fail(400, "invalid listWorkflowRuns command input");
|
|
2264
|
+
}
|
|
2265
|
+
return { ok: true, value: { workflowId: value.workflowId } };
|
|
2266
|
+
};
|
|
2267
|
+
|
|
911
2268
|
const resumeInputRequestFromUnknown = (
|
|
912
2269
|
value: unknown,
|
|
913
2270
|
): GeneratedResult<WorkspaceAgentResumeInputRequestCommandInput> => {
|
|
@@ -1142,6 +2499,33 @@ export const invokeAgentCommand = command(commandInput, ({ name, input }): Promi
|
|
|
1142
2499
|
? runtime.submitRunInput(submitInput.value.input)
|
|
1143
2500
|
: rejectFailure(submitInput);
|
|
1144
2501
|
}
|
|
2502
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.SUBMIT_SESSION_TURN) {
|
|
2503
|
+
const sessionInput = sessionTurnInputFromUnknown(input);
|
|
2504
|
+
return sessionInput.ok ? runtime.submitSessionTurn(sessionInput.value) : rejectFailure(sessionInput);
|
|
2505
|
+
}
|
|
2506
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.INSPECT_SESSION) {
|
|
2507
|
+
const sessionInput = sessionInspectInputFromUnknown(input);
|
|
2508
|
+
return sessionInput.ok ? runtime.inspectSession(sessionInput.value) : rejectFailure(sessionInput);
|
|
2509
|
+
}
|
|
2510
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.LIST_SESSIONS) {
|
|
2511
|
+
return runtime.listSessions();
|
|
2512
|
+
}
|
|
2513
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.RUN_WORKFLOW) {
|
|
2514
|
+
const workflowInput = workflowRunInputFromUnknown(input);
|
|
2515
|
+
return workflowInput.ok ? runtime.runWorkflow(workflowInput.value) : rejectFailure(workflowInput);
|
|
2516
|
+
}
|
|
2517
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.INSPECT_WORKFLOW_RUN) {
|
|
2518
|
+
const workflowInput = workflowRunRefFromUnknown(input);
|
|
2519
|
+
return workflowInput.ok
|
|
2520
|
+
? runtime.inspectWorkflowRun(workflowInput.value)
|
|
2521
|
+
: rejectFailure(workflowInput);
|
|
2522
|
+
}
|
|
2523
|
+
if (name === WORKSPACE_AGENT_PRODUCT_COMMAND.LIST_WORKFLOW_RUNS) {
|
|
2524
|
+
const workflowInput = workflowRunsInputFromUnknown(input);
|
|
2525
|
+
return workflowInput.ok
|
|
2526
|
+
? runtime.listWorkflowRuns(workflowInput.value)
|
|
2527
|
+
: rejectFailure(workflowInput);
|
|
2528
|
+
}
|
|
1145
2529
|
if (name === WORKSPACE_AGENT_COMMAND.RESUME_INPUT_REQUEST) {
|
|
1146
2530
|
const resumeInput = resumeInputRequestFromUnknown(input);
|
|
1147
2531
|
return resumeInput.ok
|
|
@@ -1500,10 +2884,29 @@ const renderSvelteKitRemote = (normalized, modules) => normalized.profile === AG
|
|
|
1500
2884
|
const renderWorkspaceStaticClient = (normalized, modules) => {
|
|
1501
2885
|
if (normalized.client.kind === AGENTOS_CONFIG_CLIENT.BROWSER_DIRECT_V1) {
|
|
1502
2886
|
return `${renderNamedImport(["createWorkspaceAgentClientBridge"], modules.workspaceAgentClient)}
|
|
1503
|
-
${renderTypeImport([
|
|
2887
|
+
${renderTypeImport([
|
|
2888
|
+
"AgentSessionListProjection",
|
|
2889
|
+
"AgentSessionProjection",
|
|
2890
|
+
"WorkflowRunListProjection",
|
|
2891
|
+
"WorkflowRunProjection",
|
|
2892
|
+
], modules.runtimeRunProjector)}
|
|
2893
|
+
${renderTypeImport([
|
|
2894
|
+
"CreateWorkspaceAgentClientOptions",
|
|
2895
|
+
"WorkspaceAgentClientBridge",
|
|
2896
|
+
"WorkspaceAgentProductCommandMap",
|
|
2897
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
2898
|
+
], modules.workspaceAgentClient)}
|
|
2899
|
+
|
|
2900
|
+
export interface GeneratedAgentClientProductProjections extends WorkspaceAgentProductProjectionTypes {
|
|
2901
|
+
readonly session: AgentSessionProjection;
|
|
2902
|
+
readonly sessionList: AgentSessionListProjection;
|
|
2903
|
+
readonly workflowRun: WorkflowRunProjection;
|
|
2904
|
+
readonly workflowRunList: WorkflowRunListProjection;
|
|
2905
|
+
}
|
|
1504
2906
|
|
|
1505
|
-
export type GeneratedAgentClientOptions =
|
|
1506
|
-
|
|
2907
|
+
export type GeneratedAgentClientOptions =
|
|
2908
|
+
CreateWorkspaceAgentClientOptions<WorkspaceAgentProductCommandMap<GeneratedAgentClientProductProjections>>;
|
|
2909
|
+
export type GeneratedAgentClient = WorkspaceAgentClientBridge<GeneratedAgentClientProductProjections>;
|
|
1507
2910
|
|
|
1508
2911
|
export const createAgentOSClient = (
|
|
1509
2912
|
options: GeneratedAgentClientOptions = {},
|
|
@@ -1514,17 +2917,33 @@ export const createAgentOSClient = (
|
|
|
1514
2917
|
import { invokeAgentCommand, runEventStream } from "./sveltekit.remote";
|
|
1515
2918
|
${renderNamedImport(["clientReadable", "selectClientReadable"], modules.clientSvelte)}
|
|
1516
2919
|
${renderTypeImport(["AgentClientSnapshot"], modules.clientCore)}
|
|
2920
|
+
${renderTypeImport([
|
|
2921
|
+
"AgentSessionListProjection",
|
|
2922
|
+
"AgentSessionProjection",
|
|
2923
|
+
"WorkflowRunListProjection",
|
|
2924
|
+
"WorkflowRunProjection",
|
|
2925
|
+
], modules.runtimeRunProjector)}
|
|
1517
2926
|
${renderTypeImport([
|
|
1518
2927
|
"CreateWorkspaceAgentClientOptions",
|
|
1519
|
-
"WorkspaceAgentClient",
|
|
1520
2928
|
"WorkspaceAgentClientBridge",
|
|
1521
|
-
"
|
|
2929
|
+
"WorkspaceAgentProductClient",
|
|
2930
|
+
"WorkspaceAgentProductCommandMap",
|
|
2931
|
+
"WorkspaceAgentProductProjectionTypes",
|
|
1522
2932
|
], modules.workspaceAgentClient)}
|
|
1523
2933
|
${renderTypeImport(["Readable"], modules.svelteStore)}
|
|
1524
2934
|
|
|
1525
|
-
export
|
|
2935
|
+
export interface GeneratedAgentClientProductProjections extends WorkspaceAgentProductProjectionTypes {
|
|
2936
|
+
readonly session: AgentSessionProjection;
|
|
2937
|
+
readonly sessionList: AgentSessionListProjection;
|
|
2938
|
+
readonly workflowRun: WorkflowRunProjection;
|
|
2939
|
+
readonly workflowRunList: WorkflowRunListProjection;
|
|
2940
|
+
}
|
|
1526
2941
|
|
|
1527
|
-
export
|
|
2942
|
+
export type GeneratedAgentClientOptions =
|
|
2943
|
+
CreateWorkspaceAgentClientOptions<WorkspaceAgentProductCommandMap<GeneratedAgentClientProductProjections>>;
|
|
2944
|
+
|
|
2945
|
+
export interface GeneratedAgentClient
|
|
2946
|
+
extends WorkspaceAgentClientBridge<GeneratedAgentClientProductProjections> {
|
|
1528
2947
|
readonly snapshot: Readable<AgentClientSnapshot>;
|
|
1529
2948
|
readonly events: Readable<AgentClientSnapshot["events"]>;
|
|
1530
2949
|
readonly connection: Readable<AgentClientSnapshot["connection"]>;
|
|
@@ -1539,8 +2958,10 @@ const generatedStreamSource: NonNullable<GeneratedAgentClientOptions["streamSour
|
|
|
1539
2958
|
}),
|
|
1540
2959
|
};
|
|
1541
2960
|
|
|
1542
|
-
const generatedRpcInvoker
|
|
1543
|
-
invokeAgentCommand({ name, input }) as
|
|
2961
|
+
const generatedRpcInvoker = ((name, input) =>
|
|
2962
|
+
invokeAgentCommand({ name, input })) as WorkspaceAgentProductClient<
|
|
2963
|
+
GeneratedAgentClientProductProjections
|
|
2964
|
+
>["invoke"];
|
|
1544
2965
|
|
|
1545
2966
|
export const createAgentOSClient = (
|
|
1546
2967
|
options: GeneratedAgentClientOptions = {},
|
|
@@ -1696,12 +3117,6 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1696
3117
|
};
|
|
1697
3118
|
}
|
|
1698
3119
|
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
3120
|
if (normalized.llm.route !== AGENTOS_CONFIG_LLM_ROUTE.OPENAI_CHAT_COMPATIBLE) {
|
|
1706
3121
|
return {
|
|
1707
3122
|
ok: false,
|
|
@@ -1709,6 +3124,150 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1709
3124
|
};
|
|
1710
3125
|
}
|
|
1711
3126
|
const toolNames = Object.keys(normalized.deployment.manifest.tools ?? {}).sort();
|
|
3127
|
+
const hasChannels = normalized.channels.length > 0;
|
|
3128
|
+
const hasSchedules = normalized.schedules.length > 0;
|
|
3129
|
+
if (normalized.target.kind === AGENTOS_CONFIG_TARGET.NODE_V1) {
|
|
3130
|
+
if (normalized.profile !== AGENTOS_CONFIG_PROFILE.WORKSPACE_V1) {
|
|
3131
|
+
return {
|
|
3132
|
+
ok: false,
|
|
3133
|
+
issues: [{ kind: "unsupported_static_target", target: normalized.target.kind }],
|
|
3134
|
+
};
|
|
3135
|
+
}
|
|
3136
|
+
const authoredManifestToolNames = toolNames.filter((toolName) => normalized.authoredToolNames.includes(toolName));
|
|
3137
|
+
const deploymentJson = {
|
|
3138
|
+
deploymentId: normalized.deployment.deploymentId,
|
|
3139
|
+
backend: normalized.deployment.backend,
|
|
3140
|
+
adapter: normalized.deployment.adapter,
|
|
3141
|
+
codec: normalized.deployment.codec,
|
|
3142
|
+
...(normalized.deployment.providerStrategy === undefined
|
|
3143
|
+
? {}
|
|
3144
|
+
: { providerStrategy: normalized.deployment.providerStrategy }),
|
|
3145
|
+
workspace: {
|
|
3146
|
+
binding: normalized.workspace.binding,
|
|
3147
|
+
bindingRef: normalized.workspace.bindingRef,
|
|
3148
|
+
root: normalized.workspace.root,
|
|
3149
|
+
topology: normalized.workspace.topology,
|
|
3150
|
+
providerResourceId: normalized.workspace.providerResourceId,
|
|
3151
|
+
},
|
|
3152
|
+
};
|
|
3153
|
+
const moduleGraph = [
|
|
3154
|
+
{ kind: "semantic-json", source: "./manifest.json", imports: ["default as declarations"] },
|
|
3155
|
+
{ kind: "semantic-json", source: "./deployment.json", imports: ["default as deployment"] },
|
|
3156
|
+
{
|
|
3157
|
+
kind: "local-runtime",
|
|
3158
|
+
source: modules.localRuntime,
|
|
3159
|
+
imports: ["lowerLocalAgentRuntime"],
|
|
3160
|
+
},
|
|
3161
|
+
{
|
|
3162
|
+
kind: "capability-runtime",
|
|
3163
|
+
source: modules.runtimeCapability,
|
|
3164
|
+
imports: ["runDynamicCapabilityResolvers"],
|
|
3165
|
+
},
|
|
3166
|
+
{
|
|
3167
|
+
kind: "workspace-host",
|
|
3168
|
+
source: modules.workspaceAgentHost,
|
|
3169
|
+
imports: ["WorkspaceAgentCustomCommandInput"],
|
|
3170
|
+
},
|
|
3171
|
+
{
|
|
3172
|
+
kind: "target-runtime",
|
|
3173
|
+
source: modules.runtimeRunProjector,
|
|
3174
|
+
imports: [
|
|
3175
|
+
"projectAgentSession",
|
|
3176
|
+
"projectAgentSessions",
|
|
3177
|
+
"projectRunInspection",
|
|
3178
|
+
"projectWorkflowRun",
|
|
3179
|
+
"projectWorkflowRuns",
|
|
3180
|
+
],
|
|
3181
|
+
},
|
|
3182
|
+
...generatedToolImports(authoredManifestToolNames),
|
|
3183
|
+
...generatedDynamicResolverImports(normalized.dynamicResolvers),
|
|
3184
|
+
...(hasChannels
|
|
3185
|
+
? [
|
|
3186
|
+
{
|
|
3187
|
+
kind: "channel-runtime",
|
|
3188
|
+
source: modules.runtimeChannel,
|
|
3189
|
+
imports: ["DefinedChannel"],
|
|
3190
|
+
},
|
|
3191
|
+
...generatedChannelImports(normalized.channels),
|
|
3192
|
+
{
|
|
3193
|
+
kind: "channel-registry",
|
|
3194
|
+
source: "./channels",
|
|
3195
|
+
imports: ["dispatchGeneratedChannelRequest", "generatedChannels"],
|
|
3196
|
+
},
|
|
3197
|
+
]
|
|
3198
|
+
: []),
|
|
3199
|
+
...(hasSchedules
|
|
3200
|
+
? [
|
|
3201
|
+
{
|
|
3202
|
+
kind: "schedule-runtime",
|
|
3203
|
+
source: modules.runtimeSchedule,
|
|
3204
|
+
imports: ["DefinedSchedule"],
|
|
3205
|
+
},
|
|
3206
|
+
...generatedScheduleImports(normalized.schedules),
|
|
3207
|
+
{
|
|
3208
|
+
kind: "schedule-registry",
|
|
3209
|
+
source: "./schedules",
|
|
3210
|
+
imports: [
|
|
3211
|
+
"dispatchGeneratedSchedule",
|
|
3212
|
+
"dispatchGeneratedScheduleDelivery",
|
|
3213
|
+
"generatedScheduleDefinitions",
|
|
3214
|
+
"generatedSchedules",
|
|
3215
|
+
],
|
|
3216
|
+
},
|
|
3217
|
+
]
|
|
3218
|
+
: []),
|
|
3219
|
+
];
|
|
3220
|
+
return {
|
|
3221
|
+
ok: true,
|
|
3222
|
+
value: {
|
|
3223
|
+
files: [
|
|
3224
|
+
generatedPath(".agentos/generated/manifest.json", stableJson(normalized.deployment.manifest)),
|
|
3225
|
+
generatedPath(".agentos/generated/deployment.json", stableJson(deploymentJson)),
|
|
3226
|
+
generatedPath(".agentos/generated/provenance.json", stableJson(normalized.provenance)),
|
|
3227
|
+
generatedPath(".agentos/generated/fingerprints.json", stableJson({
|
|
3228
|
+
deployment: digestText(stableJson(deploymentJson)),
|
|
3229
|
+
manifest: digestText(stableJson(normalized.deployment.manifest)),
|
|
3230
|
+
targetModuleGraph: digestText(stableJson(moduleGraph)),
|
|
3231
|
+
})),
|
|
3232
|
+
...(hasChannels
|
|
3233
|
+
? [
|
|
3234
|
+
generatedPath(".agentos/generated/channels.ts", renderChannelRegistry(normalized.channels, modules)),
|
|
3235
|
+
]
|
|
3236
|
+
: []),
|
|
3237
|
+
...(hasSchedules
|
|
3238
|
+
? [
|
|
3239
|
+
generatedPath(".agentos/generated/schedules.ts", renderScheduleRegistry(normalized.schedules, modules)),
|
|
3240
|
+
]
|
|
3241
|
+
: []),
|
|
3242
|
+
generatedPath(".agentos/generated/local.ts", renderLocalAgentApp(normalized, toolNames, modules)),
|
|
3243
|
+
],
|
|
3244
|
+
moduleGraph,
|
|
3245
|
+
canonicalDeployment: {
|
|
3246
|
+
profile: normalized.profile,
|
|
3247
|
+
target: normalized.target.kind,
|
|
3248
|
+
llmRoute: normalized.llm.route,
|
|
3249
|
+
client: normalized.client.kind,
|
|
3250
|
+
workspaceTopology: normalized.workspace.topology,
|
|
3251
|
+
toolNames,
|
|
3252
|
+
},
|
|
3253
|
+
mount: {
|
|
3254
|
+
driver: {
|
|
3255
|
+
kind: "local-node",
|
|
3256
|
+
target: AGENTOS_CONFIG_TARGET.NODE_V1,
|
|
3257
|
+
},
|
|
3258
|
+
projectionSinks: [
|
|
3259
|
+
"agent.info",
|
|
3260
|
+
"workspace.state",
|
|
3261
|
+
"workspace.files",
|
|
3262
|
+
"runtime.events",
|
|
3263
|
+
"runtime.input_requests",
|
|
3264
|
+
],
|
|
3265
|
+
providerResourceId: normalized.workspace.providerResourceId,
|
|
3266
|
+
},
|
|
3267
|
+
},
|
|
3268
|
+
};
|
|
3269
|
+
}
|
|
3270
|
+
const target = cloudflareTargetFor(normalized.target);
|
|
1712
3271
|
const authoredToolNames = new Set(normalized.authoredToolNames);
|
|
1713
3272
|
const authoredManifestToolNames = toolNames.filter((toolName) => authoredToolNames.has(toolName));
|
|
1714
3273
|
const deploymentJson = {
|
|
@@ -1738,10 +3297,64 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1738
3297
|
{
|
|
1739
3298
|
kind: "target-runtime",
|
|
1740
3299
|
source: modules.cloudflareDoRuntime,
|
|
1741
|
-
imports:
|
|
1742
|
-
? ["createAgentDurableObject", "installCloudflareWorkspaceOperationProvider"]
|
|
1743
|
-
: ["createAgentDurableObject"],
|
|
3300
|
+
imports: ["createAgentDurableObject"],
|
|
1744
3301
|
},
|
|
3302
|
+
...(hasChannels
|
|
3303
|
+
? [
|
|
3304
|
+
{
|
|
3305
|
+
kind: "channel-runtime",
|
|
3306
|
+
source: modules.runtimeChannel,
|
|
3307
|
+
imports: ["DefinedChannel"],
|
|
3308
|
+
},
|
|
3309
|
+
...generatedChannelImports(normalized.channels),
|
|
3310
|
+
{
|
|
3311
|
+
kind: "channel-registry",
|
|
3312
|
+
source: "./channels",
|
|
3313
|
+
imports: ["dispatchGeneratedChannelRequest", "generatedChannels"],
|
|
3314
|
+
},
|
|
3315
|
+
]
|
|
3316
|
+
: []),
|
|
3317
|
+
...(hasSchedules
|
|
3318
|
+
? [
|
|
3319
|
+
{
|
|
3320
|
+
kind: "schedule-runtime",
|
|
3321
|
+
source: modules.runtimeSchedule,
|
|
3322
|
+
imports: ["DefinedSchedule"],
|
|
3323
|
+
},
|
|
3324
|
+
...generatedScheduleImports(normalized.schedules),
|
|
3325
|
+
{
|
|
3326
|
+
kind: "schedule-registry",
|
|
3327
|
+
source: "./schedules",
|
|
3328
|
+
imports: [
|
|
3329
|
+
"dispatchGeneratedSchedule",
|
|
3330
|
+
"dispatchGeneratedScheduleDelivery",
|
|
3331
|
+
"generatedScheduleDefinitions",
|
|
3332
|
+
"generatedSchedules",
|
|
3333
|
+
],
|
|
3334
|
+
},
|
|
3335
|
+
]
|
|
3336
|
+
: []),
|
|
3337
|
+
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
3338
|
+
? [
|
|
3339
|
+
{
|
|
3340
|
+
kind: "capability-runtime",
|
|
3341
|
+
source: modules.runtimeCapability,
|
|
3342
|
+
imports: [
|
|
3343
|
+
"WORKSPACE_OPERATION_HOST_FACT",
|
|
3344
|
+
"defineHost",
|
|
3345
|
+
"resolveRuntimeInstallGraph",
|
|
3346
|
+
"runDynamicCapabilityResolvers",
|
|
3347
|
+
"workspaceOperations",
|
|
3348
|
+
],
|
|
3349
|
+
},
|
|
3350
|
+
]
|
|
3351
|
+
: [
|
|
3352
|
+
{
|
|
3353
|
+
kind: "capability-runtime",
|
|
3354
|
+
source: modules.runtimeCapability,
|
|
3355
|
+
imports: ["runDynamicCapabilityResolvers"],
|
|
3356
|
+
},
|
|
3357
|
+
]),
|
|
1745
3358
|
{
|
|
1746
3359
|
kind: "provider-runtime",
|
|
1747
3360
|
source: modules.openAiCompatibleTransport,
|
|
@@ -1755,13 +3368,9 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1755
3368
|
: ["WORKSPACE_AGENT_COMMAND"],
|
|
1756
3369
|
},
|
|
1757
3370
|
...generatedToolImports(authoredManifestToolNames),
|
|
3371
|
+
...generatedDynamicResolverImports(normalized.dynamicResolvers),
|
|
1758
3372
|
...(normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1759
3373
|
? [
|
|
1760
|
-
{
|
|
1761
|
-
kind: "workspace-binding",
|
|
1762
|
-
source: modules.workspaceBinding,
|
|
1763
|
-
imports: ["bindWorkspaceToolsForRuntime"],
|
|
1764
|
-
},
|
|
1765
3374
|
{
|
|
1766
3375
|
kind: "execution-domain-runtime",
|
|
1767
3376
|
source: modules.workspaceEnvCloudflare,
|
|
@@ -1788,8 +3397,8 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1788
3397
|
kind: "target-worker",
|
|
1789
3398
|
source: "./worker",
|
|
1790
3399
|
imports: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1791
|
-
? [
|
|
1792
|
-
: [
|
|
3400
|
+
? [target.durableObject.className, "Sandbox"]
|
|
3401
|
+
: [target.durableObject.className],
|
|
1793
3402
|
},
|
|
1794
3403
|
{
|
|
1795
3404
|
kind: "target-config",
|
|
@@ -1810,6 +3419,16 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1810
3419
|
manifest: digestText(stableJson(normalized.deployment.manifest)),
|
|
1811
3420
|
targetModuleGraph: digestText(stableJson(moduleGraph)),
|
|
1812
3421
|
})),
|
|
3422
|
+
...(hasChannels
|
|
3423
|
+
? [
|
|
3424
|
+
generatedPath(".agentos/generated/channels.ts", renderChannelRegistry(normalized.channels, modules)),
|
|
3425
|
+
]
|
|
3426
|
+
: []),
|
|
3427
|
+
...(hasSchedules
|
|
3428
|
+
? [
|
|
3429
|
+
generatedPath(".agentos/generated/schedules.ts", renderScheduleRegistry(normalized.schedules, modules)),
|
|
3430
|
+
]
|
|
3431
|
+
: []),
|
|
1813
3432
|
generatedPath(".agentos/generated/target.ts", renderStaticTarget(normalized, toolNames, modules)),
|
|
1814
3433
|
generatedPath(".agentos/generated/cloudflare-scope.ts", renderCloudflareScopeHelper(normalized, modules)),
|
|
1815
3434
|
generatedPath(".agentos/generated/worker.ts", renderCloudflareWorkerEntry(normalized, modules)),
|
|
@@ -1836,8 +3455,8 @@ export const linkWorkspaceStaticTarget = (normalized, options = {}) => {
|
|
|
1836
3455
|
mount: {
|
|
1837
3456
|
driver: {
|
|
1838
3457
|
kind: "cloudflare-do",
|
|
1839
|
-
className:
|
|
1840
|
-
binding:
|
|
3458
|
+
className: target.durableObject.className,
|
|
3459
|
+
binding: target.durableObject.binding,
|
|
1841
3460
|
},
|
|
1842
3461
|
projectionSinks: normalized.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
|
|
1843
3462
|
? [
|