Skip to content

Commit cd659ab

Browse files
jahoomabrandonkachencodebuff-teamcharleslien
authored
Set output tool! Output schema. Remove update_report (#218)
Co-authored-by: brandon chen <9735006+brandonkachen@users.noreply.github.com> Co-authored-by: Codebuff <noreply@codebuff.com> Co-authored-by: Charles Lien <charleslien97@gmail.com>
1 parent 934d77e commit cd659ab

31 files changed

+522
-253
lines changed

.agents/templates/git-committer-user-prompt.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Please follow the below steps to create a good commit message:
22

33
1. **Run two run_terminal_command tool calls:**
4+
45
- Run \`git diff\` to review both staged and unstaged modifications.
56
- Run \`git log\` to check recent commit messages, ensuring consistency with this repository’s style.
67

@@ -9,8 +10,9 @@ Please follow the below steps to create a good commit message:
910
3. **Select relevant files to include in the commit:**
1011
Use the git and file context to decide which files are pertinent to the changes. Stage any new untracked files that are relevant, but avoid committing previously modified files (from the beginning of the conversation) unless they directly relate to this commit.
1112

12-
3. **Analyze the staged changes and compose a commit message:**
13+
4. **Analyze the staged changes and compose a commit message:**
1314
Enclose your analysis in <commit_analysis> tags. Within these tags, you should:
15+
1416
- Note which files have been altered or added.
1517
- Categorize the nature of the changes (e.g., new feature, fix, refactor, documentation, etc.).
1618
- Consider the purpose or motivation behind the alterations.
@@ -22,7 +24,7 @@ Please follow the below steps to create a good commit message:
2224
- Ensure the message provides clarity—avoid generic or vague terms like “Update” or “Fix” without context.
2325
- Revisit your draft to confirm it truly reflects the changes and their intention.
2426

25-
4. **Create the commit, ending with this specific footer:**
27+
5. **Create the commit, ending with this specific footer:**
2628
\`\`\`
2729
Generated with Codebuff 🤖
2830
Co-Authored-By: Codebuff <noreply@codebuff.com>
@@ -48,7 +50,7 @@ Please follow the below steps to create a good commit message:
4850
- Make sure your commit message is concise yet descriptive, focusing on the intention behind the changes rather than merely describing them.
4951

5052
5. **Wrapping up**
51-
Finally, after creating the commit, you should use the update_report tool with a concise summary of what you committed and whether it was successful.
52-
Use end_turn to end your turn immediately after using the update_report tool.
53+
Finally, after creating the commit, you should use the set_output tool with a structured summary of what you committed and whether it was successful. The output should include fields like `success`, `message`, and `commitHash` if available.
54+
Use end_turn to end your turn immediately after using the set_output tool.
5355

54-
There's no need to write anything else outside these tool calls.
56+
There's no need to write anything else outside these tool calls.

.agents/templates/git-committer.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import { DynamicAgentConfig } from '@codebuff/common/types/dynamic-agent-templat
33
export default {
44
id: 'CodebuffAI/git-committer',
55
version: '0.0.1',
6-
model: 'google/gemini-2.5-pro',
7-
override: false,
8-
// implementation: 'llm',
6+
model: 'anthropic/claude-sonnet-4',
97
name: 'Git Committer',
108
purpose:
119
'A git committer agent specialized to commit current changes with an appropriate commit message.',
@@ -16,11 +14,11 @@ export default {
1614
},
1715
},
1816
includeMessageHistory: false,
19-
outputMode: 'report',
17+
outputMode: 'json',
2018
toolNames: [
2119
'read_files',
2220
'run_terminal_command',
23-
'update_report',
21+
'set_output',
2422
'think_deeply',
2523
'end_turn',
2624
],
@@ -30,5 +28,5 @@ export default {
3028
path: './git-committer-user-prompt.md',
3129
},
3230
agentStepPrompt:
33-
'Make sure to end your response by using update_report to update the report with a concise summary of what you committed and whether it was successful. Finally, use end_turn to end your turn.',
31+
'Make sure to end your response by using set_output to output a structured summary of what you committed and whether it was successful. Finally, use end_turn to end your turn.',
3432
} satisfies DynamicAgentConfig

backend/src/__tests__/parent-instructions.test.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ describe('Parent Instructions Injection', () => {
106106
subagents: [],
107107
messageHistory: [],
108108
stepsRemaining: 10,
109-
report: {},
109+
output: undefined,
110110
}
111111

112112
// Test parent instructions collection directly
@@ -153,17 +153,6 @@ describe('Parent Instructions Injection', () => {
153153
const researcherTemplate = agentRegistry['researcher']
154154
expect(researcherTemplate).toBeDefined()
155155

156-
// Create mock agent state
157-
const agentState: AgentState = {
158-
agentId: 'test-agent',
159-
agentType: 'researcher',
160-
agentContext: {},
161-
subagents: [],
162-
messageHistory: [],
163-
stepsRemaining: 10,
164-
report: {},
165-
}
166-
167156
// Test parent instructions collection directly
168157
const parentInstructions = await collectParentInstructions(
169158
'researcher',
@@ -249,17 +238,6 @@ describe('Parent Instructions Injection', () => {
249238
const researcherTemplate = agentRegistry['researcher']
250239
expect(researcherTemplate).toBeDefined()
251240

252-
// Create mock agent state
253-
const agentState: AgentState = {
254-
agentId: 'test-agent',
255-
agentType: 'researcher',
256-
agentContext: {},
257-
subagents: [],
258-
messageHistory: [],
259-
stepsRemaining: 10,
260-
report: {},
261-
}
262-
263241
// Test parent instructions collection directly
264242
const parentInstructions = await collectParentInstructions(
265243
'researcher',

backend/src/__tests__/run-agent-step-tools.test.ts

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,12 @@ describe('runAgentStep - update_report tool', () => {
168168
agentTemplates: {},
169169
}
170170

171-
it('should update report with simple key-value pair', async () => {
171+
it('should set output with simple key-value pair', async () => {
172172
const mockResponse =
173173
getToolCallString(
174-
'update_report',
174+
'set_output',
175175
{
176-
json_update: {
177-
message: 'Hi',
178-
},
176+
message: 'Hi',
179177
},
180178
false
181179
) + getToolCallString('end_turn', {}, true)
@@ -209,22 +207,20 @@ describe('runAgentStep - update_report tool', () => {
209207
}
210208
)
211209

212-
expect(result.agentState.report).toEqual({
210+
expect(result.agentState.output).toEqual({
213211
message: 'Hi',
214212
})
215213
expect(result.shouldEndTurn).toBe(true)
216214
})
217215

218-
it('should update report with json_update', async () => {
216+
it('should set output with complex data', async () => {
219217
const mockResponse =
220218
getToolCallString(
221-
'update_report',
219+
'set_output',
222220
{
223-
json_update: {
224-
message: 'Analysis complete',
225-
status: 'success',
226-
findings: ['Bug in auth.ts', 'Missing validation'],
227-
},
221+
message: 'Analysis complete',
222+
status: 'success',
223+
findings: ['Bug in auth.ts', 'Missing validation'],
228224
},
229225
false
230226
) + getToolCallString('end_turn', {}, true)
@@ -259,23 +255,21 @@ describe('runAgentStep - update_report tool', () => {
259255
}
260256
)
261257

262-
expect(result.agentState.report).toEqual({
258+
expect(result.agentState.output).toEqual({
263259
message: 'Analysis complete',
264260
status: 'success',
265261
findings: ['Bug in auth.ts', 'Missing validation'],
266262
})
267263
expect(result.shouldEndTurn).toBe(true)
268264
})
269265

270-
it('should merge with existing report data', async () => {
266+
it('should replace existing output data', async () => {
271267
const mockResponse =
272268
getToolCallString(
273-
'update_report',
269+
'set_output',
274270
{
275-
json_update: {
276-
newField: 'new value',
277-
existingField: 'updated value',
278-
},
271+
newField: 'new value',
272+
existingField: 'updated value',
279273
},
280274
false
281275
) + getToolCallString('end_turn', {}, true)
@@ -286,8 +280,8 @@ describe('runAgentStep - update_report tool', () => {
286280

287281
const sessionState = getInitialSessionState(mockFileContext)
288282
const agentState = sessionState.mainAgentState
289-
// Pre-populate the report with existing data
290-
agentState.report = {
283+
// Pre-populate the output with existing data
284+
agentState.output = {
291285
existingField: 'original value',
292286
anotherField: 'unchanged',
293287
}
@@ -307,37 +301,31 @@ describe('runAgentStep - update_report tool', () => {
307301
fileContext: mockFileContext,
308302
agentRegistry,
309303
agentState,
310-
prompt: 'Update the report',
304+
prompt: 'Update the output',
311305
params: undefined,
312306
assistantMessage: undefined,
313307
assistantPrefix: undefined,
314308
}
315309
)
316310

317-
expect(result.agentState.report).toEqual({
318-
existingField: 'updated value', // Should be updated
319-
anotherField: 'unchanged', // Should remain unchanged
320-
newField: 'new value', // Should be added
311+
expect(result.agentState.output).toEqual({
312+
newField: 'new value',
313+
existingField: 'updated value',
321314
})
322315
})
323316

324-
it('should handle empty json_update parameter', async () => {
317+
it('should handle empty output parameter', async () => {
325318
const mockResponse =
326-
getToolCallString(
327-
'update_report',
328-
{
329-
json_update: {},
330-
},
331-
false
332-
) + getToolCallString('end_turn', {}, true)
319+
getToolCallString('set_output', {}, false) +
320+
getToolCallString('end_turn', {}, true)
333321

334322
spyOn(aisdk, 'promptAiSdkStream').mockImplementation(async function* () {
335323
yield mockResponse
336324
})
337325

338326
const sessionState = getInitialSessionState(mockFileContext)
339327
const agentState = sessionState.mainAgentState
340-
agentState.report = { existingField: 'value' }
328+
agentState.output = { existingField: 'value' }
341329
const { agentRegistry } = await getAllAgentTemplates({
342330
fileContext: mockFileContext,
343331
})
@@ -361,9 +349,7 @@ describe('runAgentStep - update_report tool', () => {
361349
}
362350
)
363351

364-
// Should preserve existing report data
365-
expect(result.agentState.report).toEqual({
366-
existingField: 'value',
367-
})
352+
// Should replace with empty object
353+
expect(result.agentState.output).toEqual({})
368354
})
369355
})

0 commit comments

Comments
 (0)