{"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../../src/core/tools/task-tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAoD,KAAK,IAAI,EAAmB,MAAM,cAAc,CAAC;AAG5G,YAAY,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC,6BAA6B;AAC7B,QAAA,MAAM,gBAAgB;;;;;EASpB,CAAC;AAEH,2BAA2B;AAC3B,QAAA,MAAM,cAAc,yCAAkB,CAAC;AAEvC,0BAA0B;AAC1B,QAAA,MAAM,aAAa;;EAEjB,CAAC;AAEH,6BAA6B;AAC7B,QAAA,MAAM,gBAAgB;;;;;;;EAepB,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAChE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAC9D,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAMpE,yDAAyD;AACzD,KAAK,gBAAgB,GAAG,MAAM,IAAI,EAAE,CAAC;AACrC,gEAAgE;AAChE,KAAK,gBAAgB,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAEhD;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,gBAAgB,GACzB,SAAS,CAAC,OAAO,gBAAgB,CAAC,CAuCpC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,gBAAgB,GACzB,SAAS,CAAC,OAAO,cAAc,CAAC,CAelC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,gBAAgB,GACzB,SAAS,CAAC,OAAO,aAAa,CAAC,CA+BjC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,gBAAgB,GACxB,SAAS,CAAC,OAAO,gBAAgB,CAAC,CAkDpC","sourcesContent":["import type { AgentTool } from \"@apholdings/jensen-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { formatTaskDetail, formatTaskList, generateTaskId, type Task, type TaskStatus } from \"../memory.js\";\n\n// Re-export Task for consumers of this module (e.g., agent-session.ts)\nexport type { Task } from \"../memory.js\";\n\n// ============================================================================\n// Tool Schemas\n// ============================================================================\n\n/** Schema for task_create */\nconst taskCreateSchema = Type.Object({\n\tsubject: Type.String({ description: \"Brief title/subject of the task (required)\" }),\n\tdescription: Type.String({ description: \"Detailed description of what the task involves\" }),\n\tactiveForm: Type.Optional(\n\t\tType.String({ description: \"Active-form phrasing when task is in_progress (e.g., 'Implementing feature X')\" }),\n\t),\n\tmetadata: Type.Optional(\n\t\tType.Record(Type.String({}), Type.Unknown(), { description: \"Optional free-form metadata\" }),\n\t),\n});\n\n/** Schema for task_list */\nconst taskListSchema = Type.Object({});\n\n/** Schema for task_get */\nconst taskGetSchema = Type.Object({\n\ttaskId: Type.String({ description: \"The unique ID of the task to retrieve\" }),\n});\n\n/** Schema for task_update */\nconst taskUpdateSchema = Type.Object({\n\ttaskId: Type.String({ description: \"The unique ID of the task to update\" }),\n\tsubject: Type.Optional(Type.String({ description: \"New subject/title for the task\" })),\n\tdescription: Type.Optional(Type.String({ description: \"New description for the task\" })),\n\tstatus: Type.Optional(\n\t\tType.Union([Type.Literal(\"pending\"), Type.Literal(\"in_progress\"), Type.Literal(\"completed\")], {\n\t\t\tdescription: \"New status for the task\",\n\t\t}),\n\t),\n\tactiveForm: Type.Optional(Type.String({ description: \"New active-form phrasing for in_progress display\" })),\n\tmetadata: Type.Optional(\n\t\tType.Record(Type.String({}), Type.Unknown(), {\n\t\t\tdescription: \"Replacement metadata object (merges if not provided)\",\n\t\t}),\n\t),\n});\n\nexport type TaskCreateInputParsed = Static<typeof taskCreateSchema>;\nexport type TaskListInputParsed = Static<typeof taskListSchema>;\nexport type TaskGetInputParsed = Static<typeof taskGetSchema>;\nexport type TaskUpdateInputParsed = Static<typeof taskUpdateSchema>;\n\n// ============================================================================\n// Tool Factories\n// ============================================================================\n\n/** Callback to get the current task list from session */\ntype GetTasksCallback = () => Task[];\n/** Callback to set tasks in session and trigger update event */\ntype SetTasksCallback = (tasks: Task[]) => void;\n\n/**\n * Create the task_create tool.\n */\nexport function createTaskCreateTool(\n\tgetTasks: GetTasksCallback,\n\t_setTasks: SetTasksCallback,\n): AgentTool<typeof taskCreateSchema> {\n\treturn {\n\t\tname: \"task_create\",\n\t\tlabel: \"task_create\",\n\t\tdescription:\n\t\t\t\"Create a structured task for multi-step work tracking. Use when work is multi-step, should be tracked explicitly, or spans multiple sessions.\",\n\t\tparameters: taskCreateSchema,\n\t\texecute: async (_toolCallId: string, params: TaskCreateInputParsed) => {\n\t\t\tif (!params.subject?.trim()) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: subject is required and must be non-empty.\" }],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst newTask: Task = {\n\t\t\t\tid: generateTaskId(),\n\t\t\t\tsubject: params.subject.trim(),\n\t\t\t\tdescription: params.description?.trim() ?? \"\",\n\t\t\t\tstatus: \"pending\",\n\t\t\t\tactiveForm: params.activeForm?.trim() || undefined,\n\t\t\t\tmetadata: params.metadata,\n\t\t\t};\n\n\t\t\tconst currentTasks = getTasks();\n\t\t\tconst updatedTasks = [...currentTasks, newTask];\n\t\t\t_setTasks(updatedTasks);\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Created task \"${newTask.subject}\" [${newTask.id}] (status: pending)`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { task: { id: newTask.id, subject: newTask.subject, status: newTask.status } },\n\t\t\t};\n\t\t},\n\t};\n}\n\n/**\n * Create the task_list tool.\n */\nexport function createTaskListTool(\n\tgetTasks: GetTasksCallback,\n\t_setTasks: SetTasksCallback,\n): AgentTool<typeof taskListSchema> {\n\treturn {\n\t\tname: \"task_list\",\n\t\tlabel: \"task_list\",\n\t\tdescription: \"List all structured tasks with their current status. Returns a summary view grouped by status.\",\n\t\tparameters: taskListSchema,\n\t\texecute: async (_toolCallId: string, _params: TaskListInputParsed) => {\n\t\t\tconst tasks = getTasks();\n\t\t\tconst summary = formatTaskList(tasks);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: summary }],\n\t\t\t\tdetails: { tasks: tasks.map((t) => ({ id: t.id, subject: t.subject, status: t.status })) },\n\t\t\t};\n\t\t},\n\t};\n}\n\n/**\n * Create the task_get tool.\n */\nexport function createTaskGetTool(\n\tgetTasks: GetTasksCallback,\n\t_setTasks: SetTasksCallback,\n): AgentTool<typeof taskGetSchema> {\n\treturn {\n\t\tname: \"task_get\",\n\t\tlabel: \"task_get\",\n\t\tdescription:\n\t\t\t\"Retrieve full details of a specific task by its ID. Returns subject, description, status, activeForm, and metadata.\",\n\t\tparameters: taskGetSchema,\n\t\texecute: async (_toolCallId: string, params: TaskGetInputParsed) => {\n\t\t\tif (!params.taskId?.trim()) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: taskId is required.\" }],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst tasks = getTasks();\n\t\t\tconst task = tasks.find((t) => t.id === params.taskId.trim());\n\n\t\t\tif (!task) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Task not found: ${params.taskId}` }],\n\t\t\t\t\tdetails: { task: null },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: formatTaskDetail(task) }],\n\t\t\t\tdetails: { task },\n\t\t\t};\n\t\t},\n\t};\n}\n\n/**\n * Create the task_update tool.\n */\nexport function createTaskUpdateTool(\n\tgetTasks: GetTasksCallback,\n\tsetTasks: SetTasksCallback,\n): AgentTool<typeof taskUpdateSchema> {\n\treturn {\n\t\tname: \"task_update\",\n\t\tlabel: \"task_update\",\n\t\tdescription:\n\t\t\t\"Update one or more fields of an existing task. Update status as work progresses or completes. Use task_get first if you need the current state before updating.\",\n\t\tparameters: taskUpdateSchema,\n\t\texecute: async (_toolCallId: string, params: TaskUpdateInputParsed) => {\n\t\t\tif (!params.taskId?.trim()) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Error: taskId is required.\" }],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst tasks = getTasks();\n\t\t\tconst index = tasks.findIndex((t) => t.id === params.taskId.trim());\n\n\t\t\tif (index === -1) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Task not found: ${params.taskId}` }],\n\t\t\t\t\tdetails: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst existing = tasks[index];\n\t\t\tconst updated: Task = {\n\t\t\t\t...existing,\n\t\t\t\t...(params.subject !== undefined ? { subject: params.subject.trim() } : {}),\n\t\t\t\t...(params.description !== undefined ? { description: params.description.trim() } : {}),\n\t\t\t\t...(params.status !== undefined ? { status: params.status as TaskStatus } : {}),\n\t\t\t\t...(params.activeForm !== undefined ? { activeForm: params.activeForm.trim() || undefined } : {}),\n\t\t\t\t...(params.metadata !== undefined ? { metadata: params.metadata } : {}),\n\t\t\t};\n\n\t\t\tconst updatedTasks = [...tasks];\n\t\t\tupdatedTasks[index] = updated;\n\t\t\tsetTasks(updatedTasks);\n\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Updated task \"${updated.subject}\" [${updated.id}] (status: ${updated.status})`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { task: { id: updated.id, subject: updated.subject, status: updated.status } },\n\t\t\t};\n\t\t},\n\t};\n}\n"]}