@yansirplus/cli 0.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/PUBLIC_API.md +22 -0
  2. package/README.md +34 -0
  3. package/dist/build/agent-authoring/config.d.ts +177 -0
  4. package/dist/build/agent-authoring/config.js +607 -0
  5. package/dist/build/agent-authoring/manifest-compiler.d.ts +159 -0
  6. package/dist/build/agent-authoring/manifest-compiler.js +737 -0
  7. package/dist/build/agent-authoring/shared.d.ts +10 -0
  8. package/dist/build/agent-authoring/shared.js +57 -0
  9. package/dist/build/agent-authoring/static-target.d.ts +59 -0
  10. package/dist/build/agent-authoring/static-target.js +1857 -0
  11. package/dist/build/agent-authoring.d.ts +9 -0
  12. package/dist/build/agent-authoring.js +5 -0
  13. package/dist/build/build-cli.d.ts +2 -0
  14. package/dist/build/build-cli.js +264 -0
  15. package/dist/check/algorithmic/architecture-checks.mjs +971 -0
  16. package/dist/check/algorithmic/client-boundary-checks.mjs +337 -0
  17. package/dist/check/algorithmic/convergence-smoke-checks.mjs +608 -0
  18. package/dist/check/algorithmic/distribution-checks.mjs +919 -0
  19. package/dist/check/algorithmic/owner-checks.mjs +647 -0
  20. package/dist/check/algorithmic/package-boundary-checks.mjs +985 -0
  21. package/dist/check/algorithmic/projection-boundary-checks.mjs +302 -0
  22. package/dist/check/algorithmic/repo-surface-checks.mjs +267 -0
  23. package/dist/check/algorithmic/runtime-structural-checks.mjs +264 -0
  24. package/dist/check/algorithmic/source-alias-checks.mjs +106 -0
  25. package/dist/check/algorithmic/static-target-checks.mjs +447 -0
  26. package/dist/check/algorithmic-checks.mjs +482 -0
  27. package/dist/check/check-coverage.mjs +231 -0
  28. package/dist/check/command-runner.mjs +22 -0
  29. package/dist/check/default-gate.mjs +51 -0
  30. package/dist/check/gate-selector.mjs +305 -0
  31. package/dist/check/manifest-rules.mjs +223 -0
  32. package/dist/check/package-graph.mjs +464 -0
  33. package/dist/generate/generate-agent-docs.mjs +435 -0
  34. package/dist/generate/generate-carrier-reference.mjs +514 -0
  35. package/dist/generate/generate-docs.mjs +345 -0
  36. package/dist/generate/generate-effect-skill-manifests.mjs +193 -0
  37. package/dist/generate/project-docs-site.mjs +190 -0
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.js +25 -0
  40. package/dist/lib/agent-docs-model.mjs +888 -0
  41. package/dist/lib/boundary-rules.mjs +63 -0
  42. package/dist/lib/capability-routes.mjs +354 -0
  43. package/dist/lib/projection-sink.mjs +113 -0
  44. package/dist/lib/public-api-model.mjs +306 -0
  45. package/dist/main.mjs +233 -0
  46. package/dist/runner.mjs +127 -0
  47. package/package.json +32 -0
