integrate-todo-list

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Integrate Todo List

集成待办事项列表

Add a structured task-tracking feature to this Dune app. The agent will use a
TodoWrite
tool to create and update a task list as it works through multi-step queries, giving the user real-time visibility into what the agent is doing and why.
Prerequisite:
integrate-atlas-chat
must already be set up —
useAtlasChat
must be wired and
@cognite/dune-industrial-components
,
@sinclair/typebox
,
ajv
,
ajv-formats
must be installed.

为该Dune应用添加结构化的任务追踪功能。Agent将使用
TodoWrite
工具在处理多步骤查询时创建和更新任务列表,让用户实时了解Agent正在执行的操作及其原因。
前置条件:必须已完成
integrate-atlas-chat
的设置——必须已连接
useAtlasChat
,且已安装
@cognite/dune-industrial-components
@sinclair/typebox
ajv
ajv-formats

Step 1 — Read the app

步骤1 — 读取应用

Before writing anything, read:
  • package.json
    — confirm
    @tabler/icons-react
    is installed; if not, install it with the app's package manager
  • src/App.tsx
    — find where to add
    TodoProvider
  • The file that calls
    useAtlasChat
    (likely
    src/chat/useChatViewModel.ts
    or
    src/App.tsx
    ) — this is where the tool gets wired
  • The chat view component that renders messages — this is where
    TodoPanel
    and
    TodoToolResultCard
    go

在编写任何内容之前,请阅读:
  • package.json
    — 确认已安装
    @tabler/icons-react
    ;如果未安装,请使用应用的包管理器进行安装
  • src/App.tsx
    — 找到添加
    TodoProvider
    的位置
  • 调用
    useAtlasChat
    的文件(通常是
    src/chat/useChatViewModel.ts
    src/App.tsx
    )—— 这是连接工具的位置
  • 渲染消息的聊天视图组件—— 这是放置
    TodoPanel
    TodoToolResultCard
    的位置

Step 2 — Create the
src/todo/
module

步骤2 — 创建
src/todo/
模块

Find the skill directory by running
find . -path "*/.agents/skills/integrate-todo-list/code" -type d
from the project root.
Read each file from
<skill-dir>/code/
and write it into
src/todo/
with the same filename:
FilePurpose
types.ts
TodoItem
and
TodoList
types
TodoContext.tsx
React context +
TodoProvider
useTodoList.ts
Hook to read/write the todo list
todoWriteTool.ts
createTodoWriteTool
factory —
AtlasTool
with full CDF task-decomposition guidance
useTodoWriteTool.ts
Hook that memoizes the tool with current state access
TodoPanel.tsx
Card UI: progress bar + task rows
TodoItemRow.tsx
Single row with animated status icons
TodoToolResultCard.tsx
Compact summary card for tool call display
All files use relative imports (
./types
,
./TodoContext
, etc.) — no changes needed.

在项目根目录运行
find . -path "*/.agents/skills/integrate-todo-list/code" -type d
命令,找到技能目录。
读取
<skill-dir>/code/
中的每个文件,并将其写入
src/todo/
目录,保持文件名不变:
文件用途
types.ts
TodoItem
TodoList
类型定义
TodoContext.tsx
React上下文 +
TodoProvider
useTodoList.ts
用于读写待办事项列表的Hook
todoWriteTool.ts
createTodoWriteTool
工厂方法——带有完整CDF任务分解指引的
AtlasTool
useTodoWriteTool.ts
用于缓存工具并访问当前状态的Hook
TodoPanel.tsx
卡片UI:进度条 + 任务行
TodoItemRow.tsx
带有动画状态图标的单行组件
TodoToolResultCard.tsx
用于显示工具调用的紧凑摘要卡片
所有文件均使用相对导入(
./types
./TodoContext
等)——无需修改。

Step 3 — Wrap the app in
TodoProvider

步骤3 — 用
TodoProvider
包裹应用

In
src/App.tsx
(or the root component), wrap the existing tree with
<TodoProvider>
:
tsx
import { TodoProvider } from './todo/TodoContext'; // adjust path to match app conventions

function App() {
  return (
    <TodoProvider>
      {/* existing children */}
    </TodoProvider>
  );
}

src/App.tsx
(或根组件)中,用
<TodoProvider>
包裹现有组件树:
tsx
import { TodoProvider } from './todo/TodoContext'; // 根据应用约定调整路径

function App() {
  return (
    <TodoProvider>
      {/* 现有子组件 */}
    </TodoProvider>
  );
}

Step 4 — Wire the tool into
useAtlasChat

步骤4 — 将工具连接到
useAtlasChat

In the file that calls
useAtlasChat
, add the following. Adjust import paths to match the app's conventions.
ts
import { useRef, useCallback } from 'react';
import { useTodoList } from './todo/useTodoList';
import { useTodoWriteTool } from './todo/useTodoWriteTool';

// Inside the hook/component:
const { todos, setTodos } = useTodoList();
const todoWriteTool = useTodoWriteTool();

// Keep a ref so getAppContext always reads fresh state without re-creating the callback.
const todosRef = useRef(todos);
todosRef.current = todos;

