@codemation/core-nodes 0.10.1 → 0.10.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "packageName": "@codemation/core-nodes",
4
- "packageVersion": "0.10.1",
4
+ "packageVersion": "0.10.2",
5
5
  "description": "",
6
6
  "kind": "nodes",
7
7
  "nodes": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemation/core-nodes",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -32,7 +32,7 @@
32
32
  "@ai-sdk/provider": "^3.0.8",
33
33
  "ai": "^6.0.168",
34
34
  "croner": "^10.0.1",
35
- "@codemation/core": "0.13.1"
35
+ "@codemation/core": "0.13.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/node": "^25.3.5",
@@ -28,6 +28,15 @@ export class HttpBodyBuilder {
28
28
  }
29
29
 
30
30
  if (spec.kind === "json") {
31
+ // Backstop for callers that reach this with a string despite the `data: object`
32
+ // type (e.g. via `unknown`/`as`, or a resolved expression): re-stringifying it
33
+ // would double-encode into `"\"...\""`. Fail loud instead of shipping bad JSON.
34
+ if (typeof spec.data === "string") {
35
+ throw new Error(
36
+ 'HttpRequest body kind:"json" expects a serializable object for "data", but received a string. ' +
37
+ "Pass the object directly (e.g. { a: 1 }), not a pre-stringified JSON string (JSON.stringify(...)).",
38
+ );
39
+ }
31
40
  return {
32
41
  body: JSON.stringify(spec.data),
33
42
  contentType: "application/json",
@@ -11,7 +11,16 @@ export type BinaryRef = string;
11
11
  */
12
12
  export type HttpBodySpec =
13
13
  | Readonly<{ kind: "none" }>
14
- | Readonly<{ kind: "json"; data: unknown }>
14
+ | Readonly<{
15
+ kind: "json";
16
+ /**
17
+ * Serializable object/array to encode as the JSON body. Encoded exactly once via
18
+ * `JSON.stringify`, so pass the value directly (e.g. `{ a: 1 }`) — never a
19
+ * pre-stringified string (`JSON.stringify(...)`), which would double-encode it.
20
+ * Typed as `object` so a bare string/primitive is a compile-time error.
21
+ */
22
+ data: object;
23
+ }>
15
24
  | Readonly<{ kind: "form"; data: Readonly<Record<string, string>> }>
16
25
  | Readonly<{
17
26
  kind: "multipart";
@@ -596,15 +596,18 @@ export class AIAgentNode implements RunnableNode<AIAgent<any, any>> {
596
596
  }
597
597
 
598
598
  /**
599
- * Detects whether a tool config is backed by a `defineHumanApprovalNode` marker
600
- * and returns the HITL behavior config, or `undefined` when not a HITL tool.
599
+ * Resolves the HITL behavior for a tool binding, or `undefined` when it is not a HITL tool.
600
+ * A binding is HITL if either the backing node carries a `defineHumanApprovalNode` marker or the
601
+ * binding sets a per-binding `onRejected` via `asTool(..., { onRejected })`. The per-binding value
602
+ * wins over the node marker, so two tools backed by the same node can reject differently.
601
603
  */
602
604
  private resolveHumanApprovalBehavior(config: ToolConfig): Readonly<{ onRejected: "halt" | "return" }> | undefined {
603
605
  if (!this.isNodeBackedToolConfig(config)) return undefined;
604
606
  const nodeConfig = config.node as unknown as { humanApprovalToolBehavior?: { onRejected?: "halt" | "return" } };
605
607
  const marker = nodeConfig.humanApprovalToolBehavior;
606
- if (marker === undefined) return undefined;
607
- return { onRejected: marker.onRejected ?? "return" };
608
+ const perBinding = config.onRejected;
609
+ if (marker === undefined && perBinding === undefined) return undefined;
610
+ return { onRejected: perBinding ?? marker?.onRejected ?? "return" };
608
611
  }
609
612
 
610
613
  /**
@@ -79,7 +79,7 @@ export class HttpRequest<
79
79
  headers?: Readonly<Record<string, string>>;
80
80
  /** Query parameters to append to the URL. */
81
81
  query?: Readonly<Record<string, string>>;
82
- /** Request body specification. For canvas use, pass a JSON string in `body.data`. */
82
+ /** Request body specification. For `kind:"json"`, pass the object directly in `body.data` — it is JSON-encoded exactly once, so never a pre-stringified string. */
83
83
  body?: HttpBodySpec;
84
84
  /**
85
85
  * Credential slot.