Skip to content

Commit 8aeaadf

Browse files
committed
fix(agents): preserve non-null schema unions
1 parent d4b431d commit 8aeaadf

8 files changed

Lines changed: 77 additions & 31 deletions

src/agents/tool-schema-projection.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ describe("runtime tool input schema projection", () => {
135135
enum: ["last"],
136136
},
137137
flexibleId: {
138-
type: "string",
138+
anyOf: [{ type: "string", const: "last" }, { type: "string" }],
139139
},
140140
threadId: {
141-
type: "string",
141+
anyOf: [{ type: "string" }, { type: "number" }],
142142
description: "Thread/topic id",
143143
},
144144
},
@@ -158,6 +158,7 @@ describe("runtime tool input schema projection", () => {
158158
expect(projectRuntimeToolInputSchema(hiddenByProjection.parameters)).toEqual({
159159
schema: {
160160
type: "object",
161+
anyOf: [{ $dynamicRef: "#target" }, { type: "string" }],
161162
properties: {},
162163
},
163164
violations: ["parameters.anyOf[0].$dynamicRef"],

src/agents/tool-schema-projection.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,14 @@ function normalizeSchemaComposition(
190190
if (hasNullVariant && nonNullVariants.length === 1 && isJsonObject(nonNullVariants[0])) {
191191
return mergeCompositionWrapper(schema, nonNullVariants[0], keyword);
192192
}
193-
const stringVariant = nonNullVariants.find(
194-
(variant) => isJsonObject(variant) && variant.type === "string" && !("const" in variant),
195-
);
196-
if (stringVariant !== undefined && isJsonObject(stringVariant)) {
197-
return mergeCompositionWrapper(schema, stringVariant, keyword);
193+
if (hasNullVariant) {
194+
return mergeCompositionWrapper(
195+
schema,
196+
{
197+
[keyword]: nonNullVariants,
198+
},
199+
keyword,
200+
);
198201
}
199202
return undefined;
200203
}

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.discord-group.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,15 @@
232232
"type": "string"
233233
},
234234
"threadId": {
235-
"description": "Thread/topic id",
236-
"type": "string"
235+
"anyOf": [
236+
{
237+
"type": "string"
238+
},
239+
{
240+
"type": "number"
241+
}
242+
],
243+
"description": "Thread/topic id"
237244
},
238245
"to": {
239246
"description": "Delivery target",
@@ -454,8 +461,15 @@
454461
"type": "string"
455462
},
456463
"threadId": {
457-
"description": "Thread/topic id",
458-
"type": "string"
464+
"anyOf": [
465+
{
466+
"type": "string"
467+
},
468+
{
469+
"type": "number"
470+
}
471+
],
472+
"description": "Thread/topic id"
459473
},
460474
"to": {
461475
"description": "Delivery target, or null to clear",

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.heartbeat-turn.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,15 @@
232232
"type": "string"
233233
},
234234
"threadId": {
235-
"description": "Thread/topic id",
236-
"type": "string"
235+
"anyOf": [
236+
{
237+
"type": "string"
238+
},
239+
{
240+
"type": "number"
241+
}
242+
],
243+
"description": "Thread/topic id"
237244
},
238245
"to": {
239246
"description": "Delivery target",
@@ -454,8 +461,15 @@
454461
"type": "string"
455462
},
456463
"threadId": {
457-
"description": "Thread/topic id",
458-
"type": "string"
464+
"anyOf": [
465+
{
466+
"type": "string"
467+
},
468+
{
469+
"type": "number"
470+
}
471+
],
472+
"description": "Thread/topic id"
459473
},
460474
"to": {
461475
"description": "Delivery target, or null to clear",

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/codex-dynamic-tools.telegram-direct.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,15 @@
232232
"type": "string"
233233
},
234234
"threadId": {
235-
"description": "Thread/topic id",
236-
"type": "string"
235+
"anyOf": [
236+
{
237+
"type": "string"
238+
},
239+
{
240+
"type": "number"
241+
}
242+
],
243+
"description": "Thread/topic id"
237244
},
238245
"to": {
239246
"description": "Delivery target",
@@ -454,8 +461,15 @@
454461
"type": "string"
455462
},
456463
"threadId": {
457-
"description": "Thread/topic id",
458-
"type": "string"
464+
"anyOf": [
465+
{
466+
"type": "string"
467+
},
468+
{
469+
"type": "number"
470+
}
471+
],
472+
"description": "Thread/topic id"
459473
},
460474
"to": {
461475
"description": "Delivery target, or null to clear",

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/discord-group-codex-message-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
223223
"roughTokens": 0
224224
},
225225
"dynamicToolsJson": {
226-
"chars": 40904,
227-
"roughTokens": 10226
226+
"chars": 41266,
227+
"roughTokens": 10317
228228
},
229229
"openClawDeveloperInstructions": {
230230
"chars": 2988,
@@ -235,8 +235,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
235235
"roughTokens": 6925
236236
},
237237
"totalWithDynamicToolsJson": {
238-
"chars": 68606,
239-
"roughTokens": 17152
238+
"chars": 68968,
239+
"roughTokens": 17242
240240
},
241241
"userInputText": {
242242
"chars": 1629,

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-direct-codex-message-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
223223
"roughTokens": 0
224224
},
225225
"dynamicToolsJson": {
226-
"chars": 40625,
227-
"roughTokens": 10157
226+
"chars": 40987,
227+
"roughTokens": 10247
228228
},
229229
"openClawDeveloperInstructions": {
230230
"chars": 1964,
@@ -235,8 +235,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
235235
"roughTokens": 6544
236236
},
237237
"totalWithDynamicToolsJson": {
238-
"chars": 66803,
239-
"roughTokens": 16701
238+
"chars": 67165,
239+
"roughTokens": 16792
240240
},
241241
"userInputText": {
242242
"chars": 1129,

test/fixtures/agents/prompt-snapshots/codex-runtime-happy-path/telegram-heartbeat-codex-tool.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
224224
"roughTokens": 0
225225
},
226226
"dynamicToolsJson": {
227-
"chars": 41720,
228-
"roughTokens": 10430
227+
"chars": 42082,
228+
"roughTokens": 10521
229229
},
230230
"openClawDeveloperInstructions": {
231231
"chars": 1983,
@@ -236,8 +236,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
236236
"roughTokens": 6780
237237
},
238238
"totalWithDynamicToolsJson": {
239-
"chars": 68841,
240-
"roughTokens": 17211
239+
"chars": 69203,
240+
"roughTokens": 17301
241241
},
242242
"userInputText": {
243243
"chars": 1367,

0 commit comments

Comments
 (0)