todo-agent 0.2.9__py3-none-any.whl → 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ Subprocess wrapper for todo.sh operations.
4
4
 
5
5
  import os
6
6
  import subprocess # nosec B404
7
- from typing import Any, List, Optional
7
+ from typing import Any, List, Optional, TypedDict
8
8
 
9
9
  try:
10
10
  from todo_agent.core.exceptions import TodoShellError
@@ -12,6 +12,18 @@ except ImportError:
12
12
  from core.exceptions import TodoShellError # type: ignore[no-redef]
13
13
 
14
14
 
15
+ class TaskComponents(TypedDict):
16
+ """Type definition for task components."""
17
+
18
+ priority: str | None
19
+ description: str
20
+ projects: list[str]
21
+ contexts: list[str]
22
+ due: str | None
23
+ recurring: str | None
24
+ other_tags: list[str]
25
+
26
+
15
27
  class TodoShell:
16
28
  """Subprocess execution wrapper with error management."""
17
29
 
@@ -243,19 +255,19 @@ class TodoShell:
243
255
  def _extract_task_number(self, line: str) -> Optional[int]:
244
256
  """
245
257
  Extract task number from a line that may contain ANSI color codes.
246
-
258
+
247
259
  Args:
248
260
  line: Task line that may contain ANSI color codes
249
-
261
+
250
262
  Returns:
251
263
  Task number if found, None otherwise
252
264
  """
253
265
  from rich.text import Text
254
-
266
+
255
267
  # Use rich to properly handle ANSI color codes
256
268
  text = Text.from_ansi(line)
257
269
  clean_line = text.plain
258
-
270
+
259
271
  # Split on first space and check if first part is a number
260
272
  parts = clean_line.split(" ", 1)
261
273
  if parts and parts[0].isdigit():
@@ -319,7 +331,8 @@ class TodoShell:
319
331
  # Remove the project if it exists (with or without + prefix)
320
332
  project_to_remove = f"+{clean_project}"
321
333
  components["projects"] = [
322
- p for p in components["projects"]
334
+ p
335
+ for p in components["projects"]
323
336
  if p != project_to_remove and p != clean_project
324
337
  ]
325
338
  else:
@@ -345,7 +358,7 @@ class TodoShell:
345
358
  # Replace the task with the new description
346
359
  return self.replace(task_number, new_description)
347
360
 
348
- def _parse_task_components(self, task_line: str) -> dict:
361
+ def _parse_task_components(self, task_line: str) -> TaskComponents:
349
362
  """
350
363
  Parse a todo.txt task line into its components.
351
364
 
@@ -357,9 +370,10 @@ class TodoShell:
357
370
  """
358
371
  # Remove ANSI color codes first using rich
359
372
  from rich.text import Text
373
+
360
374
  text = Text.from_ansi(task_line)
361
375
  task_line = text.plain
362
-
376
+
363
377
  # Remove task number prefix if present (e.g., "1 " or "1. ")
364
378
  # First try the format without dot (standard todo.sh format)
365
379
  if " " in task_line and task_line.split(" ")[0].isdigit():
@@ -368,7 +382,7 @@ class TodoShell:
368
382
  elif ". " in task_line:
369
383
  task_line = task_line.split(". ", 1)[1]
370
384
 
