Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Instead of using one model for everything, Codebuff coordinates specialized agen
<img src="./assets/codebuff-vs-claude-code.png" alt="Codebuff vs Claude Code" width="400">
</div>

Codebuff beats Claude Code at 61% vs 53% on [our evals](evals/README.md) across 175+ coding tasks over multiple open-source repos that simulate real-world tasks.
Codebuff beats Claude Code at 61% vs 53% on [our evals](evals/buffbench/README.md) across 175+ coding tasks over multiple open-source repos that simulate real-world tasks.

## Freebuff: the free coding agent

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,43 @@ describe('Schema handling error recovery', () => {
expect(toolSet['problematic_tool']).toBeDefined()
})

test('getToolSet preserves MCP JSON Schema properties', async () => {
const customToolDefs = {
marionette__connect: {
description: 'Connect to the VM service',
inputSchema: {
type: 'object',
properties: {
uri: {
type: 'string',
description: 'VM service URI',
},
},
required: ['uri'],
additionalProperties: false,
},
endsAgentStep: true,
},
}

const toolSet = await getToolSet({
toolNames: [],
additionalToolDefinitions: async () => customToolDefs,
agentTools: {},
skills: {},
})

const inputSchema = toolSet['marionette__connect']?.inputSchema as {
properties?: Record<string, unknown>
}

expect(inputSchema).toBeDefined()
expect(inputSchema.properties).toBeDefined()
expect(inputSchema.properties?.uri).toEqual(
expect.objectContaining({ type: 'string' }),
)
})

test('ensureZodSchema converts JSON Schema to Zod schema', () => {
const jsonSchema = {
type: 'object',
Expand Down
11 changes: 6 additions & 5 deletions packages/agent-runtime/src/tools/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,14 @@ export async function getToolSet(params: {
const toolDefinitions = await additionalToolDefinitions()
for (const [toolName, toolDefinition] of Object.entries(toolDefinitions)) {
const clonedDef = cloneDeep(toolDefinition)
// Custom tool inputSchema may be JSON Schema (from SDK) or Zod (from MCP)
// Ensure it's a Zod schema for the AI SDK
const zodSchema = ensureZodSchema(clonedDef.inputSchema)
const safeSchema = ensureJsonSchemaCompatible(zodSchema)
// Custom tool inputSchema may be JSON Schema (from SDK) or Zod (from MCP).
// Keep the original schema object on the tool definition so nested JSON
// Schema details like `properties` survive registration unchanged. Use a
// Zod conversion only for description generation.
ensureZodSchema(clonedDef.inputSchema)
toolSet[toolName] = {
...clonedDef,
inputSchema: safeSchema,
inputSchema: cloneDeep(clonedDef.inputSchema),
} as (typeof toolSet)[string]
}

Expand Down