Download src/Task.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 3.15 kB
-
https://huggingface.co/chenbhao/codev/resolve/main/src/Task.ts
- Command line
-
hf download hf://chenbhao/codev/src/Task.ts
-
curl -L -o Task.ts https://huggingface.co/chenbhao/codev/resolve/main/src/Task.ts
3.15 kB
| import { randomBytes } from 'crypto' | |
| import type { AppState } from './state/AppState.js' | |
| import type { AgentId } from './types/ids.js' | |
| import { getTaskOutputPath } from './utils/task/diskOutput.js' | |
| export type TaskType = | |
| | 'local_bash' | |
| | 'local_agent' | |
| | 'remote_agent' | |
| | 'in_process_teammate' | |
| | 'local_workflow' | |
| | 'monitor_mcp' | |
| | 'dream' | |
| export type TaskStatus = | |
| | 'pending' | |
| | 'running' | |
| | 'completed' | |
| | 'failed' | |
| | 'killed' | |
| /** | |
| * True when a task is in a terminal state and will not transition further. | |
| * Used to guard against injecting messages into dead teammates, evicting | |
| * finished tasks from AppState, and orphan-cleanup paths. | |
| */ | |
| export function isTerminalTaskStatus(status: TaskStatus): boolean { | |
| return status === 'completed' || status === 'failed' || status === 'killed' | |
| } | |
| export type TaskHandle = { | |
| taskId: string | |
| cleanup?: () => void | |
| } | |
| export type SetAppState = (f: (prev: AppState) => AppState) => void | |
| export type TaskContext = { | |
| abortController: AbortController | |
| getAppState: () => AppState | |
| setAppState: SetAppState | |
| } | |
| // Base fields shared by all task states | |
| export type TaskStateBase = { | |
| id: string | |
| type: TaskType | |
| status: TaskStatus | |
| description: string | |
| toolUseId?: string | |
| startTime: number | |
| endTime?: number | |
| totalPausedMs?: number | |
| outputFile: string | |
| outputOffset: number | |
| notified: boolean | |
| } | |
| export type LocalShellSpawnInput = { | |
| command: string | |
| description: string | |
| timeout?: number | |
| toolUseId?: string | |
| agentId?: AgentId | |
| /** UI display variant: description-as-label, dialog title, status bar pill. */ | |
| kind?: 'bash' | 'monitor' | |
| } | |
| // What getTaskByType dispatches for: kill. spawn/render were never | |
| // called polymorphically (removed in #22546). All six kill implementations | |
| // use only setAppState — getAppState/abortController were dead weight. | |
| export type Task = { | |
| name: string | |
| type: TaskType | |
| kill(taskId: string, setAppState: SetAppState): Promise<void> | |
| } | |
| // Task ID prefixes | |
| const TASK_ID_PREFIXES: Record<string, string> = { | |
| local_bash: 'b', // Keep as 'b' for backward compatibility | |
| local_agent: 'a', | |
| remote_agent: 'r', | |
| in_process_teammate: 't', | |
| local_workflow: 'w', | |
| monitor_mcp: 'm', | |
| dream: 'd', | |
| } | |
| // Get task ID prefix | |
| function getTaskIdPrefix(type: TaskType): string { | |
| return TASK_ID_PREFIXES[type] ?? 'x' | |
| } | |
| // Case-insensitive-safe alphabet (digits + lowercase) for task IDs. | |
| // 36^8 ≈ 2.8 trillion combinations, sufficient to resist brute-force symlink attacks. | |
| const TASK_ID_ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz' | |
| export function generateTaskId(type: TaskType): string { | |
| const prefix = getTaskIdPrefix(type) | |
| const bytes = randomBytes(8) | |
| let id = prefix | |
| for (let i = 0; i < 8; i++) { | |
| id += TASK_ID_ALPHABET[bytes[i]! % TASK_ID_ALPHABET.length] | |
| } | |
| return id | |
| } | |
| export function createTaskStateBase( | |
| id: string, | |
| type: TaskType, | |
| description: string, | |
| toolUseId?: string, | |
| ): TaskStateBase { | |
| return { | |
| id, | |
| type, | |
| status: 'pending', | |
| description, | |
| toolUseId, | |
| startTime: Date.now(), | |
| outputFile: getTaskOutputPath(id), | |
| outputOffset: 0, | |
| notified: false, | |
| } | |
| } | |