fix(plugin): normalize bare schema refs
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -6,7 +6,7 @@ import { tmpdir } from "node:os"
|
|||||||
import { dirname, join } from "node:path"
|
import { dirname, join } from "node:path"
|
||||||
import { pathToFileURL } from "node:url"
|
import { pathToFileURL } from "node:url"
|
||||||
import { tool } from "@opencode-ai/plugin"
|
import { tool } from "@opencode-ai/plugin"
|
||||||
import { normalizeToolArgSchemas } from "./normalize-tool-arg-schemas"
|
import { normalizeToolArgSchemas, sanitizeJsonSchema } from "./normalize-tool-arg-schemas"
|
||||||
|
|
||||||
const tempDirectories: string[] = []
|
const tempDirectories: string[] = []
|
||||||
|
|
||||||
@@ -95,3 +95,36 @@ describe("normalizeToolArgSchemas", () => {
|
|||||||
expect(afterQuery?.examples).toEqual(["issue 2314"])
|
expect(afterQuery?.examples).toEqual(["issue 2314"])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("sanitizeJsonSchema", () => {
|
||||||
|
it("rewrites bare $ref values to $defs JSON pointers", () => {
|
||||||
|
// given
|
||||||
|
const schema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
new_encoding: { $ref: "Encoding" },
|
||||||
|
existing_pointer: { $ref: "#/$defs/AlreadyValid" },
|
||||||
|
},
|
||||||
|
$defs: {
|
||||||
|
Encoding: { type: "string" },
|
||||||
|
AlreadyValid: { type: "string" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// when
|
||||||
|
const sanitized = sanitizeJsonSchema(schema)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(sanitized).toEqual({
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
new_encoding: { $ref: "#/$defs/Encoding" },
|
||||||
|
existing_pointer: { $ref: "#/$defs/AlreadyValid" },
|
||||||
|
},
|
||||||
|
$defs: {
|
||||||
|
Encoding: { type: "string" },
|
||||||
|
AlreadyValid: { type: "string" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|||||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeJsonSchemaRef(value: string): string {
|
||||||
|
if (value.startsWith("#") || value.includes(":") || value.startsWith("/")) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
return `#/$defs/${value}`
|
||||||
|
}
|
||||||
|
|
||||||
export function sanitizeJsonSchema(value: unknown, depth = 0, isPropertyName = false): unknown {
|
export function sanitizeJsonSchema(value: unknown, depth = 0, isPropertyName = false): unknown {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
return value.map((item) => sanitizeJsonSchema(item, depth + 1, false))
|
return value.map((item) => sanitizeJsonSchema(item, depth + 1, false))
|
||||||
@@ -67,6 +75,11 @@ export function sanitizeJsonSchema(value: unknown, depth = 0, isPropertyName = f
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isPropertyName && key === "$ref" && typeof nestedValue === "string") {
|
||||||
|
sanitized[key] = normalizeJsonSchemaRef(nestedValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const childIsPropertyName = key === "properties" && !isPropertyName
|
const childIsPropertyName = key === "properties" && !isPropertyName
|
||||||
sanitized[key] = sanitizeJsonSchema(nestedValue, depth + 1, childIsPropertyName)
|
sanitized[key] = sanitizeJsonSchema(nestedValue, depth + 1, childIsPropertyName)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user