fix(task): avoided boolean output subschemas

Represent task output schema inputs as explicit JSON-compatible types so ArkType emits object-form subschemas accepted by llama.cpp grammar generation.

Fixes #5957
This commit is contained in:
roboomp
2026-07-18 04:11:26 +00:00
parent 1b4a4fd3fd
commit 83bfb6dbd8
3 changed files with 17 additions and 8 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Fixed `task` tool schemas emitting boolean subschemas that llama.cpp grammar generation cannot parse ([#5957](https://github.com/can1357/oh-my-pi/issues/5957)).
## [17.0.3] - 2026-07-17
### Changed
+11 -8
View File
@@ -106,11 +106,14 @@ export interface SubagentLifecyclePayload {
/** Display cap for a normalized one-line label (roster line, registry `displayName`, prompt field). */
export const LABEL_MAX = 80;
// Keep this explicit: ArkType serializes `unknown` as a boolean subschema, which llama.cpp grammars reject.
const outputSchemaInputSchema = type("object | boolean | string | null");
export const taskItemSchema = type({
"name?": "string",
agent: "string = 'task'",
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"+": "delete",
});
@@ -118,7 +121,7 @@ const taskItemSchemaIsolated = type({
"name?": "string",
agent: "string = 'task'",
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"isolated?": "boolean",
"+": "delete",
@@ -144,7 +147,7 @@ export const taskSchema = type({
"name?": "string",
agent: "string = 'task'",
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"isolated?": "boolean",
"+": "delete",
@@ -153,7 +156,7 @@ const taskSchemaNoIsolation = type({
"name?": "string",
agent: "string = 'task'",
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"+": "delete",
});
@@ -197,7 +200,7 @@ function createTaskSchema(options: {
"name?": "string",
agent,
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"isolated?": "boolean",
"+": "delete",
@@ -212,7 +215,7 @@ function createTaskSchema(options: {
"name?": "string",
agent,
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"+": "delete",
});
@@ -227,7 +230,7 @@ function createTaskSchema(options: {
"name?": "string",
agent,
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"isolated?": "boolean",
"+": "delete",
@@ -237,7 +240,7 @@ function createTaskSchema(options: {
"name?": "string",
agent,
task: "string",
"outputSchema?": "unknown",
"outputSchema?": outputSchemaInputSchema,
"schemaMode?": '"permissive" | "strict"',
"+": "delete",
});
@@ -102,6 +102,7 @@ describe("task.batch schema gating", () => {
expect(offProperties.task).toBeDefined();
expect(offProperties.name).toBeDefined();
expect(offProperties.outputSchema).toBeDefined();
expect(typeof offProperties.outputSchema).toBe("object");
expect(offProperties.schemaMode).toBeDefined();
const on = await TaskTool.create(createSession({ settings: { "task.batch": true } }));
@@ -120,6 +121,7 @@ describe("task.batch schema gating", () => {
expect(items?.properties?.name).toBeDefined();
expect(items?.properties?.agent).toBeDefined();
expect(items?.properties?.outputSchema).toBeDefined();
expect(typeof items?.properties?.outputSchema).toBe("object");
expect(items?.properties?.schemaMode).toBeDefined();
});