@smithers-orchestrator/graph 0.24.0 → 0.24.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smithers-orchestrator/graph",
3
- "version": "0.24.0",
3
+ "version": "0.24.2",
4
4
  "description": "Framework-neutral Smithers workflow graph model and extraction helpers",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "drizzle-orm": "^0.45.2",
24
24
  "zod": "^4.3.6",
25
- "@smithers-orchestrator/errors": "0.24.0"
25
+ "@smithers-orchestrator/errors": "0.24.2"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/bun": "latest",
@@ -0,0 +1 @@
1
+ export type { TaskAspects } from "./types";
package/src/extract.js CHANGED
@@ -248,6 +248,49 @@ function approvalAutoApprove(value) {
248
248
  : {}),
249
249
  };
250
250
  }
251
+ /**
252
+ * Normalize the `__aspects` element prop attached by `<Task>` into the
253
+ * `TaskAspects` budget metadata the engine enforces. Only the budget configs
254
+ * are kept; the render-time accumulator and tracking flags are dropped (the
255
+ * engine keeps its own durable per-run accumulator and budgets enforce
256
+ * regardless of tracking).
257
+ *
258
+ * @param {unknown} value
259
+ * @returns {import("./types").TaskAspects | undefined}
260
+ */
261
+ function aspects(value) {
262
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
263
+ return undefined;
264
+ }
265
+ const raw = /** @type {Record<string, unknown>} */ (value);
266
+ /** @type {import("./types").TaskAspects} */
267
+ const out = {};
268
+ const token = raw.tokenBudget;
269
+ if (token && typeof token === "object" && !Array.isArray(token) &&
270
+ typeof (/** @type {Record<string, unknown>} */ (token).max) === "number") {
271
+ const t = /** @type {Record<string, unknown>} */ (token);
272
+ out.tokenBudget = {
273
+ max: /** @type {number} */ (t.max),
274
+ ...(typeof t.perTask === "number" ? { perTask: t.perTask } : {}),
275
+ ...(t.onExceeded === "warn" || t.onExceeded === "skip-remaining" || t.onExceeded === "fail"
276
+ ? { onExceeded: /** @type {"fail" | "warn" | "skip-remaining"} */ (t.onExceeded) }
277
+ : {}),
278
+ };
279
+ }
280
+ const latency = raw.latencySlo;
281
+ if (latency && typeof latency === "object" && !Array.isArray(latency) &&
282
+ typeof (/** @type {Record<string, unknown>} */ (latency).maxMs) === "number") {
283
+ const l = /** @type {Record<string, unknown>} */ (latency);
284
+ out.latencySlo = {
285
+ maxMs: /** @type {number} */ (l.maxMs),
286
+ ...(typeof l.perTask === "number" ? { perTask: l.perTask } : {}),
287
+ ...(l.onExceeded === "warn" || l.onExceeded === "fail"
288
+ ? { onExceeded: /** @type {"fail" | "warn"} */ (l.onExceeded) }
289
+ : {}),
290
+ };
291
+ }
292
+ return out.tokenBudget || out.latencySlo ? out : undefined;
293
+ }
251
294
  /**
252
295
  * @param {"parallel" | "merge-queue"} tag
253
296
  * @param {Record<string, unknown>} raw
@@ -628,6 +671,7 @@ export function extractGraph(root, opts) {
628
671
  memoryConfig: raw.memory && typeof raw.memory === "object" && !Array.isArray(raw.memory)
629
672
  ? raw.memory
630
673
  : undefined,
674
+ aspects: aspects(raw.__aspects),
631
675
  });
632
676
  }
633
677
  let elementIndex = 0;
package/src/index.d.ts CHANGED
@@ -109,6 +109,18 @@ type ApprovalOption$1 = {
109
109
  summary?: string;
110
110
  metadata?: Record<string, unknown>;
111
111
  };
112
+ type TaskAspects$1 = {
113
+ tokenBudget?: {
114
+ max: number;
115
+ perTask?: number;
116
+ onExceeded?: "fail" | "warn" | "skip-remaining";
117
+ };
118
+ latencySlo?: {
119
+ maxMs: number;
120
+ perTask?: number;
121
+ onExceeded?: "fail" | "warn";
122
+ };
123
+ };
112
124
  type TaskDescriptor$1 = {
113
125
  nodeId: string;
114
126
  ordinal: number;
@@ -156,6 +168,7 @@ type TaskDescriptor$1 = {
156
168
  meta?: Record<string, unknown>;
157
169
  scorers?: ScorersMap$1;
158
170
  memoryConfig?: TaskMemoryConfig$1;
171
+ aspects?: TaskAspects$1;
159
172
  };
160
173
  type WorkflowGraph$2 = {
161
174
  readonly xml: XmlNode$1 | null;
@@ -222,6 +235,7 @@ type ScorerBinding = ScorerBinding$1;
222
235
  type ScorerFn = ScorerFn$1;
223
236
  type ScorerInput = ScorerInput$1;
224
237
  type ScorersMap = ScorersMap$1;
238
+ type TaskAspects = TaskAspects$1;
225
239
  type TaskDescriptor = TaskDescriptor$1;
226
240
  type TaskMemoryConfig = TaskMemoryConfig$1;
227
241
  type WorkflowGraph = WorkflowGraph$2;
@@ -229,4 +243,4 @@ type XmlElement = XmlElement$1;
229
243
  type XmlNode = XmlNode$1;
230
244
  type XmlText = XmlText$1;
231
245
 
232
- export { type AgentLike, type ApprovalOption, type CachePolicy, type ExtractGraph, type ExtractOptions, type GraphSnapshot, type HostElement, type HostNode, type HostText, type MemoryNamespace, type MemoryNamespaceKind, type RetryPolicy, type SamplingConfig, type ScoreResult, type Scorer, type ScorerBinding, type ScorerFn, type ScorerInput, type ScorersMap, type TaskDescriptor, type TaskMemoryConfig, type WorkflowGraph, type XmlElement, type XmlNode, type XmlText, extractFromHost, extractGraph, resolveWorktreePath };
246
+ export { type AgentLike, type ApprovalOption, type CachePolicy, type ExtractGraph, type ExtractOptions, type GraphSnapshot, type HostElement, type HostNode, type HostText, type MemoryNamespace, type MemoryNamespaceKind, type RetryPolicy, type SamplingConfig, type ScoreResult, type Scorer, type ScorerBinding, type ScorerFn, type ScorerInput, type ScorersMap, type TaskAspects, type TaskDescriptor, type TaskMemoryConfig, type WorkflowGraph, type XmlElement, type XmlNode, type XmlText, extractFromHost, extractGraph, resolveWorktreePath };
package/src/types.ts CHANGED
@@ -123,6 +123,26 @@ export type ApprovalOption = {
123
123
  metadata?: Record<string, unknown>;
124
124
  };
125
125
 
126
+ /**
127
+ * Resolved `<Aspects>` budget configuration that applies to a task, extracted
128
+ * from the `__aspects` element prop. The engine reads this at task-dispatch
129
+ * time to enforce per-run token and latency budgets. The render-time
130
+ * accumulator carried alongside the budgets in the component tree is dropped
131
+ * here; the engine keeps its own durable accumulator.
132
+ */
133
+ export type TaskAspects = {
134
+ tokenBudget?: {
135
+ max: number;
136
+ perTask?: number;
137
+ onExceeded?: "fail" | "warn" | "skip-remaining";
138
+ };
139
+ latencySlo?: {
140
+ maxMs: number;
141
+ perTask?: number;
142
+ onExceeded?: "fail" | "warn";
143
+ };
144
+ };
145
+
126
146
  export type TaskDescriptor = {
127
147
  nodeId: string;
128
148
  ordinal: number;
@@ -173,6 +193,8 @@ export type TaskDescriptor = {
173
193
  scorers?: ScorersMap;
174
194
 
175
195
  memoryConfig?: TaskMemoryConfig;
196
+ /** Resolved `<Aspects>` budget configuration enforced by the engine at dispatch. */
197
+ aspects?: TaskAspects;
176
198
  };
177
199
 
178
200
  export type WorkflowGraph = {