Skip to content

Commit d152a74

Browse files
Merge origin/main into brandon/tui
Thoughtfully merged changes in backend/src/run-programmatic-step.ts: - From origin/main: HandleStepsLogChunkFn, handleStepsLogChunk, sendSubagentChunk, fromHandleSteps param - From brandon/tui: parentAgentId wrapping logic for nested agent events - Combined both sets of changes for full functionality 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
2 parents 5db2beb + a670672 commit d152a74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1491
-903
lines changed

.agents/planners/generate-plan-max.ts renamed to .agents-graveyard/planners/generate-plan-max.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { publisher } from '../constants'
2-
import { type SecretAgentDefinition } from '../types/secret-agent-definition'
1+
import { publisher } from '../../.agents/constants'
2+
import { type SecretAgentDefinition } from '../../.agents/types/secret-agent-definition'
33

44
const definition: SecretAgentDefinition = {
55
id: 'generate-plan-max',
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { publisher } from '../../.agents/constants'
2+
import {
3+
PLACEHOLDER,
4+
type SecretAgentDefinition,
5+
} from '../../.agents/types/secret-agent-definition'
6+
7+
const definition: SecretAgentDefinition = {
8+
id: 'generate-plan-thinking',
9+
publisher,
10+
model: 'anthropic/claude-sonnet-4.5',
11+
displayName: 'Plan Generator Thinking',
12+
spawnerPrompt:
13+
'Thinks, then generates 5 alternative plans for a user request, analyzes them, and selects the best and simplest one that meets all requirements.',
14+
inputSchema: {},
15+
outputMode: 'structured_output',
16+
toolNames: ['spawn_agents', 'read_files', 'set_output'],
17+
spawnableAgents: ['decomposing-thinker', 'independent-thinker'],
18+
19+
includeMessageHistory: true,
20+
inheritParentSystemPrompt: true,
21+
22+
instructionsPrompt: `For reference, here is the original user request:
23+
<user_message>
24+
${PLACEHOLDER.USER_INPUT_PROMPT}
25+
</user_message>
26+
27+
You are the generate-plan-thinking agent. You are an expert planning agent that generates multiple plan alternatives and selects the optimal one.
28+
29+
IMPORTANT: You do not have access to any editing tools. You can only analyze and write out plans. Your goal is to generate the best plan for the user's request.
30+
31+
Your task is to:
32+
1. Spawn thinking agents (decomposing-thinker and independent-thinker) to deep dive and weigh alternative approaches to the user's request.
33+
2. Write out 5 distinct alternative plans for the user's request. Each plan should be complete and actionable but approach the problem differently.
34+
3. After generating all 5 plans, analyze each one against the original user requirements.
35+
4. Select the plan that:
36+
- Most closely matches all the original user requirements
37+
- Is the simplest and most straightforward to implement
38+
- Has the fewest dependencies and moving parts
39+
- Touches the fewest files
40+
- Reuses existing helper functions and other code whenever possible
41+
- Is most maintainable
42+
43+
Output format:
44+
- Spawn parallel thinking agents
45+
- Write out all 5 plans clearly labeled as "Plan 1:", "Plan 2:", etc.
46+
- Then write an analysis section comparing the plans against the requirements
47+
- Finally, call set_output with a 'plan' field containing the best plan, which you are free to rewrite (doesn't have to be one of the five already selected).
48+
49+
The selected plan in set_output should be:
50+
- Written in clear, actionable steps
51+
- Free of unnecessary complexity
52+
- Easy to understand and follow
53+
- Complete and addresses all the specific user requirements
54+
- Just the plan text itself, without labels or meta-commentary`,
55+
}
56+
57+
export default definition

.agents/planners/plan-selector.ts renamed to .agents-graveyard/planners/plan-selector-for-generate-plan.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { publisher } from '../constants'
1+
import { publisher } from '../../.agents/constants'
22
import {
33
PLACEHOLDER,
44
type SecretAgentDefinition,
5-
} from '../types/secret-agent-definition'
5+
} from '../../.agents/types/secret-agent-definition'
66

