Skip to content

Commit 2bc2a50

Browse files
committed
add new CodebuffMessage
1 parent 964f441 commit 2bc2a50

File tree

7 files changed

+189
-4
lines changed

7 files changed

+189
-4
lines changed

common/src/tools/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function getToolCallString<T extends ToolName | (string & {})>(
2121
toolName in llmToolCallSchema
2222
? llmToolCallSchema[toolName as keyof typeof llmToolCallSchema]
2323
.endsAgentStep
24-
: endsAgentStep[0]
24+
: endsAgentStep[0] ?? false
2525
const obj: Record<string, any> = {
2626
[toolNameParam]: toolName,
2727
...params,

common/src/types/json.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import z from 'zod/v4'
2+
3+
export type JSONValue =
4+
| null
5+
| string
6+
| number
7+
| boolean
8+
| JSONObject
9+
| JSONArray
10+
export const jsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>
11+
z.union([
12+
z.null(),
13+
z.string(),
14+
z.number(),
15+
z.boolean(),
16+
JSONObjectSchema,
17+
JSONArraySchema,
18+
]),
19+
)
20+
21+
export const JSONObjectSchema: z.ZodType<JSONObject> = z.lazy(() =>
22+
z.record(z.string(), jsonValueSchema),
23+
)
24+
export type JSONObject = { [key: string]: JSONValue }
25+
26+
export const JSONArraySchema: z.ZodType<JSONArray> = z.lazy(() =>
27+
z.array(jsonValueSchema),
28+
)
29+
export type JSONArray = JSONValue[]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import z from 'zod/v4'
2+
3+
import {
4+
filePartSchema,
5+
imagePartSchema,
6+
reasoningPartSchema,
7+
textPartSchema,
8+
toolCallPartSchema,
9+
toolResultPartSchema,
10+
} from './content-part'
11+
import { providerMetadataSchema } from './provider-metadata'
12+
13+
export const systemCodebuffMessageSchema = z.object({
14+
role: z.literal('system'),
15+
content: z.string(),
16+
providerOptions: providerMetadataSchema.optional(),
17+
})
18+
export type SystemCodebuffMessage = z.infer<typeof systemCodebuffMessageSchema>
19+
20+
export const userCodebuffMessageSchema = z.object({
21+
role: z.literal('user'),
22+
content: z.union([textPartSchema, imagePartSchema, filePartSchema]).array(),
23+
providerOptions: providerMetadataSchema.optional(),
24+
})
25+
export type UserCodebuffMessage = z.infer<typeof userCodebuffMessageSchema>
26+
27+
export const assistantCodebuffMessageSchema = z.object({
28+
role: z.literal('assistant'),
29+
content: z
30+
.union([
31+
textPartSchema,
32+
filePartSchema,
33+
reasoningPartSchema,
34+
toolCallPartSchema,
35+
toolResultPartSchema,
36+
])
37+
.array(),
38+
providerOptions: providerMetadataSchema.optional(),
39+
})
40+
export type AssistantCodebuffMessage = z.infer<
41+
typeof assistantCodebuffMessageSchema
42+
>
43+
44+
export const toolCodebuffMessageSchema = z.object({
45+
role: z.literal('tool'),
46+
content: toolResultPartSchema.array(),
47+
providerOptions: providerMetadataSchema.optional(),
48+
})
49+
export type ToolCodebuffMessage = z.infer<typeof toolCodebuffMessageSchema>
50+
51+
export const codebuffMessageSchema = z.union([
52+
systemCodebuffMessageSchema,
53+
userCodebuffMessageSchema,
54+
assistantCodebuffMessageSchema,
55+
toolCodebuffMessageSchema,
56+
])
57+
export type CodebuffMessage = z.infer<typeof codebuffMessageSchema>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import z from 'zod/v4'
2+
3+
import { providerMetadataSchema } from './provider-metadata'
4+
import { jsonValueSchema } from '../json'
5+
import { dataContentSchema } from './data-content'
6+
7+
export const textPartSchema = z.object({
8+
type: z.literal('text'),
9+
text: z.string(),
10+
providerOptions: providerMetadataSchema.optional(),
11+
})
12+
export type TextPart = z.infer<typeof textPartSchema>
13+
14+
export const imagePartSchema = z.object({
15+
type: z.literal('image'),
16+
image: z.union([dataContentSchema, z.instanceof(URL)]),
17+
mediaType: z.string().optional(),
18+
providerOptions: providerMetadataSchema.optional(),
19+
})
20+
export type ImagePart = z.infer<typeof imagePartSchema>
21+
22+
export const filePartSchema = z.object({
23+
type: z.literal('file'),
24+
data: z.union([dataContentSchema, z.instanceof(URL)]),
25+
filename: z.string().optional(),
26+
mediaType: z.string(),
27+
providerOptions: providerMetadataSchema.optional(),
28+
})
29+
export type FilePart = z.infer<typeof filePartSchema>
30+
31+
export const reasoningPartSchema = z.object({
32+
type: z.literal('reasoning'),
33+
text: z.string(),
34+
providerOptions: providerMetadataSchema.optional(),
35+
})
36+
export type ReasoningPart = z.infer<typeof reasoningPartSchema>
37+
38+
export const toolCallPartSchema = z.object({
39+
type: z.literal('tool-call'),
40+
toolCallId: z.string(),
41+
toolName: z.string(),
42+
input: z.record(z.string(), z.unknown()),
43+
providerOptions: providerMetadataSchema.optional(),
44+
providerExecuted: z.boolean().optional(),
45+
})
46+
export type ToolCallPart = z.infer<typeof toolCallPartSchema>
47+
48+
export const toolResultOutputSchema = z.discriminatedUnion('type', [
49+
z.object({
50+
type: z.literal('json'),
51+
value: z
52+
.discriminatedUnion('type', [
53+
z.object({
54+
type: z.literal('json'),
55+
value: jsonValueSchema,
56+
}),
57+
z.object({
58+
type: z.literal('media'),
59+
data: z.string(),
60+
mediaType: z.string(),
61+
}),
62+
])
63+
.array(),
64+
}),
65+
])
66+
export type ToolResultOutput = z.infer<typeof toolResultOutputSchema>
67+
68+
export const toolResultPartSchema = z.object({
69+
type: z.literal('tool-result'),
70+
toolCallId: z.string(),
71+
toolName: z.string(),
72+
output: toolResultOutputSchema,
73+
providerOptions: providerMetadataSchema.optional(),
74+
})
75+
export type ToolResultPart = z.infer<typeof toolResultPartSchema>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import z from 'zod/v4'
2+
3+
export const dataContentSchema = z.union([
4+
z.string(),
5+
z.instanceof(Uint8Array),
6+
z.instanceof(ArrayBuffer),
7+
z.custom<Buffer>(
8+
// Buffer might not be available in some environments such as CloudFlare:
9+
(value: unknown): value is Buffer =>
10+
globalThis.Buffer?.isBuffer(value) ?? false,
11+
{ message: 'Must be a Buffer' },
12+
),
13+
])
14+
export type DataContent = z.infer<typeof dataContentSchema>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import z from 'zod/v4'
2+
3+
import { jsonValueSchema } from '../json'
4+
5+
export const providerMetadataSchema = z.record(
6+
z.string(),
7+
z.record(z.string(), jsonValueSchema),
8+
)
9+
10+
export type ProviderMetadata = z.infer<typeof providerMetadataSchema>

common/src/types/session-state.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { z } from 'zod/v4'
22

3-
import { CodebuffMessageSchema } from './message'
3+
import { codebuffMessageSchema } from './messages/codebuff-message'
4+
import { MAX_AGENT_STEPS_DEFAULT } from '../constants/agents'
45
import { ProjectFileContextSchema } from '../util/file'
56

67
import type { CodebuffMessage } from './message'
78
import type { ProjectFileContext } from '../util/file'
8-
import { MAX_AGENT_STEPS_DEFAULT } from '../constants/agents'
99

1010
export const toolCallSchema = z.object({
1111
toolName: z.string(),
@@ -50,7 +50,7 @@ export const AgentStateSchema: z.ZodType<{
5050
agentType: z.string().nullable(),
5151
agentContext: z.record(z.string(), subgoalSchema),
5252
subagents: AgentStateSchema.array(),
53-
messageHistory: CodebuffMessageSchema.array(),
53+
messageHistory: codebuffMessageSchema.array(),
5454
stepsRemaining: z.number(),
5555
creditsUsed: z.number().default(0),
5656
output: z.record(z.string(), z.any()).optional(),

0 commit comments

Comments
 (0)