Skip to content

Commit f32486f

Browse files
committed
Expose a PublicAgentState in handleSteps. Update Messages type to be slightly more accurate
Add output to public agent state
1 parent 663bcd9 commit f32486f

File tree

13 files changed

+117
-29
lines changed

13 files changed

+117
-29
lines changed

.agents/__tests__/context-pruner.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ describe('context-pruner handleSteps', () => {
8585

8686
expect(results).toHaveLength(1)
8787
// Should preserve all messages since there aren't 3 messages to remove
88-
expect(results[0].input.messages).toHaveLength(3)
88+
expect(results[0].input.messages).toHaveLength(1)
8989

9090
})
9191

.agents/base2/gpt-5-high/planner-gpt-5-high.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ const definition: SecretAgentDefinition = {
2323
stateAfterFileExplorer.messageHistory.findLastIndex(
2424
(message) => message.role === 'assistant',
2525
)
26-
const toolResultMessage = messageHistory[lastAssistantMessageIndex + 1] ?? {
26+
const toolResultMessage = (messageHistory[
27+
lastAssistantMessageIndex + 1
28+
] as { content: string }) ?? {
2729
content: '',
2830
}
29-
const filePaths = parseFilePathsFromToolResult(toolResultMessage.content)
31+
const filePaths = parseFilePathsFromToolResult(
32+
toolResultMessage.content ?? '',
33+
)
3034

3135
// Step 2: Read the files
3236
yield {

.agents/base2/planner-factory.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ Process:
4545
stateAfterFileExplorer.messageHistory.findLastIndex(
4646
(message) => message.role === 'assistant',
4747
)
48-
const toolResultMessage = messageHistory[lastAssistantMessageIndex + 1] ?? {
48+
const toolResultMessage = (messageHistory[
49+
lastAssistantMessageIndex + 1
50+
] as { content: string }) ?? {
4951
content: '',
5052
}
5153
const filePaths = parseFilePathsFromToolResult(toolResultMessage.content)

.agents/context-pruner.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { publisher } from './constants'
22

3-
import type { AgentDefinition, Message } from './types/agent-definition'
3+
import type {
4+
AgentDefinition,
5+
Message,
6+
ToolCall,
7+
} from './types/agent-definition'
48

59
const definition: AgentDefinition = {
610
id: 'context-pruner',
@@ -109,7 +113,7 @@ const definition: AgentDefinition = {
109113
}
110114

111115
// PASS 2: Remove large tool results (any tool result > 1000 chars)
112-
const afterToolResultsPass: Message[] = afterTerminalPass.map((message) => {
116+
const afterToolResultsPass = afterTerminalPass.map((message) => {
113117
let processedContent =
114118
typeof message.content === 'string'
115119
? message.content
@@ -136,7 +140,7 @@ const definition: AgentDefinition = {
136140
input: {
137141
messages: afterToolResultsPass,
138142
},
139-
}
143+
} satisfies ToolCall
140144
return
141145
}
142146

@@ -155,7 +159,7 @@ const definition: AgentDefinition = {
155159
(maxMessageTokens - requiredTokens) * (1 - shortenedMessageTokenFactor)
156160

157161
const placeholder = 'deleted'
158-
const filteredMessages: (Message | typeof placeholder)[] = []
162+
const filteredMessages: any[] = []
159163

160164
for (const message of afterToolResultsPass) {
161165
if (
@@ -186,7 +190,7 @@ const definition: AgentDefinition = {
186190
input: {
187191
messages: finalMessages,
188192
},
189-
}
193+
} satisfies ToolCall
190194
},
191195
}
192196

.agents/types/agent-definition.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export interface AgentDefinition {
5656
// ============================================================================
5757

5858
/** Tools this agent can use. */
59-
toolNames?: ToolName[]
59+
toolNames?: (ToolName | (string & {}))[]
6060

6161
/** Other agents this agent can spawn, like 'codebuff/file-picker@0.0.1'.
6262
*
@@ -95,7 +95,7 @@ export interface AgentDefinition {
9595
*
9696
* all_messages: All messages from the agent, including tool calls and results.
9797
*
98-
* json: Make the agent output a JSON object. Can be used with outputSchema or without if you want freeform json output.
98+
* structured_output: Make the agent output a JSON object. Can be used with outputSchema or without if you want freeform json output.
9999
*/
100100
outputMode?: 'last_message' | 'all_messages' | 'structured_output'
101101

@@ -146,6 +146,14 @@ export interface AgentDefinition {
146146
* input: { paths: ['file1.txt', 'file2.txt'] }
147147
* }
148148
* yield 'STEP_ALL'
149+
*
150+
* // Optionally do a post-processing step here...
151+
* yield {
152+
* toolName: 'set_output',
153+
* input: {
154+
* output: 'The files were read successfully.',
155+
* },
156+
* }
149157
* }
150158
*
151159
* Example 2:
@@ -162,7 +170,8 @@ export interface AgentDefinition {
162170
* ],
163171
* },
164172
* }
165-
* yield 'STEP'
173+
* const { stepsComplete } = yield 'STEP'
174+
* if (stepsComplete) break
166175
* }
167176
* }
168177
*/
@@ -183,16 +192,32 @@ export interface AgentDefinition {
183192

184193
export interface AgentState {
185194
agentId: string
186-
parentId: string
195+
parentId: string | undefined
196+
197+
/** The agent's conversation history: messages from the user and the assistant. */
187198
messageHistory: Message[]
199+
200+
/** The last value set by the set_output tool. This is a plain object or undefined if not set. */
201+
output: Record<string, any> | undefined
188202
}
189203

190204
/**
191205
* Message in conversation history
192206
*/
193207
export interface Message {
194208
role: 'user' | 'assistant'
195-
content: string
209+
content:
210+
| string
211+
| Array<
212+
| {
213+
type: 'text'
214+
text: string
215+
}
216+
| {
217+
type: 'image'
218+
image: string
219+
}
220+
>
196221
}
197222

198223
/**

.agents/types/tools.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,12 @@ export interface RunTerminalCommandParams {
120120
export interface SetMessagesParams {
121121
messages: {
122122
role: 'user' | 'assistant'
123-
content: string
123+
content:
124+
| string
125+
| {
126+
type: 'text'
127+
text: string
128+
}[]
124129
}[]
125130
}
126131

@@ -155,6 +160,8 @@ export interface StrReplaceParams {
155160
old: string
156161
/** The string to replace the corresponding old string with. Can be empty to delete. */
157162
new: string
163+
/** Whether to allow multiple replacements of old string. */
164+
allowMultiple?: boolean
158165
}[]
159166
}
160167

backend/src/__tests__/run-programmatic-step.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {
3333
ToolResult,
3434
} from '@codebuff/common/types/session-state'
3535
import type { WebSocket } from 'ws'
36+
import { PublicAgentState } from '@codebuff/common/types/agent-template'
3637

3738
describe('runProgrammaticStep', () => {
3839
let mockTemplate: AgentTemplate
@@ -382,7 +383,7 @@ describe('runProgrammaticStep', () => {
382383
it('should comprehensively test STEP_ALL functionality with multiple tools and state management', async () => {
383384
// Track all tool results and state changes for verification
384385
const toolResultsReceived: (string | undefined)[] = []
385-
const stateSnapshots: AgentState[] = []
386+
const stateSnapshots: PublicAgentState[] = []
386387
let stepCount = 0
387388

388389
const mockGenerator = (function* () {

backend/src/run-programmatic-step.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { CodebuffToolCall } from '@codebuff/common/tools/list'
1111
import type {
1212
AgentTemplate,
1313
StepGenerator,
14+
PublicAgentState,
1415
} from '@codebuff/common/types/agent-template'
1516
import type { PrintModeEvent } from '@codebuff/common/types/print-mode'
1617
import type {
@@ -153,12 +154,12 @@ export async function runProgrammaticStep(
153154
do {
154155
const result = sandbox
155156
? await sandbox.executeStep({
156-
agentState: { ...state.agentState },
157+
agentState: getPublicAgentState(state.agentState),
157158
toolResult,
158159
stepsComplete,
159160
})
160161
: generator!.next({
161-
agentState: { ...state.agentState },
162+
agentState: getPublicAgentState(state.agentState),
162163
toolResult,
163164
stepsComplete,
164165
})
@@ -275,3 +276,15 @@ export async function runProgrammaticStep(
275276
}
276277
}
277278
}
279+
280+
export const getPublicAgentState = (
281+
agentState: AgentState,
282+
): PublicAgentState => {
283+
const { agentId, parentId, messageHistory, output } = agentState
284+
return {
285+
agentId,
286+
parentId,
287+
messageHistory: messageHistory as any as PublicAgentState['messageHistory'],
288+
output,
289+
}
290+
}

common/src/templates/initial-agents-dir/types/agent-definition.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ export interface AgentDefinition {
175175
* }
176176
* }
177177
*/
178-
handleSteps?: (
179-
context: AgentStepContext,
180-
) => Generator<
178+
handleSteps?: (context: AgentStepContext) => Generator<
181179
ToolCall | 'STEP' | 'STEP_ALL',
182180
void,
183181
{
@@ -194,16 +192,32 @@ export interface AgentDefinition {
194192

195193
export interface AgentState {
196194
agentId: string
197-
parentId: string
195+
parentId: string | undefined
196+
197+
/** The agent's conversation history: messages from the user and the assistant. */
198198
messageHistory: Message[]
199+
200+
/** The last value set by the set_output tool. This is a plain object or undefined if not set. */
201+
output: Record<string, any> | undefined
199202
}
200203

201204
/**
202205
* Message in conversation history
203206
*/
204207
export interface Message {
205208
role: 'user' | 'assistant'
206-
content: string
209+
content:
210+
| string
211+
| Array<
212+
| {
213+
type: 'text'
214+
text: string
215+
}
216+
| {
217+
type: 'image'
218+
image: string
219+
}
220+
>
207221
}
208222

209223
/**

common/src/templates/initial-agents-dir/types/tools.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,12 @@ export interface RunTerminalCommandParams {
120120
export interface SetMessagesParams {
121121
messages: {
122122
role: 'user' | 'assistant'
123-
content: string
123+
content:
124+
| string
125+
| {
126+
type: 'text'
127+
text: string
128+
}[]
124129
}[]
125130
}
126131

0 commit comments

Comments
 (0)