kader 0.1.6__py3-none-any.whl → 1.1.0__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.
- cli/app.py +108 -36
- cli/app.tcss +20 -0
- cli/llm_factory.py +165 -0
- cli/utils.py +19 -11
- cli/widgets/conversation.py +50 -4
- kader/__init__.py +2 -0
- kader/agent/agents.py +8 -0
- kader/agent/base.py +84 -7
- kader/config.py +10 -2
- kader/memory/types.py +60 -0
- kader/prompts/__init__.py +9 -1
- kader/prompts/agent_prompts.py +28 -0
- kader/prompts/templates/executor_agent.j2 +70 -0
- kader/prompts/templates/kader_planner.j2 +71 -0
- kader/providers/__init__.py +2 -0
- kader/providers/google.py +690 -0
- kader/providers/ollama.py +2 -2
- kader/tools/__init__.py +26 -0
- kader/tools/agent.py +452 -0
- kader/tools/filesys.py +1 -1
- kader/tools/todo.py +43 -2
- kader/utils/__init__.py +10 -0
- kader/utils/checkpointer.py +371 -0
- kader/utils/context_aggregator.py +347 -0
- kader/workflows/__init__.py +13 -0
- kader/workflows/base.py +71 -0
- kader/workflows/planner_executor.py +251 -0
- {kader-0.1.6.dist-info → kader-1.1.0.dist-info}/METADATA +39 -1
- kader-1.1.0.dist-info/RECORD +56 -0
- kader-0.1.6.dist-info/RECORD +0 -45
- {kader-0.1.6.dist-info → kader-1.1.0.dist-info}/WHEEL +0 -0
- {kader-0.1.6.dist-info → kader-1.1.0.dist-info}/entry_points.txt +0 -0
kader/agent/base.py
CHANGED
|
@@ -23,7 +23,9 @@ from kader.providers.base import (
|
|
|
23
23
|
Message,
|
|
24
24
|
ModelConfig,
|
|
25
25
|
StreamChunk,
|
|
26
|
+
Usage,
|
|
26
27
|
)
|
|
28
|
+
from kader.providers.google import GoogleProvider
|
|
27
29
|
from kader.providers.ollama import OllamaProvider
|
|
28
30
|
from kader.tools import BaseTool, ToolRegistry
|
|
29
31
|
|
|
@@ -48,11 +50,15 @@ class BaseAgent:
|
|
|
48
50
|
provider: Optional[BaseLLMProvider] = None,
|
|
49
51
|
memory: Optional[ConversationManager] = None,
|
|
50
52
|
retry_attempts: int = 3,
|
|
53
|
+
retry_wait_min: int = 1,
|
|
54
|
+
retry_wait_max: int = 5,
|
|
51
55
|
model_name: str = "qwen3-coder:480b-cloud",
|
|
52
56
|
session_id: Optional[str] = None,
|
|
53
57
|
use_persistence: bool = False,
|
|
54
58
|
interrupt_before_tool: bool = True,
|
|
55
59
|
tool_confirmation_callback: Optional[callable] = None,
|
|
60
|
+
direct_execution_callback: Optional[callable] = None,
|
|
61
|
+
tool_execution_result_callback: Optional[callable] = None,
|
|
56
62
|
) -> None:
|
|
57
63
|
"""
|
|
58
64
|
Initialize the Base Agent.
|
|
@@ -75,8 +81,12 @@ class BaseAgent:
|
|
|
75
81
|
self.name = name
|
|
76
82
|
self.system_prompt = system_prompt
|
|
77
83
|
self.retry_attempts = retry_attempts
|
|
84
|
+
self.retry_wait_min = retry_wait_min
|
|
85
|
+
self.retry_wait_max = retry_wait_max
|
|
78
86
|
self.interrupt_before_tool = interrupt_before_tool
|
|
79
87
|
self.tool_confirmation_callback = tool_confirmation_callback
|
|
88
|
+
self.direct_execution_callback = direct_execution_callback
|
|
89
|
+
self.tool_execution_result_callback = tool_execution_result_callback
|
|
80
90
|
|
|
81
91
|
# Persistence Configuration
|
|
82
92
|
self.session_id = session_id
|
|
@@ -214,6 +224,8 @@ class BaseAgent:
|
|
|
214
224
|
provider_type = "openai"
|
|
215
225
|
if isinstance(self.provider, OllamaProvider):
|
|
216
226
|
provider_type = "ollama"
|
|
227
|
+
elif isinstance(self.provider, GoogleProvider):
|
|
228
|
+
provider_type = "google"
|
|
217
229
|
|
|
218
230
|
base_config = ModelConfig(
|
|
219
231
|
temperature=base_config.temperature,
|
|
@@ -339,6 +351,31 @@ class BaseAgent:
|
|
|
339
351
|
if llm_content and len(llm_content) > 0:
|
|
340
352
|
display_str = f"{llm_content}\n\n{display_str}"
|
|
341
353
|
|
|
354
|
+
# Extract tool name for direct execution check
|
|
355
|
+
fn_info = tool_call_dict.get("function", {})
|
|
356
|
+
if not fn_info and "name" in tool_call_dict:
|
|
357
|
+
fn_info = tool_call_dict
|
|
358
|
+
tool_name = fn_info.get("name", "")
|
|
359
|
+
|
|
360
|
+
# List of tools to execute directly (show message but don't ask for confirmation)
|
|
361
|
+
direct_execution_tools = {
|
|
362
|
+
"read_file",
|
|
363
|
+
"glob",
|
|
364
|
+
"grep",
|
|
365
|
+
"read_directory",
|
|
366
|
+
"read_dir",
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
# Direct execution for specific tools - applies regardless of callback
|
|
370
|
+
if tool_name in direct_execution_tools:
|
|
371
|
+
# Notify via direct_execution_callback if available (for CLI/TUI display)
|
|
372
|
+
if self.direct_execution_callback:
|
|
373
|
+
self.direct_execution_callback(display_str, tool_name)
|
|
374
|
+
else:
|
|
375
|
+
# Fallback: print to console
|
|
376
|
+
print(display_str)
|
|
377
|
+
return True, None
|
|
378
|
+
|
|
342
379
|
# Use callback if provided (e.g., for GUI/TUI)
|
|
343
380
|
if self.tool_confirmation_callback:
|
|
344
381
|
return self.tool_confirmation_callback(display_str)
|
|
@@ -435,6 +472,18 @@ class BaseAgent:
|
|
|
435
472
|
# Execute tool
|
|
436
473
|
tool_result = self._tool_registry.run(tool_call)
|
|
437
474
|
|
|
475
|
+
# Notify about tool execution result if callback available
|
|
476
|
+
if self.tool_execution_result_callback:
|
|
477
|
+
# Handle both enum and string status
|
|
478
|
+
status = tool_result.status
|
|
479
|
+
status_value = (
|
|
480
|
+
status.value if hasattr(status, "value") else str(status)
|
|
481
|
+
)
|
|
482
|
+
success = status_value == "success"
|
|
483
|
+
self.tool_execution_result_callback(
|
|
484
|
+
tool_call.name, success, tool_result.content
|
|
485
|
+
)
|
|
486
|
+
|
|
438
487
|
# add result to memory
|
|
439
488
|
# But here we just return messages, caller handles memory add
|
|
440
489
|
tool_msg = Message.tool(
|
|
@@ -482,6 +531,18 @@ class BaseAgent:
|
|
|
482
531
|
# Execute tool async
|
|
483
532
|
tool_result = await self._tool_registry.arun(tool_call)
|
|
484
533
|
|
|
534
|
+
# Notify about tool execution result if callback available
|
|
535
|
+
if self.tool_execution_result_callback:
|
|
536
|
+
# Handle both enum and string status
|
|
537
|
+
status = tool_result.status
|
|
538
|
+
status_value = (
|
|
539
|
+
status.value if hasattr(status, "value") else str(status)
|
|
540
|
+
)
|
|
541
|
+
success = status_value == "success"
|
|
542
|
+
self.tool_execution_result_callback(
|
|
543
|
+
tool_call.name, success, tool_result.content
|
|
544
|
+
)
|
|
545
|
+
|
|
485
546
|
tool_msg = Message.tool(
|
|
486
547
|
tool_call_id=tool_result.tool_call_id, content=tool_result.content
|
|
487
548
|
)
|
|
@@ -509,7 +570,9 @@ class BaseAgent:
|
|
|
509
570
|
|
|
510
571
|
runner = Retrying(
|
|
511
572
|
stop=stop_after_attempt(self.retry_attempts),
|
|
512
|
-
wait=wait_exponential(
|
|
573
|
+
wait=wait_exponential(
|
|
574
|
+
multiplier=1, min=self.retry_wait_min, max=self.retry_wait_max
|
|
575
|
+
),
|
|
513
576
|
reraise=True,
|
|
514
577
|
)
|
|
515
578
|
|
|
@@ -565,7 +628,12 @@ class BaseAgent:
|
|
|
565
628
|
)
|
|
566
629
|
|
|
567
630
|
# estimate the cost...
|
|
568
|
-
|
|
631
|
+
usage_obj = Usage(
|
|
632
|
+
prompt_tokens=token_usage["prompt_tokens"],
|
|
633
|
+
completion_tokens=token_usage["completion_tokens"],
|
|
634
|
+
total_tokens=token_usage["total_tokens"],
|
|
635
|
+
)
|
|
636
|
+
estimated_cost = self.provider.estimate_cost(usage_obj)
|
|
569
637
|
|
|
570
638
|
# Calculate and log cost
|
|
571
639
|
agent_logger.calculate_cost(
|
|
@@ -652,7 +720,9 @@ class BaseAgent:
|
|
|
652
720
|
|
|
653
721
|
runner = Retrying(
|
|
654
722
|
stop=stop_after_attempt(self.retry_attempts),
|
|
655
|
-
wait=wait_exponential(
|
|
723
|
+
wait=wait_exponential(
|
|
724
|
+
multiplier=1, min=self.retry_wait_min, max=self.retry_wait_max
|
|
725
|
+
),
|
|
656
726
|
reraise=True,
|
|
657
727
|
)
|
|
658
728
|
|
|
@@ -689,7 +759,9 @@ class BaseAgent:
|
|
|
689
759
|
|
|
690
760
|
runner = AsyncRetrying(
|
|
691
761
|
stop=stop_after_attempt(self.retry_attempts),
|
|
692
|
-
wait=wait_exponential(
|
|
762
|
+
wait=wait_exponential(
|
|
763
|
+
multiplier=1, min=self.retry_wait_min, max=self.retry_wait_max
|
|
764
|
+
),
|
|
693
765
|
reraise=True,
|
|
694
766
|
)
|
|
695
767
|
|
|
@@ -733,7 +805,12 @@ class BaseAgent:
|
|
|
733
805
|
)
|
|
734
806
|
|
|
735
807
|
# estimate the cost...
|
|
736
|
-
|
|
808
|
+
usage_obj = Usage(
|
|
809
|
+
prompt_tokens=token_usage["prompt_tokens"],
|
|
810
|
+
completion_tokens=token_usage["completion_tokens"],
|
|
811
|
+
total_tokens=token_usage["total_tokens"],
|
|
812
|
+
)
|
|
813
|
+
estimated_cost = self.provider.estimate_cost(usage_obj)
|
|
737
814
|
|
|
738
815
|
# Calculate and log cost
|
|
739
816
|
agent_logger.calculate_cost(
|
|
@@ -905,9 +982,9 @@ class BaseAgent:
|
|
|
905
982
|
if registry is None:
|
|
906
983
|
# Lazy import to avoid circular dependencies if any
|
|
907
984
|
try:
|
|
908
|
-
from kader.tools import
|
|
985
|
+
from kader.tools import get_cached_default_registry
|
|
909
986
|
|
|
910
|
-
registry =
|
|
987
|
+
registry = get_cached_default_registry()
|
|
911
988
|
except ImportError:
|
|
912
989
|
pass
|
|
913
990
|
|
kader/config.py
CHANGED
|
@@ -69,13 +69,21 @@ def ensure_kader_directory():
|
|
|
69
69
|
def ensure_env_file(kader_dir):
|
|
70
70
|
"""
|
|
71
71
|
Ensure that the .env file exists in the .kader directory with the
|
|
72
|
-
required
|
|
72
|
+
required API key configurations.
|
|
73
73
|
"""
|
|
74
74
|
env_file = kader_dir / ".env"
|
|
75
75
|
|
|
76
76
|
# Create the .env file if it doesn't exist
|
|
77
77
|
if not env_file.exists():
|
|
78
|
-
|
|
78
|
+
default_env_content = """# Kader Configuration
|
|
79
|
+
# Ollama API Key (for local Ollama models)
|
|
80
|
+
OLLAMA_API_KEY=''
|
|
81
|
+
|
|
82
|
+
# Google Gemini API Key (for Google Gemini models)
|
|
83
|
+
# Get your API key from: https://aistudio.google.com/apikey
|
|
84
|
+
GEMINI_API_KEY=''
|
|
85
|
+
"""
|
|
86
|
+
env_file.write_text(default_env_content, encoding="utf-8")
|
|
79
87
|
|
|
80
88
|
# Set appropriate permissions for the .env file on Unix-like systems
|
|
81
89
|
if not sys.platform.startswith("win"):
|
kader/memory/types.py
CHANGED
|
@@ -114,3 +114,63 @@ def load_json(path: Path) -> dict[str, Any]:
|
|
|
114
114
|
return {}
|
|
115
115
|
with open(path, "r", encoding="utf-8") as f:
|
|
116
116
|
return decode_bytes_values(json.load(f))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# --- Async File I/O Utilities ---
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
async def aread_text(path: Path, encoding: str = "utf-8") -> str:
|
|
123
|
+
"""Asynchronously read text from a file.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
path: Path to the file
|
|
127
|
+
encoding: File encoding (default: utf-8)
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
File contents as string
|
|
131
|
+
"""
|
|
132
|
+
import aiofiles
|
|
133
|
+
|
|
134
|
+
async with aiofiles.open(path, "r", encoding=encoding) as f:
|
|
135
|
+
return await f.read()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
async def awrite_text(path: Path, content: str, encoding: str = "utf-8") -> None:
|
|
139
|
+
"""Asynchronously write text to a file.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
path: Path to the file
|
|
143
|
+
content: Text content to write
|
|
144
|
+
encoding: File encoding (default: utf-8)
|
|
145
|
+
"""
|
|
146
|
+
import aiofiles
|
|
147
|
+
|
|
148
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
149
|
+
async with aiofiles.open(path, "w", encoding=encoding) as f:
|
|
150
|
+
await f.write(content)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
async def asave_json(path: Path, data: dict[str, Any]) -> None:
|
|
154
|
+
"""Asynchronously save data to a JSON file.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
path: Path to the JSON file
|
|
158
|
+
data: Data to save
|
|
159
|
+
"""
|
|
160
|
+
content = json.dumps(encode_bytes_values(data), indent=2, ensure_ascii=False)
|
|
161
|
+
await awrite_text(path, content)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
async def aload_json(path: Path) -> dict[str, Any]:
|
|
165
|
+
"""Asynchronously load data from a JSON file.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
path: Path to the JSON file
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
Loaded data, or empty dict if file doesn't exist
|
|
172
|
+
"""
|
|
173
|
+
if not path.exists():
|
|
174
|
+
return {}
|
|
175
|
+
content = await aread_text(path)
|
|
176
|
+
return decode_bytes_values(json.loads(content))
|
kader/prompts/__init__.py
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
from .agent_prompts import
|
|
1
|
+
from .agent_prompts import (
|
|
2
|
+
BasicAssistancePrompt,
|
|
3
|
+
ExecutorAgentPrompt,
|
|
4
|
+
KaderPlannerPrompt,
|
|
5
|
+
PlanningAgentPrompt,
|
|
6
|
+
ReActAgentPrompt,
|
|
7
|
+
)
|
|
2
8
|
from .base import PromptBase
|
|
3
9
|
|
|
4
10
|
__all__ = [
|
|
@@ -6,4 +12,6 @@ __all__ = [
|
|
|
6
12
|
"BasicAssistancePrompt",
|
|
7
13
|
"ReActAgentPrompt",
|
|
8
14
|
"PlanningAgentPrompt",
|
|
15
|
+
"KaderPlannerPrompt",
|
|
16
|
+
"ExecutorAgentPrompt",
|
|
9
17
|
]
|
kader/prompts/agent_prompts.py
CHANGED
|
@@ -25,3 +25,31 @@ class PlanningAgentPrompt(PromptBase):
|
|
|
25
25
|
|
|
26
26
|
def __init__(self, **kwargs: Any) -> None:
|
|
27
27
|
super().__init__(template_path="planning_agent.j2", **kwargs)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class KaderPlannerPrompt(PromptBase):
|
|
31
|
+
"""
|
|
32
|
+
Prompt for Kader Planner Agent.
|
|
33
|
+
|
|
34
|
+
Enhanced planning prompt with specific instructions for:
|
|
35
|
+
- Using Agent as a Tool with proper task/context parameters
|
|
36
|
+
- Tracking completed actions to avoid repetition
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
40
|
+
super().__init__(template_path="kader_planner.j2", **kwargs)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ExecutorAgentPrompt(PromptBase):
|
|
44
|
+
"""
|
|
45
|
+
Prompt for Executor Agent (sub-agents in PlannerExecutorWorkflow).
|
|
46
|
+
|
|
47
|
+
Emphasizes:
|
|
48
|
+
- Careful thinking before each action
|
|
49
|
+
- Safe execution with error handling
|
|
50
|
+
- Detailed step-by-step reporting of what was done
|
|
51
|
+
- Structured final answer with files created, summary, and issues
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
55
|
+
super().__init__(template_path="executor_agent.j2", **kwargs)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
You are Kader, an Executor Agent specialized in deep and complex tasks.
|
|
2
|
+
|
|
3
|
+
You excel at:
|
|
4
|
+
- Writing high-quality code and implementing features
|
|
5
|
+
- Deep research and comprehensive analysis
|
|
6
|
+
- Complex problem-solving and debugging
|
|
7
|
+
- Thorough documentation and testing
|
|
8
|
+
|
|
9
|
+
You have access to the following tools:
|
|
10
|
+
|
|
11
|
+
{% for tool in tools %}
|
|
12
|
+
{{ tool.name }}: {{ tool.description }}
|
|
13
|
+
{% endfor %}
|
|
14
|
+
|
|
15
|
+
## Your Objective
|
|
16
|
+
|
|
17
|
+
Complete the assigned task safely and thoroughly. Think carefully before each action.
|
|
18
|
+
|
|
19
|
+
## Execution Process
|
|
20
|
+
|
|
21
|
+
1. **Analyze the Task**: Before taking any action, carefully think about:
|
|
22
|
+
- What exactly needs to be done
|
|
23
|
+
- What could go wrong and how to prevent it
|
|
24
|
+
- The safest approach to complete the task
|
|
25
|
+
|
|
26
|
+
2. **Plan Your Steps**: Create a mental action plan before executing
|
|
27
|
+
|
|
28
|
+
3. **Execute Safely**: For each action:
|
|
29
|
+
- Think about potential side effects
|
|
30
|
+
- Verify inputs before executing
|
|
31
|
+
- Handle errors gracefully
|
|
32
|
+
|
|
33
|
+
4. **Track Your Work**: Keep track of:
|
|
34
|
+
- Files created or modified
|
|
35
|
+
- Commands executed
|
|
36
|
+
- Any issues encountered
|
|
37
|
+
|
|
38
|
+
## Response Format
|
|
39
|
+
|
|
40
|
+
Use the following format for reasoning:
|
|
41
|
+
|
|
42
|
+
Thought: Analyze what needs to be done and plan the approach
|
|
43
|
+
Action: the action to take, should be one of [{{ tool_names }}]
|
|
44
|
+
Action Input: the input to the action
|
|
45
|
+
Observation: the result of the action
|
|
46
|
+
... (this Thought/Action/Action Input/Observation can repeat N times)
|
|
47
|
+
Thought: I have completed the task
|
|
48
|
+
Final Answer: [Your detailed execution report]
|
|
49
|
+
|
|
50
|
+
## CRITICAL: Final Answer Requirements
|
|
51
|
+
|
|
52
|
+
Your Final Answer MUST include a structured execution report with:
|
|
53
|
+
|
|
54
|
+
### What Has Been Done
|
|
55
|
+
- List each action completed with details
|
|
56
|
+
|
|
57
|
+
### Files Created/Modified
|
|
58
|
+
- Full path and purpose of each file
|
|
59
|
+
- If no files: state "No files were created or modified"
|
|
60
|
+
|
|
61
|
+
### Execution Summary
|
|
62
|
+
- Brief summary of the overall execution
|
|
63
|
+
- Whether the task was completed successfully
|
|
64
|
+
|
|
65
|
+
### Issues/Notes
|
|
66
|
+
- Any errors encountered and how they were resolved
|
|
67
|
+
- Any warnings or important notes for the caller
|
|
68
|
+
- If no issues: state "No issues encountered"
|
|
69
|
+
|
|
70
|
+
Begin!
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
You are Kader, an intelligent planning agent. You have access to the following tools:
|
|
2
|
+
|
|
3
|
+
{% for tool in tools %}
|
|
4
|
+
{{ tool.name }}: {{ tool.description }}
|
|
5
|
+
{% endfor %}
|
|
6
|
+
|
|
7
|
+
{% if context %}
|
|
8
|
+
## Previous Context (What Has Been Done)
|
|
9
|
+
|
|
10
|
+
The following summarizes what has been accomplished in previous rounds. Consider this context when planning your next steps to avoid repeating completed work:
|
|
11
|
+
|
|
12
|
+
{{ context }}
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
Your goal is to complete the user's request by creating a plan and executing it step-by-step.
|
|
16
|
+
|
|
17
|
+
## Core Instructions
|
|
18
|
+
|
|
19
|
+
1. Break down the user request into logical steps.
|
|
20
|
+
2. For each step, determine if a tool is needed.
|
|
21
|
+
3. Execute necessary tools.
|
|
22
|
+
4. CRITICAL: Always create a TODO using the TODO Tool for the plan.
|
|
23
|
+
5. CRITICAL: Follow the instructions of the TODO list strictly. The current item in the TODO list is your PRIMARY instruction.
|
|
24
|
+
6. CRITICAL: After completing a step (e.g., creating a file, running a test), you MUST immediately use the TODO Tool to update the status of that item to 'completed'. Do not proceed to the next item without updating the TODO list.
|
|
25
|
+
7. If you have enough information, provide the final answer.
|
|
26
|
+
|
|
27
|
+
## Using Agent as a Tool
|
|
28
|
+
|
|
29
|
+
When delegating tasks to sub-agents using the Agent Tool, follow these guidelines:
|
|
30
|
+
|
|
31
|
+
### Task Parameter
|
|
32
|
+
- **Primary Instruction**: This MUST come directly from the current item in your TODO list (e.g., "Implement unit tests", "Create database schema").
|
|
33
|
+
- **Secondary Instructions (Objectives)**: These are the supporting details or objectives for the sub-agent (e.g., "View the code to understand the context", "Ensure 100% coverage").
|
|
34
|
+
- **Structure**:
|
|
35
|
+
- Start with the Primary Instruction.
|
|
36
|
+
- Follow with "Objectives:" listing the Secondary Instructions.
|
|
37
|
+
- **Example**:
|
|
38
|
+
- If the TODO item is "Implement feature X", and you need the agent to also read the docs:
|
|
39
|
+
- Task: "Implement feature X. Objectives: 1. Read documentation at doc/feature.md. 2. Verify implementation with tests."
|
|
40
|
+
- **REQUIRED**: Include instruction that the agent MUST return:
|
|
41
|
+
- What has been done (actions completed)
|
|
42
|
+
- What files have been written or modified (if any)
|
|
43
|
+
- A summary of the execution
|
|
44
|
+
- Any issues or errors that occurred during execution
|
|
45
|
+
|
|
46
|
+
### Context Parameter (REQUIRED)
|
|
47
|
+
The context parameter MUST include:
|
|
48
|
+
1. **Brief about latest actions**: Summarize what has been done so far and the current state
|
|
49
|
+
2. **Completed actions to avoid repetition**: List actions that were successfully completed so the sub-agent does NOT repeat them
|
|
50
|
+
|
|
51
|
+
Example Agent Tool usage:
|
|
52
|
+
```
|
|
53
|
+
task: "Create unit tests for the user authentication module"
|
|
54
|
+
context: "We are building a user management system. So far, the User model and AuthService have been implemented in src/auth/. Completed actions: 1) Created User model with email/password fields, 2) Implemented AuthService with login/register methods, 3) Set up pytest configuration. Do NOT recreate these files."
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Example Planning Flow
|
|
58
|
+
|
|
59
|
+
Task: Implement a ML Inference Endpoint
|
|
60
|
+
|
|
61
|
+
Plan:
|
|
62
|
+
1. Analyze the requirements and design the system architecture
|
|
63
|
+
2. Implement the endpoint using a web framework
|
|
64
|
+
3. Test the endpoint to ensure it works as expected
|
|
65
|
+
4. Deploy the endpoint to a production environment
|
|
66
|
+
|
|
67
|
+
When executing this plan:
|
|
68
|
+
- Create the TODO list first
|
|
69
|
+
- For each step, consider if delegation to an Agent Tool is appropriate
|
|
70
|
+
- Update TODO status after completing each step
|
|
71
|
+
- Provide context to sub-agents about completed work
|