Skip to content

Commit 3a22eb0

Browse files
committed
prompt tune tool call summarization + add user objective -> bullet summary
1 parent 9fa5fc4 commit 3a22eb0

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

packages/core/src/agents/executor.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
210210
turnCounter: number,
211211
turnSignal: AbortSignal,
212212
timeoutSignal: AbortSignal, // Pass the timeout controller's signal
213+
objective: string,
213214
): Promise<AgentTurnResult> {
214215
const promptId = `${this.agentId}#${turnCounter}`;
215216

@@ -312,7 +313,12 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
312313
}
313314

314315
const { nextMessage, submittedOutput, taskCompleted } =
315-
await this.processFunctionCalls(functionCalls, turnSignal, promptId);
316+
await this.processFunctionCalls(
317+
functionCalls,
318+
turnSignal,
319+
promptId,
320+
objective,
321+
);
316322

317323
if (taskCompleted) {
318324
let finalResult = submittedOutput ?? 'Task completed successfully.';
@@ -419,6 +425,9 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
419425
turnCounter, // This will be the "last" turn number
420426
combinedSignal,
421427
graceTimeoutController.signal, // Pass grace signal to identify a *grace* timeout
428+
// The objective for a recovery turn is to complete the task,
429+
// so we'll pass a concise instruction to that effect.
430+
`Complete the interrupted task with your best answer, explaining the interruption.`, // Objective for recovery
422431
);
423432

424433
if (
@@ -495,7 +504,10 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
495504
tools = this.prepareToolsList();
496505
const query = this.definition.promptConfig.query
497506
? templateString(this.definition.promptConfig.query, inputs)
498-
: 'Get Started!';
507+
: inputs['objective'] !== undefined
508+
? (inputs['objective'] as string)
509+
: 'Get Started!';
510+
499511
let currentMessage: GeminiContent = {
500512
role: 'user',
501513
parts: [{ text: query }],
@@ -529,6 +541,7 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
529541
turnCounter++,
530542
combinedSignal,
531543
timeoutController.signal,
544+
query, // Pass the objective here
532545
);
533546

534547
if (turnResult.status === 'stop') {
@@ -1104,6 +1117,7 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
11041117
functionCalls: FunctionCall[],
11051118
signal: AbortSignal,
11061119
promptId: string,
1120+
objective: string,
11071121
): Promise<{
11081122
nextMessage: GeminiContent;
11091123
submittedOutput: string | null;
@@ -1375,6 +1389,7 @@ export class AgentExecutor<TOutput extends z.ZodTypeAny> {
13751389
const summary = await this.summarizationService.summarize(
13761390
toolResponse.responseParts,
13771391
this.definition.modelConfig,
1392+
objective,
13781393
);
13791394
if (summary) {
13801395
debugLogger.log(

packages/core/src/services/summarizer.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,34 @@ import { StreamEventType } from '../core/geminiChat.js';
1111
import { debugLogger } from '../utils/debugLogger.js';
1212
import * as fs from 'node:fs/promises';
1313

14-
const SUMMARIZER_SYSTEM_PROMPT = `You are a text summarizer. Your sole purpose is to receive text and provide a concise, factual summary of it. Do not add any commentary or analysis. Focus on the key information presented in the text.`;
14+
const SUMMARIZER_SYSTEM_PROMPT = `## Role
15+
You are an expert Tool Call Output Summarizer.
16+
17+
## Task Definition
18+
Your task is to summarize a given tool call output. The summary must specifically highlight how the tool call output contributes to or addresses the user's overall objective.
19+
20+
## Instruction
21+
When generating the summary, focus solely on the information within the \`toolcall\` that directly addresses or fulfills aspects of the \`objective\`. **The summary must be as exhaustive as possible, capturing every relevant detail from the tool call, and must be presented as a bulleted list.** Do not include extraneous details or interpret the tool call beyond its direct relevance to the objective.
22+
23+
## Response Format Constraints
24+
The response **must be a bulleted list** containing **up to 20 points** (maximum). Each bullet point should be concise. DO NOT include any explicit explanations, reasoning, or thinking process outside of the bullet points. Your output must ONLY be the bulleted summary.`;
25+
26+
const SUMMARIZER_USER_PROMPT = `## Input
27+
User's Objective: {{objective}}
28+
Tool Call Output: {{toolcall}}
29+
30+
## Output Reminder
31+
Take a deep breath, read the instructions again, read the inputs again. Each instruction is crucial and must be executed with utmost care and attention to detail.
32+
33+
Summary:`;
1534

1635
export class SummarizationService {
1736
constructor() {}
1837

1938
async summarize(
2039
tollResponseParts: GeminiPart[],
2140
modelConfig: OllamaModelConfig | ModelConfig,
41+
objective: string,
2242
): Promise<string | null> {
2343
debugLogger.log(
2444
`[SummarizationService] Starting summarization using model: ${modelConfig.model}`,
@@ -34,13 +54,34 @@ export class SummarizationService {
3454
}
3555
}
3656

57+
try {
58+
await fs.writeFile(
59+
'summarize_tool_prompt.txt',
60+
JSON.stringify(userParts, null, 2),
61+
);
62+
debugLogger.log(
63+
'[DEBUG] Summarized tool output saved to summarize_tool_prompt.txt',
64+
);
65+
} catch (error) {
66+
debugLogger.error(
67+
'[DEBUG] Failed to save summarized tool output to summarize_tool_prompt.txt:',
68+
error,
69+
);
70+
}
71+
3772
const chat = new OllamaChat(
3873
modelConfig as OllamaModelConfig,
3974
SUMMARIZER_SYSTEM_PROMPT,
4075
);
4176

77+
const toolCallJson = JSON.stringify(userParts);
78+
const userPrompt = SUMMARIZER_USER_PROMPT.replace(
79+
'{{objective}}',
80+
objective,
81+
).replace('{{toolcall}}', toolCallJson);
82+
4283
const messageParams = {
43-
message: userParts,
84+
message: [{ text: userPrompt }],
4485
};
4586

4687
const responseStream = await chat.sendMessageStream(

0 commit comments

Comments
 (0)