11import {
22 AgentState ,
33 AgentTemplateType ,
4+ ToolResult ,
45} from '@codebuff/common/types/session-state'
56import { ProjectFileContext } from '@codebuff/common/util/file'
67import { WebSocket } from 'ws'
78import { runTool } from './run-tool'
8- import {
9- ProgrammaticAgentContext ,
10- ProgrammaticAgentTemplate ,
11- } from './templates/types'
9+ import { AgentTemplate , StepGenerator } from './templates/types'
1210import { CodebuffToolCall } from './tools/constants'
1311import { logger } from './util/logger'
1412import { getRequestContext } from './websockets/request-context'
1513
14+ // Maintains generator state for all agents. Generator state can't be serialized, so we store it in memory.
15+ const agentIdToGenerator : Record < string , StepGenerator | undefined > = { }
16+
1617// Function to handle programmatic agents
17- export async function runProgrammaticAgent (
18- template : ProgrammaticAgentTemplate ,
19- options : {
18+ export async function runProgrammaticStep (
19+ agentState : AgentState ,
20+ params : {
21+ template : AgentTemplate
2022 userId : string | undefined
2123 userInputId : string
2224 clientSessionId : string
2325 fingerprintId : string
2426 onResponseChunk : ( chunk : string ) => void
2527 agentType : AgentTemplateType
2628 fileContext : ProjectFileContext
27- agentState : AgentState
2829 prompt : string | undefined
2930 params : Record < string , any > | undefined
3031 assistantMessage : string | undefined
@@ -33,38 +34,55 @@ export async function runProgrammaticAgent(
3334 }
3435) : Promise < AgentState > {
3536 const {
36- agentState ,
37+ template ,
3738 onResponseChunk,
3839 ws,
3940 userId,
4041 userInputId,
4142 clientSessionId,
4243 fingerprintId,
4344 fileContext,
44- } = options
45+ } = params
4546
4647 logger . info (
4748 {
4849 template : template . id ,
49- agentType : options . agentType ,
50- prompt : options . prompt ,
51- params : options . params ,
50+ agentType : params . agentType ,
51+ prompt : params . prompt ,
52+ params : params . params ,
5253 } ,
53- 'Running programmatic agent '
54+ 'Running programmatic step '
5455 )
55- // Create context for the programmatic agent
56- const context : ProgrammaticAgentContext = {
57- prompt : options . prompt || '' ,
58- params : options . params || { } ,
56+
57+ let generator = agentIdToGenerator [ agentState . agentId ]
58+ if ( ! generator ) {
59+ if ( ! template . handleStep ) {
60+ throw new Error ( 'No step handler found for agent template ' + template . id )
61+ }
62+ generator = template . handleStep ( agentState )
63+ agentIdToGenerator [ agentState . agentId ] = generator
5964 }
6065
66+ if ( Math . random ( ) <= 1 ) {
67+ throw new Error ( 'Not implemented yet!' )
68+ }
69+
70+ let toolResult : ToolResult | undefined
71+
6172 try {
62- // Run the generator function and handle tool calls
63- const generator = template . handler ( context )
64- let result = generator . next ( )
73+ do {
74+ let result = generator . next ( toolResult )
75+ if ( result . done ) {
76+ break
77+ }
78+ if ( result . value === 'STEP' ) {
79+ break
80+ }
81+ if ( result . value === 'STEP_ALL' ) {
82+ break
83+ }
6584
66- // Process tool calls yielded by the generator
67- while ( ! result . done ) {
85+ // Process tool calls yielded by the generator
6886 const toolCallWithoutId = result . value
6987 const toolCall = {
7088 ...toolCallWithoutId ,
@@ -79,7 +97,7 @@ export async function runProgrammaticAgent(
7997 const repoId = requestContext ?. processedRepoId
8098
8199 // Execute the tool call using the simplified wrapper
82- const toolResult = await runTool ( toolCall , {
100+ toolResult = await runTool ( toolCall , {
83101 ws,
84102 userId,
85103 userInputId,
@@ -93,13 +111,10 @@ export async function runProgrammaticAgent(
93111 agentState,
94112 } )
95113
96- // Send the tool result back to the generator
97- result = generator . next ( toolResult )
98-
99114 if ( result . value && result . value . toolName === 'end_turn' ) {
100115 break
101116 }
102- }
117+ } while ( true )
103118
104119 logger . info (
105120 { report : agentState . report } ,
0 commit comments