xpander-sdk 2.0.158__tar.gz → 2.0.159__tar.gz
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.
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/PKG-INFO +1 -1
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/setup.py +1 -1
- xpander_sdk-2.0.159/src/xpander_sdk/models/deep_planning.py +15 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/events.py +3 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/agno.py +184 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/events_module.py +20 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/sub_modules/task.py +72 -3
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk.egg-info/PKG-INFO +1 -1
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk.egg-info/SOURCES.txt +1 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/LICENSE +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/README.md +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/pyproject.toml +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/setup.cfg +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/consts/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/consts/api_routes.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/core/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/core/module_base.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/core/state.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/core/xpander_api_client.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/exceptions/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/exceptions/module_exception.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/activity.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/configuration.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/frameworks.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/shared.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/models/user.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/agents_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/agent.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/agent_list.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/knowledge_bases.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/sub_modules/agent.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/utils/generic.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/backend_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/dispatch.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/utils/mcp_oauth.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_boot.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_shutdown.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_task.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/models/deployments.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/models/events.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/utils/generic.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/utils/git_init.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/sub_modules/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/models/task.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/models/tasks_list.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/sub_modules/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/tasks_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/utils/files.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/decorators/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/decorators/register_tool.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/models/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/models/mcp.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/sub_modules/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/sub_modules/tool.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/tools_repository_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/utils/generic.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/utils/local_tools.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/utils/schemas.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/utils/__init__.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/utils/env.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/utils/event_loop.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/utils/tools.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk.egg-info/dependency_links.txt +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk.egg-info/requires.txt +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk.egg-info/top_level.txt +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_agents_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_api_client.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_backend_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_boot_shutdown_handlers.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_configuration.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_knowledge_bases_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_tasks_module.py +0 -0
- {xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/tests/test_tools_repository.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from .shared import XPanderSharedModel
|
|
3
|
+
|
|
4
|
+
class DeepPlanningItem(XPanderSharedModel):
|
|
5
|
+
id: str
|
|
6
|
+
title: str
|
|
7
|
+
completed: Optional[bool] = False
|
|
8
|
+
|
|
9
|
+
class DeepPlanning(XPanderSharedModel):
|
|
10
|
+
enabled: Optional[bool] = False
|
|
11
|
+
tasks: Optional[List[DeepPlanningItem]] = []
|
|
12
|
+
|
|
13
|
+
class PlanFollowingStatus(XPanderSharedModel):
|
|
14
|
+
can_finish: bool
|
|
15
|
+
uncompleted_tasks: Optional[List[DeepPlanningItem]] = []
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/agno.py
RENAMED
|
@@ -213,8 +213,192 @@ async def build_agent_args(
|
|
|
213
213
|
if args["model"] and args["model"].id and args["model"].id.startswith("gpt-5"):
|
|
214
214
|
del args["model"].temperature
|
|
215
215
|
|
|
216
|
+
# configure deep planning guidance
|
|
217
|
+
_configure_deep_planning_guidance(args=args, agent=xpander_agent, task=task)
|
|
216
218
|
return args
|
|
217
219
|
|
|
220
|
+
def _configure_deep_planning_guidance(args: Dict[str, Any], agent: Agent, task: Optional[Task]) -> None:
|
|
221
|
+
if args and agent and task and agent.deep_planning and task.deep_planning.enabled == True:
|
|
222
|
+
# add instructions guidance
|
|
223
|
+
if not "instructions" in args:
|
|
224
|
+
args["instructions"] = ""
|
|
225
|
+
|
|
226
|
+
args["instructions"] += """\n
|
|
227
|
+
<important_planning_instructions>
|
|
228
|
+
## **Deep Planning Tools - Essential for Multi-Step Tasks**
|
|
229
|
+
|
|
230
|
+
When handling complex tasks with multiple steps, use these planning tools to track progress systematically.
|
|
231
|
+
|
|
232
|
+
### **Core Workflow**
|
|
233
|
+
1. **CREATE** plan at the start (`xpcreate-agent-plan`)
|
|
234
|
+
2. **CHECK** plan before each action (`xpget-agent-plan`)
|
|
235
|
+
3. **COMPLETE** task immediately after finishing it (`xpcomplete-agent-plan-item`)
|
|
236
|
+
4. Repeat steps 2-3 until all tasks are done
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### **Tool Reference**
|
|
241
|
+
|
|
242
|
+
#### **1. xpcreate-agent-plan** - Create Initial Plan
|
|
243
|
+
**When to use**: At the very start of any multi-step task, ONLY if no plan exists yet
|
|
244
|
+
|
|
245
|
+
**How to use**:
|
|
246
|
+
- Pass an array of task objects (NOT strings)
|
|
247
|
+
- Each task must have a `title` field with short, explanatory description
|
|
248
|
+
- Example format:
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"body_params": {
|
|
252
|
+
"tasks": [
|
|
253
|
+
{"title": "Research API requirements"},
|
|
254
|
+
{"title": "Design data schema"},
|
|
255
|
+
{"title": "Implement endpoints"},
|
|
256
|
+
{"title": "Write tests"},
|
|
257
|
+
{"title": "Deploy to staging"}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
**Important**:
|
|
263
|
+
- Include ALL steps needed from start to finish
|
|
264
|
+
- Each title should be clear and actionable (3-6 words)
|
|
265
|
+
- Do NOT pass plain strings like `["Task 1", "Task 2"]` - must be objects!
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
#### **2. xpget-agent-plan** - View Current Plan
|
|
270
|
+
**When to use**: Before deciding what to do next; to check progress
|
|
271
|
+
|
|
272
|
+
**Returns**:
|
|
273
|
+
- All tasks with their IDs, titles, and completion status
|
|
274
|
+
- Use this to know what's done and what remains
|
|
275
|
+
|
|
276
|
+
**No parameters needed** - just call the tool
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
#### **3. xpcomplete-agent-plan-item** - Mark Task Complete
|
|
281
|
+
**When to use**: **IMMEDIATELY** after finishing each task (NOT before!)
|
|
282
|
+
|
|
283
|
+
**How to use**:
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"body_params": {
|
|
287
|
+
"id": "task-uuid-from-plan"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
**CRITICAL**:
|
|
292
|
+
- Only mark complete AFTER work is actually done
|
|
293
|
+
- This is MANDATORY for progress tracking
|
|
294
|
+
- Get the task ID from `xpget-agent-plan` results
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
#### **4. xpadd-new-agent-plan-item** - Add Discovered Task
|
|
299
|
+
**When to use**: When you discover additional work needed during execution
|
|
300
|
+
|
|
301
|
+
**How to use**:
|
|
302
|
+
```json
|
|
303
|
+
{
|
|
304
|
+
"body_params": {
|
|
305
|
+
"title": "Validate input schemas",
|
|
306
|
+
"completed": false
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
#### **5. xpupdate-agent-plan-item** - Modify Existing Task
|
|
313
|
+
**When to use**: When task details change or need clarification
|
|
314
|
+
|
|
315
|
+
**How to use**:
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"body_params": {
|
|
319
|
+
"id": "task-uuid",
|
|
320
|
+
"title": "Updated description",
|
|
321
|
+
"completed": true
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
(All fields optional except `id`)
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
#### **6. xpdelete-agent-plan-item** - Remove Task
|
|
330
|
+
**When to use**: When a task becomes unnecessary or redundant
|
|
331
|
+
|
|
332
|
+
**How to use**:
|
|
333
|
+
```json
|
|
334
|
+
{
|
|
335
|
+
"body_params": {
|
|
336
|
+
"id": "task-uuid"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
### **Best Practices**
|
|
343
|
+
|
|
344
|
+
✅ **DO:**
|
|
345
|
+
- Create comprehensive plans with ALL necessary steps
|
|
346
|
+
- Use descriptive, actionable task titles
|
|
347
|
+
- Check plan before each action to stay oriented
|
|
348
|
+
- Mark tasks complete immediately after finishing them
|
|
349
|
+
- Call plan tools **sequentially** (one at a time, never in parallel)
|
|
350
|
+
|
|
351
|
+
❌ **DON'T:**
|
|
352
|
+
- Mark tasks complete before they're actually done
|
|
353
|
+
- Pass plain string arrays - must be objects with `title` field
|
|
354
|
+
- Call plan tools in parallel with each other
|
|
355
|
+
- Skip checking the plan between major steps
|
|
356
|
+
- Forget to mark completed tasks
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
### **Example Complete Workflow**
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
1. User: "Build a REST API for user management"
|
|
364
|
+
|
|
365
|
+
2. Call: xpcreate-agent-plan
|
|
366
|
+
tasks: [
|
|
367
|
+
{"title": "Design user schema"},
|
|
368
|
+
{"title": "Create database migration"},
|
|
369
|
+
{"title": "Implement CRUD endpoints"},
|
|
370
|
+
{"title": "Add authentication"},
|
|
371
|
+
{"title": "Write integration tests"}
|
|
372
|
+
]
|
|
373
|
+
|
|
374
|
+
3. Call: xpget-agent-plan
|
|
375
|
+
→ See: Task 1 (ID: abc-123) - Design user schema - Not complete
|
|
376
|
+
|
|
377
|
+
4. [Do the work: Design schema]
|
|
378
|
+
|
|
379
|
+
5. Call: xpcomplete-agent-plan-item
|
|
380
|
+
id: "abc-123"
|
|
381
|
+
|
|
382
|
+
6. Call: xpget-agent-plan
|
|
383
|
+
→ See: Task 1 ✓ complete, Task 2 next...
|
|
384
|
+
|
|
385
|
+
7. [Continue through remaining tasks]
|
|
386
|
+
```
|
|
387
|
+
**Remember**: The plan is your roadmap. Check it often, update it as needed, and always mark tasks complete when done!
|
|
388
|
+
</important_planning_instructions>
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
# add the expected output guidance
|
|
392
|
+
if not "expected_output" in args:
|
|
393
|
+
args["expected_output"] = ""
|
|
394
|
+
args["expected_output"] += "\nAll planned tasks completed and marked as done."
|
|
395
|
+
|
|
396
|
+
# add the plan to additional_context
|
|
397
|
+
if not "additional_context" in args:
|
|
398
|
+
args["additional_context"] = ""
|
|
399
|
+
|
|
400
|
+
plan_str = task.deep_planning.model_dump_json() if task.deep_planning and task.deep_planning.enabled and len(task.deep_planning.tasks) != 0 else "No execution plan, please generate"
|
|
401
|
+
args["additional_context"] += f" \n Current execution plan: {plan_str}"
|
|
218
402
|
|
|
219
403
|
def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]]) -> Any:
|
|
220
404
|
"""
|
|
@@ -330,6 +330,7 @@ class Events(ModuleBase):
|
|
|
330
330
|
agent_worker: DeployedAsset,
|
|
331
331
|
task: Task,
|
|
332
332
|
on_execution_request: ExecutionRequestHandler,
|
|
333
|
+
retry_count: Optional[int] = 0,
|
|
333
334
|
) -> None:
|
|
334
335
|
"""
|
|
335
336
|
Handle an incoming task execution request.
|
|
@@ -338,6 +339,7 @@ class Events(ModuleBase):
|
|
|
338
339
|
agent_worker (DeployedAsset): The deployed asset (agent) to handle the task.
|
|
339
340
|
task (Task): The task object containing execution details.
|
|
340
341
|
on_execution_request (ExecutionRequestHandler): The handler function to process the task.
|
|
342
|
+
retry_count (Optional[int]): Current retry attempt count. Defaults to 0.
|
|
341
343
|
"""
|
|
342
344
|
error = None
|
|
343
345
|
try:
|
|
@@ -351,6 +353,24 @@ class Events(ModuleBase):
|
|
|
351
353
|
on_execution_request,
|
|
352
354
|
task,
|
|
353
355
|
)
|
|
356
|
+
|
|
357
|
+
# Check if plan is complete, retry if not
|
|
358
|
+
plan_following_status = await task.aget_plan_following_status()
|
|
359
|
+
if not plan_following_status.can_finish:
|
|
360
|
+
# Check if we've exceeded max retries
|
|
361
|
+
if retry_count >= 2: # 0, 1, 2 = 3 total attempts
|
|
362
|
+
raise Exception(f"Failed to complete plan after {retry_count + 1} attempts. Remaining incomplete tasks.")
|
|
363
|
+
|
|
364
|
+
# Recursively call with incremented retry count
|
|
365
|
+
logger.info(f"Plan not complete, retrying (attempt {retry_count + 2}/3)")
|
|
366
|
+
await self.handle_task_execution_request(
|
|
367
|
+
agent_worker,
|
|
368
|
+
task,
|
|
369
|
+
on_execution_request,
|
|
370
|
+
retry_count=retry_count + 1
|
|
371
|
+
)
|
|
372
|
+
return
|
|
373
|
+
|
|
354
374
|
except Exception as e:
|
|
355
375
|
logger.exception(f"Execution handler failed - {str(e)}")
|
|
356
376
|
error = str(e)
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/sub_modules/task.py
RENAMED
|
@@ -43,12 +43,14 @@ from httpx import HTTPStatusError
|
|
|
43
43
|
import httpx
|
|
44
44
|
import json
|
|
45
45
|
from httpx_sse import aconnect_sse
|
|
46
|
+
from pydantic import Field, computed_field
|
|
46
47
|
|
|
47
48
|
from xpander_sdk.consts.api_routes import APIRoute
|
|
48
49
|
from xpander_sdk.core.xpander_api_client import APIClient
|
|
49
50
|
from xpander_sdk.exceptions.module_exception import ModuleException
|
|
50
51
|
from xpander_sdk.models.activity import AgentActivityThread
|
|
51
52
|
from xpander_sdk.models.configuration import Configuration
|
|
53
|
+
from xpander_sdk.models.deep_planning import PlanFollowingStatus, DeepPlanning
|
|
52
54
|
from xpander_sdk.models.events import (
|
|
53
55
|
TaskUpdateEventType,
|
|
54
56
|
ToolCallRequest,
|
|
@@ -85,7 +87,7 @@ from xpander_sdk.utils.event_loop import run_sync
|
|
|
85
87
|
T = TypeVar("T", bound="Task")
|
|
86
88
|
|
|
87
89
|
TaskUpdateEventData = Union[
|
|
88
|
-
T, ToolCallRequest, ToolCallResult, MCPOAuthGetTokenResponse
|
|
90
|
+
T, ToolCallRequest, ToolCallResult, MCPOAuthGetTokenResponse, DeepPlanning
|
|
89
91
|
]
|
|
90
92
|
|
|
91
93
|
|
|
@@ -133,6 +135,7 @@ class Task(XPanderSharedModel):
|
|
|
133
135
|
mcp_servers (Optional[List[MCPServerDetails]]): Optional list of mcp servers to use.
|
|
134
136
|
triggering_agent_id (Optional[str]): Optional triggering agent id.
|
|
135
137
|
title (Optional[str]): Optional task title.
|
|
138
|
+
deep_planning: Optional[DeepPlanning] = Field(default_factory=DeepPlanning)
|
|
136
139
|
|
|
137
140
|
Example:
|
|
138
141
|
>>> task = Task.load(task_id="task_123")
|
|
@@ -180,6 +183,7 @@ class Task(XPanderSharedModel):
|
|
|
180
183
|
title: Optional[str] = (None,)
|
|
181
184
|
think_mode: Optional[ThinkMode] = ThinkMode.Default
|
|
182
185
|
disable_attachment_injection: Optional[bool] = False
|
|
186
|
+
deep_planning: Optional[DeepPlanning] = Field(default_factory=DeepPlanning)
|
|
183
187
|
|
|
184
188
|
# metrics
|
|
185
189
|
tokens: Optional[Tokens] = None
|
|
@@ -348,7 +352,7 @@ class Task(XPanderSharedModel):
|
|
|
348
352
|
response = await client.make_request(
|
|
349
353
|
path=APIRoute.UpdateTask.format(task_id=self.id),
|
|
350
354
|
method="PATCH",
|
|
351
|
-
payload=self.model_dump_safe(),
|
|
355
|
+
payload=self.model_dump_safe(exclude={"configuration","deep_planning"}),
|
|
352
356
|
)
|
|
353
357
|
updated_task = Task(**response, configuration=self.configuration)
|
|
354
358
|
for field, value in updated_task.__dict__.items():
|
|
@@ -536,6 +540,17 @@ class Task(XPanderSharedModel):
|
|
|
536
540
|
for f in readable_files:
|
|
537
541
|
message += f"\n{json.dumps(f)}"
|
|
538
542
|
|
|
543
|
+
if self.deep_planning and self.deep_planning.enabled == True:
|
|
544
|
+
self.reload()
|
|
545
|
+
uncompleted_tasks = [task for task in self.deep_planning.tasks if not task.completed]
|
|
546
|
+
if len(uncompleted_tasks) != 0:
|
|
547
|
+
message = "\n".join([
|
|
548
|
+
"Task not finished, uncompleted tasks detected:",
|
|
549
|
+
f"Uncompleted tasks: {[task.model_dump_json() for task in uncompleted_tasks]}",
|
|
550
|
+
"You must complete tasks if fulfilled",
|
|
551
|
+
f"User's original request: \"{message}\""
|
|
552
|
+
])
|
|
553
|
+
|
|
539
554
|
return message
|
|
540
555
|
|
|
541
556
|
async def aget_activity_log(self) -> AgentActivityThread:
|
|
@@ -750,6 +765,60 @@ class Task(XPanderSharedModel):
|
|
|
750
765
|
None
|
|
751
766
|
"""
|
|
752
767
|
return run_sync(self.areport_metrics(configuration=configuration))
|
|
768
|
+
|
|
769
|
+
async def aget_plan_following_status(self) -> PlanFollowingStatus:
|
|
770
|
+
"""
|
|
771
|
+
Asynchronously check if the task's deep planning is complete.
|
|
772
|
+
|
|
773
|
+
Reloads the task to get the latest deep planning state and checks for
|
|
774
|
+
any uncompleted tasks. If deep planning is disabled or all tasks are
|
|
775
|
+
completed, returns a status indicating the task can finish.
|
|
776
|
+
|
|
777
|
+
Returns:
|
|
778
|
+
PlanFollowingStatus: Status object containing:
|
|
779
|
+
- can_finish (bool): True if all tasks are completed or deep planning is disabled.
|
|
780
|
+
- uncompleted_tasks (List[DeepPlanningItem]): List of tasks not yet completed.
|
|
781
|
+
|
|
782
|
+
Example:
|
|
783
|
+
>>> status = await task.aget_plan_following_status()
|
|
784
|
+
>>> if not status.can_finish:
|
|
785
|
+
... print(f"Remaining tasks: {len(status.uncompleted_tasks)}")
|
|
786
|
+
"""
|
|
787
|
+
try:
|
|
788
|
+
if self.deep_planning and self.deep_planning.enabled:
|
|
789
|
+
await self.areload()
|
|
790
|
+
|
|
791
|
+
uncompleted_tasks = [
|
|
792
|
+
task for task in self.deep_planning.tasks if not task.completed
|
|
793
|
+
]
|
|
794
|
+
if len(uncompleted_tasks) != 0:
|
|
795
|
+
return PlanFollowingStatus(
|
|
796
|
+
can_finish=False, uncompleted_tasks=uncompleted_tasks
|
|
797
|
+
)
|
|
798
|
+
except Exception:
|
|
799
|
+
pass
|
|
800
|
+
|
|
801
|
+
return PlanFollowingStatus(can_finish=True)
|
|
802
|
+
|
|
803
|
+
def get_plan_following_status(self) -> PlanFollowingStatus:
|
|
804
|
+
"""
|
|
805
|
+
Check if the task's deep planning is complete synchronously.
|
|
806
|
+
|
|
807
|
+
This function wraps the asynchronous aget_plan_following_status method.
|
|
808
|
+
Reloads the task to get the latest deep planning state and checks for
|
|
809
|
+
any uncompleted tasks.
|
|
810
|
+
|
|
811
|
+
Returns:
|
|
812
|
+
PlanFollowingStatus: Status object containing:
|
|
813
|
+
- can_finish (bool): True if all tasks are completed or deep planning is disabled.
|
|
814
|
+
- uncompleted_tasks (List[DeepPlanningItem]): List of tasks not yet completed.
|
|
815
|
+
|
|
816
|
+
Example:
|
|
817
|
+
>>> status = task.get_plan_following_status()
|
|
818
|
+
>>> if not status.can_finish:
|
|
819
|
+
... print(f"Remaining tasks: {len(status.uncompleted_tasks)}")
|
|
820
|
+
"""
|
|
821
|
+
return run_sync(self.aget_plan_following_status())
|
|
753
822
|
|
|
754
823
|
@classmethod
|
|
755
824
|
async def areport_external_task(
|
|
@@ -884,4 +953,4 @@ class Task(XPanderSharedModel):
|
|
|
884
953
|
duration=duration,
|
|
885
954
|
used_tools=used_tools,
|
|
886
955
|
)
|
|
887
|
-
)
|
|
956
|
+
)
|
|
@@ -19,6 +19,7 @@ src/xpander_sdk/exceptions/module_exception.py
|
|
|
19
19
|
src/xpander_sdk/models/__init__.py
|
|
20
20
|
src/xpander_sdk/models/activity.py
|
|
21
21
|
src/xpander_sdk/models/configuration.py
|
|
22
|
+
src/xpander_sdk/models/deep_planning.py
|
|
22
23
|
src/xpander_sdk/models/events.py
|
|
23
24
|
src/xpander_sdk/models/frameworks.py
|
|
24
25
|
src/xpander_sdk/models/shared.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/agent_list.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/models/knowledge_bases.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/sub_modules/__init__.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/sub_modules/agent.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/agents/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/backend_module.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/__init__.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/frameworks/dispatch.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/utils/__init__.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/backend/utils/mcp_oauth.py
RENAMED
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/__init__.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_boot.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_shutdown.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/decorators/on_task.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/models/__init__.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/models/deployments.py
RENAMED
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/events/utils/git_init.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/knowledge_bases/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/models/tasks_list.py
RENAMED
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tasks/sub_modules/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xpander_sdk-2.0.158 → xpander_sdk-2.0.159}/src/xpander_sdk/modules/tools_repository/models/mcp.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|