xpander-sdk 2.0.158__py3-none-any.whl → 2.0.160__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.
- xpander_sdk/models/deep_planning.py +18 -0
- xpander_sdk/models/events.py +3 -0
- xpander_sdk/modules/agents/sub_modules/agent.py +2 -0
- xpander_sdk/modules/backend/frameworks/agno.py +236 -0
- xpander_sdk/modules/events/events_module.py +20 -0
- xpander_sdk/modules/tasks/sub_modules/task.py +76 -3
- {xpander_sdk-2.0.158.dist-info → xpander_sdk-2.0.160.dist-info}/METADATA +1 -1
- {xpander_sdk-2.0.158.dist-info → xpander_sdk-2.0.160.dist-info}/RECORD +11 -10
- {xpander_sdk-2.0.158.dist-info → xpander_sdk-2.0.160.dist-info}/WHEEL +0 -0
- {xpander_sdk-2.0.158.dist-info → xpander_sdk-2.0.160.dist-info}/licenses/LICENSE +0 -0
- {xpander_sdk-2.0.158.dist-info → xpander_sdk-2.0.160.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
enforce: Optional[bool] = False
|
|
12
|
+
started: Optional[bool] = False
|
|
13
|
+
question_raised: Optional[bool] = False
|
|
14
|
+
tasks: Optional[List[DeepPlanningItem]] = []
|
|
15
|
+
|
|
16
|
+
class PlanFollowingStatus(XPanderSharedModel):
|
|
17
|
+
can_finish: bool
|
|
18
|
+
uncompleted_tasks: Optional[List[DeepPlanningItem]] = []
|
xpander_sdk/models/events.py
CHANGED
|
@@ -154,6 +154,7 @@ class Agent(XPanderSharedModel):
|
|
|
154
154
|
model_name: str
|
|
155
155
|
llm_reasoning_effort: Optional[LLMReasoningEffort] = LLMReasoningEffort.Medium
|
|
156
156
|
deep_planning: Optional[bool] = False
|
|
157
|
+
enforce_deep_planning: Optional[bool] = False
|
|
157
158
|
llm_api_base: Optional[str]
|
|
158
159
|
webhook_url: Optional[str]
|
|
159
160
|
created_at: Optional[datetime]
|
|
@@ -197,6 +198,7 @@ class Agent(XPanderSharedModel):
|
|
|
197
198
|
model_name: str
|
|
198
199
|
llm_reasoning_effort: Optional[LLMReasoningEffort] = LLMReasoningEffort.Medium
|
|
199
200
|
deep_planning: Optional[bool] = False
|
|
201
|
+
enforce_deep_planning: Optional[bool] = False
|
|
200
202
|
llm_api_base: Optional[str] = None
|
|
201
203
|
webhook_url: Optional[str] = None
|
|
202
204
|
created_at: Optional[datetime] = None
|
|
@@ -213,8 +213,244 @@ 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. **START** plan execution (`xpstart-execution-plan`) - MANDATORY to enable enforcement
|
|
235
|
+
3. **CHECK** plan before each action (`xpget-agent-plan`)
|
|
236
|
+
4. **COMPLETE** task immediately after finishing it (`xpcomplete-agent-plan-item`)
|
|
237
|
+
5. **ASK** user for info if needed (`xpask-for-information`)
|
|
238
|
+
6. Repeat steps 3-5 until all tasks are done
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### **Tool Reference**
|
|
243
|
+
|
|
244
|
+
#### **1. xpcreate-agent-plan** - Create Initial Plan
|
|
245
|
+
**When to use**: At the very start of any multi-step task, ONLY if no plan exists yet
|
|
246
|
+
**Note**: After creating a plan, you MUST call `xpstart-execution-plan` to begin enforcement
|
|
247
|
+
|
|
248
|
+
**How to use**:
|
|
249
|
+
- Pass an array of task objects (NOT strings)
|
|
250
|
+
- Each task must have a `title` field with short, explanatory description
|
|
251
|
+
- Example format:
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"body_params": {
|
|
255
|
+
"tasks": [
|
|
256
|
+
{"title": "Research API requirements"},
|
|
257
|
+
{"title": "Design data schema"},
|
|
258
|
+
{"title": "Implement endpoints"},
|
|
259
|
+
{"title": "Write tests"},
|
|
260
|
+
{"title": "Deploy to staging"}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
**Important**:
|
|
266
|
+
- Include ALL steps needed from start to finish
|
|
267
|
+
- Each title should be clear and actionable (3-6 words)
|
|
268
|
+
- Do NOT pass plain strings like `["Task 1", "Task 2"]` - must be objects!
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
#### **2. xpget-agent-plan** - View Current Plan
|
|
273
|
+
**When to use**: Before deciding what to do next; to check progress
|
|
274
|
+
|
|
275
|
+
**Returns**:
|
|
276
|
+
- All tasks with their IDs, titles, and completion status
|
|
277
|
+
- Use this to know what's done and what remains
|
|
278
|
+
|
|
279
|
+
**No parameters needed** - just call the tool
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
#### **3. xpcomplete-agent-plan-item** - Mark Task Complete
|
|
284
|
+
**When to use**: **IMMEDIATELY** after finishing each task (NOT before!)
|
|
285
|
+
|
|
286
|
+
**How to use**:
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"body_params": {
|
|
290
|
+
"id": "task-uuid-from-plan"
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
**CRITICAL**:
|
|
295
|
+
- Only mark complete AFTER work is actually done
|
|
296
|
+
- This is MANDATORY for progress tracking
|
|
297
|
+
- Get the task ID from `xpget-agent-plan` results
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
#### **4. xpadd-new-agent-plan-item** - Add Discovered Task
|
|
302
|
+
**When to use**: When you discover additional work needed during execution
|
|
303
|
+
|
|
304
|
+
**How to use**:
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"body_params": {
|
|
308
|
+
"title": "Validate input schemas",
|
|
309
|
+
"completed": false
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
#### **5. xpupdate-agent-plan-item** - Modify Existing Task
|
|
316
|
+
**When to use**: When task details change or need clarification
|
|
317
|
+
|
|
318
|
+
**How to use**:
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"body_params": {
|
|
322
|
+
"id": "task-uuid",
|
|
323
|
+
"title": "Updated description",
|
|
324
|
+
"completed": true
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
(All fields optional except `id`)
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
#### **6. xpdelete-agent-plan-item** - Remove Task
|
|
333
|
+
**When to use**: When a task becomes unnecessary or redundant
|
|
334
|
+
|
|
335
|
+
**How to use**:
|
|
336
|
+
```json
|
|
337
|
+
{
|
|
338
|
+
"body_params": {
|
|
339
|
+
"id": "task-uuid"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
#### **7. xpstart-execution-plan** - Start Plan Execution
|
|
346
|
+
**When to use**: Immediately after creating a plan with `xpcreate-agent-plan`
|
|
347
|
+
**CRITICAL**: Must be called to enable enforcement mode before executing tasks
|
|
348
|
+
|
|
349
|
+
**How to use**:
|
|
350
|
+
```json
|
|
351
|
+
{
|
|
352
|
+
"body_params": {}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
**No parameters needed** - just call after plan creation
|
|
356
|
+
|
|
357
|
+
**What it does**:
|
|
358
|
+
- Marks plan as "started"
|
|
359
|
+
- Enables enforcement mode if `enforce` flag is true
|
|
360
|
+
- Allows plan execution to proceed
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
#### **8. xpask-for-information** - Ask User a Question
|
|
365
|
+
**When to use**: When you need information from the user during plan execution
|
|
366
|
+
**PREREQUISITE**: Plan must be started (running) first
|
|
367
|
+
|
|
368
|
+
**How to use**:
|
|
369
|
+
```json
|
|
370
|
+
{
|
|
371
|
+
"body_params": {
|
|
372
|
+
"question": "What is the customer email address?"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**What it does**:
|
|
378
|
+
- Sets `question_raised` flag to true
|
|
379
|
+
- Prints the question for the user
|
|
380
|
+
- Keeps enforcement active (does NOT pause execution)
|
|
381
|
+
- Returns waiting status
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
### **Best Practices**
|
|
386
|
+
|
|
387
|
+
✅ **DO:**
|
|
388
|
+
- Create comprehensive plans with ALL necessary steps
|
|
389
|
+
- **START** the plan with `xpstart-execution-plan` after creating it
|
|
390
|
+
- Use descriptive, actionable task titles
|
|
391
|
+
- Check plan before each action to stay oriented
|
|
392
|
+
- Mark tasks complete immediately after finishing them
|
|
393
|
+
- Ask for user information when needed with `xpask-for-information`
|
|
394
|
+
- Call plan tools **sequentially** (one at a time, never in parallel)
|
|
395
|
+
|
|
396
|
+
❌ **DON'T:**
|
|
397
|
+
- Mark tasks complete before they're actually done
|
|
398
|
+
- Pass plain string arrays - must be objects with `title` field
|
|
399
|
+
- Call plan tools in parallel with each other
|
|
400
|
+
- Skip checking the plan between major steps
|
|
401
|
+
- Forget to mark completed tasks
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
### **Example Complete Workflow**
|
|
406
|
+
|
|
407
|
+
```
|
|
408
|
+
1. User: "Build a REST API for user management"
|
|
409
|
+
|
|
410
|
+
2. Call: xpcreate-agent-plan
|
|
411
|
+
tasks: [
|
|
412
|
+
{"title": "Design user schema"},
|
|
413
|
+
{"title": "Create database migration"},
|
|
414
|
+
{"title": "Implement CRUD endpoints"},
|
|
415
|
+
{"title": "Add authentication"},
|
|
416
|
+
{"title": "Write integration tests"}
|
|
417
|
+
]
|
|
418
|
+
|
|
419
|
+
3. Call: xpstart-execution-plan
|
|
420
|
+
→ Plan now started, enforcement enabled (if enforce=true)
|
|
421
|
+
|
|
422
|
+
4. Call: xpget-agent-plan
|
|
423
|
+
→ See: Task 1 (ID: abc-123) - Design user schema - Not complete
|
|
424
|
+
|
|
425
|
+
5. [Realize need user input] Call: xpask-for-information
|
|
426
|
+
question: "Which database should we use - PostgreSQL or MySQL?"
|
|
427
|
+
→ question_raised=true, waiting for response
|
|
428
|
+
|
|
429
|
+
6. [After user responds, do the work: Design schema]
|
|
430
|
+
|
|
431
|
+
7. Call: xpcomplete-agent-plan-item
|
|
432
|
+
id: "abc-123"
|
|
433
|
+
|
|
434
|
+
8. Call: xpget-agent-plan
|
|
435
|
+
→ See: Task 1 ✓ complete, Task 2 next...
|
|
436
|
+
|
|
437
|
+
9. [Continue through remaining tasks]
|
|
438
|
+
```
|
|
439
|
+
**Remember**: The plan is your roadmap. Check it often, update it as needed, and always mark tasks complete when done!
|
|
440
|
+
</important_planning_instructions>
|
|
441
|
+
"""
|
|
442
|
+
|
|
443
|
+
# add the expected output guidance
|
|
444
|
+
if not "expected_output" in args:
|
|
445
|
+
args["expected_output"] = ""
|
|
446
|
+
args["expected_output"] += "\nAll planned tasks completed and marked as done."
|
|
447
|
+
|
|
448
|
+
# add the plan to additional_context
|
|
449
|
+
if not "additional_context" in args:
|
|
450
|
+
args["additional_context"] = ""
|
|
451
|
+
|
|
452
|
+
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"
|
|
453
|
+
args["additional_context"] += f" \n Current execution plan: {plan_str}"
|
|
218
454
|
|
|
219
455
|
def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]]) -> Any:
|
|
220
456
|
"""
|
|
@@ -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)
|
|
@@ -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,64 @@ 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 and self.deep_planning.started and self.deep_planning.enforce:
|
|
789
|
+
await self.areload()
|
|
790
|
+
|
|
791
|
+
# allow early exit to ask question
|
|
792
|
+
if self.deep_planning.question_raised:
|
|
793
|
+
return PlanFollowingStatus(can_finish=True)
|
|
794
|
+
|
|
795
|
+
uncompleted_tasks = [
|
|
796
|
+
task for task in self.deep_planning.tasks if not task.completed
|
|
797
|
+
]
|
|
798
|
+
if len(uncompleted_tasks) != 0:
|
|
799
|
+
return PlanFollowingStatus(
|
|
800
|
+
can_finish=False, uncompleted_tasks=uncompleted_tasks
|
|
801
|
+
)
|
|
802
|
+
except Exception:
|
|
803
|
+
pass
|
|
804
|
+
|
|
805
|
+
return PlanFollowingStatus(can_finish=True)
|
|
806
|
+
|
|
807
|
+
def get_plan_following_status(self) -> PlanFollowingStatus:
|
|
808
|
+
"""
|
|
809
|
+
Check if the task's deep planning is complete synchronously.
|
|
810
|
+
|
|
811
|
+
This function wraps the asynchronous aget_plan_following_status method.
|
|
812
|
+
Reloads the task to get the latest deep planning state and checks for
|
|
813
|
+
any uncompleted tasks.
|
|
814
|
+
|
|
815
|
+
Returns:
|
|
816
|
+
PlanFollowingStatus: Status object containing:
|
|
817
|
+
- can_finish (bool): True if all tasks are completed or deep planning is disabled.
|
|
818
|
+
- uncompleted_tasks (List[DeepPlanningItem]): List of tasks not yet completed.
|
|
819
|
+
|
|
820
|
+
Example:
|
|
821
|
+
>>> status = task.get_plan_following_status()
|
|
822
|
+
>>> if not status.can_finish:
|
|
823
|
+
... print(f"Remaining tasks: {len(status.uncompleted_tasks)}")
|
|
824
|
+
"""
|
|
825
|
+
return run_sync(self.aget_plan_following_status())
|
|
753
826
|
|
|
754
827
|
@classmethod
|
|
755
828
|
async def areport_external_task(
|
|
@@ -884,4 +957,4 @@ class Task(XPanderSharedModel):
|
|
|
884
957
|
duration=duration,
|
|
885
958
|
used_tools=used_tools,
|
|
886
959
|
)
|
|
887
|
-
)
|
|
960
|
+
)
|
|
@@ -10,7 +10,8 @@ xpander_sdk/exceptions/module_exception.py,sha256=2Urni1QEdzOrCdYSRc5eLpuz8aDlvR
|
|
|
10
10
|
xpander_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
xpander_sdk/models/activity.py,sha256=I3CxOzUNbrKwHqynCbm7FJja6vanVkCzwwBwET7qvzA,2085
|
|
12
12
|
xpander_sdk/models/configuration.py,sha256=Un8p3C3p3eMiqKK5VsHaZdWhZTRYHbrw2aPUMV8lJSc,3370
|
|
13
|
-
xpander_sdk/models/
|
|
13
|
+
xpander_sdk/models/deep_planning.py,sha256=pCFV5iNSfT99ap1-09k7oO_DIwXx2vPJ3aVM472xL4w,554
|
|
14
|
+
xpander_sdk/models/events.py,sha256=2vIkuPGAbntN_7xggJRw5sMJ1_EzcXyljxPH0ekISlw,2235
|
|
14
15
|
xpander_sdk/models/frameworks.py,sha256=Ptf4aMjZ44L_x8WsCc5X0kjsJObv4dwgSM61no0aW6E,2937
|
|
15
16
|
xpander_sdk/models/shared.py,sha256=gW88kA_UslNinUjtQKpLVF0sHDZnckwLWexRapxPivU,3125
|
|
16
17
|
xpander_sdk/models/user.py,sha256=_FTG0JO6iTrbcvJp-BBJ6nuj281zhyQB5ldQkBCyYDU,749
|
|
@@ -22,18 +23,18 @@ xpander_sdk/modules/agents/models/agent.py,sha256=tJXNogRjvwlxzJPzesdHm-NBhMOzDn
|
|
|
22
23
|
xpander_sdk/modules/agents/models/agent_list.py,sha256=byEayS2uLwDKaVT3lAHltrFocQFKpr8XEwQ6NTEEEMo,4081
|
|
23
24
|
xpander_sdk/modules/agents/models/knowledge_bases.py,sha256=YimpjVJxWe8YTbGMD6oGQOA_YV8ztHQHTTBOaBB44ZM,1037
|
|
24
25
|
xpander_sdk/modules/agents/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
-
xpander_sdk/modules/agents/sub_modules/agent.py,sha256=
|
|
26
|
+
xpander_sdk/modules/agents/sub_modules/agent.py,sha256=HHVz00hrRCFZV9uj8Q5TvZHO_ObijMwQw5Gqdwa_nDY,36298
|
|
26
27
|
xpander_sdk/modules/agents/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
28
|
xpander_sdk/modules/agents/utils/generic.py,sha256=XbG4OeHMQo4gVYCsasMlW_b8OoqS1xL3MlUZSjXivu0,81
|
|
28
29
|
xpander_sdk/modules/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
30
|
xpander_sdk/modules/backend/backend_module.py,sha256=wYghMuNXEtXgoyMXBgbMhgE7wYcbRwXJcpEyybF30kA,18927
|
|
30
31
|
xpander_sdk/modules/backend/frameworks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
xpander_sdk/modules/backend/frameworks/agno.py,sha256
|
|
32
|
+
xpander_sdk/modules/backend/frameworks/agno.py,sha256=VDrNb2M2RaKDPjlmc-yQeXJZVDpTifF4zl2xaLXvDeg,32538
|
|
32
33
|
xpander_sdk/modules/backend/frameworks/dispatch.py,sha256=5dP4c37C42U53VjM2kkwIRwEw1i0IN3G0YESHH7J3OE,1557
|
|
33
34
|
xpander_sdk/modules/backend/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
35
|
xpander_sdk/modules/backend/utils/mcp_oauth.py,sha256=a4xQGQwRGf2T9h38Vc9VNUwpIeY9y7Mn6B4D2G3tMQM,4387
|
|
35
36
|
xpander_sdk/modules/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
xpander_sdk/modules/events/events_module.py,sha256=
|
|
37
|
+
xpander_sdk/modules/events/events_module.py,sha256=E5cXbUjcRuTCRrKb85DG9bqsfXQ-j-eaZd1cvN5xYTY,25291
|
|
37
38
|
xpander_sdk/modules/events/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
39
|
xpander_sdk/modules/events/decorators/on_boot.py,sha256=VGtoQcgs3g5bmx3Ze4QB_-ZwBESATYYVR0oZe35eCww,3076
|
|
39
40
|
xpander_sdk/modules/events/decorators/on_shutdown.py,sha256=rFgChspnLDnZm9FS1K636dvZSQDkeugf2e3M83SDgAY,3127
|
|
@@ -58,7 +59,7 @@ xpander_sdk/modules/tasks/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
58
59
|
xpander_sdk/modules/tasks/models/task.py,sha256=B0_fwzQEkRE_pZMSLnWuXsUBMdy8HEIxm1FfRpCQma0,5000
|
|
59
60
|
xpander_sdk/modules/tasks/models/tasks_list.py,sha256=8V1T0vCtGN79qLMPwe37pOA7Wvuf8pbJNOhWL0BPo-8,5126
|
|
60
61
|
xpander_sdk/modules/tasks/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
-
xpander_sdk/modules/tasks/sub_modules/task.py,sha256=
|
|
62
|
+
xpander_sdk/modules/tasks/sub_modules/task.py,sha256=RlYe4XAhWeUGk2JwlRC__SWP7OFoym8fnCTluYrhHLg,36135
|
|
62
63
|
xpander_sdk/modules/tasks/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
64
|
xpander_sdk/modules/tasks/utils/files.py,sha256=KqqwSQSrwim2-H3XP5wOadDDfngAyEI034tA7Oon-vc,3631
|
|
64
65
|
xpander_sdk/modules/tools_repository/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -78,8 +79,8 @@ xpander_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
78
79
|
xpander_sdk/utils/env.py,sha256=U_zIhqWgKs5fk2-HXjAaODj4oWMc5dRQ0fvw6fqVcFk,1522
|
|
79
80
|
xpander_sdk/utils/event_loop.py,sha256=kJrN0upgBhyI86tkTdfHeajznrIZl44Rl6WDiDG3GHE,2516
|
|
80
81
|
xpander_sdk/utils/tools.py,sha256=lyFkq2yP7DxBkyXYVlnFRwDhQCvf0fZZMDm5fBycze4,1244
|
|
81
|
-
xpander_sdk-2.0.
|
|
82
|
-
xpander_sdk-2.0.
|
|
83
|
-
xpander_sdk-2.0.
|
|
84
|
-
xpander_sdk-2.0.
|
|
85
|
-
xpander_sdk-2.0.
|
|
82
|
+
xpander_sdk-2.0.160.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
83
|
+
xpander_sdk-2.0.160.dist-info/METADATA,sha256=KRfnTL_z2awclUG4SAg_LCOGdPkYoQl8F4AxVLD6nBI,15312
|
|
84
|
+
xpander_sdk-2.0.160.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
85
|
+
xpander_sdk-2.0.160.dist-info/top_level.txt,sha256=UCjnxQpsMy5Zoe7lmRuVDO6DI2V_6PgRFfm4oizRbVs,12
|
|
86
|
+
xpander_sdk-2.0.160.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|