@@ -0,0 +1,607 @@
1
+ import { authoredValue } from "@yansirplus/core/authored-value";
2
+ import { WORKSPACE_TOPOLOGY, manifestScopeRefResult, workspaceBindingRef, workspaceProviderResourceId, } from "@yansirplus/core/runtime-protocol";
3
+ import { WORKSPACE_TOOL_DEFAULT_DECLARATIONS, } from "@yansirplus/runtime";
4
+ import { digestHex64, isNonEmptyString, isRecord } from "./shared.js";
5
+ import { workspaceManifestMacroOrigin } from "./manifest-compiler.js";
6
+ export const AGENTOS_CONFIG_PROFILE = {
7
+ WORKSPACE_V1: "workspace@1",
8
+ CHAT_V1: "chat@1",
9
+ };
10
+ export const AGENTOS_CONFIG_TARGET = {
11
+ CLOUDFLARE_DO_V1: "cloudflare-do@1",
12
+ };
13
+ export const AGENTOS_CONFIG_CLIENT = {
14
+ SVELTE_KIT_REMOTE_V1: "svelte-kit-remote@1",
15
+ BROWSER_DIRECT_V1: "browser-direct@1",
16
+ };
17
+ export const AGENTOS_CONFIG_LLM_ROUTE = {
18
+ OPENAI_CHAT_COMPATIBLE: "openai-chat-compatible",
19
+ };
20
+ const configAuthorOrigin = (factKey) => `author:agentos.config.jsonc#${factKey}`;
21
+ const workspaceMacroOrigin = (factKey) => `macro(${AGENTOS_CONFIG_PROFILE.WORKSPACE_V1})#${factKey}`;
22
+ const chatMacroOrigin = (factKey) => `macro(${AGENTOS_CONFIG_PROFILE.CHAT_V1})#${factKey}`;
23
+ const materialEnvPrefix = (kind) => kind === "endpoint"
24
+ ? "AGENTOS_ENDPOINT"
25
+ : kind === "credential"
26
+ ? "AGENTOS_CREDENTIAL"
27
+ : "AGENTOS_MODEL";
28
+ const materialEnvSuffix = (ref) => ref
29
+ .toUpperCase()
30
+ .replace(/[^A-Z0-9]+/g, "_")
31
+ .replace(/^_+|_+$/g, "") || "REF";
32
+ export const materialEnvNameForRef = (kind, ref) => `${materialEnvPrefix(kind)}_${materialEnvSuffix(ref)}`;
33
+ export const llmMaterialEnvBindingsForRefs = (refs) => refs.map(({ kind, ref }) => ({ kind, ref, envName: materialEnvNameForRef(kind, ref) }));
34
+ export const llmMaterialEnvNameCollisionIssues = (bindings) => {
35
+ const byEnv = new Map();
36
+ const issues = [];
37
+ for (const binding of bindings) {
38
+ const materialRef = `${binding.kind}:${binding.ref}`;
39
+ const existing = byEnv.get(binding.envName);
40
+ if (existing === undefined) {
41
+ byEnv.set(binding.envName, materialRef);
42
+ }
43
+ else if (existing !== materialRef) {
44
+ issues.push({
45
+ kind: "llm_material_env_name_collision",
46
+ path: "agentos.config.jsonc#/llm",
47
+ envName: binding.envName,
48
+ refs: [existing, materialRef],
49
+ });
50
+ }
51
+ }
52
+ return issues;
53
+ };
54
+ export const llmMaterialEnvBindings = (llm) => llmMaterialEnvBindingsForRefs([
55
+ { kind: "endpoint", ref: llm.endpointRef },
56
+ { kind: "credential", ref: llm.credentialRef },
57
+ { kind: "model", ref: llm.modelRef },
58
+ ]);
59
+ const configAllowedFields = new Set([
60
+ "$schema",
61
+ "profile",
62
+ "agent",
63
+ "deployment",
64
+ "target",
65
+ "client",
66
+ "llm",
67
+ "workspace",
68
+ ]);
69
+ const deploymentAllowedFields = new Set(["id", "version"]);
70
+ const targetAllowedFields = new Set(["kind", "durableObject"]);
71
+ const durableObjectAllowedFields = new Set(["className", "binding"]);
72
+ const clientAllowedFields = new Set(["kind"]);
73
+ const llmAllowedFields = new Set(["route", "endpointRef", "credentialRef", "modelRef"]);
74
+ const workspaceAllowedFields = new Set(["binding", "root", "topology"]);
75
+ const topologyAllowedFields = new Set(["kind", "allocator"]);
76
+ const configRuntimeFactFields = new Set([
77
+ "continuation",
78
+ "continuationRef",
79
+ "inputRequestRef",
80
+ "snapshot",
81
+ "actualTriggerTime",
82
+ "resumePayload",
83
+ "resolvedMaterial",
84
+ "secret",
85
+ "credential",
86
+ "triggerTime",
87
+ ]);
88
+ const issueInvalidConfigValue = (issues, path, field, reason) => {
89
+ issues.push({ kind: "invalid_config_value", path, field, reason });
90
+ };
91
+ const assertConfigAllowedFields = (issues, path, value, allowed) => {
92
+ for (const field of Object.keys(value)) {
93
+ if (!allowed.has(field))
94
+ issues.push({ kind: "unknown_field", path, field });
95
+ }
96
+ };
97
+ const assertNoConfigRuntimeFacts = (issues, path, value) => {
98
+ const visit = (record, fieldPrefix) => {
99
+ for (const [field, child] of Object.entries(record)) {
100
+ const fieldPath = fieldPrefix.length === 0 ? field : `${fieldPrefix}.${field}`;
101
+ if (configRuntimeFactFields.has(field)) {
102
+ issues.push({ kind: "runtime_fact_forbidden", path, field: fieldPath });
103
+ }
104
+ if (typeof child === "function") {
105
+ issues.push({ kind: "function_in_config", path: `${path}.${fieldPath}` });
106
+ }
107
+ if (isRecord(child))
108
+ visit(child, fieldPath);
109
+ if (Array.isArray(child)) {
110
+ for (let index = 0; index < child.length; index += 1) {
111
+ const item = child[index];
112
+ if (isRecord(item))
113
+ visit(item, `${fieldPath}[${index}]`);
114
+ if (typeof item === "function") {
115
+ issues.push({ kind: "function_in_config", path: `${path}.${fieldPath}[${index}]` });
116
+ }
117
+ }
118
+ }
119
+ }
120
+ };
121
+ visit(value, "");
122
+ };
123
+ const configStringField = (issues, path, field, value) => {
124
+ if (isNonEmptyString(value))
125
+ return value;
126
+ issueInvalidConfigValue(issues, path, field, "non_empty_string_required");
127
+ return null;
128
+ };
129
+ const configOptionalStringField = (issues, path, field, value) => {
130
+ if (value === undefined)
131
+ return undefined;
132
+ return configStringField(issues, path, field, value) ?? undefined;
133
+ };
134
+ const configRequiredRecord = (issues, path, field, value) => {
135
+ if (isRecord(value))
136
+ return value;
137
+ issueInvalidConfigValue(issues, path, field, "object_required");
138
+ return null;
139
+ };
140
+ const decodeDeploymentConfig = (issues, value) => {
141
+ const record = configRequiredRecord(issues, "agentos.config.jsonc", "/deployment", value);
142
+ if (record === null)
143
+ return null;
144
+ assertConfigAllowedFields(issues, "/deployment", record, deploymentAllowedFields);
145
+ const id = configStringField(issues, "/deployment", "/deployment/id", record.id);
146
+ const version = configOptionalStringField(issues, "/deployment", "/deployment/version", record.version);
147
+ return id === null ? null : { id, ...(version === undefined ? {} : { version }) };
148
+ };
149
+ const decodeTargetConfig = (issues, value) => {
150
+ const record = configRequiredRecord(issues, "agentos.config.jsonc", "/target", value);
151
+ if (record === null)
152
+ return null;
153
+ assertConfigAllowedFields(issues, "/target", record, targetAllowedFields);
154
+ if (record.kind !== AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1) {
155
+ issueInvalidConfigValue(issues, "/target", "/target/kind", "target_kind_invalid");
156
+ return null;
157
+ }
158
+ const durableObject = configRequiredRecord(issues, "/target", "/target/durableObject", record.durableObject);
159
+ if (durableObject === null)
160
+ return null;
161
+ assertConfigAllowedFields(issues, "/target/durableObject", durableObject, durableObjectAllowedFields);
162
+ const className = configStringField(issues, "/target/durableObject", "/target/durableObject/className", durableObject.className);
163
+ const binding = configStringField(issues, "/target/durableObject", "/target/durableObject/binding", durableObject.binding);
164
+ return className === null || binding === null
165
+ ? null
166
+ : {
167
+ kind: AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1,
168
+ durableObject: { className, binding },
169
+ };
170
+ };
171
+ const decodeClientConfig = (issues, value) => {
172
+ const record = configRequiredRecord(issues, "agentos.config.jsonc", "/client", value);
173
+ if (record === null)
174
+ return null;
175
+ assertConfigAllowedFields(issues, "/client", record, clientAllowedFields);
176
+ if (record.kind !== AGENTOS_CONFIG_CLIENT.SVELTE_KIT_REMOTE_V1 &&
177
+ record.kind !== AGENTOS_CONFIG_CLIENT.BROWSER_DIRECT_V1) {
178
+ issueInvalidConfigValue(issues, "/client", "/client/kind", "client_kind_invalid");
179
+ return null;
180
+ }
181
+ return { kind: record.kind };
182
+ };
183
+ const decodeLlmConfig = (issues, value) => {
184
+ const record = configRequiredRecord(issues, "agentos.config.jsonc", "/llm", value);
185
+ if (record === null)
186
+ return null;
187
+ assertConfigAllowedFields(issues, "/llm", record, llmAllowedFields);
188
+ if (record.route !== AGENTOS_CONFIG_LLM_ROUTE.OPENAI_CHAT_COMPATIBLE) {
189
+ issueInvalidConfigValue(issues, "/llm", "/llm/route", "llm_route_invalid");
190
+ return null;
191
+ }
192
+ const endpointRef = configStringField(issues, "/llm", "/llm/endpointRef", record.endpointRef);
193
+ const credentialRef = configStringField(issues, "/llm", "/llm/credentialRef", record.credentialRef);
194
+ const modelRef = configStringField(issues, "/llm", "/llm/modelRef", record.modelRef);
195
+ return endpointRef === null || credentialRef === null || modelRef === null
196
+ ? null
197
+ : {
198
+ route: AGENTOS_CONFIG_LLM_ROUTE.OPENAI_CHAT_COMPATIBLE,
199
+ endpointRef,
200
+ credentialRef,
201
+ modelRef,
202
+ };
203
+ };
204
+ const decodeWorkspaceTopologyConfig = (issues, value) => {
205
+ const record = configRequiredRecord(issues, "/workspace", "/workspace/topology", value);
206
+ if (record === null)
207
+ return null;
208
+ assertConfigAllowedFields(issues, "/workspace/topology", record, topologyAllowedFields);
209
+ if (record.kind !== WORKSPACE_TOPOLOGY.PER_SCOPE) {
210
+ issueInvalidConfigValue(issues, "/workspace/topology", "/workspace/topology/kind", "workspace_topology_kind_invalid");
211
+ return null;
212
+ }
213
+ const allocator = configStringField(issues, "/workspace/topology", "/workspace/topology/allocator", record.allocator);
214
+ return allocator === null ? null : { kind: WORKSPACE_TOPOLOGY.PER_SCOPE, allocator };
215
+ };
216
+ const decodeWorkspaceConfig = (issues, value) => {
217
+ const record = configRequiredRecord(issues, "agentos.config.jsonc", "/workspace", value);
218
+ if (record === null)
219
+ return null;
220
+ assertConfigAllowedFields(issues, "/workspace", record, workspaceAllowedFields);
221
+ const binding = configStringField(issues, "/workspace", "/workspace/binding", record.binding);
222
+ const root = configStringField(issues, "/workspace", "/workspace/root", record.root);
223
+ const topology = record.topology === undefined
224
+ ? undefined
225
+ : decodeWorkspaceTopologyConfig(issues, record.topology);
226
+ return binding === null || root === null || topology === null
227
+ ? null
228
+ : { binding, root, ...(topology === undefined ? {} : { topology }) };
229
+ };
230
+ export const decodeAgentOsConfig = (value) => {
231
+ const issues = [];
232
+ if (!isRecord(value))
233
+ return { ok: false, issues: [{ kind: "config_not_object", path: "agentos.config.jsonc" }] };
234
+ assertConfigAllowedFields(issues, "agentos.config.jsonc", value, configAllowedFields);
235
+ assertNoConfigRuntimeFacts(issues, "agentos.config.jsonc", value);
236
+ const schema = configOptionalStringField(issues, "agentos.config.jsonc", "/$schema", value.$schema);
237
+ if (value.profile !== AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 &&
238
+ value.profile !== AGENTOS_CONFIG_PROFILE.CHAT_V1) {
239
+ issueInvalidConfigValue(issues, "agentos.config.jsonc", "/profile", "profile_invalid");
240
+ }
241
+ const agent = configStringField(issues, "agentos.config.jsonc", "/agent", value.agent);
242
+ const deployment = decodeDeploymentConfig(issues, value.deployment);
243
+ const target = decodeTargetConfig(issues, value.target);
244
+ const client = decodeClientConfig(issues, value.client);
245
+ const llm = decodeLlmConfig(issues, value.llm);
246
+ const workspace = value.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
247
+ ? decodeWorkspaceConfig(issues, value.workspace)
248
+ : null;
249
+ if (value.profile === AGENTOS_CONFIG_PROFILE.CHAT_V1 &&
250
+ Object.prototype.hasOwnProperty.call(value, "workspace")) {
251
+ issueInvalidConfigValue(issues, "agentos.config.jsonc", "/workspace", "workspace_forbidden_for_chat_profile");
252
+ }
253
+ if (issues.length > 0 ||
254
+ agent === null ||
255
+ deployment === null ||
256
+ target === null ||
257
+ client === null ||
258
+ llm === null ||
259
+ (value.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1 && workspace === null)) {
260
+ return { ok: false, issues };
261
+ }
262
+ const base = {
263
+ ...(schema === undefined ? {} : { $schema: schema }),
264
+ agent,
265
+ deployment,
266
+ target,
267
+ client,
268
+ llm,
269
+ };
270
+ if (value.profile === AGENTOS_CONFIG_PROFILE.CHAT_V1) {
271
+ return {
272
+ ok: true,
273
+ value: {
274
+ ...base,
275
+ profile: AGENTOS_CONFIG_PROFILE.CHAT_V1,
276
+ },
277
+ };
278
+ }
279
+ return {
280
+ ok: true,
281
+ value: {
282
+ ...base,
283
+ profile: AGENTOS_CONFIG_PROFILE.WORKSPACE_V1,
284
+ workspace: workspace,
285
+ },
286
+ };
287
+ };
288
+ const defaultWorkspaceTopology = () => ({
289
+ kind: WORKSPACE_TOPOLOGY.PER_SCOPE,
290
+ allocator: "workspace-per-scope-v1",
291
+ });
292
+ const workspaceMaterialRef = (providerResourceId) => ({
293
+ kind: "external_resource",
294
+ provider: "agent-os",
295
+ resourceKind: "workspace-env",
296
+ ref: providerResourceId,
297
+ });
298
+ const workspaceDefaultToolFactKey = (toolId, field) => `/tools/${toolId}/${field}`;
299
+ const workspaceExecutionDomainFactKey = "/executionDomains/workspace/bindingRef";
300
+ const workspaceMaterialFactKey = "/materials/workspace";
301
+ const defaultWorkspaceToolEntry = (tool, control) => ({
302
+ bindingRef: tool.name,
303
+ executionDomain: tool.executionDomain,
304
+ interaction: control?.kind === "override" && control.interaction !== undefined
305
+ ? control.interaction.value
306
+ : tool.interaction,
307
+ materialRefs: tool.materialRefs,
308
+ effects: tool.effects,
309
+ receiptPolicy: tool.receiptPolicy,
310
+ });
311
+ const addDefaultWorkspaceToolProvenance = (provenance, tool, control) => {
312
+ provenance[workspaceDefaultToolFactKey(tool.name, "bindingRef")] = workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "bindingRef"));
313
+ provenance[workspaceDefaultToolFactKey(tool.name, "executionDomain")] =
314
+ workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "executionDomain"));
315
+ provenance[workspaceDefaultToolFactKey(tool.name, "interaction")] =
316
+ control?.kind === "override" && control.interaction !== undefined
317
+ ? control.interaction.origin
318
+ : workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "interaction"));
319
+ provenance[workspaceDefaultToolFactKey(tool.name, "materialRefs")] = workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "materialRefs"));
320
+ provenance[workspaceDefaultToolFactKey(tool.name, "effects")] = workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "effects"));
321
+ provenance[workspaceDefaultToolFactKey(tool.name, "receiptPolicy")] =
322
+ workspaceManifestMacroOrigin(workspaceDefaultToolFactKey(tool.name, "receiptPolicy"));
323
+ };
324
+ const applyWorkspaceDefaultTools = (compiled) => {
325
+ const issues = [];
326
+ const tools = { ...compiled.manifest.tools };
327
+ const executionDomains = {
328
+ ...compiled.manifest.executionDomains,
329
+ };
330
+ const provenance = {
331
+ ...compiled.provenance,
332
+ };
333
+ const exclusions = {};
334
+ if (executionDomains.workspace === undefined) {
335
+ executionDomains.workspace = { bindingRef: "workspace" };
336
+ provenance[workspaceExecutionDomainFactKey] = workspaceManifestMacroOrigin(workspaceExecutionDomainFactKey);
337
+ }
338
+ for (const defaultTool of WORKSPACE_TOOL_DEFAULT_DECLARATIONS) {
339
+ const control = compiled.workspaceToolControls[defaultTool.name];
340
+ const existing = compiled.manifest.tools?.[defaultTool.name];
341
+ if (control?.kind === "disabled") {
342
+ exclusions[`/tools/${defaultTool.name}`] = control.origin;
343
+ continue;
344
+ }
345
+ if (existing !== undefined) {
346
+ issues.push({
347
+ kind: "workspace_default_tool_shadowed",
348
+ path: compiled.toolFilePaths[defaultTool.name] ?? `agent/tools/${defaultTool.name}.ts`,
349
+ toolId: defaultTool.name,
350
+ });
351
+ continue;
352
+ }
353
+ tools[defaultTool.name] = defaultWorkspaceToolEntry(defaultTool, control);
354
+ addDefaultWorkspaceToolProvenance(provenance, defaultTool, control);
355
+ }
356
+ const manifestWithoutTools = { ...compiled.manifest };
357
+ delete manifestWithoutTools.tools;
358
+ delete manifestWithoutTools.executionDomains;
359
+ const sortedTools = Object.fromEntries(Object.entries(tools).sort(([left], [right]) => left.localeCompare(right)));
360
+ const sortedExecutionDomains = Object.fromEntries(Object.entries(executionDomains).sort(([left], [right]) => left.localeCompare(right)));
361
+ return {
362
+ manifest: authoredValue({
363
+ ...manifestWithoutTools,
364
+ ...(Object.keys(sortedTools).length === 0 ? {} : { tools: sortedTools }),
365
+ ...(Object.keys(sortedExecutionDomains).length === 0
366
+ ? {}
367
+ : { executionDomains: sortedExecutionDomains }),
368
+ }),
369
+ provenance,
370
+ exclusions,
371
+ issues,
372
+ };
373
+ };
374
+ const addWorkspaceMaterial = (manifest, provenance, providerResourceId) => {
375
+ if (manifest.materials?.workspace !== undefined) {
376
+ return { manifest, provenance };
377
+ }
378
+ const materials = {
379
+ ...manifest.materials,
380
+ workspace: workspaceMaterialRef(providerResourceId),
381
+ };
382
+ const sortedMaterials = Object.fromEntries(Object.entries(materials).sort(([left], [right]) => left.localeCompare(right)));
383
+ return {
384
+ manifest: authoredValue({
385
+ ...manifest,
386
+ materials: sortedMaterials,
387
+ }),
388
+ provenance: {
389
+ ...provenance,
390
+ [workspaceMaterialFactKey]: workspaceManifestMacroOrigin(workspaceMaterialFactKey),
391
+ },
392
+ };
393
+ };
394
+ const validateManifestToolReferences = (manifest) => {
395
+ const issues = [];
396
+ for (const [toolId, tool] of Object.entries(manifest.tools ?? {}).sort(([left], [right]) => left.localeCompare(right))) {
397
+ for (const materialRef of tool.materialRefs ?? []) {
398
+ if (manifest.materials?.[materialRef] === undefined) {
399
+ issues.push({ kind: "tool_material_ref_unresolved", toolId, materialRef });
400
+ }
401
+ }
402
+ if (tool.executionDomain !== undefined &&
403
+ manifest.executionDomains?.[tool.executionDomain] === undefined) {
404
+ issues.push({
405
+ kind: "tool_execution_domain_ref_unresolved",
406
+ toolId,
407
+ executionDomain: tool.executionDomain,
408
+ });
409
+ }
410
+ if (tool.interaction !== undefined && manifest.interactions?.[tool.interaction] === undefined) {
411
+ issues.push({
412
+ kind: "tool_interaction_ref_unresolved",
413
+ toolId,
414
+ interaction: tool.interaction,
415
+ });
416
+ }
417
+ }
418
+ return issues;
419
+ };
420
+ const cloudflareSandboxIdPrefix = (deploymentNamespace, workspaceBindingRef, scopeRef) => `${deploymentNamespace}-${workspaceBindingRef}-${scopeRef.kind}-${scopeRef.scopeId}`
421
+ .toLowerCase()
422
+ .replace(/[^a-z0-9-]+/g, "-")
423
+ .replace(/-+/g, "-")
424
+ .replace(/^-|-$/g, "");
425
+ const cloudflareWorkspaceSandboxId = (input) => {
426
+ const digest = digestHex64(input.providerResourceId);
427
+ const suffix = `-${digest}`;
428
+ const rawPrefix = cloudflareSandboxIdPrefix(input.deploymentNamespace, input.workspaceBindingRef, input.scopeRef);
429
+ const prefix = rawPrefix.length === 0 ? "agentos-sandbox" : rawPrefix;
430
+ const prefixBudget = 63 - suffix.length;
431
+ const shortenedPrefix = prefix.slice(0, prefixBudget).replace(/-+$/g, "") || "agentos-sandbox";
432
+ return `${shortenedPrefix}${suffix}`;
433
+ };
434
+ export const normalizeAgentOsConfig = (config, compiled) => {
435
+ const decoded = decodeAgentOsConfig(config);
436
+ if (!decoded.ok)
437
+ return decoded;
438
+ const value = decoded.value;
439
+ const llmEnvIssues = llmMaterialEnvNameCollisionIssues(llmMaterialEnvBindings(value.llm));
440
+ if (llmEnvIssues.length > 0) {
441
+ return { ok: false, issues: llmEnvIssues };
442
+ }
443
+ const profileManifest = value.profile === AGENTOS_CONFIG_PROFILE.WORKSPACE_V1
444
+ ? applyWorkspaceDefaultTools(compiled)
445
+ : {
446
+ manifest: compiled.manifest,
447
+ provenance: compiled.provenance,
448
+ exclusions: {},
449
+ issues: [],
450
+ };
451
+ if (profileManifest.issues.length > 0) {
452
+ return { ok: false, issues: profileManifest.issues };
453
+ }
454
+ const scopeRef = manifestScopeRefResult(profileManifest.manifest);
455
+ if (!scopeRef.ok) {
456
+ return {
457
+ ok: false,
458
+ issues: [
459
+ {
460
+ kind: "workspace_scope_not_manifest_owned",
461
+ path: "agent/agent.json#/scope",
462
+ reason: scopeRef.reason,
463
+ },
464
+ ],
465
+ };
466
+ }
467
+ if (value.profile === AGENTOS_CONFIG_PROFILE.CHAT_V1) {
468
+ const referenceIssues = validateManifestToolReferences(profileManifest.manifest);
469
+ if (referenceIssues.length > 0) {
470
+ return { ok: false, issues: referenceIssues };
471
+ }
472
+ const origins = {
473
+ "/profile": configAuthorOrigin("/profile"),
474
+ "/agent": configAuthorOrigin("/agent"),
475
+ "/deployment/id": configAuthorOrigin("/deployment/id"),
476
+ ...(value.deployment.version === undefined
477
+ ? {}
478
+ : { "/deployment/version": configAuthorOrigin("/deployment/version") }),
479
+ "/target/kind": configAuthorOrigin("/target/kind"),
480
+ "/target/durableObject/className": configAuthorOrigin("/target/durableObject/className"),
481
+ "/target/durableObject/binding": configAuthorOrigin("/target/durableObject/binding"),
482
+ "/client/kind": configAuthorOrigin("/client/kind"),
483
+ "/llm/route": configAuthorOrigin("/llm/route"),
484
+ "/llm/endpointRef": configAuthorOrigin("/llm/endpointRef"),
485
+ "/llm/credentialRef": configAuthorOrigin("/llm/credentialRef"),
486
+ "/llm/modelRef": configAuthorOrigin("/llm/modelRef"),
487
+ "/deployment/backend": `derived:/target/kind`,
488
+ "/deployment/adapter": `derived:/target/kind`,
489
+ "/deployment/codec": chatMacroOrigin("/deployment/codec"),
490
+ "/deployment/providerStrategy": `derived:/llm/route`,
491
+ };
492
+ return {
493
+ ok: true,
494
+ value: {
495
+ profile: AGENTOS_CONFIG_PROFILE.CHAT_V1,
496
+ config: value,
497
+ deployment: {
498
+ deploymentId: value.deployment.id,
499
+ manifest: profileManifest.manifest,
500
+ backend: "cloudflare-do",
501
+ adapter: AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1,
502
+ codec: "agentos-json@1",
503
+ providerStrategy: value.llm.route,
504
+ },
505
+ ...(value.deployment.version === undefined
506
+ ? {}
507
+ : { deploymentVersion: value.deployment.version }),
508
+ authoredToolNames: Object.keys(compiled.toolFilePaths).sort(),
509
+ target: value.target,
510
+ client: value.client,
511
+ llm: value.llm,
512
+ origins,
513
+ provenance: {
514
+ manifest: profileManifest.provenance,
515
+ deployment: origins,
516
+ exclusions: profileManifest.exclusions,
517
+ },
518
+ },
519
+ };
520
+ }
521
+ const topology = value.workspace.topology ?? defaultWorkspaceTopology();
522
+ const bindingRef = workspaceBindingRef(value.workspace.binding);
523
+ const providerResourceId = workspaceProviderResourceId({
524
+ deploymentNamespace: value.deployment.id,
525
+ workspaceBindingRef: bindingRef,
526
+ topology,
527
+ scopeRef: scopeRef.value,
528
+ });
529
+ const cloudflareSandboxId = cloudflareWorkspaceSandboxId({
530
+ deploymentNamespace: value.deployment.id,
531
+ workspaceBindingRef: bindingRef,
532
+ scopeRef: scopeRef.value,
533
+ providerResourceId,
534
+ });
535
+ const manifestWithWorkspaceMaterial = addWorkspaceMaterial(profileManifest.manifest, profileManifest.provenance, providerResourceId);
536
+ const referenceIssues = validateManifestToolReferences(manifestWithWorkspaceMaterial.manifest);
537
+ if (referenceIssues.length > 0) {
538
+ return { ok: false, issues: referenceIssues };
539
+ }
540
+ const origins = {
541
+ "/profile": configAuthorOrigin("/profile"),
542
+ "/agent": configAuthorOrigin("/agent"),
543
+ "/deployment/id": configAuthorOrigin("/deployment/id"),
544
+ ...(value.deployment.version === undefined
545
+ ? {}
546
+ : { "/deployment/version": configAuthorOrigin("/deployment/version") }),
547
+ "/target/kind": configAuthorOrigin("/target/kind"),
548
+ "/target/durableObject/className": configAuthorOrigin("/target/durableObject/className"),
549
+ "/target/durableObject/binding": configAuthorOrigin("/target/durableObject/binding"),
550
+ "/client/kind": configAuthorOrigin("/client/kind"),
551
+ "/llm/route": configAuthorOrigin("/llm/route"),
552
+ "/llm/endpointRef": configAuthorOrigin("/llm/endpointRef"),
553
+ "/llm/credentialRef": configAuthorOrigin("/llm/credentialRef"),
554
+ "/llm/modelRef": configAuthorOrigin("/llm/modelRef"),
555
+ "/workspace/binding": configAuthorOrigin("/workspace/binding"),
556
+ "/workspace/bindingRef": `derived:/workspace/binding`,
557
+ "/workspace/root": configAuthorOrigin("/workspace/root"),
558
+ "/workspace/topology/kind": value.workspace.topology === undefined
559
+ ? workspaceMacroOrigin("/workspace/topology/kind")
560
+ : configAuthorOrigin("/workspace/topology/kind"),
561
+ "/workspace/topology/allocator": value.workspace.topology === undefined
562
+ ? workspaceMacroOrigin("/workspace/topology/allocator")
563
+ : configAuthorOrigin("/workspace/topology/allocator"),
564
+ "/deployment/backend": `derived:/target/kind`,
565
+ "/deployment/adapter": `derived:/target/kind`,
566
+ "/deployment/codec": workspaceMacroOrigin("/deployment/codec"),
567
+ "/deployment/providerStrategy": `derived:/llm/route`,
568
+ "/workspace/providerResourceId": `derived:/deployment/id+/workspace/binding+/workspace/topology+/agent/scope`,
569
+ "/workspace/cloudflareSandboxId": `derived:/workspace/providerResourceId`,
570
+ };
571
+ return {
572
+ ok: true,
573
+ value: {
574
+ profile: AGENTOS_CONFIG_PROFILE.WORKSPACE_V1,
575
+ config: value,
576
+ deployment: {
577
+ deploymentId: value.deployment.id,
578
+ manifest: manifestWithWorkspaceMaterial.manifest,
579
+ backend: "cloudflare-do",
580
+ adapter: AGENTOS_CONFIG_TARGET.CLOUDFLARE_DO_V1,
581
+ codec: "agentos-json@1",
582
+ providerStrategy: value.llm.route,
583
+ },
584
+ ...(value.deployment.version === undefined
585
+ ? {}
586
+ : { deploymentVersion: value.deployment.version }),
587
+ authoredToolNames: Object.keys(compiled.toolFilePaths).sort(),
588
+ target: value.target,
589
+ client: value.client,
590
+ llm: value.llm,
591
+ workspace: {
592
+ binding: value.workspace.binding,
593
+ bindingRef,
594
+ root: value.workspace.root,
595
+ topology,
596
+ providerResourceId,
597
+ cloudflareSandboxId,
598
+ },
599
+ origins,
600
+ provenance: {
601
+ manifest: manifestWithWorkspaceMaterial.provenance,
602
+ deployment: origins,
603
+ exclusions: profileManifest.exclusions,
604
+ },
605
+ },
606
+ };
607
+ };