371
- components = {
385
+ components: TaskComponents = {
372
386
  "priority": None,
373
387
  "description": "",
374
388
  "projects": [],
@@ -430,13 +444,13 @@ class TodoShell:
430
444
  components["description"] = word
431
445
 
432
446
  # Convert sets back to sorted lists for consistent ordering
433
- components["projects"] = sorted(list(projects_set))
434
- components["contexts"] = sorted(list(contexts_set))
435
- components["other_tags"] = sorted(list(other_tags_set))
447
+ components["projects"] = sorted(projects_set)
448
+ components["contexts"] = sorted(contexts_set)
449
+ components["other_tags"] = sorted(other_tags_set)
436
450
 
437
451
  return components
438
452
 
439
- def _reconstruct_task(self, components: dict) -> str:
453
+ def _reconstruct_task(self, components: TaskComponents) -> str:
440
454
  """
441
455
  Reconstruct a task description from parsed components.
442
456
 
@@ -244,10 +244,10 @@ class CLI:
244
244
  # Format the response and create a panel
245
245
  formatted_response = ResponseFormatter.format_response(response)
246
246
 
247
- # Get memory usage
247
+ # Get memory usage
248
248
  # DISABLED FOR NOW
249
249
  # memory_usage = self._get_memory_usage()
250
- memory_usage = None
250
+ memory_usage = None
251
251
 
252
252
  # Create response panel with memory usage
253
253
  response_panel = PanelFormatter.create_response_panel(
@@ -6,8 +6,8 @@ AVAILABLE TOOLS:
6
6
  Discovery Tools (Call FIRST):
7
7
  - list_projects() - Get all available projects from todo.txt
8
8
  - list_contexts() - Get all available contexts from todo.txt
9
- - list_tasks(filter?) - List current tasks with optional filtering
10
- - list_completed_tasks(filter?, project?, context?, text_search?, date_from?, date_to?) - List completed tasks with optional filtering
9
+ - list_tasks() - List all current tasks from todo.txt
10
+ - list_completed_tasks() - List all completed tasks from done.txt
11
11
 
12
12
  Task Management Tools:
13
13
  - add_task(description, priority?, project?, context?, due?, recurring?) - Add new task to todo.txt
@@ -89,34 +89,18 @@ class ToolCallHandler:
89
89
  "function": {
90
90
  "name": "list_tasks",
91
91
  "description": (
92
- "List current tasks with optional filtering. Use this when: "
92
+ "List all current tasks from todo.txt. Use this when: "
93
93
  "1) User wants to see their tasks, "
94
- "2) You need to find a specific task by description, "
95
- "3) You need to check for potential duplicates before adding new tasks, "
96
- "4) You need to understand the current state before making changes, "
97
- "5) User says they finished/completed a task and you need to find the matching task. "
94
+ "2) You need to check for potential duplicates before adding new tasks, "
95
+ "3) You need to understand the current state before making changes, "
96
+ "4) User says they finished/completed a task and you need to find the matching task. "
98
97
  "CRITICAL: ALWAYS use this before add_task() to check for similar existing tasks. "
99
98
  "CRITICAL: ALWAYS use this when user mentions task completion to find the correct task number. "
100
- "COMPLETION INTELLIGENCE: When searching for completion matches, if exactly one task clearly "
101
- "matches the user's description, proceed to complete it immediately without asking for confirmation. "
102
- "IMPORTANT: When presenting the results to the user, convert the raw todo.txt format "
103
- "into conversational language. Do not show the raw format like '(A) task +project @context'. "
104
99
  "STRATEGIC CONTEXT: This is the primary discovery tool - call this FIRST when you need to "
105
- "understand existing tasks before making any modifications."
100
+ "understand existing tasks before making any modifications. Always get the complete task list "
101
+ "for full context rather than trying to filter."
106
102
  ),
107
- "parameters": {
108
- "type": "object",
109
- "properties": {
110
- "filter": {
111
- "type": "string",
112
- "description": (
113
- "Optional filter string (e.g., '+work', '@office', '(A)') - "
114
- "use when you want to see only specific tasks or when searching for completion matches"
115
- ),
116
- }
117
- },
118
- "required": [],
119
- },
103
+ "parameters": {"type": "object", "properties": {}, "required": []},
120
104
  },
121
105
  },
122
106
  {
@@ -124,72 +108,17 @@ class ToolCallHandler:
124
108
  "function": {
125
109
  "name": "list_completed_tasks",
126
110
  "description": (
127
- "List completed tasks from done.txt with optional filtering. Use this when: "
111
+ "List all completed tasks from done.txt. Use this when: "
128
112
  "1) User tries to complete a task that might already be done, "
129
113
  "2) User asks about completed tasks, "
130
114
  "3) You need to verify task status before taking action, "
131
- "4) User wants to search for specific completed tasks by project, context, text, or date. "
115
+ "4) User wants to see their task completion history. "
132
116
  "STRATEGIC CONTEXT: Call this BEFORE complete_task() to verify the task hasn't already "
133
117
  "been completed, preventing duplicate completion attempts. "
134
- "FILTERING: Use the filtering parameters to help users find specific completed tasks "
135
- "when they ask about work tasks, home tasks, tasks from a specific date, etc. "
136
- "DATE FILTERING LIMITATIONS: Due to todo.sh constraints, date filtering has specific behavior: "
137
- "• When both date_from and date_to are provided, filtering uses the year-month pattern (YYYY-MM) "
138
- "from date_from, matching all tasks in that month. "
139
- "• When only date_from is provided, filtering uses the exact date pattern (YYYY-MM-DD). "
140
- "• When only date_to is provided, filtering uses the year-month pattern (YYYY-MM) from date_to. "
141
- "• Complex date ranges (e.g., spanning multiple months) are not supported by todo.sh."
118
+ "Always get the complete completed task list for full historical context rather than "
119
+ "trying to filter by specific criteria."
142
120
  ),
143
- "parameters": {
144
- "type": "object",
145
- "properties": {
146
- "filter": {
147
- "type": "string",
148
- "description": (
149
- "Optional raw filter string (e.g., '+work', '@office') - "
150
- "use for advanced filtering when other parameters aren't sufficient"
151
- ),
152
- },
153
- "project": {
154
- "type": "string",
155
- "description": (
156
- "Optional project name to filter by (without the + symbol) - "
157
- "e.g., 'work', 'home', 'bills'"
158
- ),
159
- },
160
- "context": {
161
- "type": "string",
162
- "description": (
163
- "Optional context name to filter by (without the @ symbol) - "
164
- "e.g., 'office', 'home', 'phone'"
165
- ),
166
- },
167
- "text_search": {
168
- "type": "string",
169
- "description": (
170
- "Optional text to search for in task descriptions - "
171
- "e.g., 'review', 'call', 'email'"
172
- ),
173
- },
174
- "date_from": {
175
- "type": "string",
176
- "description": (
177
- "Optional start date for filtering (YYYY-MM-DD format) - "
178
- "e.g., '2025-08-01'. When used alone, matches exact date. "
179
- "When used with date_to, uses year-month pattern (YYYY-MM) for month-based filtering."
180
- ),
181
- },
182
- "date_to": {
183
- "type": "string",
184
- "description": (
185
- "Optional end date for filtering (YYYY-MM-DD format) - "
186
- "e.g., '2025-08-31'. When used alone, uses year-month pattern (YYYY-MM) "
187
- "for month-based filtering. When used with date_from, uses date_from's year-month pattern."
188
- ),
189
- },
190
- },
191
- "required": [],
192
- },
121
+ "parameters": {"type": "object", "properties": {}, "required": []},
193
122
  },
194
123
  },
195
124
  {
@@ -197,18 +126,21 @@ class ToolCallHandler:
197
126
  "function": {
198
127
  "name": "add_task",
199
128
  "description": (
200
- "Add a new task to todo.txt. CRITICAL: Before adding ANY task, you MUST "
201
- "use list_tasks() and list_completed_tasks() to check for potential duplicates. Look for tasks with "
202
- "similar descriptions, keywords, or intent. If you find similar tasks, "
129
+ "Add a NEW task to todo.txt with intelligent automatic inference capabilities. "
130
+ "USE CASE: Call this when user wants to create a NEW task, not when they want to complete, modify, or work with existing tasks. "
131
+ "CRITICAL: Before adding ANY task, you MUST use list_tasks() and list_completed_tasks() to check for potential duplicates. "
132
+ "Look for tasks with similar descriptions, keywords, or intent. If you find similar tasks, "
203
133
  "ask the user if they want to add a new task or modify an existing one. "
204
- "AUTOMATIC INFERENCE: When project, context, or due date is not specified, automatically infer appropriate tags "
205
- "and due dates based on the task content, natural language expressions, task nature, calendar context, and existing patterns. "
206
- "DUE DATE INFERENCE: Use parse_date() tool to convert any temporal expressions to YYYY-MM-DD format. "
207
- "Extract temporal expressions and use common sense to infer appropriate due dates based on task type, "
208
- "work patterns, personal schedules, and existing task due date patterns. Only ask for clarification when genuinely ambiguous. "
209
- "Always provide a complete, natural response to the user. "
210
- "STRATEGIC CONTEXT: This is a modification tool - call this LAST after using "
211
- "discovery tools (list_tasks, list_projects, list_contexts list_completed_tasks) "
134
+ "INTELLIGENT INFERENCE ENGINE: This tool automatically infers missing elements to create complete, actionable tasks: "
135
+ "PROJECT INFERENCE: Automatically detect and add appropriate +project tags based on task keywords, semantic patterns, and existing project usage. "
136
+ "CONTEXT INFERENCE: Automatically infer @context tags from task nature, location requirements, and historical context patterns. "
137
+ "DUE DATE INFERENCE: Use parse_date() tool to convert natural language expressions ('tomorrow', 'next week', 'by Friday') to YYYY-MM-DD format. "
138
+ "Apply strategic timing based on task type, work patterns, personal schedules, and existing due date patterns. "
139
+ "DURATION INFERENCE: Automatically estimate appropriate duration: tags based on task complexity, context, and historical patterns. "
140
+ "PRIORITY INFERENCE: Suggest appropriate priority levels (A-Z) based on urgency, importance, and existing priority patterns. "
141
+ "Only ask for clarification when genuinely ambiguous. Always provide a complete, natural response to the user. "
142
+ "STRATEGIC CONTEXT: This is a CREATION tool - call this LAST after using "
143
+ "discovery tools (list_tasks, list_projects, list_contexts, list_completed_tasks) "
212
144
  "to gather all necessary context and verify no duplicates exist."
213
145
  ),
214
146
  "parameters": {
@@ -238,6 +170,10 @@ class ToolCallHandler:
238
170
  "type": "string",
239
171
  "description": "Optional recurring pattern in rec:frequency[:interval] format (e.g., 'rec:daily', 'rec:weekly:2', 'rec:monthly'). Use for tasks that repeat automatically.",
240
172
  },
173
+ "duration": {
174
+ "type": "string",
175
+ "description": "Optional duration estimate in format: minutes (e.g., '30m'), hours (e.g., '2h'), or days (e.g., '1d'). Use for time planning and task prioritization.",
176
+ },
241
177
  },
242
178
  "required": ["description"],
243
179
  },
@@ -248,14 +184,11 @@ class ToolCallHandler:
248
184
  "function": {
249
185
  "name": "complete_task",
250
186
  "description": (
251
- "Mark a specific task as complete by its line number. IMPORTANT: "
252
- "When user says they finished/completed a task, FIRST use list_tasks() to find matching tasks, "
253
- "then list_completed_tasks() to verify it's not already done. "
254
- "COMPLETION LOGIC: If user's statement clearly matches exactly one task, complete it immediately. "
255
- "If multiple tasks match, show numbered options and ask for clarification. "
256
- "If the match is ambiguous, ask for confirmation. "
257
- "STRATEGIC CONTEXT: This is a modification tool - call this LAST after using "
258
- "discovery tools (list_tasks, list_completed_tasks) to verify the task exists and status."
187
+ "Mark an existing task as complete by its line number. "
188
+ "USE CASE: Only call this when user explicitly states they have finished/completed a task. "
189
+ "WORKFLOW: 1) Use list_tasks() to find the task to complete, 2) Use list_completed_tasks() to verify it's not already done, 3) Call complete_task() with the task number. "
190
+ "NOT FOR: Adding new tasks, modifying task content, or any other task operations. "
191
+ "This tool ONLY marks existing tasks as complete."
259
192
  ),
260
193
  "parameters": {
261
194
  "type": "object",
@@ -274,8 +207,10 @@ class ToolCallHandler:
274
207
  "function": {
275
208
  "name": "replace_task",
276
209
  "description": (
277
- "Replace the entire content of a task. IMPORTANT: Use list_tasks() first "
278
- "to find the correct task number if user doesn't specify it. "
210
+ "Replace the entire content of an EXISTING task. "
211
+ "USE CASE: Call this when user wants to completely rewrite an existing task description. "
212
+ "NOT FOR: Creating new tasks, completing tasks, or adding to tasks. "
213
+ "Use list_tasks() first to find the correct task number if user doesn't specify it. "
279
214
  "If multiple tasks match the description, ask for clarification."
280
215
  ),
281
216
  "parameters": {
@@ -299,12 +234,13 @@ class ToolCallHandler:
299
234
  "function": {
300
235
  "name": "append_to_task",
301
236
  "description": (
302
- "Add text to the end of an existing task. Use this when user wants "
303
- "to add additional information to a task without replacing it entirely. "
237
+ "Add text to the end of an EXISTING task. "
238
+ "USE CASE: Call this when user wants to add additional descriptive text, notes, or comments to an existing task. "
239
+ "NOT FOR: Creating new tasks, completing tasks, or adding project/context/due date tags. "
304
240
  "CRITICAL: DO NOT use this for adding project tags (+project) or context tags (@context) - "
305
241
  "use set_project() or set_context() instead. "
306
242
  "DO NOT use this for adding due dates - use set_due_date() instead. "
307
- "This tool is for adding descriptive text, notes, or comments to tasks."
243
+ "This tool is ONLY for adding descriptive text, notes, or comments to existing tasks."
308
244
  ),
309
245
  "parameters": {
310
246
  "type": "object",
@@ -327,8 +263,10 @@ class ToolCallHandler:
327
263
  "function": {
328
264
  "name": "prepend_to_task",
329
265
  "description": (
330
- "Add text to the beginning of an existing task. Use this when user "
331
- "wants to add a prefix or modifier to a task."
266
+ "Add text to the beginning of an EXISTING task. "
267
+ "USE CASE: Call this when user wants to add a prefix or modifier to an existing task. "
268
+ "NOT FOR: Creating new tasks, completing tasks, or adding project/context/due date tags. "
269
+ "This tool is ONLY for modifying existing tasks by adding text at the beginning."
332
270
  ),
333
271
  "parameters": {
334
272
  "type": "object",
@@ -351,7 +289,9 @@ class ToolCallHandler:
351
289
  "function": {
352
290
  "name": "delete_task",
353
291
  "description": (
354
- "Delete an entire task or remove a specific term from a task. "
292
+ "Delete an entire EXISTING task or remove a specific term from an EXISTING task. "
293
+ "USE CASE: Call this when user wants to delete a task completely or remove specific text from an existing task. "
294
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
355
295
  "IMPORTANT: Use list_tasks() first to find the correct task number "
356
296
  "if user doesn't specify it."
357
297
  ),
@@ -379,7 +319,9 @@ class ToolCallHandler:
379
319
  "function": {
380
320
  "name": "set_priority",
381
321
  "description": (
382
- "Set or change the priority of a task (A-Z, where A is highest). "
322
+ "Set or change the priority of an EXISTING task (A-Z, where A is highest). "
323
+ "USE CASE: Call this when user wants to add, change, or remove priority on an existing task. "
324
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
383
325
  "IMPORTANT: Use list_tasks() first to find the correct task number "
384
326
  "if user doesn't specify it."
385
327
  ),
@@ -404,7 +346,10 @@ class ToolCallHandler:
404
346
  "function": {
405
347
  "name": "remove_priority",
406
348
  "description": (
407
- "Remove the priority from a task. IMPORTANT: Use list_tasks() first "
349
+ "Remove the priority from an EXISTING task. "
350
+ "USE CASE: Call this when user wants to remove priority from an existing task. "
351
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
352
+ "IMPORTANT: Use list_tasks() first "
408
353
  "to find the correct task number if user doesn't specify it."
409
354
  ),
410
355
  "parameters": {
@@ -424,7 +369,9 @@ class ToolCallHandler:
424
369
  "function": {
425
370
  "name": "set_due_date",
426
371
  "description": (
427
- "Set or update the due date for a task by intelligently rewriting it. "
372
+ "Set or update the due date for an EXISTING task by intelligently rewriting it. "
373
+ "USE CASE: Call this when user wants to add, change, or remove a due date on an existing task. "
374
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
428
375
  "This preserves all existing task components (priority, projects, contexts, etc.) "
429
376
  "while updating or adding the due date. Use empty string to remove the due date. "
430
377
  "IMPORTANT: Use list_tasks() first "
@@ -453,7 +400,9 @@ class ToolCallHandler:
453
400
  "function": {
454
401
  "name": "set_context",
455
402
  "description": (
456
- "Set or update the context for a task by intelligently rewriting it. "
403
+ "Set or update the context for an EXISTING task by intelligently rewriting it. "
404
+ "USE CASE: Call this when user wants to add, change, or remove a context tag on an existing task. "
405
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
457
406
  "This preserves all existing task components (priority, projects, due date, etc.) "
458
407
  "while updating or adding the context. Use empty string to remove the context. "
459
408
  "PREFERRED METHOD: Use this instead of append_to_task() when adding context tags (@context). "
@@ -482,7 +431,9 @@ class ToolCallHandler:
482
431
  "function": {
483
432
  "name": "set_project",
484
433
  "description": (
485
- "Set or update projects for a task by intelligently rewriting it. "
434
+ "Set or update projects for an EXISTING task by intelligently rewriting it. "
435
+ "USE CASE: Call this when user wants to add, change, or remove project tags on an existing task. "
436
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
486
437
  "This preserves all existing task components and manages projects intelligently. "
487
438
  "Supports multiple projects, prevents duplicates, and groups them together. "
488
439
  "Empty array or empty strings are NOOPs (no changes). "
@@ -526,7 +477,9 @@ class ToolCallHandler:
526
477
  "function": {
527
478
  "name": "move_task",
528
479
  "description": (
529
- "Move a task from one file to another (e.g., from todo.txt to done.txt). "
480
+ "Move an EXISTING task from one file to another (e.g., from todo.txt to done.txt). "
481
+ "USE CASE: Call this when user wants to move a task between different todo files. "
482
+ "NOT FOR: Creating new tasks, completing tasks, or any other task operations. "
530
483
  "IMPORTANT: Use list_tasks() first to find the correct task number "
531
484
  "if user doesn't specify it."
532
485
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: todo-agent
3
- Version: 0.2.9
3
+ Version: 0.3.1
4
4
  Summary: A natural language interface for todo.sh task management
5
5
  Author: codeprimate
6
6
  Maintainer: codeprimate
@@ -1,29 +1,29 @@
1
1
  todo_agent/__init__.py,sha256=RUowhd14r3tqB_7rl83unGV8oBjra3UOIl7jix-33fk,254
2
- todo_agent/_version.py,sha256=051on7ZmwGNyKvbO1AXKoElw7RjLuRmeJqVOApytNd4,704
2
+ todo_agent/_version.py,sha256=gGLpQUQx-ty9SEy9PYw9OgJWWzJLBnCpfJOfzL7SjlI,704
3
3
  todo_agent/main.py,sha256=-ryhMm4c4sz4e4anXI8B-CYnpEh5HIkmnYcnGxcWHDk,1628
4
4
  todo_agent/core/__init__.py,sha256=QAZ4it63pXv5-DxtNcuSAmg7ZnCY5ackI5yycvKHr9I,365
5
5
  todo_agent/core/conversation_manager.py,sha256=nRFcDMqZtumVipggzVe94Hwz9HDbc2CrTssk_HImwEI,13548
6
6
  todo_agent/core/exceptions.py,sha256=cPvvkIbKdI7l51wC7cE-ZxUi54P3nf2m7x2lMNMRFYM,399
7
- todo_agent/core/todo_manager.py,sha256=wT82Wpwby6LR9VacLXhdDiGiMNoQbovXmU9943e5X2M,14908
7
+ todo_agent/core/todo_manager.py,sha256=wOgwXZCS5xZw7lHDnIar0L8r1pvgdUguu6kmFF9xSi8,16282
8
8
  todo_agent/infrastructure/__init__.py,sha256=SGbHXgzq6U1DMgOfWPMsWEK99zjPSF-6gzy7xqc5fsI,284
9
9
  todo_agent/infrastructure/calendar_utils.py,sha256=HmF0ykXF_6GbdoJvZLIv6fKwT6ipixoywdTMkIXmkGU,1871
10
10
  todo_agent/infrastructure/config.py,sha256=zyp6qOlg1nN_awphivlgGNBE6fL0Hf66YgvWxR8ldyQ,2117
11
- todo_agent/infrastructure/inference.py,sha256=PJouydXREgTIkZQVumdCvrwIbMdPR79baRV1W0s2TLA,11802
11
+ todo_agent/infrastructure/inference.py,sha256=T_xwSd2oB5CsPKExJoQ_RahpMB4U0PKIOUMR0vQyE5I,11883
12
12
  todo_agent/infrastructure/llm_client.py,sha256=ZoObyqaRP6i_eqGYGfJWGeWTJ-VNxpY70ay04vt2v_E,1390
13
13
  todo_agent/infrastructure/llm_client_factory.py,sha256=-tktnVOIF7B45WR7AuLoi7MKnEyuM8lgg1jjc4T1FhM,1929
14
14
  todo_agent/infrastructure/logger.py,sha256=2ykG_0lyzmEGxDF6ZRl1qiTUGDuFeQgzv4Na6vRmXcM,4110
15
15
  todo_agent/infrastructure/ollama_client.py,sha256=RVgHqX37k7q5xEaEXdhcCv2HYQiszs1QV39RxFFMIas,5902
16
- todo_agent/infrastructure/openrouter_client.py,sha256=FV240sQxoJ8j_Umh0qc6IorHkwk3LAFTSekGHKxuFwk,7000
17
- todo_agent/infrastructure/todo_shell.py,sha256=kYS0UwDZU1OpUVpWMkVsnsxnHINoWliRqzDRD8VTXJQ,17375
16
+ todo_agent/infrastructure/openrouter_client.py,sha256=2Ysf69z265dgkgDMLJR92v26-32DkuSAqKSN-ZCEX_Y,6948
17
+ todo_agent/infrastructure/todo_shell.py,sha256=0-GT_ReYMPCujy1KrB5PEQ98fbIZJm9-sVre5iCkFYE,17633
18
18
  todo_agent/infrastructure/token_counter.py,sha256=PCKheOVJbp1s89yhh_i6iKgURMt9mVoYkwjQJCc2xCE,4958
19
- todo_agent/infrastructure/prompts/system_prompt.txt,sha256=HTv7Yl2oQi-AbQgdBzZKNKnmAMdOuOVRlbi75L-w-5g,19962
19
+ todo_agent/infrastructure/prompts/system_prompt.txt,sha256=sin8wOFrDntTgKL1udlwE3iNxf_Pk1H1ZGzxGon23Wc,18931
20
20
  todo_agent/interface/__init__.py,sha256=vDD3rQu4qDkpvVwGVtkDzE1M4IiSHYzTif4GbYSFWaI,457
21
- todo_agent/interface/cli.py,sha256=9DUKTrxTwKx5Go0cA8nNCKDuM6QDmAG8jzK4_v_1WS8,12096
21
+ todo_agent/interface/cli.py,sha256=rSHJjSlKEV8dirCcMT1zX55i8raMOE_3IB6CUFGLgiI,12094
22
22
  todo_agent/interface/formatters.py,sha256=DiQLemndiuFWjLcBRPpu1wVnJcoYAFP8t_fJstOgaDs,18918
23
- todo_agent/interface/tools.py,sha256=OE9qOwWo7itqmNc85tZSCqWHCvValMa4fQE-EygnNNQ,45929
24
- todo_agent-0.2.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
25
- todo_agent-0.2.9.dist-info/METADATA,sha256=OPm-ho33qlhnZqrnNlqRR2p4tLqlXzkNk-fgcY73Dg0,10134
26
- todo_agent-0.2.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- todo_agent-0.2.9.dist-info/entry_points.txt,sha256=4W7LrCib6AXP5IZDwWRht8S5gutLu5oNfTJHGbt4oHs,52
28
- todo_agent-0.2.9.dist-info/top_level.txt,sha256=a65mlPIhPZHuq2bRIi_sCMAIJsUddvXt171OBF6r6co,11
29
- todo_agent-0.2.9.dist-info/RECORD,,
23
+ todo_agent/interface/tools.py,sha256=nPO4Sx-JlRUv0-JTzg6caSdDr7tGLGagMvEqblnDJfU,44364
24
+ todo_agent-0.3.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
25
+ todo_agent-0.3.1.dist-info/METADATA,sha256=HXdjiFn4ELWARfPjhQjpLY8lx2tiHezZ7ylkvQ8EXsI,10134
26
+ todo_agent-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ todo_agent-0.3.1.dist-info/entry_points.txt,sha256=4W7LrCib6AXP5IZDwWRht8S5gutLu5oNfTJHGbt4oHs,52
28
+ todo_agent-0.3.1.dist-info/top_level.txt,sha256=a65mlPIhPZHuq2bRIi_sCMAIJsUddvXt171OBF6r6co,11
29
+ todo_agent-0.3.1.dist-info/RECORD,,