const getAppContext = useCallback(() => {
  const t = todosRef.current;
  if (t.length === 0) return undefined;
  const lines = t.map((item, i) => `${i + 1}. [${item.status}] ${item.content}`);
  return `Current todo list:\n${lines.join('\n')}`;
}, []);

// Add to useAtlasChat options:
const { messages, send, isStreaming, progress, error, reset, abort } = useAtlasChat({
  client: isLoading ? null : sdk,
  agentExternalId: AGENT_EXTERNAL_ID,
  tools: [todoWriteTool],   // add alongside any existing tools
  getAppContext,
});

// In the reset handler, clear the todo list:
const handleReset = useCallback(() => {
  reset();
  setTodos([]);
}, [reset, setTodos]);

// Expose todos in the return value so the view can render TodoPanel:
return { ..., todos };

在调用
useAtlasChat
的文件中,添加以下代码。根据应用约定调整导入路径。
ts
import { useRef, useCallback } from 'react';
import { useTodoList } from './todo/useTodoList';
import { useTodoWriteTool } from './todo/useTodoWriteTool';

// 在Hook/组件内部:
const { todos, setTodos } = useTodoList();
const todoWriteTool = useTodoWriteTool();

// 使用ref确保getAppContext始终读取最新状态,而无需重新创建回调。
const todosRef = useRef(todos);
todosRef.current = todos;

const getAppContext = useCallback(() => {
  const t = todosRef.current;
  if (t.length === 0) return undefined;
  const lines = t.map((item, i) => `${i + 1}. [${item.status}] ${item.content}`);
  return `Current todo list:\n${lines.join('\n')}`;
}, []);

// 添加到useAtlasChat选项中:
const { messages, send, isStreaming, progress, error, reset, abort } = useAtlasChat({
  client: isLoading ? null : sdk,
  agentExternalId: AGENT_EXTERNAL_ID,
  tools: [todoWriteTool],   // 与现有工具一起添加
  getAppContext,
});

// 在重置处理函数中,清空待办事项列表:
const handleReset = useCallback(() => {
  reset();
  setTodos([]);
}, [reset, setTodos]);

// 在返回值中暴露todos,以便视图可以渲染TodoPanel:
return { ..., todos };

Step 5 — Render
TodoPanel
in the chat view

步骤5 — 在聊天视图中渲染
TodoPanel

In the component that renders the chat input area, add
<TodoPanel>
above the input field:
tsx
import { TodoPanel } from './todo/TodoPanel'; // adjust path

// In the render:
<TodoPanel todos={todos} />
<YourChatInput ... />
TodoPanel
returns
null
when the list is empty, so it's safe to always render it.

在渲染聊天输入区域的组件中,在输入字段上方添加
<TodoPanel>
tsx
import { TodoPanel } from './todo/TodoPanel'; // 调整路径

// 在渲染部分:
<TodoPanel todos={todos} />
<YourChatInput ... />
当列表为空时,
TodoPanel
会返回
null
,因此可以安全地始终渲染它。

Step 6 — Render
TodoToolResultCard
for tool call steps

步骤6 — 为工具调用步骤渲染
TodoToolResultCard

In the component that renders per-message tool calls (typically a steps accordion or similar), branch on the tool name:
tsx
import { TodoToolResultCard } from './todo/TodoToolResultCard'; // adjust path

{toolCalls.map((tc, i) =>
  tc.name === 'TodoWrite' ? (
    <TodoToolResultCard key={i} toolCall={tc} />
  ) : (
    <YourDefaultToolCallCard key={i} toolCall={tc} />
  )
)}

在渲染每条消息的工具调用的组件中(通常是步骤折叠面板或类似组件),根据工具名称进行分支处理:
tsx
import { TodoToolResultCard } from './todo/TodoToolResultCard'; // 调整路径

{toolCalls.map((tc, i) =>
  tc.name === 'TodoWrite' ? (
    <TodoToolResultCard key={i} toolCall={tc} />
  ) : (
    <YourDefaultToolCallCard key={i} toolCall={tc} />
  )
)}

Step 7 — Verify

步骤7 — 验证

Run the app's type-check command (typically
pnpm tsc --noEmit
) and confirm there are no errors. If the project has tests, run them to confirm nothing regressed.

运行应用的类型检查命令(通常是
pnpm tsc --noEmit
),确认没有错误。如果项目有测试,请运行测试以确保没有回归问题。

Done

完成

The agent can now use
TodoWrite
to create and track tasks. It will:
  • Show a task panel as soon as it starts multi-step work
  • Update task status in real-time (
    pending
    in_progress
    completed
    )
  • Clear the list automatically when all tasks are done
  • Inject the current task list into each prompt via
    getAppContext
    so it knows where it left off
现在Agent可以使用
TodoWrite
来创建和跟踪任务。它将:
  • 一旦开始多步骤工作,就显示任务面板
  • 实时更新任务状态(
    pending
    in_progress
    completed
  • 当所有任务完成时自动清空列表
  • 通过
    getAppContext
    将当前任务列表注入每个提示,以便Agent知道自己的进度