mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-27 20:29:44 +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
|
## 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).
|
- 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.
|
- Treat the <system-reminder> text returned by those tools as internal guidance—never echo these reminders to the user verbatim.
|
||||||
|
|
||||||
## Execution reminders
|
## Execution reminders
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { LlmStepStreamEvent } from "../entities/llm-step-events.js";
|
||||||
import { execTool } from "./exec-tool.js";
|
import { execTool } from "./exec-tool.js";
|
||||||
import { RunEvent } from "../entities/run-events.js";
|
import { RunEvent } from "../entities/run-events.js";
|
||||||
import { BuiltinTools } from "./builtin-tools.js";
|
import { BuiltinTools } from "./builtin-tools.js";
|
||||||
|
import { readTodoState, pushTodoState, popTodoState } from "./todo-store.js";
|
||||||
import { collectSystemReminders } from "../assistant/reminders/manager.js";
|
import { collectSystemReminders } from "../assistant/reminders/manager.js";
|
||||||
|
|
||||||
export async function mapAgentTool(t: z.infer<typeof ToolAttachment>): Promise<Tool> {
|
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>;
|
messages: z.infer<typeof MessageList>;
|
||||||
}): AsyncGenerator<z.infer<typeof RunEvent>, void, unknown> {
|
}): AsyncGenerator<z.infer<typeof RunEvent>, void, unknown> {
|
||||||
const { agent, messages } = opts;
|
const { agent, messages } = opts;
|
||||||
|
pushTodoState();
|
||||||
|
try {
|
||||||
|
|
||||||
// set up tools
|
// set up tools
|
||||||
const tools: ToolSet = {};
|
const tools: ToolSet = {};
|
||||||
|
|
@ -350,9 +353,21 @@ export async function* streamAgentTurn(opts: {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const completionReminder = await outstandingTodosReminder();
|
||||||
|
if (completionReminder) {
|
||||||
|
messages.push({
|
||||||
|
role: "system",
|
||||||
|
content: completionReminder,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// otherwise, break
|
// otherwise, break
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
popTodoState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function* streamLlm(
|
async function* streamLlm(
|
||||||
|
|
@ -444,6 +459,15 @@ function attachRemindersToResult(result: any, reminders: string[]) {
|
||||||
systemReminders: reminders,
|
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({
|
export const MappedToolCall = z.object({
|
||||||
toolCall: ToolCallPart,
|
toolCall: ToolCallPart,
|
||||||
agentTool: ToolAttachment,
|
agentTool: ToolAttachment,
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ export const BuiltinTools: z.infer<typeof BuiltinToolsSchema> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
todoList: {
|
todoList: {
|
||||||
description: 'Return the durable todo list for the current session',
|
description: 'Return the todo list for the current copilot session',
|
||||||
inputSchema: z.object({}),
|
inputSchema: z.object({}),
|
||||||
execute: async () => {
|
execute: async () => {
|
||||||
const state = await readTodoState();
|
const state = await readTodoState();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue