@warlock.js/ai 4.13.0 → 4.15.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to `@warlock.js/ai` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 4.15.0
8
+
9
+ ### Fixed
10
+
11
+ - **`ctx.run(agent, payload)` now stringifies a non-string payload, as it always claimed to.** `coerceInlineInput` in `src/supervisor/execution.ts` gated on `!("signature" in executable)` to decide whether the target was an agent — but every member of `SupervisableExecutable` (`AgentContract`, `WorkflowInstance`, `SupervisorContract`) declares `signature`, so the condition was **permanently false and the coercion never ran**. A supervisor intent calling `ctx.run(someAgent, { question: "why", attempt: 2 })` handed the raw object to `agent.execute()`, where it landed as the user message `content` — `[object Object]` in the prompt, or a provider-side payload rejection, depending on the adapter. The check now discriminates on `isAnonymous`, the one member unique to `AgentContract`. A regression test covers it; the old guard fails it with `Expected: "string" / Received: "object"`. The unreferenced `isSupervisor()` duck-type helper — whose own JSDoc admitted it could not tell a supervisor from a workflow — is removed
12
+ - **`ToolMeta` no longer forces `label` and `actionLabel` on every tool that supplies `meta`.** It was declared as `Record<"label" | "actionLabel" | (string & {}), unknown>`, which makes both keys **required**, not optional — so any tool author who set one metadata field was made to set all of them. Now an optional-key shape with an index signature
13
+ - **`ToolConfig.action` is checked bivariantly**, via a `ToolActionResolver<T>` method-in-wrapper. The strictly contravariant parameter position rejected heterogeneous tool arrays that work correctly at runtime
14
+ - **`new Error(msg, { cause })` compiles.** `tsconfig.json` declared no `lib`, so it inherited the `target` default of ES2020, where `ErrorOptions` does not exist. `lib` is now `["ES2022"]`; this also resolves the `Array.at` and `String.replaceAll` errors. Emit is unchanged — `target` is still ES2020. Note `src/skills/sources/url-source.ts:122` was **not** a defect: the `cause` was always passed at runtime, the compiler simply had no type for it
15
+ - **`TeamMemberValue` accepts the callback member form** (`IntentCallback`), which has always worked at runtime and was only rejected by the type
16
+ - **`PlanSchema` no longer erases `~standard.jsonSchema`** from its return type
17
+
18
+ ### Changed
19
+
20
+ - **`MockModelResponse.usage` is a new `MockUsage` type rather than the emitted `Usage`.** The script is an input, not a result: `MockModel.buildResponse` honours only `input` / `output` / `cachedTokens`, so a fixture declaring `cost` or `reasoningTokens` was silently discarded while the type promised otherwise. `total` is optional and documented as derived, because the mock recomputes it as `input + output` — an existing spec deliberately asserts that a mismatched scripted `total` is overridden
21
+ - **The mock honours `deltas`.** Fixtures already declared the field; the mock ignored it
22
+ - `MockSDK.model()` declares its `MockModel` return type — it always returned one, so `callHistory` is now reachable without a cast. `MockUsage` is exported from the barrel
23
+
24
+ ### Notes
25
+
26
+ - Typecheck against the package's own TypeScript 6.0.3: **89 → 24 errors, and all 24 remaining are a monorepo-only artifact** (`TS6059`, `@warlock.js/cache` resolved through a `paths` mapping outside `rootDir`). They do not affect the published package, which ships built `exports` and `.d.mts`. In-scope errors are zero
27
+ - Suite: **173 files / 1878 tests passing**, up one from the new regression test
28
+
7
29
  ## 4.12.0
8
30
 
9
31
  ### Changed
package/cjs/index.cjs CHANGED
@@ -11846,7 +11846,8 @@ var MockModel = class {
11846
11846
  }
