@xemahq/agent-session-runtime 0.4.0 → 0.6.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch-contract.d.ts","sourceRoot":"","sources":["../../src/lib/dispatch-contract.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAMrE,eAAO,MAAM,wBAAwB;;;CAK3B,CAAC;AAEX,MAAM,MAAM,6BAA6B,GACvC,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAC;AAa3E,MAAM,WAAW,aAAa;IAM5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAQD,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAKnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAMD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC,cAAc,CAAC;IAE9D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IASxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAOD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC,cAAc,CAAC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAED,MAAM,MAAM,2BAA2B,GACnC,oBAAoB,GACpB,oBAAoB,CAAC;AAUzB,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAK9C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IAKnC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC;AAQD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB"}
1
+ {"version":3,"file":"dispatch-contract.d.ts","sourceRoot":"","sources":["../../src/lib/dispatch-contract.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAMrE,eAAO,MAAM,wBAAwB;;;CAK3B,CAAC;AAEX,MAAM,MAAM,6BAA6B,GACvC,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAC;AAa3E,MAAM,WAAW,aAAa;IAM5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAQD,MAAM,WAAW,qBAAqB;IAEpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAMxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAKnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAMD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC,cAAc,CAAC;IAE9D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IASxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAOD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,wBAAwB,CAAC,cAAc,CAAC;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,SAAS,aAAa,EAAE,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAED,MAAM,MAAM,2BAA2B,GACnC,oBAAoB,GACpB,oBAAoB,CAAC;AAUzB,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,QAAQ,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IAK9C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IAKnC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC;AAQD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xemahq/agent-session-runtime",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -37,8 +37,8 @@
37
37
  "typescript": "5.9.3"
38
38
  },
39
39
  "dependencies": {
40
- "@xemahq/dsl": "^0.2.0",
41
- "@xemahq/kernel-contracts": "^0.4.0"
40
+ "@xemahq/dsl": "^0.4.0",
41
+ "@xemahq/kernel-contracts": "^0.6.0"
42
42
  },
43
43
  "scripts": {
44
44
  "clean": "rm -rf dist",
@@ -277,7 +277,7 @@ export class DefaultWorkspaceImageComposer implements WorkspaceImageComposer {
277
277
  mode: WorkspaceMountMode.ReadOnly,
278
278
  mountKey: `agent-bundle:${req.manifest.agent.slug}`,
279
279
  source: {
280
- kind: 'agent-definition',
280
+ kind: 'agent-kernel',
281
281
  orgId: req.orgId,
282
282
  agentSlug: req.manifest.agent.slug,
283
283
  stageKey: req.manifest.agent.stageKey,
@@ -294,7 +294,7 @@ export class DefaultWorkspaceImageComposer implements WorkspaceImageComposer {
294
294
  mode: WorkspaceMountMode.ReadOnly,
295
295
  mountKey: `agent-bundle:${sub}`,
296
296
  source: {
297
- kind: 'agent-definition',
297
+ kind: 'agent-kernel',
298
298
  orgId: req.orgId,
299
299
  agentSlug: sub,
300
300
  stageKey: req.manifest.agent.stageKey,
@@ -1,7 +1,7 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
2
  // ── Shared composition-resolver primitives ──
3
3
  //
4
- // The "one resolver, not N" foundation. Composition (agent) tree resolution
4
+ // The "one resolver, not N" foundation. Agent (agent) tree resolution
5
5
  // — walk the tree, collect skills / tools, append instructions, merge the
6
6
  // permission/model overlay, and project to a runtime config — was
7
7
  // re-implemented in agent-session-api, the workflow-runtime-worker, and
@@ -9,14 +9,14 @@
9
9
  // `modelOverride` and collected only the root node's skills). This module
10
10
  // extracts the PURE parts so every consumer shares ONE implementation.
11
11
  //
12
- // All inputs are kernel `ResolvedComposition` / `ResolvedCompositionNode`
12
+ // All inputs are kernel `ResolvedAgent` / `ResolvedAgentNode`
13
13
  // shapes (`@xemahq/kernel-contracts/agent-composition`). Each node `extends
14
14
  // NodeOverlayFragment`, so its `modelOverride` / `instructions` / `permission`
15
15
  // overlay trio is read directly off the node — no per-shape restatement.
16
16
  //
17
17
  // Tier-1 functions (collect / walk) copy the canonical agent-session-api
18
18
  // resolver semantics EXACTLY: depth-first PRE-ORDER over DESCENDANTS,
19
- // FIRST-occurrence-by-slug wins. Tier-2 (`projectCompositionToRuntimeConfig`)
19
+ // FIRST-occurrence-by-slug wins. Tier-2 (`projectAgentToRuntimeConfig`)
20
20
  // assembles those into the runtime projection.
21
21
  //
22
22
  // `RuntimeAgentConfig` lives HERE, not in `@xemahq/kernel-contracts`, because
@@ -35,8 +35,8 @@ import {
35
35
  type SubAgentBinding,
36
36
  } from '@xemahq/kernel-contracts/workflow';
37
37
  import type {
38
- ResolvedComposition,
39
- ResolvedCompositionNode,
38
+ ResolvedAgent,
39
+ ResolvedAgentNode,
40
40
  } from '@xemahq/kernel-contracts/agent-composition';
41
41
  import type { PermissionMap } from '@xemahq/kernel-contracts/agent-permission';
42
42
  import {
@@ -52,10 +52,10 @@ import {
52
52
  * composition resolver in llm-registry-api owns the wire format, so drift is
53
53
  * a platform bug, not a user error. Fail-fast: no silent coercion.
54
54
  */
55
- export class CompositionResolutionError extends Error {
55
+ export class AgentResolutionError extends Error {
56
56
  constructor(context: string, detail: string) {
57
- super(`Composition resolution failed for "${context}": ${detail}`);
58
- this.name = 'CompositionResolutionError';
57
+ super(`Agent resolution failed for "${context}": ${detail}`);
58
+ this.name = 'AgentResolutionError';
59
59
  }
60
60
  }
61
61
 
@@ -68,7 +68,7 @@ export class CompositionResolutionError extends Error {
68
68
  * dropped. Mirrors {@link SubAgentBinding} minus the kernel's intrinsic-floor
69
69
  * semantics (those are merged downstream, per-consumer).
70
70
  */
71
- export interface FlattenedCompositionNode {
71
+ export interface FlattenedAgentNode {
72
72
  readonly slug: string;
73
73
  readonly alias?: string;
74
74
  readonly modelOverride?: ModelRef;
@@ -91,7 +91,7 @@ export interface CollectScopeOptions {
91
91
  * PROJECTION, not a wire contract — lives in this lib, not kernel-contracts.
92
92
  */
93
93
  export interface RuntimeAgentConfig {
94
- readonly compositionRef: string;
94
+ readonly agentRef: string;
95
95
  readonly primaryAgentSlug: string;
96
96
  /** Root instructions (+ overlay), normalized; `null` when none. */
97
97
  readonly primaryInstructions: string | null;
@@ -123,14 +123,14 @@ export interface RuntimeAgentConfig {
123
123
  * This is where the worker drift is corrected: `modelOverride` is carried on
124
124
  * every entry, never dropped.
125
125
  */
126
- export function flattenCompositionTree(
127
- root: ResolvedCompositionNode,
128
- ): readonly FlattenedCompositionNode[] {
126
+ export function flattenAgentTree(
127
+ root: ResolvedAgentNode,
128
+ ): readonly FlattenedAgentNode[] {
129
129
  const seen = new Set<string>();
130
- const out: FlattenedCompositionNode[] = [];
131
- const visit = (node: ResolvedCompositionNode): void => {
130
+ const out: FlattenedAgentNode[] = [];
131
+ const visit = (node: ResolvedAgentNode): void => {
132
132
  for (const child of node.children) {
133
- const slug = child.agent.slug;
133
+ const slug = child.kernel.slug;
134
134
  if (slug.length === 0) {
135
135
  continue;
136
136
  }
@@ -160,13 +160,13 @@ export function flattenCompositionTree(
160
160
  * only.
161
161
  */
162
162
  export function collectSkills(
163
- root: ResolvedCompositionNode,
163
+ root: ResolvedAgentNode,
164
164
  opts?: CollectScopeOptions,
165
165
  ): readonly string[] {
166
166
  const scope = opts?.scope ?? 'tree';
167
167
  const seen = new Set<string>();
168
168
  const out: string[] = [];
169
- const addNode = (node: ResolvedCompositionNode): void => {
169
+ const addNode = (node: ResolvedAgentNode): void => {
170
170
  for (const slug of projectSkillSlugs(node.skills)) {
171
171
  if (!seen.has(slug)) {
172
172
  seen.add(slug);
@@ -176,7 +176,7 @@ export function collectSkills(
176
176
  };
177
177
  addNode(root);
178
178
  if (scope === 'tree') {
179
- const visit = (node: ResolvedCompositionNode): void => {
179
+ const visit = (node: ResolvedAgentNode): void => {
180
180
  for (const child of node.children) {
181
181
  addNode(child);
182
182
  visit(child);
@@ -194,18 +194,18 @@ export function collectSkills(
194
194
  * fail-fast via {@link projectToolSelection}.
195
195
  */
196
196
  export function collectTools(
197
- root: ResolvedCompositionNode,
197
+ root: ResolvedAgentNode,
198
198
  opts?: CollectScopeOptions,
199
199
  ): readonly ToolSelectionEntry[] {
200
200
  const scope = opts?.scope ?? 'root';
201
- const ctx = root.agent.slug;
201
+ const ctx = root.kernel.slug;
202
202
  if (scope === 'root') {
203
203
  return projectToolSelection(root.tools, ctx);
204
204
  }
205
205
  const out: ToolSelectionEntry[] = [...projectToolSelection(root.tools, ctx)];
206
- const visit = (node: ResolvedCompositionNode): void => {
206
+ const visit = (node: ResolvedAgentNode): void => {
207
207
  for (const child of node.children) {
208
- out.push(...projectToolSelection(child.tools, child.agent.slug));
208
+ out.push(...projectToolSelection(child.tools, child.kernel.slug));
209
209
  visit(child);
210
210
  }
211
211
  };
@@ -215,11 +215,11 @@ export function collectTools(
215
215
 
216
216
  /**
217
217
  * Per-descendant-slug normalized instructions, keyed by agent slug. Mirrors
218
- * {@link flattenCompositionTree} (DFS pre-order, first-wins). A descendant
218
+ * {@link flattenAgentTree} (DFS pre-order, first-wins). A descendant
219
219
  * with no (or whitespace-only) instructions contributes no key.
220
220
  */
221
221
  export function collectInstructionsBySlug(
222
- root: ResolvedCompositionNode,
222
+ root: ResolvedAgentNode,
223
223
  ): Readonly<Record<string, string>> {
224
224
  return collectDescendantOverlay(root, (child) =>
225
225
  normalizeInstructions(child.instructions),
@@ -231,7 +231,7 @@ export function collectInstructionsBySlug(
231
231
  * first-wins. A descendant with no (or empty) override contributes no key.
232
232
  */
233
233
  export function collectPermissionsBySlug(
234
- root: ResolvedCompositionNode,
234
+ root: ResolvedAgentNode,
235
235
  ): Readonly<Record<string, PermissionMap>> {
236
236
  return collectDescendantOverlay(root, (child) =>
237
237
  normalizePermission(child.permission),
@@ -244,10 +244,10 @@ export function collectPermissionsBySlug(
244
244
  * with no override contributes no key. Each override is validated fail-fast.
245
245
  */
246
246
  export function collectModelOverridesBySlug(
247
- root: ResolvedCompositionNode,
247
+ root: ResolvedAgentNode,
248
248
  ): Readonly<Record<string, ModelRef>> {
249
249
  return collectDescendantOverlay(root, (child) =>
250
- projectModelOverride(child.modelOverride, child.agent.slug),
250
+ projectModelOverride(child.modelOverride, child.kernel.slug),
251
251
  );
252
252
  }
253
253
 
@@ -258,14 +258,14 @@ export function collectModelOverridesBySlug(
258
258
  * with no override. Centralizes the walk the three per-slug collectors share.
259
259
  */
260
260
  function collectDescendantOverlay<T>(
261
- root: ResolvedCompositionNode,
262
- project: (child: ResolvedCompositionNode) => T | null,
261
+ root: ResolvedAgentNode,
262
+ project: (child: ResolvedAgentNode) => T | null,
263
263
  ): Readonly<Record<string, T>> {
264
264
  const out: Record<string, T> = {};
265
265
  const seen = new Set<string>();
266
- const visit = (node: ResolvedCompositionNode): void => {
266
+ const visit = (node: ResolvedAgentNode): void => {
267
267
  for (const child of node.children) {
268
- const slug = child.agent.slug;
268
+ const slug = child.kernel.slug;
269
269
  if (slug.length === 0) {
270
270
  continue;
271
271
  }
@@ -354,7 +354,7 @@ export function projectModelOverride(
354
354
  }
355
355
  if (raw.kind === ModelRefKind.CONCRETE) {
356
356
  if (typeof raw.modelId !== 'string' || raw.modelId.trim().length === 0) {
357
- throw new CompositionResolutionError(
357
+ throw new AgentResolutionError(
358
358
  context,
359
359
  'concrete modelOverride is missing a modelId',
360
360
  );
@@ -368,7 +368,7 @@ export function projectModelOverride(
368
368
  modelClass === undefined ||
369
369
  !MODEL_CLASS_VALUES.includes(modelClass as ModelClass)
370
370
  ) {
371
- throw new CompositionResolutionError(
371
+ throw new AgentResolutionError(
372
372
  context,
373
373
  `strategy modelOverride.modelClass must be one of ${MODEL_CLASS_VALUES.join(
374
374
  ', ',
@@ -380,7 +380,7 @@ export function projectModelOverride(
380
380
 
381
381
  /** Project a node's skill refs into a flat, non-empty slug list. */
382
382
  function projectSkillSlugs(
383
- skills: ResolvedCompositionNode['skills'] | undefined,
383
+ skills: ResolvedAgentNode['skills'] | undefined,
384
384
  ): string[] {
385
385
  if (!Array.isArray(skills)) {
386
386
  return [];
@@ -397,7 +397,7 @@ function projectSkillSlugs(
397
397
  * Fail-fast on shape errors — the composition resolver owns the wire format.
398
398
  */
399
399
  function projectToolSelection(
400
- tools: ResolvedCompositionNode['tools'] | undefined,
400
+ tools: ResolvedAgentNode['tools'] | undefined,
401
401
  context: string,
402
402
  ): ToolSelectionEntry[] {
403
403
  if (!Array.isArray(tools)) {
@@ -410,7 +410,7 @@ function projectToolSelection(
410
410
  typeof tool.providerKind !== 'string' ||
411
411
  !validKinds.has(tool.providerKind)
412
412
  ) {
413
- throw new CompositionResolutionError(
413
+ throw new AgentResolutionError(
414
414
  context,
415
415
  `tools[${idx}].providerKind must be one of ${Object.values(
416
416
  ToolProviderKind,
@@ -421,7 +421,7 @@ function projectToolSelection(
421
421
  typeof tool.resourceId !== 'string' ||
422
422
  tool.resourceId.trim().length === 0
423
423
  ) {
424
- throw new CompositionResolutionError(
424
+ throw new AgentResolutionError(
425
425
  context,
426
426
  `tools[${idx}].resourceId must be a non-empty string`,
427
427
  );
@@ -437,7 +437,7 @@ function projectToolSelection(
437
437
  typeof tool.toolName !== 'string' ||
438
438
  tool.toolName.trim().length === 0
439
439
  ) {
440
- throw new CompositionResolutionError(
440
+ throw new AgentResolutionError(
441
441
  context,
442
442
  `tools[${idx}].toolName must be a non-empty string for kind='tool'`,
443
443
  );
@@ -449,7 +449,7 @@ function projectToolSelection(
449
449
  toolName: tool.toolName,
450
450
  });
451
451
  } else {
452
- throw new CompositionResolutionError(
452
+ throw new AgentResolutionError(
453
453
  context,
454
454
  `tools[${idx}].kind must be "provider" or "tool"`,
455
455
  );
@@ -461,7 +461,7 @@ function projectToolSelection(
461
461
  // ─── Tier-2: projection ───────────────────────────────────────────────────────
462
462
 
463
463
  /**
464
- * Project a `ResolvedComposition` into a {@link RuntimeAgentConfig} — the
464
+ * Project a `ResolvedAgent` into a {@link RuntimeAgentConfig} — the
465
465
  * runtime-facing shape a driver materializes the primary agent + delegates
466
466
  * from. The single resolver every consumer shares.
467
467
  *
@@ -477,12 +477,12 @@ function projectToolSelection(
477
477
  * deep-merge against the AGENT's authored permission happens in the
478
478
  * downstream materializer, not in this projection).
479
479
  */
480
- export function projectCompositionToRuntimeConfig(
481
- resolved: ResolvedComposition,
480
+ export function projectAgentToRuntimeConfig(
481
+ resolved: ResolvedAgent,
482
482
  overlay?: NodeOverlayFragment,
483
483
  ): RuntimeAgentConfig {
484
484
  const root = resolved.root;
485
- const compositionRef = `${resolved.slug}@${resolved.version}`;
485
+ const agentRef = `${resolved.slug}@${resolved.version}`;
486
486
 
487
487
  const rootInstructions = normalizeInstructions(root.instructions);
488
488
  const overlayInstructions = normalizeInstructions(overlay?.instructions);
@@ -494,21 +494,21 @@ export function projectCompositionToRuntimeConfig(
494
494
 
495
495
  const rootModelOverride = projectModelOverride(
496
496
  root.modelOverride,
497
- compositionRef,
497
+ agentRef,
498
498
  );
499
499
  const overlayModelOverride = projectModelOverride(
500
500
  overlay?.modelOverride,
501
- `${compositionRef}#overlay`,
501
+ `${agentRef}#overlay`,
502
502
  );
503
503
 
504
504
  const rootPermission = normalizePermission(root.permission);
505
505
  const overlayPermission = normalizePermission(overlay?.permission);
506
506
 
507
- const flattened = flattenCompositionTree(root);
507
+ const flattened = flattenAgentTree(root);
508
508
 
509
509
  return {
510
- compositionRef,
511
- primaryAgentSlug: root.agent.slug,
510
+ agentRef,
511
+ primaryAgentSlug: root.kernel.slug,
512
512
  primaryInstructions:
513
513
  primaryInstructions.length > 0 ? primaryInstructions : null,
514
514
  primaryPermission: overlayPermission ?? rootPermission,
@@ -1,5 +1,5 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
- // ── Composition → CompiledWorkspaceManifest reconstruction ──
2
+ // ── Agent → CompiledWorkspaceManifest reconstruction ──
3
3
  //
4
4
  // Phase 10 (`workspace-manifests-api` retirement). The composer turns a
5
5
  // `CompiledWorkspaceManifest` into a `WorkspaceMountPlan`; before this
@@ -7,7 +7,7 @@
7
7
  // `WorkspaceManifest` row from `workspace-manifests-api` and run
8
8
  // `compileManifest` on it.
9
9
  //
10
- // The Agent Composition primitive now carries the user-data MOUNT LAYOUT
10
+ // The Agent primitive now carries the user-data MOUNT LAYOUT
11
11
  // on its `workspace.mountLayout` block: the boot-seeder in `llm-registry-api`
12
12
  // projects each biome manifest's `extends:`-flattened RAW `spec.mounts` /
13
13
  // `spec.seedFiles` / `spec.inputs` there. This module reconstructs a
@@ -62,22 +62,22 @@ export type { CompiledWorkspaceManifest };
62
62
  * composition ref, or a `compileManifest` failure. Fail-fast: a session /
63
63
  * run cannot bootstrap a `/workspace/` tree without a valid mount layout.
64
64
  */
65
- export class CompositionMountLayoutError extends Error {
66
- constructor(compositionRef: string, detail: string) {
65
+ export class AgentMountLayoutError extends Error {
66
+ constructor(agentRef: string, detail: string) {
67
67
  super(
68
- `Cannot derive a workspace mount layout from Agent Composition ` +
69
- `"${compositionRef}": ${detail}`,
68
+ `Cannot derive a workspace mount layout from Agent ` +
69
+ `"${agentRef}": ${detail}`,
70
70
  );
71
- this.name = 'CompositionMountLayoutError';
71
+ this.name = 'AgentMountLayoutError';
72
72
  }
73
73
  }
74
74
 
75
75
  /**
76
76
  * The agent run-config the seeder projects from the source manifest's
77
- * `spec.agent` block. Mirrors `CompositionAgentRunConfigDto` without
77
+ * `spec.agent` block. Mirrors `AgentRunConfigDto` without
78
78
  * importing the generated client.
79
79
  */
80
- export interface CompositionAgentRunConfigInput {
80
+ export interface AgentRunConfigInput {
81
81
  /** Stage key. */
82
82
  readonly stage: string;
83
83
  /** Canonical `AgentRunRole` — drives renderer + system-overlay framing. */
@@ -96,11 +96,11 @@ export interface CompositionAgentRunConfigInput {
96
96
  * / `inputs` against the manifest DSL's authoritative schema, so the loose
97
97
  * typing here is checked downstream, not silently trusted.
98
98
  */
99
- export interface CompositionMountLayoutInput {
99
+ export interface AgentMountLayoutInput {
100
100
  /** Raw `spec.mounts` block — manifest DSL mount-declaration map. */
101
101
  readonly mounts: Readonly<Record<string, unknown>>;
102
102
  /** Projected `spec.agent` run-config. */
103
- readonly agentRunConfig: CompositionAgentRunConfigInput;
103
+ readonly agentRunConfig: AgentRunConfigInput;
104
104
  /** Raw `spec.seedFiles` array — manifest DSL seed-file entries. */
105
105
  readonly seedFiles: readonly unknown[];
106
106
  /** Raw `spec.inputs` block — manifest DSL input-declaration map. */
@@ -118,7 +118,7 @@ export interface CompositionMountLayoutInput {
118
118
  * worker drift). All optional ⇒ backward-compatible with callers that only
119
119
  * supply `slug` / `alias`.
120
120
  */
121
- export interface CompositionSubAgentBindingInput {
121
+ export interface AgentSubAgentBindingInput {
122
122
  readonly slug: string;
123
123
  readonly alias?: string;
124
124
  /** Per-delegate model override — OVERRIDE on the referenced agent's model. */
@@ -141,7 +141,7 @@ export interface CompositionSubAgentBindingInput {
141
141
  * same kind/root/port the bundle-apply path reads from
142
142
  * `composition.workspace.outputSurface`.
143
143
  */
144
- export interface CompositionOutputSurfaceInput {
144
+ export interface AgentOutputSurfaceInput {
145
145
  readonly kind: 'none' | 'web' | 'static' | 'app' | 'tunnel';
146
146
  readonly port?: number;
147
147
  readonly healthPath?: string;
@@ -156,19 +156,19 @@ export interface CompositionOutputSurfaceInput {
156
156
  * `WorkspaceManifest` from. The caller maps its richer resolved-composition
157
157
  * shape onto this — keeping the runtime package free of any API client.
158
158
  */
159
- export interface CompositionManifestSource {
159
+ export interface AgentManifestSource {
160
160
  /** Version-pinned `slug@version` of the resolved composition. */
161
- readonly compositionRef: string;
161
+ readonly agentRef: string;
162
162
  /** Root node's agent slug — the manifest's primary agent. */
163
163
  readonly primaryAgentSlug: string;
164
164
  /** Manifest-declared sub-agent bindings (descendant nodes). */
165
- readonly subAgentBindings: readonly CompositionSubAgentBindingInput[];
165
+ readonly subAgentBindings: readonly AgentSubAgentBindingInput[];
166
166
  /**
167
167
  * The composition's `workspace.mountLayout` block. `undefined` when the
168
168
  * composition declared no `workspace` block or the seeder did not project
169
169
  * a layout — a fail-fast condition.
170
170
  */
171
- readonly mountLayout: CompositionMountLayoutInput | undefined;
171
+ readonly mountLayout: AgentMountLayoutInput | undefined;
172
172
  /**
173
173
  * The composition's `workspace.outputSurface` block. Threaded into the
174
174
  * reconstructed manifest's `spec.outputSurface` so the compiled
@@ -178,7 +178,7 @@ export interface CompositionManifestSource {
178
178
  * composition declared no surface — the DSL compile then yields the
179
179
  * `{ kind: 'none' }` default.
180
180
  */
181
- readonly outputSurface?: CompositionOutputSurfaceInput;
181
+ readonly outputSurface?: AgentOutputSurfaceInput;
182
182
  /**
183
183
  * The composition's `workspace.credentials` block. Threaded into the
184
184
  * reconstructed manifest's `spec.credentials` so the compiled manifest's
@@ -218,7 +218,7 @@ export interface CompositionManifestSource {
218
218
  * it, and no first-party manifest does today. Optional so a caller with
219
219
  * no run-scoped id at all can omit it.
220
220
  */
221
- export interface CompositionManifestImplicitInputs {
221
+ export interface AgentManifestImplicitInputs {
222
222
  readonly orgId: string;
223
223
  readonly projectId: string;
224
224
  readonly sessionId?: string;
@@ -242,18 +242,18 @@ type ManifestInputValue =
242
242
  * shape.
243
243
  *
244
244
  * `bindInputs` is the resolved manifest input bag (explicit inputs ∪
245
- * implicit inputs), built by {@link buildCompositionManifestBindInputs}.
245
+ * implicit inputs), built by {@link buildAgentManifestBindInputs}.
246
246
  * The compile fails fast on an unresolved required input or an enum
247
247
  * violation — exactly the legacy behaviour.
248
248
  */
249
- export function compileCompositionWorkspaceManifest(
250
- source: CompositionManifestSource,
249
+ export function compileAgentWorkspaceManifest(
250
+ source: AgentManifestSource,
251
251
  bindInputs: Readonly<Record<string, unknown>>,
252
252
  ): CompiledWorkspaceManifest {
253
253
  const mountLayout = source.mountLayout;
254
254
  if (!mountLayout) {
255
- throw new CompositionMountLayoutError(
256
- source.compositionRef,
255
+ throw new AgentMountLayoutError(
256
+ source.agentRef,
257
257
  'the composition declares no `workspace.mountLayout` block — its ' +
258
258
  'source workspace manifest was not projected by the llm-registry-api ' +
259
259
  'composition seeder. Re-seed compositions (boot llm-registry-api) or ' +
@@ -261,7 +261,7 @@ export function compileCompositionWorkspaceManifest(
261
261
  );
262
262
  }
263
263
 
264
- const [slug, version] = splitCompositionRef(source.compositionRef);
264
+ const [slug, version] = splitAgentRef(source.agentRef);
265
265
 
266
266
  // Sub-agents the composition resolved become the manifest agent block's
267
267
  // `subAgents[]`. The composer + EnvironmentResolver surface these on the
@@ -333,7 +333,7 @@ export function compileCompositionWorkspaceManifest(
333
333
  metadata: {
334
334
  slug,
335
335
  version,
336
- // Compositions resolved for a session bootstrap are, by definition,
336
+ // Agents resolved for a session bootstrap are, by definition,
337
337
  // agent-session compatible — the runtime EnvironmentResolver still
338
338
  // re-asserts `surfaceCompat` against the AGENT_SESSION surface.
339
339
  surfaceCompat: [ManifestSurface.AGENT_SESSION],
@@ -343,8 +343,8 @@ export function compileCompositionWorkspaceManifest(
343
343
 
344
344
  const result = compileManifest(envelope, bindInputs);
345
345
  if (!result.ok) {
346
- throw new CompositionMountLayoutError(
347
- source.compositionRef,
346
+ throw new AgentMountLayoutError(
347
+ source.agentRef,
348
348
  `reconstructed manifest failed to compile: ${result.errors
349
349
  .map((e) => `${e.path}: ${e.message}`)
350
350
  .join('; ')}`,
@@ -355,7 +355,7 @@ export function compileCompositionWorkspaceManifest(
355
355
 
356
356
  /**
357
357
  * Project the composition's `workspace.outputSurface` block (carried on
358
- * the runtime-agnostic `CompositionManifestSource`) into the manifest DSL's
358
+ * the runtime-agnostic `AgentManifestSource`) into the manifest DSL's
359
359
  * `ManifestOutputSurface` shape so the reconstructed envelope's
360
360
  * `spec.outputSurface` carries the same kind/root/port as the source. The
361
361
  * `kind` value strings match the DSL enum 1:1 (`none` / `web` / `static` /
@@ -366,7 +366,7 @@ export function compileCompositionWorkspaceManifest(
366
366
  * `{ kind: 'none', autoOpen: false, mode: 'single' }`.
367
367
  */
368
368
  function projectOutputSurface(
369
- surface: CompositionOutputSurfaceInput | undefined,
369
+ surface: AgentOutputSurfaceInput | undefined,
370
370
  ): ManifestOutputSurface | undefined {
371
371
  if (!surface) return undefined;
372
372
  return {
@@ -386,7 +386,7 @@ function projectOutputSurface(
386
386
 
387
387
  /**
388
388
  * Project the composition's `workspace.credentials` block (carried on the
389
- * runtime-agnostic `CompositionManifestSource` as the kernel
389
+ * runtime-agnostic `AgentManifestSource` as the kernel
390
390
  * `CompiledManifestCredential[]`) into the manifest DSL's authored
391
391
  * `ManifestCredential[]` shape so the reconstructed envelope's
392
392
  * `spec.credentials` carries the same entries as the source.
@@ -415,7 +415,7 @@ function projectCredentials(
415
415
 
416
416
  /**
417
417
  * Project the composition's `workspace.permissions` block (carried on the
418
- * runtime-agnostic `CompositionManifestSource` as the kernel
418
+ * runtime-agnostic `AgentManifestSource` as the kernel
419
419
  * `CompiledManifestPermissions`) into the manifest DSL's authored
420
420
  * `ManifestPermissions` shape so the reconstructed envelope's
421
421
  * `spec.permissions` carries the same tool allow/deny lists as the source.
@@ -457,10 +457,10 @@ function projectPermissions(
457
457
  *
458
458
  * Returns `{}` when the composition declared no inputs.
459
459
  */
460
- export function buildCompositionManifestBindInputs(
461
- source: CompositionManifestSource,
460
+ export function buildAgentManifestBindInputs(
461
+ source: AgentManifestSource,
462
462
  explicitInputs: Record<string, unknown> | null,
463
- implicitInputs: CompositionManifestImplicitInputs,
463
+ implicitInputs: AgentManifestImplicitInputs,
464
464
  ): Readonly<Record<string, unknown>> {
465
465
  const declared = new Set(Object.keys(source.mountLayout?.inputs ?? {}));
466
466
  if (declared.size === 0) {
@@ -471,20 +471,20 @@ export function buildCompositionManifestBindInputs(
471
471
  explicitInputs !== null &&
472
472
  (typeof explicitInputs !== 'object' || Array.isArray(explicitInputs))
473
473
  ) {
474
- throw new CompositionMountLayoutError(
475
- source.compositionRef,
474
+ throw new AgentMountLayoutError(
475
+ source.agentRef,
476
476
  'explicit manifest inputs must be an object when provided',
477
477
  );
478
478
  }
479
479
  const explicit = explicitInputs ?? {};
480
480
  for (const [key, value] of Object.entries(explicit)) {
481
481
  if (!declared.has(key)) {
482
- throw new CompositionMountLayoutError(
483
- source.compositionRef,
482
+ throw new AgentMountLayoutError(
483
+ source.agentRef,
484
484
  `manifest inputs contain undeclared key "${key}"`,
485
485
  );
486
486
  }
487
- assertManifestInputValue(source.compositionRef, key, value);
487
+ assertManifestInputValue(source.agentRef, key, value);
488
488
  }
489
489
 
490
490
  const implicit: Record<string, ManifestInputValue> = {
@@ -509,10 +509,10 @@ export function buildCompositionManifestBindInputs(
509
509
  }
510
510
 
511
511
  /** Split a `slug@version` composition ref; fail fast on a bare slug. */
512
- function splitCompositionRef(ref: string): [slug: string, version: string] {
512
+ function splitAgentRef(ref: string): [slug: string, version: string] {
513
513
  const at = ref.lastIndexOf('@');
514
514
  if (at <= 0 || at === ref.length - 1) {
515
- throw new CompositionMountLayoutError(
515
+ throw new AgentMountLayoutError(
516
516
  ref,
517
517
  'expected a version-pinned `slug@version` composition ref — the ' +
518
518
  'session resolver always pins the resolved version',
@@ -528,7 +528,7 @@ function splitCompositionRef(ref: string): [slug: string, version: string] {
528
528
  * boundary so the error surfaces near the cause.
529
529
  */
530
530
  function assertManifestInputValue(
531
- compositionRef: string,
531
+ agentRef: string,
532
532
  key: string,
533
533
  value: unknown,
534
534
  ): void {
@@ -539,8 +539,8 @@ function assertManifestInputValue(
539
539
  typeof value !== 'boolean' &&
540
540
  !Array.isArray(value)
541
541
  ) {
542
- throw new CompositionMountLayoutError(
543
- compositionRef,
542
+ throw new AgentMountLayoutError(
543
+ agentRef,
544
544
  `manifest input "${key}" must be a primitive ` +
545
545
  `(string, number, boolean, string[]) — got ${typeof value}`,
546
546
  );
@@ -549,8 +549,8 @@ function assertManifestInputValue(
549
549
  Array.isArray(value) &&
550
550
  !value.every((entry) => typeof entry === 'string')
551
551
  ) {
552
- throw new CompositionMountLayoutError(
553
- compositionRef,
552
+ throw new AgentMountLayoutError(
553
+ agentRef,
554
554
  `manifest input "${key}" is an array — every element must be a string`,
555
555
  );
556
556
  }
@@ -84,14 +84,14 @@ export interface CreateAndRunDispatch {
84
84
  /** Stable spine identity within the workflow run. */
85
85
  readonly jobKey: string;
86
86
  /**
87
- * Agent Composition ref (`slug` = latest published, or `slug@version`)
87
+ * Agent ref (`slug` = latest published, or `slug@version`)
88
88
  * the new pipeline-owned session should bootstrap from. The dispatch
89
- * service stamps this onto `Session.compositionRef`; the session
89
+ * service stamps this onto `Session.agentRef`; the session
90
90
  * lifecycle resolves it via llm-registry-api's `GET /compositions/
91
91
  * resolve/:ref` for both the agent/skill/tool tree and the workspace
92
92
  * mount layout.
93
93
  */
94
- readonly compositionRef: string;
94
+ readonly agentRef: string;
95
95
  readonly agentSlug: string;
96
96
  readonly promptContext: DispatchPromptContext;
97
97
  }