xpander-sdk 2.0.161__py3-none-any.whl → 2.0.192__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/__init__.py +6 -0
- xpander_sdk/consts/api_routes.py +8 -0
- xpander_sdk/models/compactization.py +112 -0
- xpander_sdk/models/events.py +3 -0
- xpander_sdk/models/frameworks.py +2 -2
- xpander_sdk/models/generic.py +27 -0
- xpander_sdk/models/notifications.py +98 -0
- xpander_sdk/models/orchestrations.py +271 -0
- xpander_sdk/modules/agents/models/agent.py +7 -4
- xpander_sdk/modules/agents/sub_modules/agent.py +18 -10
- xpander_sdk/modules/backend/__init__.py +8 -0
- xpander_sdk/modules/backend/backend_module.py +47 -2
- xpander_sdk/modules/backend/decorators/__init__.py +7 -0
- xpander_sdk/modules/backend/decorators/on_auth_event.py +131 -0
- xpander_sdk/modules/backend/events_registry.py +172 -0
- xpander_sdk/modules/backend/frameworks/agno.py +176 -54
- xpander_sdk/modules/backend/frameworks/dispatch.py +3 -1
- xpander_sdk/modules/backend/utils/mcp_oauth.py +36 -24
- xpander_sdk/modules/events/decorators/__init__.py +3 -0
- xpander_sdk/modules/events/decorators/on_tool.py +384 -0
- xpander_sdk/modules/events/events_module.py +9 -3
- xpander_sdk/modules/tasks/models/task.py +3 -14
- xpander_sdk/modules/tasks/sub_modules/task.py +54 -20
- xpander_sdk/modules/tools_repository/sub_modules/tool.py +46 -15
- xpander_sdk/modules/tools_repository/utils/generic.py +3 -0
- xpander_sdk/utils/agents/__init__.py +0 -0
- xpander_sdk/utils/agents/compactization_agent.py +257 -0
- xpander_sdk/utils/generic.py +5 -0
- {xpander_sdk-2.0.161.dist-info → xpander_sdk-2.0.192.dist-info}/METADATA +97 -13
- {xpander_sdk-2.0.161.dist-info → xpander_sdk-2.0.192.dist-info}/RECORD +33 -22
- {xpander_sdk-2.0.161.dist-info → xpander_sdk-2.0.192.dist-info}/WHEEL +0 -0
- {xpander_sdk-2.0.161.dist-info → xpander_sdk-2.0.192.dist-info}/licenses/LICENSE +0 -0
- {xpander_sdk-2.0.161.dist-info → xpander_sdk-2.0.192.dist-info}/top_level.txt +0 -0
|
@@ -41,6 +41,7 @@ from xpander_sdk.modules.tools_repository.utils.schemas import (
|
|
|
41
41
|
schema_enforcement_block_and_descriptions,
|
|
42
42
|
)
|
|
43
43
|
from xpander_sdk.utils.event_loop import run_sync
|
|
44
|
+
from xpander_sdk.modules.events.decorators.on_tool import ToolHooksRegistry
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class Tool(XPanderSharedModel):
|
|
@@ -376,6 +377,15 @@ class Tool(XPanderSharedModel):
|
|
|
376
377
|
task_id=task_id,
|
|
377
378
|
)
|
|
378
379
|
|
|
380
|
+
# Execute before hooks
|
|
381
|
+
await ToolHooksRegistry.execute_before_hooks(
|
|
382
|
+
tool=self,
|
|
383
|
+
payload=payload,
|
|
384
|
+
payload_extension=payload_extension,
|
|
385
|
+
tool_call_id=tool_call_id,
|
|
386
|
+
agent_version=agent_version
|
|
387
|
+
)
|
|
388
|
+
|
|
379
389
|
try:
|
|
380
390
|
if self.schema and payload:
|
|
381
391
|
try:
|
|
@@ -386,32 +396,43 @@ class Tool(XPanderSharedModel):
|
|
|
386
396
|
) from validation_error
|
|
387
397
|
|
|
388
398
|
if self.is_local:
|
|
389
|
-
await self.agraph_preflight_check(
|
|
390
|
-
agent_id=agent_id,
|
|
391
|
-
agent_version=agent_version,
|
|
392
|
-
configuration=configuration,
|
|
393
|
-
task_id=task_id,
|
|
394
|
-
)
|
|
395
|
-
|
|
396
399
|
if self.fn is None:
|
|
397
400
|
raise RuntimeError(
|
|
398
401
|
f"No local function provided for this tool ({self.id})."
|
|
399
402
|
)
|
|
400
403
|
|
|
401
404
|
result = await invoke_local_fn(fn=self.fn, payload=payload)
|
|
405
|
+
|
|
406
|
+
await self.agraph_preflight_check(
|
|
407
|
+
agent_id=agent_id,
|
|
408
|
+
agent_version=agent_version,
|
|
409
|
+
configuration=configuration,
|
|
410
|
+
task_id=task_id,
|
|
411
|
+
payload={"input": payload, "output": result.model_dump() if isinstance(result, BaseModel) else result}
|
|
412
|
+
)
|
|
413
|
+
|
|
402
414
|
tool_invocation_result.result = result
|
|
403
415
|
tool_invocation_result.is_success = True
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
416
|
+
else:
|
|
417
|
+
tool_invocation_result.result = await self.acall_remote_tool(
|
|
418
|
+
agent_id=agent_id,
|
|
419
|
+
agent_version=agent_version,
|
|
420
|
+
payload=payload,
|
|
421
|
+
payload_extension=payload_extension,
|
|
422
|
+
configuration=configuration,
|
|
423
|
+
task_id=task_id,
|
|
424
|
+
)
|
|
425
|
+
tool_invocation_result.is_success = True
|
|
426
|
+
|
|
427
|
+
# Execute after hooks on success
|
|
428
|
+
await ToolHooksRegistry.execute_after_hooks(
|
|
429
|
+
tool=self,
|
|
409
430
|
payload=payload,
|
|
410
431
|
payload_extension=payload_extension,
|
|
411
|
-
|
|
412
|
-
|
|
432
|
+
tool_call_id=tool_call_id,
|
|
433
|
+
agent_version=agent_version,
|
|
434
|
+
result=tool_invocation_result.result
|
|
413
435
|
)
|
|
414
|
-
tool_invocation_result.is_success = True
|
|
415
436
|
|
|
416
437
|
except Exception as e:
|
|
417
438
|
tool_invocation_result.is_error = True
|
|
@@ -421,6 +442,16 @@ class Tool(XPanderSharedModel):
|
|
|
421
442
|
else:
|
|
422
443
|
tool_invocation_result.status_code = 500
|
|
423
444
|
tool_invocation_result.result = str(e)
|
|
445
|
+
|
|
446
|
+
# Execute error hooks on failure
|
|
447
|
+
await ToolHooksRegistry.execute_error_hooks(
|
|
448
|
+
tool=self,
|
|
449
|
+
payload=payload,
|
|
450
|
+
payload_extension=payload_extension,
|
|
451
|
+
tool_call_id=tool_call_id,
|
|
452
|
+
agent_version=agent_version,
|
|
453
|
+
error=e
|
|
454
|
+
)
|
|
424
455
|
|
|
425
456
|
return tool_invocation_result
|
|
426
457
|
|
|
@@ -38,6 +38,9 @@ def json_type_to_python(json_type: str, prop_schema: dict = None):
|
|
|
38
38
|
item_type = json_type_to_python(items.get("type"), items)
|
|
39
39
|
return List[item_type]
|
|
40
40
|
|
|
41
|
+
if isinstance(json_type, list) and len(json_type) > 1:
|
|
42
|
+
json_type = next((t for t in json_type if t != "null"), None)
|
|
43
|
+
|
|
41
44
|
return {
|
|
42
45
|
"string": str,
|
|
43
46
|
"integer": int,
|
|
File without changes
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, List, Union
|
|
2
|
+
from agno.agent import Agent as AgnoAgent
|
|
3
|
+
from loguru import logger
|
|
4
|
+
import json
|
|
5
|
+
from xpander_sdk.models.compactization import TaskCompactizationEvent, TaskCompactizationOutput, TaskCompactizationInput, TaskCompactizationRetryEvent
|
|
6
|
+
from xpander_sdk.models.deep_planning import DeepPlanningItem
|
|
7
|
+
from xpander_sdk.models.events import TaskUpdateEventType
|
|
8
|
+
from xpander_sdk.models.frameworks import Framework
|
|
9
|
+
from xpander_sdk.models.shared import Tokens
|
|
10
|
+
from xpander_sdk.modules.agents.agents_module import Agents
|
|
11
|
+
from xpander_sdk.modules.backend.backend_module import Backend
|
|
12
|
+
from xpander_sdk.modules.backend.utils.mcp_oauth import push_event
|
|
13
|
+
from xpander_sdk.modules.tasks.sub_modules.task import TaskUpdateEvent
|
|
14
|
+
from xpander_sdk.utils.event_loop import run_sync
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from xpander_sdk.modules.tasks.sub_modules.task import Task
|
|
18
|
+
|
|
19
|
+
def run_task_compactization(message: str, task: "Task", uncompleted_tasks: List[DeepPlanningItem]) -> Union[str, TaskCompactizationOutput]:
|
|
20
|
+
try:
|
|
21
|
+
|
|
22
|
+
# report retry event
|
|
23
|
+
try:
|
|
24
|
+
run_sync(
|
|
25
|
+
push_event(
|
|
26
|
+
task=task,
|
|
27
|
+
event=TaskCompactizationEvent(type="retry", data=TaskCompactizationRetryEvent(is_retry=True)),
|
|
28
|
+
event_type=TaskUpdateEventType.TaskCompactization
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
# get agent to identify framework
|
|
35
|
+
agent = Agents(configuration=task.configuration).get(agent_id=task.agent_id,version=task.agent_version)
|
|
36
|
+
|
|
37
|
+
# non agno, let the same agent handle it
|
|
38
|
+
if agent.framework != Framework.Agno:
|
|
39
|
+
return "\n".join([
|
|
40
|
+
"Task not finished, uncompleted tasks detected:",
|
|
41
|
+
f"Uncompleted tasks: {[task.model_dump_json() for task in uncompleted_tasks]}",
|
|
42
|
+
"You must complete tasks if fulfilled",
|
|
43
|
+
f"User's original request: \"{message}\""
|
|
44
|
+
])
|
|
45
|
+
|
|
46
|
+
# load backend args for consistency of model provider and settings
|
|
47
|
+
agno_args = Backend(configuration=agent.configuration).get_args(agent_id=agent.id, agent_version=agent.version, task=task)
|
|
48
|
+
|
|
49
|
+
if agent.model_provider == "openai":
|
|
50
|
+
agno_args["model"].id = "gpt-5-mini"
|
|
51
|
+
|
|
52
|
+
# create compacitzation agent
|
|
53
|
+
compactization_agent = AgnoAgent(
|
|
54
|
+
output_schema=TaskCompactizationOutput,
|
|
55
|
+
name="Task Compactization Agent",
|
|
56
|
+
model=agno_args.get("model"),
|
|
57
|
+
description="""
|
|
58
|
+
You are a system component that handles early/unapproved agent task exits.
|
|
59
|
+
|
|
60
|
+
When an agent stops execution with uncompleted tasks, you analyze the state and generate a continuation prompt
|
|
61
|
+
that will be sent DIRECTLY to that agent to resume its work.
|
|
62
|
+
|
|
63
|
+
Your output becomes the agent's next input - it must guide the agent to:
|
|
64
|
+
1. Continue from where it stopped (seamlessly, no restart)
|
|
65
|
+
2. Complete ALL remaining uncompleted tasks
|
|
66
|
+
3. Use correct tools (especially xpask_for_information for questions)
|
|
67
|
+
4. NOT expose internal orchestration (xp* tools, task IDs) to the user
|
|
68
|
+
|
|
69
|
+
You are a bridge between system orchestration and agent execution.
|
|
70
|
+
""",
|
|
71
|
+
role="""
|
|
72
|
+
You are the **Compactization Agent** - a system component for handling early agent exits.
|
|
73
|
+
|
|
74
|
+
**The Flow:**
|
|
75
|
+
1. Agent A (e.g., researcher) starts task and creates plan
|
|
76
|
+
2. Agent A executes but stops/exits early with uncompleted tasks
|
|
77
|
+
3. System detects uncompleted tasks and triggers YOU
|
|
78
|
+
4. You analyze Agent A's execution state and generate continuation guidance
|
|
79
|
+
5. Your output goes DIRECTLY to Agent A as its next prompt
|
|
80
|
+
6. Agent A resumes and completes remaining work
|
|
81
|
+
|
|
82
|
+
**Your Mission:**
|
|
83
|
+
Generate a prompt that Agent A will receive to continue its work. This prompt must:
|
|
84
|
+
- Guide Agent A on what's been done and what remains
|
|
85
|
+
- Correct any protocol violations (e.g., asking questions without tool)
|
|
86
|
+
- Instruct Agent A to NOT expose internal xp* tools to the user
|
|
87
|
+
- Make Agent A's continuation feel seamless to the user
|
|
88
|
+
|
|
89
|
+
You are NOT talking to the user. You are talking to Agent A.
|
|
90
|
+
""",
|
|
91
|
+
instructions="""
|
|
92
|
+
## Your Role: Agent-to-Agent Handoff
|
|
93
|
+
|
|
94
|
+
You are writing a message that will be sent TO the agent (Agent A) to continue its task.
|
|
95
|
+
|
|
96
|
+
**Key Understanding:**
|
|
97
|
+
- Your `new_task_prompt` = The message Agent A will receive
|
|
98
|
+
- Agent A will see this message and continue working
|
|
99
|
+
- The user will see Agent A's response, not your message directly
|
|
100
|
+
- You must guide Agent A to work seamlessly without exposing internals
|
|
101
|
+
|
|
102
|
+
## Core Principles
|
|
103
|
+
|
|
104
|
+
* **You are guiding Agent A**, not the user
|
|
105
|
+
* **Agent A must complete ALL uncompleted tasks** - tell it what remains
|
|
106
|
+
* **Stay factual** - Use "Unknown" for missing info
|
|
107
|
+
* **Preserve exact state** - Keep IDs, names, paths, outputs unchanged in context
|
|
108
|
+
* **Correct violations** - If Agent A asked questions without tool, tell it to use the tool
|
|
109
|
+
* **Hide orchestration** - Instruct Agent A to NOT mention xp* tools, task IDs, or internals to user
|
|
110
|
+
|
|
111
|
+
## What You Must Capture
|
|
112
|
+
|
|
113
|
+
* **Tool call history.** For each tool: name/id, purpose, inputs (high-level), outputs (high-level), errors. Include plan tools (xpcreate_agent_plan, xpcomplete_agent_plan_item, etc.).
|
|
114
|
+
* **Artifacts and state.** All created files, IDs, URLs, variables, decisions, and configurations.
|
|
115
|
+
* **What worked / what didn't.** Successes, failures, blockers, missing info, wrong assumptions.
|
|
116
|
+
* **Task completion status.** For each uncompleted task: exact ID, title, and specific reason it's incomplete.
|
|
117
|
+
* **PROTOCOL VIOLATIONS.** Check if agent asked questions in response text AFTER calling xpstart_execution_plan (violates protocol).
|
|
118
|
+
|
|
119
|
+
## Detecting Protocol Violations
|
|
120
|
+
|
|
121
|
+
If the agent's last message contains questions to the user AFTER the plan was started (after xpstart_execution_plan was called):
|
|
122
|
+
- This is a PROTOCOL VIOLATION
|
|
123
|
+
- The agent should have used xpask_for_information tool instead
|
|
124
|
+
|
|
125
|
+
When violation is detected, you MUST make it SUPER CLEAR in BOTH output fields:
|
|
126
|
+
|
|
127
|
+
**In `new_task_prompt`:**
|
|
128
|
+
- START with: "CRITICAL PROTOCOL VIOLATION DETECTED: You asked questions directly after starting the plan."
|
|
129
|
+
- Explicitly state: "You MUST use xpask_for_information tool to ask questions once plan is running."
|
|
130
|
+
- Include: "NEVER write questions in your response text after calling xpstart_execution_plan."
|
|
131
|
+
- Then provide the continuation instructions
|
|
132
|
+
|
|
133
|
+
**In `task_context`:**
|
|
134
|
+
- Add a dedicated section at the TOP before section 1: "**PROTOCOL VIOLATION DETECTED**"
|
|
135
|
+
- State clearly: "Agent asked questions in response text after calling xpstart_execution_plan. This violates execution protocol."
|
|
136
|
+
- Remind: "Rule: After xpstart_execution_plan is called, questions MUST be asked using xpask_for_information tool, NOT written in response text."
|
|
137
|
+
|
|
138
|
+
Signs of protocol violation in messages:
|
|
139
|
+
- Phrases like "Before I proceed", "I need clarification", "Please choose", "Which option"
|
|
140
|
+
- Questions written in response text after xpstart_execution_plan was called
|
|
141
|
+
|
|
142
|
+
## Continuation Prompt: Your Message TO Agent A
|
|
143
|
+
|
|
144
|
+
Your `new_task_prompt` is what Agent A will read. Structure it as guidance TO the agent:
|
|
145
|
+
|
|
146
|
+
1. **IF protocol violation:** "You asked questions without using xpask_for_information tool. Use the tool for questions."
|
|
147
|
+
2. **Orient Agent A:** "You were working on [task]. You've completed [X, Y, Z]."
|
|
148
|
+
3. **State what remains:** "You still need to complete: [list remaining work in plain language]."
|
|
149
|
+
4. **Guide next steps:** "Continue by: [step-by-step what to do next]."
|
|
150
|
+
5. **Hide internals instruction:** "Important: Do NOT mention xp* tools, task IDs, or internal workflow to the user. Present your work naturally."
|
|
151
|
+
6. **Enforce protocol:** "Mark each task complete immediately after finishing using xpcomplete_agent_plan_item."
|
|
152
|
+
7. **Natural tone:** "Continue your response to the user seamlessly, as if you never stopped."
|
|
153
|
+
|
|
154
|
+
You are INSTRUCTING Agent A on how to continue, not writing the user-facing response yourself.
|
|
155
|
+
|
|
156
|
+
## Task Context Requirements
|
|
157
|
+
|
|
158
|
+
Your `task_context` must:
|
|
159
|
+
1. **IF protocol violation detected:** Add "PROTOCOL VIOLATION DETECTED" section at the TOP before section 1
|
|
160
|
+
2. Follow the exact 9-heading structure specified in the output schema (or 10 if violation detected)
|
|
161
|
+
3. Be deterministic and parseable by downstream systems
|
|
162
|
+
4. Focus on actionable continuation steps in section 9 (NEXT ACTIONS)
|
|
163
|
+
5. Include task IDs for all uncompleted tasks
|
|
164
|
+
6. Emphasize that ALL tasks must be completed and marked complete
|
|
165
|
+
|
|
166
|
+
## Critical Rules
|
|
167
|
+
|
|
168
|
+
❌ **NEVER:**
|
|
169
|
+
- Suggest restarting or creating a new plan
|
|
170
|
+
- Mark tasks as complete that aren't actually done
|
|
171
|
+
- Invent details or speculate
|
|
172
|
+
- Write a "fresh start" prompt
|
|
173
|
+
|
|
174
|
+
✅ **ALWAYS:**
|
|
175
|
+
- Write as instructions TO Agent A (you're guiding it, not doing its work)
|
|
176
|
+
- Tell Agent A what it's done and what remains
|
|
177
|
+
- Instruct Agent A to complete remaining tasks
|
|
178
|
+
- Tell Agent A to use correct tools (xpask_for_information for questions)
|
|
179
|
+
- Instruct Agent A to hide xp* tools and internals from user
|
|
180
|
+
- Include technical details (task IDs, tool names) in task_context for Agent A's reference
|
|
181
|
+
- Correct any protocol violations Agent A made
|
|
182
|
+
""",
|
|
183
|
+
expected_output="""
|
|
184
|
+
Return a JSON object with exactly these two fields:
|
|
185
|
+
|
|
186
|
+
- new_task_prompt (string): Instructions TO Agent A for continuing its task.
|
|
187
|
+
|
|
188
|
+
This message will be sent directly to Agent A. Write it as guidance:
|
|
189
|
+
|
|
190
|
+
IF PROTOCOL VIOLATION:
|
|
191
|
+
"You asked questions without using xpask_for_information tool. Use the tool for questions after plan starts."
|
|
192
|
+
|
|
193
|
+
Then:
|
|
194
|
+
"You were working on [task name]. You've completed [work done in plain language].
|
|
195
|
+
|
|
196
|
+
You still need to complete: [list remaining uncompleted work naturally].
|
|
197
|
+
|
|
198
|
+
Continue by: [specific steps for Agent A to take].
|
|
199
|
+
|
|
200
|
+
IMPORTANT: When responding to the user, do NOT mention xp* tools, task IDs, or internal workflow.
|
|
201
|
+
Present your work naturally as if execution never stopped. The user should not see any interruption.
|
|
202
|
+
|
|
203
|
+
Mark each task complete immediately after finishing using xpcomplete_agent_plan_item."
|
|
204
|
+
|
|
205
|
+
- task_context (string): Comprehensive context for continuation.
|
|
206
|
+
IF PROTOCOL VIOLATION DETECTED:
|
|
207
|
+
- Add section at TOP: "**PROTOCOL VIOLATION DETECTED**\nAgent asked questions in response text after calling xpstart_execution_plan. This violates execution protocol. Rule: After xpstart_execution_plan is called, questions MUST be asked using xpask_for_information tool, NOT written in response text.\n\n"
|
|
208
|
+
Then follow the EXACT 9-section structure defined in TaskCompactizationOutput.task_context.
|
|
209
|
+
Must be deterministic, actionable, and focused on completing ALL remaining tasks and marking them as completed.
|
|
210
|
+
|
|
211
|
+
Important:
|
|
212
|
+
- Do NOT invent details; write 'Unknown' when information is missing.
|
|
213
|
+
- Preserve exact IDs, names, file paths, numbers, and user phrasing.
|
|
214
|
+
- Final actions must include marking each remaining task as completed with the plan tools.
|
|
215
|
+
- IF protocol violation: Make it SUPER CLEAR in both fields that tool must be used for questions.
|
|
216
|
+
"""
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
session = agent.get_session(session_id=task.id)
|
|
220
|
+
|
|
221
|
+
# run compactization
|
|
222
|
+
run_result = compactization_agent.run(
|
|
223
|
+
input=TaskCompactizationInput(
|
|
224
|
+
user_input=task.input,
|
|
225
|
+
agent_instructions=agent.instructions,
|
|
226
|
+
task_context_and_messages=json.dumps({"messages": [message.model_dump() for message in session.get_messages() if message.role != "system"]}),
|
|
227
|
+
uncompleted_tasks=uncompleted_tasks
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# reset old session
|
|
232
|
+
agent.delete_session(session_id=task.id)
|
|
233
|
+
|
|
234
|
+
# report LLM Metrics
|
|
235
|
+
task.tokens = Tokens(
|
|
236
|
+
completion_tokens=run_result.metrics.output_tokens,
|
|
237
|
+
prompt_tokens=run_result.metrics.input_tokens
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
task.report_metrics(configuration=task.configuration)
|
|
241
|
+
|
|
242
|
+
# report compactization event
|
|
243
|
+
try:
|
|
244
|
+
run_sync(
|
|
245
|
+
push_event(
|
|
246
|
+
task=task,
|
|
247
|
+
event=TaskCompactizationEvent(type="summarization", data=run_result.content),
|
|
248
|
+
event_type=TaskUpdateEventType.TaskCompactization
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
except Exception as e:
|
|
252
|
+
pass
|
|
253
|
+
|
|
254
|
+
return run_result.content
|
|
255
|
+
except Exception as e:
|
|
256
|
+
logger.warning(f"Failed to run task compactization - {str(e)}")
|
|
257
|
+
return message
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xpander-sdk
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.192
|
|
4
4
|
Summary: xpander.ai Backend-as-a-service for AI Agents - SDK
|
|
5
5
|
Home-page: https://www.xpander.ai
|
|
6
6
|
Author: xpanderAI
|
|
@@ -11,15 +11,16 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: >=3.9
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
-
Requires-Dist: python-dotenv
|
|
15
|
-
Requires-Dist: packaging
|
|
16
|
-
Requires-Dist: pydantic
|
|
17
|
-
Requires-Dist: loguru
|
|
18
|
-
Requires-Dist: httpx
|
|
19
|
-
Requires-Dist: httpx_sse
|
|
20
|
-
Requires-Dist: nest-asyncio
|
|
21
|
-
Requires-Dist: strands-agents
|
|
22
|
-
Requires-Dist: openai-agents
|
|
14
|
+
Requires-Dist: python-dotenv>=1.2.1
|
|
15
|
+
Requires-Dist: packaging>=25.0
|
|
16
|
+
Requires-Dist: pydantic>=2.12.5
|
|
17
|
+
Requires-Dist: loguru>=0.7.3
|
|
18
|
+
Requires-Dist: httpx>=0.28.1
|
|
19
|
+
Requires-Dist: httpx_sse>=0.4.3
|
|
20
|
+
Requires-Dist: nest-asyncio>=1.6.0
|
|
21
|
+
Requires-Dist: strands-agents>=1.20.0
|
|
22
|
+
Requires-Dist: openai-agents>=0.6.4
|
|
23
|
+
Requires-Dist: python-toon>=0.1.3
|
|
23
24
|
Provides-Extra: agno
|
|
24
25
|
Requires-Dist: agno; extra == "agno"
|
|
25
26
|
Requires-Dist: sqlalchemy; extra == "agno"
|
|
@@ -47,7 +48,7 @@ Dynamic: requires-dist
|
|
|
47
48
|
Dynamic: requires-python
|
|
48
49
|
Dynamic: summary
|
|
49
50
|
|
|
50
|
-
# xpander.ai SDK
|
|
51
|
+
# xpander.ai SDK
|
|
51
52
|
|
|
52
53
|
[](https://www.python.org/downloads/) [](https://opensource.org/licenses/MIT) [](https://docs.xpander.ai) [](https://pypi.org/project/xpander-sdk/) [](https://pepy.tech/project/xpander-sdk)
|
|
53
54
|
|
|
@@ -292,6 +293,89 @@ async for event in task.aevents():
|
|
|
292
293
|
print(f"Event Data: {event.data}")
|
|
293
294
|
```
|
|
294
295
|
|
|
296
|
+
### Authentication Events Callback
|
|
297
|
+
|
|
298
|
+
Handle authentication events in real-time. This callback is triggered only for authentication flows (e.g., MCP OAuth requiring user login).
|
|
299
|
+
|
|
300
|
+
**You can use both approaches simultaneously** - decorated handlers will always be invoked, and you can also pass an explicit callback for additional handling.
|
|
301
|
+
|
|
302
|
+
You can provide the callback in two ways:
|
|
303
|
+
|
|
304
|
+
#### Option 1: Direct Function
|
|
305
|
+
|
|
306
|
+
```python
|
|
307
|
+
from xpander_sdk import Backend
|
|
308
|
+
from xpander_sdk.modules.agents.sub_modules.agent import Agent
|
|
309
|
+
from xpander_sdk.modules.tasks.sub_modules.task import Task, TaskUpdateEvent
|
|
310
|
+
from agno.agent import Agent as AgnoAgent
|
|
311
|
+
|
|
312
|
+
# Define event callback (async or sync)
|
|
313
|
+
async def my_event_callback(agent: Agent, task: Task, event: TaskUpdateEvent):
|
|
314
|
+
"""Called for authentication events only"""
|
|
315
|
+
# event.type will always be "auth_event"
|
|
316
|
+
print(f"Authentication required: {event.data}")
|
|
317
|
+
# Display login URL or handle OAuth flow
|
|
318
|
+
|
|
319
|
+
# Get args with callback
|
|
320
|
+
backend = Backend(configuration=config)
|
|
321
|
+
args = await backend.aget_args(
|
|
322
|
+
agent_id="agent-123",
|
|
323
|
+
task=my_task,
|
|
324
|
+
auth_events_callback=my_event_callback
|
|
325
|
+
)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
#### Option 2: Decorator (Auto-registered)
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
from xpander_sdk import Backend, on_auth_event
|
|
332
|
+
from xpander_sdk.modules.agents.sub_modules.agent import Agent
|
|
333
|
+
from xpander_sdk.modules.tasks.sub_modules.task import Task, TaskUpdateEvent
|
|
334
|
+
from agno.agent import Agent as AgnoAgent
|
|
335
|
+
|
|
336
|
+
# Use decorator - auto-registers globally
|
|
337
|
+
@on_auth_event
|
|
338
|
+
async def handle_auth(agent: Agent, task: Task, event: TaskUpdateEvent):
|
|
339
|
+
# event.type will always be "auth_event"
|
|
340
|
+
print(f"Authentication required for {agent.name}")
|
|
341
|
+
print(f"Auth data: {event.data}")
|
|
342
|
+
|
|
343
|
+
# Decorated handler is automatically invoked - no need to pass it
|
|
344
|
+
backend = Backend(configuration=config)
|
|
345
|
+
args = await backend.aget_args(
|
|
346
|
+
agent_id="agent-123",
|
|
347
|
+
task=my_task
|
|
348
|
+
)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### Option 3: Combine Both
|
|
352
|
+
|
|
353
|
+
```python
|
|
354
|
+
from xpander_sdk import Backend, on_auth_event
|
|
355
|
+
|
|
356
|
+
# Global handler for all auth events
|
|
357
|
+
@on_auth_event
|
|
358
|
+
async def log_auth(agent, task, event):
|
|
359
|
+
print(f"[GLOBAL] Auth event for {agent.name}")
|
|
360
|
+
|
|
361
|
+
# Additional one-time handler
|
|
362
|
+
async def custom_handler(agent, task, event):
|
|
363
|
+
print(f"[CUSTOM] Specific handling for this call")
|
|
364
|
+
|
|
365
|
+
# Both handlers will be invoked
|
|
366
|
+
args = await backend.aget_args(
|
|
367
|
+
agent_id="agent-123",
|
|
368
|
+
auth_events_callback=custom_handler # Optional additional callback
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
# Use with Agno
|
|
372
|
+
agno_agent = AgnoAgent(**args)
|
|
373
|
+
result = await agno_agent.arun(
|
|
374
|
+
input="Process this data",
|
|
375
|
+
stream=True
|
|
376
|
+
)
|
|
377
|
+
```
|
|
378
|
+
|
|
295
379
|
### Task Activity Monitoring
|
|
296
380
|
|
|
297
381
|
```python
|
|
@@ -483,11 +567,11 @@ async def main():
|
|
|
483
567
|
organization_id="your-org-id",
|
|
484
568
|
base_url="https://agent-controller.my-company.com"
|
|
485
569
|
)
|
|
486
|
-
|
|
570
|
+
|
|
487
571
|
# Load agent from self-hosted deployment
|
|
488
572
|
agent = await Agent.aload("agent-123", configuration=config)
|
|
489
573
|
print(f"Agent: {agent.name}")
|
|
490
|
-
|
|
574
|
+
|
|
491
575
|
# Create and execute task
|
|
492
576
|
task = await agent.acreate_task(
|
|
493
577
|
prompt="Analyze Q4 sales data",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
xpander_sdk/__init__.py,sha256=
|
|
1
|
+
xpander_sdk/__init__.py,sha256=34l3YcvIdkj81DTfMp_bgZgXpj2U1lTKpHQ0shwnc_8,2927
|
|
2
2
|
xpander_sdk/consts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
xpander_sdk/consts/api_routes.py,sha256=
|
|
3
|
+
xpander_sdk/consts/api_routes.py,sha256=jRIxZqqufz14FOwE9gcFMURtm99vQ5g4uw6QLEAS6ks,2621
|
|
4
4
|
xpander_sdk/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
xpander_sdk/core/module_base.py,sha256=YiUonUBXnXqa9wms5O8C9tEfQeWBJCIZg6xzEorV8gI,5480
|
|
6
6
|
xpander_sdk/core/state.py,sha256=GKGJaMALpTGVV2-iPV3cPrQW4dNdFoZPv3oXBjHDhIY,214
|
|
@@ -9,36 +9,44 @@ xpander_sdk/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
9
9
|
xpander_sdk/exceptions/module_exception.py,sha256=2Urni1QEdzOrCdYSRc5eLpuz8aDlvRcn8KNejo_2nGc,1687
|
|
10
10
|
xpander_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
xpander_sdk/models/activity.py,sha256=I3CxOzUNbrKwHqynCbm7FJja6vanVkCzwwBwET7qvzA,2085
|
|
12
|
+
xpander_sdk/models/compactization.py,sha256=I0tfDQZKaaKvWHIg1O07oJUPUrbwvr4Q0azDsx5OfAE,5596
|
|
12
13
|
xpander_sdk/models/configuration.py,sha256=Un8p3C3p3eMiqKK5VsHaZdWhZTRYHbrw2aPUMV8lJSc,3370
|
|
13
14
|
xpander_sdk/models/deep_planning.py,sha256=pCFV5iNSfT99ap1-09k7oO_DIwXx2vPJ3aVM472xL4w,554
|
|
14
|
-
xpander_sdk/models/events.py,sha256=
|
|
15
|
-
xpander_sdk/models/frameworks.py,sha256
|
|
15
|
+
xpander_sdk/models/events.py,sha256=HnootQSUIIRM4BIdaTbuPUEJ55hLVtA7KDCSsnHeBKw,2313
|
|
16
|
+
xpander_sdk/models/frameworks.py,sha256=-7W_m5cvgS1qLp0gGAFP4noNWT82IT1ZqtQv5WuOC2k,2939
|
|
17
|
+
xpander_sdk/models/generic.py,sha256=yw5rBRdZ-6ucTI4AwtskenddepOooiFRM--9xx5jrL8,681
|
|
18
|
+
xpander_sdk/models/notifications.py,sha256=3tK4Z2gmA6YxRtqsWgzjiVISgJyHvmjTooiRgzrj5zY,3373
|
|
19
|
+
xpander_sdk/models/orchestrations.py,sha256=uMXkTZ_tdE10rbVUy8H8vxfh71HZGZcaJUEy61wwz2k,9898
|
|
16
20
|
xpander_sdk/models/shared.py,sha256=gW88kA_UslNinUjtQKpLVF0sHDZnckwLWexRapxPivU,3125
|
|
17
21
|
xpander_sdk/models/user.py,sha256=_FTG0JO6iTrbcvJp-BBJ6nuj281zhyQB5ldQkBCyYDU,749
|
|
18
22
|
xpander_sdk/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
23
|
xpander_sdk/modules/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
24
|
xpander_sdk/modules/agents/agents_module.py,sha256=3EhKOIPb4c39GOrNt4zU4V6WbsGj7W_yWwRNSJBKmfc,6419
|
|
21
25
|
xpander_sdk/modules/agents/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
xpander_sdk/modules/agents/models/agent.py,sha256=
|
|
26
|
+
xpander_sdk/modules/agents/models/agent.py,sha256=lHWz37a4_qB9Hq4sZhvjILjj566hJHZbDlj7JJ6iO68,15340
|
|
23
27
|
xpander_sdk/modules/agents/models/agent_list.py,sha256=byEayS2uLwDKaVT3lAHltrFocQFKpr8XEwQ6NTEEEMo,4081
|
|
24
28
|
xpander_sdk/modules/agents/models/knowledge_bases.py,sha256=YimpjVJxWe8YTbGMD6oGQOA_YV8ztHQHTTBOaBB44ZM,1037
|
|
25
29
|
xpander_sdk/modules/agents/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
xpander_sdk/modules/agents/sub_modules/agent.py,sha256=
|
|
30
|
+
xpander_sdk/modules/agents/sub_modules/agent.py,sha256=O3y2qKAFb19yO7gt2Ey6BNJGwA9cMHMuKG4_iNjqKL0,36841
|
|
27
31
|
xpander_sdk/modules/agents/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
32
|
xpander_sdk/modules/agents/utils/generic.py,sha256=XbG4OeHMQo4gVYCsasMlW_b8OoqS1xL3MlUZSjXivu0,81
|
|
29
|
-
xpander_sdk/modules/backend/__init__.py,sha256
|
|
30
|
-
xpander_sdk/modules/backend/backend_module.py,sha256=
|
|
33
|
+
xpander_sdk/modules/backend/__init__.py,sha256=-NjikuZgHBhOM9xHML2vKsG0ICX9S2RKHktrWaODCBE,171
|
|
34
|
+
xpander_sdk/modules/backend/backend_module.py,sha256=A8NW5QqVy28O-E5eL1VU2iUHgtxyz7rFN7Ih0Jnv-TE,21713
|
|
35
|
+
xpander_sdk/modules/backend/events_registry.py,sha256=d0V-lsz3I3G1QB643EM1i-a5oJCiHnEfqBY_SmN2WrE,5983
|
|
36
|
+
xpander_sdk/modules/backend/decorators/__init__.py,sha256=ub9c8G0Ll6AuCvfcFB6rqR8iamMJxtcW7QjWw3WSkPU,106
|
|
37
|
+
xpander_sdk/modules/backend/decorators/on_auth_event.py,sha256=Xt_x9nncujMcF_SgM5hG6M-iZ6B-rDS97EPmgZkGdMk,4715
|
|
31
38
|
xpander_sdk/modules/backend/frameworks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
xpander_sdk/modules/backend/frameworks/agno.py,sha256=
|
|
33
|
-
xpander_sdk/modules/backend/frameworks/dispatch.py,sha256=
|
|
39
|
+
xpander_sdk/modules/backend/frameworks/agno.py,sha256=djHGWFGaMOetKfD6XNKEYxYzBm8GwPlhuPFRkB8PFkg,41712
|
|
40
|
+
xpander_sdk/modules/backend/frameworks/dispatch.py,sha256=ht9hT5-cHATofQbWsbWeTARx51Hne3TNNNjw6KECRtA,1814
|
|
34
41
|
xpander_sdk/modules/backend/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
xpander_sdk/modules/backend/utils/mcp_oauth.py,sha256=
|
|
42
|
+
xpander_sdk/modules/backend/utils/mcp_oauth.py,sha256=5sYJcw557V3pSgutxUFzkBp5YxUJFUoB1V1rEe814pc,5430
|
|
36
43
|
xpander_sdk/modules/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
xpander_sdk/modules/events/events_module.py,sha256=
|
|
38
|
-
xpander_sdk/modules/events/decorators/__init__.py,sha256=
|
|
44
|
+
xpander_sdk/modules/events/events_module.py,sha256=tAjfc6kfjgmswQkgm-rcVs8wVpOYYPv03kqZHTVE8Uo,25737
|
|
45
|
+
xpander_sdk/modules/events/decorators/__init__.py,sha256=8GhR9afoLiS83a0OMLpn7TN2W6iTnlcVqos6bM34nac,129
|
|
39
46
|
xpander_sdk/modules/events/decorators/on_boot.py,sha256=VGtoQcgs3g5bmx3Ze4QB_-ZwBESATYYVR0oZe35eCww,3076
|
|
40
47
|
xpander_sdk/modules/events/decorators/on_shutdown.py,sha256=rFgChspnLDnZm9FS1K636dvZSQDkeugf2e3M83SDgAY,3127
|
|
41
48
|
xpander_sdk/modules/events/decorators/on_task.py,sha256=G3jk0xzi3pqH96Bbut_GMJKExIlyyMYk4PbKfc6koa4,8551
|
|
49
|
+
xpander_sdk/modules/events/decorators/on_tool.py,sha256=ZacZ6tADjvl79ISqKxTSH1P0nZUS8C3mRwOL2SyLeZE,13750
|
|
42
50
|
xpander_sdk/modules/events/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
51
|
xpander_sdk/modules/events/models/deployments.py,sha256=6uwxFsybrZ-eHeohJzkm2RtQq4Eo_0xjHk7QouvszxU,1335
|
|
44
52
|
xpander_sdk/modules/events/models/events.py,sha256=T_89pq48e7fMIbJcCbtM9Ocb6YKXQP7pbF6VbECiGcI,1550
|
|
@@ -56,10 +64,10 @@ xpander_sdk/modules/knowledge_bases/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-
|
|
|
56
64
|
xpander_sdk/modules/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
65
|
xpander_sdk/modules/tasks/tasks_module.py,sha256=wOMegfNQ4qoY7PEII5828SjWrP0Jocg2TRsFOaaCmW0,20444
|
|
58
66
|
xpander_sdk/modules/tasks/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
-
xpander_sdk/modules/tasks/models/task.py,sha256=
|
|
67
|
+
xpander_sdk/modules/tasks/models/task.py,sha256=pYzXg0jnE6ft4pVFvxiVexO5eMUFkg1VxXybzFtL1ys,4483
|
|
60
68
|
xpander_sdk/modules/tasks/models/tasks_list.py,sha256=8V1T0vCtGN79qLMPwe37pOA7Wvuf8pbJNOhWL0BPo-8,5126
|
|
61
69
|
xpander_sdk/modules/tasks/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
62
|
-
xpander_sdk/modules/tasks/sub_modules/task.py,sha256=
|
|
70
|
+
xpander_sdk/modules/tasks/sub_modules/task.py,sha256=zRDHsE_LnYYa3OC79wVQqeRnpAogddHVI2R6-3IepJ4,37920
|
|
63
71
|
xpander_sdk/modules/tasks/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
72
|
xpander_sdk/modules/tasks/utils/files.py,sha256=KqqwSQSrwim2-H3XP5wOadDDfngAyEI034tA7Oon-vc,3631
|
|
65
73
|
xpander_sdk/modules/tools_repository/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -70,17 +78,20 @@ xpander_sdk/modules/tools_repository/models/__init__.py,sha256=47DEQpj8HBSa-_TIm
|
|
|
70
78
|
xpander_sdk/modules/tools_repository/models/mcp.py,sha256=qGpaiXKiuXw6gAcK8CW6ek6FkZNbBxDXUf1PWF6Tenw,1863
|
|
71
79
|
xpander_sdk/modules/tools_repository/models/tool_invocation_result.py,sha256=Dhowt_fv8v8xWv7xMRJxo6hA8DawXKbWIrsJFMpt5H4,447
|
|
72
80
|
xpander_sdk/modules/tools_repository/sub_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
-
xpander_sdk/modules/tools_repository/sub_modules/tool.py,sha256=
|
|
81
|
+
xpander_sdk/modules/tools_repository/sub_modules/tool.py,sha256=rivnznxi6CrrOWE1rukkBRmad2H-rthhrelC7ei1IXM,23617
|
|
74
82
|
xpander_sdk/modules/tools_repository/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
-
xpander_sdk/modules/tools_repository/utils/generic.py,sha256=
|
|
83
|
+
xpander_sdk/modules/tools_repository/utils/generic.py,sha256=bQ31-RoAq12lpDoIWsgmqAt7NL5YdzW1j3WKqZtYb2A,1904
|
|
76
84
|
xpander_sdk/modules/tools_repository/utils/local_tools.py,sha256=zp5P8hVnRUJQb-w-2jCEMV5eUB_awmvYfY_rin5qvEw,1875
|
|
77
85
|
xpander_sdk/modules/tools_repository/utils/schemas.py,sha256=EUi35h7CRrOVXV-TH-lyCpOdK5pu1uODDxvGB1JGDXY,13734
|
|
78
86
|
xpander_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
87
|
xpander_sdk/utils/env.py,sha256=U_zIhqWgKs5fk2-HXjAaODj4oWMc5dRQ0fvw6fqVcFk,1522
|
|
80
88
|
xpander_sdk/utils/event_loop.py,sha256=kJrN0upgBhyI86tkTdfHeajznrIZl44Rl6WDiDG3GHE,2516
|
|
89
|
+
xpander_sdk/utils/generic.py,sha256=XrRj2-L8c0YWpfPdDyXE-pVL-6lKF9VpyZzKHQ4wuCc,127
|
|
81
90
|
xpander_sdk/utils/tools.py,sha256=lyFkq2yP7DxBkyXYVlnFRwDhQCvf0fZZMDm5fBycze4,1244
|
|
82
|
-
xpander_sdk
|
|
83
|
-
xpander_sdk
|
|
84
|
-
xpander_sdk-2.0.
|
|
85
|
-
xpander_sdk-2.0.
|
|
86
|
-
xpander_sdk-2.0.
|
|
91
|
+
xpander_sdk/utils/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
92
|
+
xpander_sdk/utils/agents/compactization_agent.py,sha256=S_U1dSmDC7I0JUsp_THUYjfutEI5QMBaMPJEXGp0_Sw,14389
|
|
93
|
+
xpander_sdk-2.0.192.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
94
|
+
xpander_sdk-2.0.192.dist-info/METADATA,sha256=NM6k5GsEGHR8qvT1GWi7H9s3C4R_5OvE-Pwm1eWnh0g,17945
|
|
95
|
+
xpander_sdk-2.0.192.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
96
|
+
xpander_sdk-2.0.192.dist-info/top_level.txt,sha256=UCjnxQpsMy5Zoe7lmRuVDO6DI2V_6PgRFfm4oizRbVs,12
|
|
97
|
+
xpander_sdk-2.0.192.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|