11847
11847
  /**
11848
11848
  * Record the call, optionally delay, then emit the scripted response as a
11849
- * sequence of stream chunks: content split word-by-word as `delta`
11849
+ * sequence of stream chunks: the scripted `deltas` when the entry
11850
+ * supplies them, otherwise content split word-by-word, as `delta`
11850
11851
  * chunks, each scripted tool call as a `tool-call` chunk, and finally a
11851
11852
  * `done` chunk with finish reason + usage. Throws eagerly if the scripted
11852
11853
  * entry carries an `error`.
@@ -11859,10 +11860,10 @@ var MockModel = class {
11859
11860
  const mock = this.nextResponse();
11860
11861
  if (mock.delay) await new Promise((resolve) => setTimeout(resolve, mock.delay));
11861
11862
  if (mock.error) throw mock.error;
11862
- const words = mock.content.split(" ");
11863
- for (const word of words) yield {
11863
+ const chunks = mock.deltas ?? mock.content.split(" ").map((word) => word + " ");
11864
+ for (const chunk of chunks) yield {
11864
11865
  type: "delta",
11865
- content: word + " "
11866
+ content: chunk
11866
11867
  };
11867
11868
  if (mock.toolCalls) for (const toolCall of mock.toolCalls) yield {
11868
11869
  type: "tool-call",
@@ -14514,24 +14515,10 @@ var SupervisorExecution = class {
14514
14515
  * through unchanged so structured inputs work.
14515
14516
  */
14516
14517
  coerceInlineInput(executable, input) {
14517
- if (!("signature" in executable) && typeof executable.execute === "function" && !this.isSupervisor(executable) && typeof input !== "string") return safeStringify(input);
14518
+ if ("isAnonymous" in executable && typeof input !== "string") return safeStringify(input);
14518
14519
  return input;
14519
14520
  }
14520
14521
  /**
14521
- * Heuristic detection of `SupervisorContract` — the contract carries
14522
- * a `signature` getter same as workflows, but supervisors expose
14523
- * `resume()` while workflows expose `resume(runId, options)` too.
14524
- * Cleanest distinguisher in the public surface: supervisors carry
14525
- * the `asTool` method name `as` … unfortunately so do workflows.
14526
- * Use the `streamableType` brand if we add one in v2; for now lean
14527
- * on a duck-typed check that's good enough for the ctx.run path
14528
- * (incorrect routing for workflows would still produce a runnable
14529
- * call — workflow.execute accepts the same args either way).
14530
- */
14531
- isSupervisor(executable) {
14532
- return typeof executable.resume === "function" && typeof executable.signature === "string" && typeof executable.stream === "function";
14533
- }
14534
- /**
14535
14522
  * Invoke the underlying dispatchable unit. Agents and workflows
14536
14523
  * both satisfy `ExecutableContract<string, …>` so the call shape
14537
14524
  * is uniform; the `type` discriminator picks which options get
@@ -17253,25 +17240,6 @@ function assertAcyclic(nodes, byId, plannerName) {
17253
17240
 
17254
17241
  //#endregion
17255
17242
  //#region ../ai/src/planner/plan-schema.ts
17256
- /**
17257
- * Build the Standard Schema the planning agent emits — an ordered
17258
- * `{ steps: [...], summary? }` plan whose every step references one of
17259
- * `capabilityNames` via the `capability` field.
17260
- *
17261
- * Mirrors the router's hand-built schema approach
17262
- * (`supervisor/router-factory.ts`): the JSON Schema extension carries
17263
- * the capability names as an `enum` so capable providers enforce the
17264
- * choice natively, while `validate()` still accepts the shape softly so
17265
- * providers without native structured output can pass a parsed object
17266
- * through. Validation is intentionally lenient on `capability` — an
17267
- * unknown name is surfaced later by the planner as a typed
17268
- * `PlannerPlanInvalidError`, with the full forensic context, rather
17269
- * than as an opaque schema issue here.
17270
- *
17271
- * `maxSteps`, when provided, is emitted as the `steps` array's
17272
- * `maxItems` so capable providers refuse to over-produce up front
17273
- * (the planner still truncates the tail to `skipped` defensively).
17274
- */
17275
17243
  function planSchema(capabilityNames, maxSteps) {
17276
17244
  const jsonSchema = {
17277
17245
  type: "object",