mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-24 13:01:29 -07:00
feat: add 'blocked' status to tasks and todos (#22735)
This commit is contained in:
@@ -13,7 +13,8 @@ updates to the CLI interface.
|
||||
- `todos` (array of objects, required): The complete list of tasks. Each object
|
||||
includes:
|
||||
- `description` (string): Technical description of the task.
|
||||
- `status` (enum): `pending`, `in_progress`, `completed`, or `cancelled`.
|
||||
- `status` (enum): `pending`, `in_progress`, `completed`, `cancelled`, or
|
||||
`blocked`.
|
||||
|
||||
## Technical behavior
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ describe('<ChecklistItem />', () => {
|
||||
{ status: 'in_progress', label: 'Doing this' },
|
||||
{ status: 'completed', label: 'Done this' },
|
||||
{ status: 'cancelled', label: 'Skipped this' },
|
||||
{ status: 'blocked', label: 'Blocked this' },
|
||||
] as ChecklistItemData[])('renders %s item correctly', async (item) => {
|
||||
const { lastFrame, waitUntilReady } = render(<ChecklistItem item={item} />);
|
||||
await waitUntilReady();
|
||||
|
||||
@@ -13,7 +13,8 @@ export type ChecklistStatus =
|
||||
| 'pending'
|
||||
| 'in_progress'
|
||||
| 'completed'
|
||||
| 'cancelled';
|
||||
| 'cancelled'
|
||||
| 'blocked';
|
||||
|
||||
export interface ChecklistItemData {
|
||||
status: ChecklistStatus;
|
||||
@@ -48,6 +49,12 @@ const ChecklistStatusDisplay: React.FC<{ status: ChecklistStatus }> = ({
|
||||
✗
|
||||
</Text>
|
||||
);
|
||||
case 'blocked':
|
||||
return (
|
||||
<Text color={theme.status.warning} aria-label="Blocked">
|
||||
⛔
|
||||
</Text>
|
||||
);
|
||||
default:
|
||||
checkExhaustive(status);
|
||||
}
|
||||
@@ -70,6 +77,7 @@ export const ChecklistItem: React.FC<ChecklistItemProps> = ({
|
||||
return theme.text.accent;
|
||||
case 'completed':
|
||||
case 'cancelled':
|
||||
case 'blocked':
|
||||
return theme.text.secondary;
|
||||
case 'pending':
|
||||
return theme.text.primary;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<ChecklistItem /> > renders { status: 'blocked', label: 'Blocked this' } item correctly 1`] = `
|
||||
"⛔ Blocked this
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ChecklistItem /> > renders { status: 'cancelled', label: 'Skipped this' } item correctly 1`] = `
|
||||
"✗ Skipped this
|
||||
"
|
||||
|
||||
@@ -22,6 +22,7 @@ export const TASK_TYPE_LABELS: Record<TaskType, string> = {
|
||||
export enum TaskStatus {
|
||||
OPEN = 'open',
|
||||
IN_PROGRESS = 'in_progress',
|
||||
BLOCKED = 'blocked',
|
||||
CLOSED = 'closed',
|
||||
}
|
||||
export const TaskStatusSchema = z.nativeEnum(TaskStatus);
|
||||
|
||||
@@ -697,6 +697,7 @@ DO NOT use this tool for simple tasks that can be completed in less than 2 steps
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
- blocked: Subtask is blocked and cannot be completed at this time.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
@@ -766,6 +767,7 @@ The agent did not use the todo list because this task could be completed by a ti
|
||||
"in_progress",
|
||||
"completed",
|
||||
"cancelled",
|
||||
"blocked",
|
||||
],
|
||||
"type": "string",
|
||||
},
|
||||
@@ -1451,6 +1453,7 @@ DO NOT use this tool for simple tasks that can be completed in less than 2 steps
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
- blocked: Subtask is blocked and cannot be completed at this time.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
@@ -1520,6 +1523,7 @@ The agent did not use the todo list because this task could be completed by a ti
|
||||
"in_progress",
|
||||
"completed",
|
||||
"cancelled",
|
||||
"blocked",
|
||||
],
|
||||
"type": "string",
|
||||
},
|
||||
|
||||
@@ -543,6 +543,7 @@ DO NOT use this tool for simple tasks that can be completed in less than 2 steps
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
- blocked: Subtask is blocked and cannot be completed at this time.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
@@ -609,7 +610,13 @@ The agent did not use the todo list because this task could be completed by a ti
|
||||
[TODOS_ITEM_PARAM_STATUS]: {
|
||||
type: 'string',
|
||||
description: 'The current status of the task.',
|
||||
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
||||
enum: [
|
||||
'pending',
|
||||
'in_progress',
|
||||
'completed',
|
||||
'cancelled',
|
||||
'blocked',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: [TODOS_ITEM_PARAM_DESCRIPTION, TODOS_ITEM_PARAM_STATUS],
|
||||
|
||||
@@ -518,6 +518,7 @@ DO NOT use this tool for simple tasks that can be completed in less than 2 steps
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
- blocked: Subtask is blocked and cannot be completed at this time.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
@@ -584,7 +585,13 @@ The agent did not use the todo list because this task could be completed by a ti
|
||||
[TODOS_ITEM_PARAM_STATUS]: {
|
||||
type: 'string',
|
||||
description: 'The current status of the task.',
|
||||
enum: ['pending', 'in_progress', 'completed', 'cancelled'],
|
||||
enum: [
|
||||
'pending',
|
||||
'in_progress',
|
||||
'completed',
|
||||
'cancelled',
|
||||
'blocked',
|
||||
],
|
||||
},
|
||||
},
|
||||
required: [TODOS_ITEM_PARAM_DESCRIPTION, TODOS_ITEM_PARAM_STATUS],
|
||||
|
||||
@@ -823,7 +823,12 @@ export type ToolResultDisplay =
|
||||
| TodoList
|
||||
| SubagentProgress;
|
||||
|
||||
export type TodoStatus = 'pending' | 'in_progress' | 'completed' | 'cancelled';
|
||||
export type TodoStatus =
|
||||
| 'pending'
|
||||
| 'in_progress'
|
||||
| 'completed'
|
||||
| 'cancelled'
|
||||
| 'blocked';
|
||||
|
||||
export interface Todo {
|
||||
description: string;
|
||||
|
||||
@@ -222,15 +222,23 @@ describe('Tracker Tools Integration', () => {
|
||||
status: TaskStatus.IN_PROGRESS,
|
||||
dependencies: [],
|
||||
};
|
||||
const t4 = {
|
||||
id: 't4',
|
||||
title: 'T4',
|
||||
type: TaskType.TASK,
|
||||
status: TaskStatus.BLOCKED,
|
||||
dependencies: [],
|
||||
};
|
||||
|
||||
const mockService = {
|
||||
listTasks: async () => [t1, t2, t3],
|
||||
listTasks: async () => [t1, t2, t3, t4],
|
||||
} as unknown as TrackerService;
|
||||
const display = await buildTodosReturnDisplay(mockService);
|
||||
|
||||
expect(display.todos).toEqual([
|
||||
{ description: `task: T3 (t3)`, status: 'in_progress' },
|
||||
{ description: `task: T2 (t2)`, status: 'pending' },
|
||||
{ description: `task: T4 (t4)`, status: 'blocked' },
|
||||
{ description: `task: T1 (t1)`, status: 'completed' },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -48,10 +48,11 @@ export async function buildTodosReturnDisplay(
|
||||
}
|
||||
}
|
||||
|
||||
const statusOrder = {
|
||||
const statusOrder: Record<TaskStatus, number> = {
|
||||
[TaskStatus.IN_PROGRESS]: 0,
|
||||
[TaskStatus.OPEN]: 1,
|
||||
[TaskStatus.CLOSED]: 2,
|
||||
[TaskStatus.BLOCKED]: 2,
|
||||
[TaskStatus.CLOSED]: 3,
|
||||
};
|
||||
|
||||
const sortTasks = (a: TrackerTask, b: TrackerTask) => {
|
||||
@@ -80,6 +81,8 @@ export async function buildTodosReturnDisplay(
|
||||
status = 'in_progress';
|
||||
} else if (task.status === TaskStatus.CLOSED) {
|
||||
status = 'completed';
|
||||
} else if (task.status === TaskStatus.BLOCKED) {
|
||||
status = 'blocked';
|
||||
}
|
||||
|
||||
const indent = ' '.repeat(depth);
|
||||
@@ -585,6 +588,7 @@ class TrackerVisualizeInvocation extends BaseToolInvocation<
|
||||
const statusEmojis: Record<TaskStatus, string> = {
|
||||
open: '⭕',
|
||||
in_progress: '🚧',
|
||||
blocked: '⛔',
|
||||
closed: '✅',
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ describe('WriteTodosTool', () => {
|
||||
{ description: 'Task 1', status: 'pending' },
|
||||
{ description: 'Task 2', status: 'in_progress' },
|
||||
{ description: 'Task 3', status: 'completed' },
|
||||
{ description: 'Task 4', status: 'blocked' },
|
||||
],
|
||||
};
|
||||
await expect(tool.buildAndExecute(params, signal)).resolves.toBeDefined();
|
||||
@@ -96,13 +97,15 @@ describe('WriteTodosTool', () => {
|
||||
{ description: 'First task', status: 'completed' },
|
||||
{ description: 'Second task', status: 'in_progress' },
|
||||
{ description: 'Third task', status: 'pending' },
|
||||
{ description: 'Fourth task', status: 'blocked' },
|
||||
],
|
||||
};
|
||||
const result = await tool.buildAndExecute(params, signal);
|
||||
const expectedOutput = `Successfully updated the todo list. The current list is now:
|
||||
1. [completed] First task
|
||||
2. [in_progress] Second task
|
||||
3. [pending] Third task`;
|
||||
3. [pending] Third task
|
||||
4. [blocked] Fourth task`;
|
||||
expect(result.llmContent).toBe(expectedOutput);
|
||||
expect(result.returnDisplay).toEqual(params);
|
||||
});
|
||||
|
||||
@@ -22,6 +22,7 @@ const TODO_STATUSES = [
|
||||
'in_progress',
|
||||
'completed',
|
||||
'cancelled',
|
||||
'blocked',
|
||||
] as const;
|
||||
|
||||
export interface WriteTodosToolParams {
|
||||
|
||||
Reference in New Issue
Block a user