Skip to content

Commit 8b9cb88

Browse files
committed
remove json schema
1 parent f833cff commit 8b9cb88

File tree

9 files changed

+94
-101
lines changed

9 files changed

+94
-101
lines changed

common/src/util/file.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { z } from 'zod/v4'
55

66
import { CodebuffConfigSchema } from '../json-config/constants'
77

8+
import type { CodebuffConfig } from '../json-config/constants'
89
import type { CodebuffFileSystem } from '../types/filesystem'
910

1011
export const FileTreeNodeSchema: z.ZodType<FileTreeNode> = z.object({
@@ -43,14 +44,16 @@ export const customToolDefinitionsSchema = z
4344
.record(
4445
z.string(),
4546
z.object({
46-
inputJsonSchema: z.any(),
47+
inputSchema: z.custom<z.ZodType>(),
4748
endsAgentStep: z.boolean().optional().default(false),
4849
description: z.string().optional(),
4950
exampleInputs: z.record(z.string(), z.any()).array().optional(),
5051
}),
5152
)
5253
.default(() => ({}))
53-
export type CustomToolDefinitions = z.input<typeof customToolDefinitionsSchema>
54+
export type CustomToolDefinitions = NonNullable<
55+
z.input<typeof customToolDefinitionsSchema>
56+
>
5457

5558
export const ProjectFileContextSchema = z.object({
5659
projectRoot: z.string(),
@@ -83,7 +86,34 @@ export const ProjectFileContextSchema = z.object({
8386
}),
8487
})
8588

86-
export type ProjectFileContext = z.infer<typeof ProjectFileContextSchema>
89+
export type ProjectFileContext = {
90+
projectRoot: string
91+
cwd: string
92+
fileTree: FileTreeNode[]
93+
fileTokenScores: Record<string, Record<string, number>>
94+
tokenCallers?: Record<string, Record<string, string[]>>
95+
knowledgeFiles: Record<string, string>
96+
userKnowledgeFiles?: Record<string, string>
97+
agentTemplates: Record<string, any>
98+
customToolDefinitions: CustomToolDefinitions
99+
codebuffConfig?: CodebuffConfig
100+
gitChanges: {
101+
status: string
102+
diff: string
103+
diffCached: string
104+
lastCommitMessages: string
105+
}
106+
changesSinceLastChat: Record<string, string>
107+
shellConfigFiles: Record<string, string>
108+
systemInfo: {
109+
platform: string
110+
shell: string
111+
nodeVersion: string
112+
arch: string
113+
homedir: string
114+
cpus: number
115+
}
116+
}
87117

88118
export const fileRegex =
89119
/<write_file>\s*<path>([^<]+)<\/path>\s*<content>([\s\S]*?)<\/content>\s*<\/write_file>/g

packages/agent-runtime/src/mcp.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import { convertJsonSchemaToZod } from 'zod-from-json-schema'
2+
13
import type { AgentTemplate } from './templates/types'
24
import type { RequestMcpToolDataFn } from '@codebuff/common/types/contracts/client'
35
import type { OptionalFields } from '@codebuff/common/types/function-params'
4-
import type { ProjectFileContext } from '@codebuff/common/util/file'
6+
import type {
7+
CustomToolDefinitions,
8+
ProjectFileContext,
9+
} from '@codebuff/common/util/file'
510

611
export async function getMCPToolData(
712
params: OptionalFields<
@@ -13,7 +18,7 @@ export async function getMCPToolData(
1318
},
1419
'writeTo'
1520
>,
16-
): Promise<ProjectFileContext['customToolDefinitions']> {
21+
): Promise<CustomToolDefinitions> {
1722
const withDefaults = { writeTo: {}, ...params }
1823
const { toolNames, mcpServers, writeTo, requestMcpToolData } = withDefaults
1924

@@ -41,7 +46,7 @@ export async function getMCPToolData(
4146

4247
for (const { name, description, inputSchema } of mcpData) {
4348
writeTo[mcpName + '/' + name] = {
44-
inputJsonSchema: inputSchema,
49+
inputSchema: convertJsonSchemaToZod(inputSchema as any) as any,
4550
endsAgentStep: true,
4651
description,
4752
}

packages/agent-runtime/src/templates/strings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export async function formatPrompt(
111111
[PLACEHOLDER.PROJECT_ROOT]: () => fileContext.projectRoot,
112112
[PLACEHOLDER.SYSTEM_INFO_PROMPT]: () => getSystemInfoPrompt(fileContext),
113113
[PLACEHOLDER.TOOLS_PROMPT]: async () =>
114-
getToolsInstructions(tools, await additionalToolDefinitions()),
114+
getToolsInstructions(tools, (await additionalToolDefinitions()) ?? {}),
115115
[PLACEHOLDER.AGENTS_PROMPT]: () => buildSpawnableAgentsDescription(params),
116116
[PLACEHOLDER.USER_CWD]: () => fileContext.cwd,
117117
[PLACEHOLDER.USER_INPUT_PROMPT]: () => escapeString(lastUserInput ?? ''),

packages/agent-runtime/src/tools/prompts.ts

Lines changed: 33 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,30 @@ import { toolParams } from '@codebuff/common/tools/list'
33
import { getToolCallString } from '@codebuff/common/tools/utils'
44
import { buildArray } from '@codebuff/common/util/array'
55
import { pluralize } from '@codebuff/common/util/string'
6+
import { cloneDeep } from 'lodash'
67
import z from 'zod/v4'
78

89
import type { ToolName } from '@codebuff/common/tools/constants'
9-
import type { customToolDefinitionsSchema } from '@codebuff/common/util/file'
10-
import type { JSONSchema } from 'zod/v4/core'
10+
import type {
11+
CustomToolDefinitions,
12+
customToolDefinitionsSchema,
13+
} from '@codebuff/common/util/file'
14+
import type { ToolSet } from 'ai'
1115

12-
function paramsSection(params: {
13-
schema:
14-
| { type: 'zod'; value: z.ZodObject }
15-
| { type: 'json'; value: JSONSchema.BaseSchema }
16-
endsAgentStep: boolean
17-
}) {
16+
function paramsSection(params: { schema: z.ZodType; endsAgentStep: boolean }) {
1817
const { schema, endsAgentStep } = params
19-
const schemaWithEndsAgentStepParam =
20-
schema.type === 'zod'
21-
? z.toJSONSchema(
22-
endsAgentStep
23-
? schema.value.extend({
24-
[endsAgentStepParam]: z
25-
.literal(endsAgentStep)
26-
.describe('Easp flag must be set to true'),
27-
})
28-
: schema.value,
29-
{ io: 'input' },
18+
const schemaWithEndsAgentStepParam = z.toJSONSchema(
19+
endsAgentStep
20+
? schema.and(
21+
z.object({
22+
[endsAgentStepParam]: z
23+
.literal(endsAgentStep)
24+
.describe('Easp flag must be set to true'),
25+
}),
3026
)
31-
: JSON.parse(JSON.stringify(schema.value))
32-
if (schema.type === 'json') {
33-
if (!schemaWithEndsAgentStepParam.properties) {
34-
schemaWithEndsAgentStepParam.properties = {}
35-
}
36-
schemaWithEndsAgentStepParam.properties[endsAgentStepParam] = {
37-
const: true,
38-
type: 'boolean',
39-
description: 'Easp flag must be set to true',
40-
}
41-
if (!schemaWithEndsAgentStepParam.required) {
42-
schemaWithEndsAgentStepParam.required = []
43-
}
44-
schemaWithEndsAgentStepParam.required.push(endsAgentStepParam)
45-
}
27+
: schema,
28+
{ io: 'input' },
29+
)
4630

4731
const jsonSchema = schemaWithEndsAgentStepParam
4832
delete jsonSchema.description
@@ -63,9 +47,7 @@ function paramsSection(params: {
6347
// Helper function to build the full tool description markdown
6448
export function buildToolDescription(params: {
6549
toolName: string
66-
schema:
67-
| { type: 'zod'; value: z.ZodObject }
68-
| { type: 'json'; value: JSONSchema.BaseSchema }
50+
schema: z.ZodType
6951
description?: string
7052
endsAgentStep: boolean
7153
exampleInputs?: any[]
@@ -88,7 +70,7 @@ export function buildToolDescription(params: {
8870
).join('\n\n')
8971
return buildArray([
9072
`### ${toolName}`,
91-
schema.value.description || '',
73+
schema.description || '',
9274
paramsSection({ schema, endsAgentStep }),
9375
descriptionWithExamples,
9476
]).join('\n\n')
@@ -99,7 +81,7 @@ export const toolDescriptions = Object.fromEntries(
9981
name,
10082
buildToolDescription({
10183
toolName: name,
102-
schema: { type: 'zod', value: config.inputSchema },
84+
schema: config.inputSchema,
10385
description: config.description,
10486
endsAgentStep: config.endsAgentStep,
10587
}),
@@ -108,9 +90,7 @@ export const toolDescriptions = Object.fromEntries(
10890

10991
function buildShortToolDescription(params: {
11092
toolName: string
111-
schema:
112-
| { type: 'zod'; value: z.ZodObject }
113-
| { type: 'json'; value: JSONSchema.BaseSchema }
93+
schema: z.ZodType
11494
endsAgentStep: boolean
11595
}): string {
11696
const { toolName, schema, endsAgentStep } = params
@@ -119,7 +99,9 @@ function buildShortToolDescription(params: {
11999

120100
export const getToolsInstructions = (
121101
tools: readonly string[],
122-
additionalToolDefinitions: z.infer<typeof customToolDefinitionsSchema>,
102+
additionalToolDefinitions: NonNullable<
103+
z.input<typeof customToolDefinitionsSchema>
104+
>,
123105
) => {
124106
if (
125107
tools.length === 0 &&
@@ -201,7 +183,7 @@ ${fullToolList(tools, additionalToolDefinitions)}
201183

202184
export const fullToolList = (
203185
toolNames: readonly string[],
204-
additionalToolDefinitions: z.infer<typeof customToolDefinitionsSchema>,
186+
additionalToolDefinitions: CustomToolDefinitions,
205187
) => {
206188
if (
207189
toolNames.length === 0 &&
@@ -224,9 +206,9 @@ ${[
224206
const toolDef = additionalToolDefinitions[toolName]
225207
return buildToolDescription({
226208
toolName,
227-
schema: { type: 'json', value: toolDef.inputJsonSchema },
209+
schema: toolDef.inputSchema,
228210
description: toolDef.description,
229-
endsAgentStep: toolDef.endsAgentStep,
211+
endsAgentStep: toolDef.endsAgentStep ?? true,
230212
exampleInputs: toolDef.exampleInputs,
231213
})
232214
}),
@@ -235,7 +217,7 @@ ${[
235217

236218
export const getShortToolInstructions = (
237219
toolNames: readonly string[],
238-
additionalToolDefinitions: z.infer<typeof customToolDefinitionsSchema>,
220+
additionalToolDefinitions: CustomToolDefinitions,
239221
) => {
240222
if (
241223
toolNames.length === 0 &&
@@ -253,16 +235,16 @@ export const getShortToolInstructions = (
253235
const tool = toolParams[name]
254236
return buildShortToolDescription({
255237
toolName: name,
256-
schema: { type: 'zod', value: tool.inputSchema },
238+
schema: tool.inputSchema,
257239
endsAgentStep: tool.endsAgentStep,
258240
})
259241
}),
260242
...Object.keys(additionalToolDefinitions).map((name) => {
261-
const { inputJsonSchema, endsAgentStep } = additionalToolDefinitions[name]
243+
const { inputSchema, endsAgentStep } = additionalToolDefinitions[name]
262244
return buildShortToolDescription({
263245
toolName: name,
264-
schema: { type: 'json', value: inputJsonSchema },
265-
endsAgentStep,
246+
schema: inputSchema,
247+
endsAgentStep: endsAgentStep ?? true,
266248
})
267249
}),
268250
]

packages/agent-runtime/src/tools/stream-parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ export async function processStreamWithTools(
175175
...params,
176176
processors: Object.fromEntries([
177177
...toolNames.map((toolName) => [toolName, toolCallback(toolName)]),
178-
...Object.keys(fileContext.customToolDefinitions).map((toolName) => [
178+
...Object.keys(fileContext.customToolDefinitions ?? {}).map((toolName) => [
179179
toolName,
180180
customToolCallback(toolName),
181181
]),

packages/agent-runtime/src/tools/tool-executor.ts

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { jsonToolResult } from '@codebuff/common/util/messages'
44
import { generateCompactId } from '@codebuff/common/util/string'
55
import { cloneDeep } from 'lodash'
66
import z from 'zod/v4'
7-
import { convertJsonSchemaToZod } from 'zod-from-json-schema'
87

98
import { checkLiveUserInput } from '../live-user-inputs'
109
import { getMCPToolData } from '../mcp'
@@ -30,7 +29,7 @@ import type { ToolResultOutput } from '@codebuff/common/types/messages/content-p
3029
import type { PrintModeEvent } from '@codebuff/common/types/print-mode'
3130
import type { AgentState, Subgoal } from '@codebuff/common/types/session-state'
3231
import type {
33-
customToolDefinitionsSchema,
32+
CustomToolDefinitions,
3433
ProjectFileContext,
3534
} from '@codebuff/common/util/file'
3635
import type { ToolCallPart } from 'ai'
@@ -293,7 +292,7 @@ export function executeToolCall<T extends ToolName>(
293292
}
294293

295294
export function parseRawCustomToolCall(params: {
296-
customToolDefs: z.infer<typeof customToolDefinitionsSchema>
295+
customToolDefs: CustomToolDefinitions
297296
rawToolCall: {
298297
toolName: string
299298
toolCallId: string
@@ -304,7 +303,10 @@ export function parseRawCustomToolCall(params: {
304303
const { customToolDefs, rawToolCall, autoInsertEndStepParam = false } = params
305304
const toolName = rawToolCall.toolName
306305

307-
if (!(toolName in customToolDefs) && !toolName.includes('/')) {
306+
if (
307+
!(customToolDefs && toolName in customToolDefs) &&
308+
!toolName.includes('/')
309+
) {
308310
return {
309311
toolName,
310312
toolCallId: rawToolCall.toolCallId,
@@ -321,30 +323,13 @@ export function parseRawCustomToolCall(params: {
321323
// Add the required codebuff_end_step parameter with the correct value for this tool if requested
322324
if (autoInsertEndStepParam) {
323325
processedParameters[endsAgentStepParam] =
324-
customToolDefs[toolName].endsAgentStep
326+
customToolDefs?.[toolName]?.endsAgentStep
325327
}
326328

327-
const jsonSchema = cloneDeep(customToolDefs[toolName].inputJsonSchema)
328-
if (customToolDefs[toolName].endsAgentStep) {
329-
if (!jsonSchema.properties) {
330-
jsonSchema.properties = {}
331-
}
332-
jsonSchema.properties[endsAgentStepParam] = {
333-
const: true,
334-
type: 'boolean',
335-
description: 'Easp flag must be set to true',
336-
}
337-
if (!jsonSchema.required) {
338-
jsonSchema.required = []
339-
}
340-
jsonSchema.required.push(endsAgentStepParam)
341-
}
342-
const paramsSchema = convertJsonSchemaToZod(jsonSchema)
343-
const result = paramsSchema.safeParse(
344-
processedParameters,
345-
) as z.ZodSafeParseResult<any>
329+
const paramsSchema = customToolDefs?.[toolName]?.inputSchema
330+
const result = paramsSchema?.safeParse(processedParameters)
346331

347-
if (!result.success) {
332+
if (result && !result.success) {
348333
return {
349334
toolName: toolName,
350335
toolCallId: rawToolCall.toolCallId,

sdk/src/__tests__/initial-session-state.test.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,7 @@ describe('Initial Session State', () => {
252252
const customToolDefinitions = [
253253
{
254254
toolName: 'custom_tool',
255-
zodSchema: inputSchema,
256-
inputJsonSchema: {
257-
type: 'object' as const,
258-
properties: {
259-
input: { type: 'string' as const },
260-
},
261-
},
255+
inputSchema,
262256
description: 'A custom tool',
263257
endsAgentStep: false,
264258
exampleInputs: [],
@@ -276,10 +270,11 @@ describe('Initial Session State', () => {
276270

277271
expect(sessionState.fileContext.customToolDefinitions).toBeDefined()
278272
expect(
279-
sessionState.fileContext.customToolDefinitions['custom_tool'],
273+
sessionState.fileContext.customToolDefinitions?.['custom_tool'],
280274
).toBeDefined()
281275
expect(
282-
sessionState.fileContext.customToolDefinitions['custom_tool'].description,
276+
sessionState.fileContext.customToolDefinitions?.['custom_tool']
277+
?.description,
283278
).toBe('A custom tool')
284279
})
285280

0 commit comments

Comments
 (0)