77
const definition: SecretAgentDefinition = {
88
id: 'plan-selector',

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ describe('context-pruner handleSteps', () => {
6565
})
6666

6767
const runHandleSteps = (messages: Message[]) => {
68-
mockAgentState.messageHistory = messages
68+
// Add instructions prompt that will be removed by context-pruner
69+
const messagesWithInstructions = [
70+
...messages,
71+
createMessage('user', 'Instructions prompt'),
72+
]
73+
mockAgentState.messageHistory = messagesWithInstructions
6974
const mockLogger = {
7075
debug: () => {},
7176
info: () => {},
@@ -332,7 +337,12 @@ describe('context-pruner edge cases', () => {
332337
})
333338

334339
const runHandleSteps = (messages: Message[]) => {
335-
mockAgentState.messageHistory = messages
340+
// Add instructions prompt that will be removed by context-pruner
341+
const messagesWithInstructions = [
342+
...messages,
343+
createMessage('user', 'Instructions prompt'),
344+
]
345+
mockAgentState.messageHistory = messagesWithInstructions
336346
const mockLogger = {
337347
debug: () => {},
338348
info: () => {},
@@ -502,15 +512,15 @@ describe('context-pruner edge cases', () => {
502512
},
503513
{
504514
content: 'spawn_agent_inline call for "context-pruner" with quotes',
505-
shouldRemove: true, // Has context-pruner and 3 total messages
515+
shouldRemove: true, // Has context-pruner and 3 total messages before instructions
506516
},
507517
{
508518
content: 'spawn_agent_inline\n "agent_type": "context-pruner"',
509-
shouldRemove: true, // Has context-pruner and 3 total messages
519+
shouldRemove: true, // Has context-pruner and 3 total messages before instructions
510520
},
511521
{
512522
content: 'Multiple spawn_agent_inline calls, one for context-pruner',
513-
shouldRemove: true, // Has context-pruner and 3 total messages
523+
shouldRemove: true, // Has context-pruner and 3 total messages before instructions
514524
},
515525
]
516526

@@ -531,7 +541,7 @@ describe('context-pruner edge cases', () => {
531541
createMessage('user', 'Hello'),
532542
)
533543
} else {
534-
// Should preserve all messages
544+
// Should preserve all messages (4 original messages)
535545
expect((results[0] as any).input.messages).toHaveLength(4)
536546
}
537547
})

.agents/agent-builder.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,19 @@ const researcherGrok4FastExampleContent = readFileSync(
2222
join(__dirname, 'researcher', 'researcher-grok-4-fast.ts'),
2323
'utf8',
2424
)
25-
const implementationPlannerExampleContent = readFileSync(
25+
const generatePlanExampleContent = readFileSync(
2626
join(__dirname, 'planners', 'generate-plan.ts'),
2727
'utf8',
2828
)
29-
const planSelectorExampleContent = readFileSync(
30-
join(__dirname, 'planners', 'plan-selector.ts'),
31-
'utf8',
32-
)
33-
const implementationPlannerMaxExampleContent = readFileSync(
34-
join(__dirname, 'planners', 'generate-plan-max.ts'),
29+
const reviewerExampleContent = readFileSync(
30+
join(__dirname, 'reviewer', 'reviewer.ts'),
3531
'utf8',
3632
)
3733
const examplesAgentsContent = [
3834
researcherDocExampleContent,
3935
researcherGrok4FastExampleContent,
40-
implementationPlannerExampleContent,
41-
planSelectorExampleContent,
42-
implementationPlannerMaxExampleContent,
36+
generatePlanExampleContent,
37+
reviewerExampleContent,
4338
]
4439

4540
const definition: AgentDefinition = {

.agents/base/base-max.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const definition: SecretAgentDefinition = {
1212
'find-all-referencer',
1313
'researcher-web-sonnet',
1414
'researcher-docs-sonnet',
15-
'decomposing-planner',
15+
'generate-plan',
1616
'decomposing-thinker',
1717
'reviewer',
1818
'context-pruner',
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createBase2 } from './base2'
2+
import type { SecretAgentDefinition } from '../types/secret-agent-definition'
3+
4+
const definition: SecretAgentDefinition = {
5+
...createBase2('normal'),
6+
id: 'base2-gpt-5-single-step',
7+
model: 'openai/gpt-5',
8+
reasoningOptions: {
9+
enabled: true,
10+
effort: 'medium',
11+
exclude: false,
12+
},
13+
14+
inputSchema: {},
15+
16+
handleSteps: function* ({ params }) {
17+
// Run context-pruner before each step
18+
yield {
19+
toolName: 'spawn_agent_inline',
20+
input: {
21+
agent_type: 'context-pruner',
22+
params: params ?? {},
23+
},
24+
includeToolCall: false,
25+
} as any
26+
27+
yield 'STEP'
28+
},
29+
}
30+
31+
export default definition

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { buildArray } from '@codebuff/common/util/array'
2+
import { createBase2 } from './base2'
3+
import type { SecretAgentDefinition } from '../types/secret-agent-definition'
4+
5+
const base = createBase2('normal')
6+
7+
const definition: SecretAgentDefinition = {
8+
...base,
9+
id: 'base2-gpt-5',
10+
model: 'openai/gpt-5',
11+
spawnableAgents: buildArray(
12+
'file-picker',
13+
'find-all-referencer',
14+
'researcher-web',
15+
'researcher-docs',
16+
'commander',
17+
'reviewer-gpt-5',
18+
'editor-gpt-5',
19+
'context-pruner',
20+
),
21+
}
22+
23+
export default definition

.agents/base2/base2-max.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
import { createBase2 } from './base2'
2+
import type { SecretAgentDefinition } from '../types/secret-agent-definition'
23

3-
const definition = { ...createBase2('max'), id: 'base2-max' }
4+
const base2 = createBase2('max')
5+
const definition: SecretAgentDefinition = {
6+
...base2,
7+
id: 'base2-max',
8+
spawnableAgents: [
9+
...(base2.spawnableAgents ?? []),
10+
'base2-gpt-5-single-step',
11+
],
12+
handleSteps: function* ({ params }) {
13+
while (true) {
14+
// Run context-pruner before each step
15+
yield {
16+
toolName: 'spawn_agent_inline',
17+
input: {
18+
agent_type: 'context-pruner',
19+
params: params ?? {},
20+
},
21+
includeToolCall: false,
22+
} as any
23+
24+
const { stepsComplete } = yield 'STEP'
25+
if (stepsComplete) break
26+
27+
yield {
28+
toolName: 'spawn_agent_inline',
29+
input: {
30+
agent_type: 'base2-gpt-5-single-step',
31+
},
32+
}
33+
}
34+
},
35+
}
436

537
export default definition

0 commit comments

Comments
 (0)