mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-12 19:55:19 +02:00
checks all todos are done before responding
This commit is contained in:
parent
cb26602a02
commit
fda8c4c024
3 changed files with 26 additions and 1 deletions
|
|
@ -22,6 +22,7 @@ Always consult this catalog first so you load the right skills before taking act
|
|||
|
||||
## Task tracking
|
||||
- Maintain a durable todo list for multi-step efforts using the \`todoList\`, \`todoWrite\`, and \`todoUpdate\` builtin tools (state persists only within this copilot session).
|
||||
- Before delivering your final response, verify every todo is marked \`done\` or \`blocked\`—use \`todoUpdate\` to reflect progress or issues.
|
||||
- Treat the <system-reminder> text returned by those tools as internal guidance—never echo these reminders to the user verbatim.
|
||||
|
||||
## Execution reminders
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { LlmStepStreamEvent } from "../entities/llm-step-events.js";
|
|||
import { execTool } from "./exec-tool.js";
|
||||
import { RunEvent } from "../entities/run-events.js";
|
||||
import { BuiltinTools } from "./builtin-tools.js";
|
||||
import { readTodoState, pushTodoState, popTodoState } from "./todo-store.js";
|
||||
import { collectSystemReminders } from "../assistant/reminders/manager.js";
|
||||
|
||||
export async function mapAgentTool(t: z.infer<typeof ToolAttachment>): Promise<Tool> {
|
||||
|
|
@ -237,6 +238,8 @@ export async function* streamAgentTurn(opts: {
|
|||
messages: z.infer<typeof MessageList>;
|
||||
}): AsyncGenerator<z.infer<typeof RunEvent>, void, unknown> {
|
||||
const { agent, messages } = opts;
|
||||
pushTodoState();
|
||||
try {
|
||||
|
||||
// set up tools
|
||||
const tools: ToolSet = {};
|
||||
|
|
@ -350,9 +353,21 @@ export async function* streamAgentTurn(opts: {
|
|||
continue;
|
||||
}
|
||||
|
||||
const completionReminder = await outstandingTodosReminder();
|
||||
if (completionReminder) {
|
||||
messages.push({
|
||||
role: "system",
|
||||
content: completionReminder,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise, break
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
popTodoState();
|
||||
}
|
||||
}
|
||||
|
||||
async function* streamLlm(
|
||||
|
|
@ -444,6 +459,15 @@ function attachRemindersToResult(result: any, reminders: string[]) {
|
|||
systemReminders: reminders,
|
||||
};
|
||||
}
|
||||
async function outstandingTodosReminder(): Promise<string | null> {
|
||||
const state = await readTodoState();
|
||||
const remaining = state.todos.filter(todo => todo.status !== "done" && todo.status !== "blocked");
|
||||
if (remaining.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return `<system-reminder>\nBefore concluding, finish every todo via the todo tools or mark it as blocked if an issue prevents completion. Outstanding items: ${JSON.stringify(remaining)}\n</system-reminder>`;
|
||||
}
|
||||
|
||||
export const MappedToolCall = z.object({
|
||||
toolCall: ToolCallPart,
|
||||
agentTool: ToolAttachment,
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ export const BuiltinTools: z.infer<typeof BuiltinToolsSchema> = {
|
|||
},
|
||||
|
||||
todoList: {
|
||||
description: 'Return the durable todo list for the current session',
|
||||
description: 'Return the todo list for the current copilot session',
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => {
|
||||
const state = await readTodoState();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue