zero-agent-core-multi-agent 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,450 @@
1
+ """多 Agent 编排的可持久化值对象。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+ from dataclasses import dataclass, field, replace
7
+ from datetime import UTC, datetime
8
+ from typing import Any, Literal, cast
9
+
10
+ from agent_core import AccessContext, RunEvent
11
+
12
+ AgentResultStatus = Literal["completed", "failed", "cancelled", "interrupted"]
13
+ CoordinationStatus = Literal["queued", "running", "completed", "failed", "cancelled", "interrupted"]
14
+
15
+
16
+ def _now() -> str:
17
+ return datetime.now(UTC).isoformat()
18
+
19
+
20
+ def _non_empty(value: str, field_name: str) -> str:
21
+ normalized = value.strip()
22
+ if not normalized:
23
+ raise ValueError(f"{field_name} 不能为空")
24
+ return normalized
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class AgentDescriptor:
29
+ """一个可被 Supervisor 发现和调用的 Agent。"""
30
+
31
+ agent_id: str
32
+ description: str
33
+ capabilities: frozenset[str] = field(default_factory=frozenset)
34
+ aliases: frozenset[str] = field(default_factory=frozenset)
35
+ required_roles: frozenset[str] = field(default_factory=frozenset)
36
+ priority: int = 0
37
+ max_concurrency: int | None = None
38
+ metadata: dict[str, Any] = field(default_factory=dict)
39
+
40
+ def __post_init__(self) -> None:
41
+ object.__setattr__(self, "agent_id", _non_empty(self.agent_id, "agent_id"))
42
+ object.__setattr__(self, "description", _non_empty(self.description, "description"))
43
+ object.__setattr__(
44
+ self,
45
+ "capabilities",
46
+ frozenset(_non_empty(value, "capability") for value in self.capabilities),
47
+ )
48
+ object.__setattr__(
49
+ self,
50
+ "aliases",
51
+ frozenset(_non_empty(value, "alias") for value in self.aliases),
52
+ )
53
+ object.__setattr__(
54
+ self,
55
+ "required_roles",
56
+ frozenset(_non_empty(value, "required_role") for value in self.required_roles),
57
+ )
58
+ object.__setattr__(self, "metadata", dict(self.metadata))
59
+ if self.agent_id in self.aliases:
60
+ raise ValueError("aliases 不需要重复 agent_id")
61
+ if self.max_concurrency is not None and self.max_concurrency <= 0:
62
+ raise ValueError("max_concurrency 必须大于 0")
63
+
64
+ def can_invoke(self, access: AccessContext | None) -> bool:
65
+ if not self.required_roles:
66
+ return True
67
+ return access is not None and self.required_roles.issubset(access.roles)
68
+
69
+ def to_dict(self) -> dict[str, Any]:
70
+ return {
71
+ "agent_id": self.agent_id,
72
+ "description": self.description,
73
+ "capabilities": sorted(self.capabilities),
74
+ "aliases": sorted(self.aliases),
75
+ "required_roles": sorted(self.required_roles),
76
+ "priority": self.priority,
77
+ "max_concurrency": self.max_concurrency,
78
+ "metadata": dict(self.metadata),
79
+ }
80
+
81
+
82
+ @dataclass(frozen=True)
83
+ class HandoffRequest:
84
+ """当前 Agent 请求把任务交给另一个 Agent。"""
85
+
86
+ target_agent_id: str | None = None
87
+ required_capability: str | None = None
88
+ input: str | None = None
89
+ reason: str = ""
90
+ context: dict[str, Any] = field(default_factory=dict)
91
+ metadata: dict[str, Any] = field(default_factory=dict)
92
+
93
+ def __post_init__(self) -> None:
94
+ target = self.target_agent_id.strip() if self.target_agent_id else None
95
+ capability = self.required_capability.strip() if self.required_capability else None
96
+ if not target and not capability:
97
+ raise ValueError("handoff 必须指定 target_agent_id 或 required_capability")
98
+ object.__setattr__(self, "target_agent_id", target)
99
+ object.__setattr__(self, "required_capability", capability)
100
+ object.__setattr__(self, "context", dict(self.context))
101
+ object.__setattr__(self, "metadata", dict(self.metadata))
102
+
103
+ def to_dict(self) -> dict[str, Any]:
104
+ return {
105
+ "target_agent_id": self.target_agent_id,
106
+ "required_capability": self.required_capability,
107
+ "input": self.input,
108
+ "reason": self.reason,
109
+ "context": dict(self.context),
110
+ "metadata": dict(self.metadata),
111
+ }
112
+
113
+ @classmethod
114
+ def from_dict(cls, value: dict[str, Any]) -> HandoffRequest:
115
+ return cls(
116
+ target_agent_id=value.get("target_agent_id"),
117
+ required_capability=value.get("required_capability"),
118
+ input=value.get("input"),
119
+ reason=str(value.get("reason", "")),
120
+ context=dict(value.get("context") or {}),
121
+ metadata=dict(value.get("metadata") or {}),
122
+ )
123
+
124
+
125
+ @dataclass(frozen=True)
126
+ class AgentTask:
127
+ """Supervisor 交给某个 Agent 的不可变任务。"""
128
+
129
+ input: str
130
+ thread_id: str
131
+ target_agent_id: str | None = None
132
+ required_capability: str | None = None
133
+ context: dict[str, Any] = field(default_factory=dict)
134
+ access: AccessContext | None = None
135
+ metadata: dict[str, Any] = field(default_factory=dict)
136
+ task_id: str = field(default_factory=lambda: str(uuid.uuid4()))
137
+ root_task_id: str | None = None
138
+ parent_task_id: str | None = None
139
+ parent_run_id: str | None = None
140
+ coordination_id: str | None = None
141
+ idempotency_key: str | None = None
142
+ resume_requested: bool = False
143
+ depth: int = 0
144
+ lineage: tuple[str, ...] = ()
145
+
146
+ def __post_init__(self) -> None:
147
+ object.__setattr__(self, "input", _non_empty(self.input, "input"))
148
+ object.__setattr__(self, "thread_id", _non_empty(self.thread_id, "thread_id"))
149
+ object.__setattr__(self, "task_id", _non_empty(self.task_id, "task_id"))
150
+ object.__setattr__(self, "root_task_id", self.root_task_id or self.task_id)
151
+ object.__setattr__(self, "context", dict(self.context))
152
+ object.__setattr__(self, "metadata", dict(self.metadata))
153
+ object.__setattr__(self, "lineage", tuple(self.lineage))
154
+ if self.depth < 0:
155
+ raise ValueError("depth 不能小于 0")
156
+ if self.target_agent_id is not None and not self.target_agent_id.strip():
157
+ raise ValueError("target_agent_id 不能为空字符串")
158
+ if self.required_capability is not None and not self.required_capability.strip():
159
+ raise ValueError("required_capability 不能为空字符串")
160
+ if self.target_agent_id is not None:
161
+ object.__setattr__(self, "target_agent_id", self.target_agent_id.strip())
162
+ if self.required_capability is not None:
163
+ object.__setattr__(self, "required_capability", self.required_capability.strip())
164
+
165
+ def bind_execution(self, execution_id: str) -> AgentTask:
166
+ """把根任务绑定到协调实例,并生成稳定的子调用幂等键。"""
167
+ return replace(
168
+ self,
169
+ coordination_id=execution_id,
170
+ idempotency_key=self.idempotency_key or f"multi-agent:{execution_id}:{self.task_id}",
171
+ )
172
+
173
+ def handoff(
174
+ self,
175
+ request: HandoffRequest,
176
+ *,
177
+ current_agent_id: str,
178
+ parent_run_id: str | None,
179
+ fallback_input: str,
180
+ ) -> AgentTask:
181
+ """从 handoff 请求构造下一个子任务。"""
182
+ task_id = str(uuid.uuid4())
183
+ context = {**self.context, **request.context}
184
+ metadata = {**self.metadata, **request.metadata, "handoff_reason": request.reason}
185
+ return AgentTask(
186
+ task_id=task_id,
187
+ root_task_id=self.root_task_id,
188
+ parent_task_id=self.task_id,
189
+ parent_run_id=parent_run_id or self.parent_run_id,
190
+ coordination_id=self.coordination_id,
191
+ thread_id=self.thread_id,
192
+ input=request.input or fallback_input,
193
+ target_agent_id=request.target_agent_id,
194
+ required_capability=request.required_capability,
195
+ context=context,
196
+ access=self.access,
197
+ metadata=metadata,
198
+ idempotency_key=f"multi-agent:{self.coordination_id}:{task_id}",
199
+ depth=self.depth + 1,
200
+ lineage=(*self.lineage, current_agent_id),
201
+ )
202
+
203
+ def to_dict(self) -> dict[str, Any]:
204
+ return {
205
+ "task_id": self.task_id,
206
+ "root_task_id": self.root_task_id,
207
+ "parent_task_id": self.parent_task_id,
208
+ "parent_run_id": self.parent_run_id,
209
+ "coordination_id": self.coordination_id,
210
+ "thread_id": self.thread_id,
211
+ "input": self.input,
212
+ "target_agent_id": self.target_agent_id,
213
+ "required_capability": self.required_capability,
214
+ "context": dict(self.context),
215
+ "access": self.access.to_dict() if self.access else None,
216
+ "metadata": dict(self.metadata),
217
+ "idempotency_key": self.idempotency_key,
218
+ "resume_requested": self.resume_requested,
219
+ "depth": self.depth,
220
+ "lineage": list(self.lineage),
221
+ }
222
+
223
+ @classmethod
224
+ def from_dict(cls, value: dict[str, Any]) -> AgentTask:
225
+ access_value = value.get("access")
226
+ access = None
227
+ if isinstance(access_value, dict):
228
+ access = AccessContext(
229
+ user_id=str(access_value.get("user_id", "anonymous")),
230
+ tenant_id=str(access_value.get("tenant_id", "default")),
231
+ roles=frozenset(str(role) for role in access_value.get("roles", ["user"])),
232
+ )
233
+ return cls(
234
+ task_id=str(value["task_id"]),
235
+ root_task_id=value.get("root_task_id"),
236
+ parent_task_id=value.get("parent_task_id"),
237
+ parent_run_id=value.get("parent_run_id"),
238
+ coordination_id=value.get("coordination_id"),
239
+ thread_id=str(value["thread_id"]),
240
+ input=str(value["input"]),
241
+ target_agent_id=value.get("target_agent_id"),
242
+ required_capability=value.get("required_capability"),
243
+ context=dict(value.get("context") or {}),
244
+ access=access,
245
+ metadata=dict(value.get("metadata") or {}),
246
+ idempotency_key=value.get("idempotency_key"),
247
+ resume_requested=bool(value.get("resume_requested", False)),
248
+ depth=int(value.get("depth", 0)),
249
+ lineage=tuple(str(item) for item in value.get("lineage", [])),
250
+ )
251
+
252
+
253
+ @dataclass(frozen=True)
254
+ class AgentResult:
255
+ """子 Agent 的统一执行结果。"""
256
+
257
+ task_id: str
258
+ agent_id: str
259
+ status: AgentResultStatus
260
+ output: str = ""
261
+ run_id: str | None = None
262
+ handoff: HandoffRequest | None = None
263
+ error: str | None = None
264
+ retryable: bool = False
265
+ usage: dict[str, float] = field(default_factory=dict)
266
+ metadata: dict[str, Any] = field(default_factory=dict)
267
+
268
+ def __post_init__(self) -> None:
269
+ object.__setattr__(self, "task_id", _non_empty(self.task_id, "task_id"))
270
+ object.__setattr__(self, "agent_id", _non_empty(self.agent_id, "agent_id"))
271
+ object.__setattr__(self, "usage", {str(key): float(value) for key, value in self.usage.items()})
272
+ object.__setattr__(self, "metadata", dict(self.metadata))
273
+ if self.status not in {"completed", "failed", "cancelled", "interrupted"}:
274
+ raise ValueError(f"无效 AgentResult status:{self.status}")
275
+ if self.handoff is not None and self.status != "completed":
276
+ raise ValueError("只有 completed 结果可以携带 handoff")
277
+ if self.status == "failed" and not self.error:
278
+ raise ValueError("failed 结果必须提供 error")
279
+
280
+ def to_dict(self) -> dict[str, Any]:
281
+ return {
282
+ "task_id": self.task_id,
283
+ "agent_id": self.agent_id,
284
+ "status": self.status,
285
+ "output": self.output,
286
+ "run_id": self.run_id,
287
+ "handoff": self.handoff.to_dict() if self.handoff else None,
288
+ "error": self.error,
289
+ "retryable": self.retryable,
290
+ "usage": dict(self.usage),
291
+ "metadata": dict(self.metadata),
292
+ }
293
+
294
+ @classmethod
295
+ def from_dict(cls, value: dict[str, Any]) -> AgentResult:
296
+ handoff = value.get("handoff")
297
+ return cls(
298
+ task_id=str(value["task_id"]),
299
+ agent_id=str(value["agent_id"]),
300
+ status=cast(AgentResultStatus, value["status"]),
301
+ output=str(value.get("output", "")),
302
+ run_id=value.get("run_id"),
303
+ handoff=HandoffRequest.from_dict(handoff) if isinstance(handoff, dict) else None,
304
+ error=value.get("error"),
305
+ retryable=bool(value.get("retryable", False)),
306
+ usage={str(key): float(item) for key, item in dict(value.get("usage") or {}).items()},
307
+ metadata=dict(value.get("metadata") or {}),
308
+ )
309
+
310
+
311
+ @dataclass
312
+ class CoordinationExecution:
313
+ """可在每个 Agent 边界保存和恢复的协调实例。"""
314
+
315
+ root_task: AgentTask
316
+ current_task: AgentTask | None
317
+ execution_id: str
318
+ status: CoordinationStatus = "queued"
319
+ current_agent_id: str | None = None
320
+ results: list[AgentResult] = field(default_factory=list)
321
+ route_history: list[str] = field(default_factory=list)
322
+ events: list[RunEvent] = field(default_factory=list)
323
+ output: str = ""
324
+ error: str | None = None
325
+ usage: dict[str, float] = field(default_factory=dict)
326
+ handoffs_completed: int = 0
327
+ agent_calls: int = 0
328
+ version: int = 0
329
+ created_at: str = field(default_factory=_now)
330
+ updated_at: str = field(default_factory=_now)
331
+
332
+ def __post_init__(self) -> None:
333
+ self.execution_id = _non_empty(self.execution_id, "execution_id")
334
+ if self.status not in {"queued", "running", "completed", "failed", "cancelled", "interrupted"}:
335
+ raise ValueError(f"无效 CoordinationExecution status:{self.status}")
336
+
337
+ @property
338
+ def access(self) -> AccessContext | None:
339
+ return self.root_task.access
340
+
341
+ def emit(self, event_type: str, **payload: Any) -> RunEvent:
342
+ error_value = payload.get("error")
343
+ usage_value = payload.get("usage")
344
+ event = RunEvent(
345
+ event_type=event_type,
346
+ run_id=self.execution_id,
347
+ thread_id=self.root_task.thread_id,
348
+ sequence=len(self.events),
349
+ payload=payload,
350
+ parent_run_id=self.root_task.parent_run_id,
351
+ component="multi_agent",
352
+ tags=["multi-agent"],
353
+ usage=dict(usage_value) if isinstance(usage_value, dict) else {},
354
+ error=str(error_value) if error_value is not None else None,
355
+ )
356
+ self.events.append(event)
357
+ return event
358
+
359
+ def to_dict(self) -> dict[str, Any]:
360
+ return {
361
+ "execution_id": self.execution_id,
362
+ "root_task": self.root_task.to_dict(),
363
+ "current_task": self.current_task.to_dict() if self.current_task else None,
364
+ "status": self.status,
365
+ "current_agent_id": self.current_agent_id,
366
+ "results": [result.to_dict() for result in self.results],
367
+ "route_history": list(self.route_history),
368
+ "events": [event.to_dict() for event in self.events],
369
+ "output": self.output,
370
+ "error": self.error,
371
+ "usage": dict(self.usage),
372
+ "handoffs_completed": self.handoffs_completed,
373
+ "agent_calls": self.agent_calls,
374
+ "version": self.version,
375
+ "created_at": self.created_at,
376
+ "updated_at": self.updated_at,
377
+ }
378
+
379
+ @classmethod
380
+ def from_dict(cls, value: dict[str, Any]) -> CoordinationExecution:
381
+ current = value.get("current_task")
382
+ return cls(
383
+ execution_id=str(value["execution_id"]),
384
+ root_task=AgentTask.from_dict(dict(value["root_task"])),
385
+ current_task=AgentTask.from_dict(current) if isinstance(current, dict) else None,
386
+ status=cast(CoordinationStatus, value.get("status", "queued")),
387
+ current_agent_id=value.get("current_agent_id"),
388
+ results=[AgentResult.from_dict(item) for item in value.get("results", [])],
389
+ route_history=[str(item) for item in value.get("route_history", [])],
390
+ events=[RunEvent.from_dict(item) for item in value.get("events", [])],
391
+ output=str(value.get("output", "")),
392
+ error=value.get("error"),
393
+ usage={str(key): float(item) for key, item in dict(value.get("usage") or {}).items()},
394
+ handoffs_completed=int(value.get("handoffs_completed", 0)),
395
+ agent_calls=int(value.get("agent_calls", 0)),
396
+ version=int(value.get("version", 0)),
397
+ created_at=str(value.get("created_at") or _now()),
398
+ updated_at=str(value.get("updated_at") or _now()),
399
+ )
400
+
401
+
402
+ @dataclass(frozen=True)
403
+ class RoutingDecision:
404
+ """一次可审计的路由结果。"""
405
+
406
+ agent_id: str
407
+ reason: str
408
+
409
+
410
+ @dataclass(frozen=True)
411
+ class CoordinationPolicy:
412
+ """Supervisor 的调用、恢复和资源预算。"""
413
+
414
+ max_handoffs: int = 8
415
+ max_agent_calls: int = 16
416
+ max_visits_per_agent: int = 2
417
+ max_agent_attempts: int = 1
418
+ agent_timeout_seconds: float = 120.0
419
+ retry_base_seconds: float = 0.5
420
+ max_parallelism: int = 4
421
+ max_total_tokens: float | None = None
422
+ max_total_cost: float | None = None
423
+ require_access: bool = False
424
+ lease_seconds: float = 30.0
425
+ heartbeat_seconds: float = 10.0
426
+
427
+ def __post_init__(self) -> None:
428
+ positive_ints = {
429
+ "max_agent_calls": self.max_agent_calls,
430
+ "max_visits_per_agent": self.max_visits_per_agent,
431
+ "max_agent_attempts": self.max_agent_attempts,
432
+ "max_parallelism": self.max_parallelism,
433
+ }
434
+ if self.max_handoffs < 0:
435
+ raise ValueError("max_handoffs 不能小于 0")
436
+ for name, value in positive_ints.items():
437
+ if value <= 0:
438
+ raise ValueError(f"{name} 必须大于 0")
439
+ if self.agent_timeout_seconds <= 0:
440
+ raise ValueError("agent_timeout_seconds 必须大于 0")
441
+ if self.retry_base_seconds < 0:
442
+ raise ValueError("retry_base_seconds 不能小于 0")
443
+ if self.max_total_tokens is not None and self.max_total_tokens <= 0:
444
+ raise ValueError("max_total_tokens 必须大于 0")
445
+ if self.max_total_cost is not None and self.max_total_cost <= 0:
446
+ raise ValueError("max_total_cost 必须大于 0")
447
+ if self.lease_seconds <= 0:
448
+ raise ValueError("lease_seconds 必须大于 0")
449
+ if self.heartbeat_seconds <= 0 or self.heartbeat_seconds >= self.lease_seconds:
450
+ raise ValueError("heartbeat_seconds 必须大于 0 且小于 lease_seconds")
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.5
2
+ Name: zero-agent-core-multi-agent
3
+ Version: 0.1.0
4
+ Summary: Handwritten Agent Core 的多 Agent 编排扩展
5
+ Project-URL: Homepage, https://github.com/qiuzixu/agent-core
6
+ Project-URL: Repository, https://github.com/qiuzixu/agent-core
7
+ License-Expression: Apache-2.0
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Typing :: Typed
14
+ Requires-Python: <3.14,>=3.13
15
+ Requires-Dist: zero-agent-core<0.3,>=0.2.0
16
+ Provides-Extra: dev
17
+ Requires-Dist: mypy<2,>=1.18; extra == 'dev'
18
+ Requires-Dist: pytest-asyncio<2,>=1.3; extra == 'dev'
19
+ Requires-Dist: pytest<10,>=9; extra == 'dev'
20
+ Requires-Dist: ruff<1,>=0.14; extra == 'dev'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Handwritten Agent Core Multi-Agent
24
+
25
+ `zero-agent-core-multi-agent` 是 Agent Core 的可选多 Agent 编排扩展。它不依赖
26
+ LangChain、LangGraph、AutoGen 或 CrewAI,直接复用 Core 的运行时、事件、访问上下文、Workflow Store
27
+ 和 Run Lease。
28
+
29
+ ```bash
30
+ pip install zero-agent-core-multi-agent
31
+ ```
32
+
33
+ ```python
34
+ from agent_core_multi_agent import (
35
+ AgentDescriptor,
36
+ AgentRegistry,
37
+ AgentTask,
38
+ CallableAgentInvoker,
39
+ HandoffRequest,
40
+ SupervisorAgent,
41
+ )
42
+
43
+ registry = AgentRegistry()
44
+
45
+
46
+ async def researcher(task):
47
+ return "检索完成"
48
+
49
+
50
+ registry.register(
51
+ AgentDescriptor(
52
+ agent_id="researcher",
53
+ description="检索资料",
54
+ capabilities=frozenset({"research"}),
55
+ ),
56
+ CallableAgentInvoker("researcher", researcher),
57
+ )
58
+
59
+ supervisor = SupervisorAgent(registry)
60
+ execution = await supervisor.run(
61
+ AgentTask(
62
+ thread_id="thread-1",
63
+ input="查询飞行规则",
64
+ required_capability="research",
65
+ )
66
+ )
67
+ print(execution.output)
68
+ ```
69
+
70
+ 具体应用可以用 `RuntimeAgentInvoker` 包装现有 `AgentRuntime`。`WorkflowCoordinationStore` 支持复用
71
+ Core 的内存、SQLite、PostgreSQL Workflow Store;多 Worker 部署时再注入对应的 `RunLeaseStore`。
72
+ 每次路由、调用和 handoff 都会落 checkpoint,恢复时使用相同任务 ID 和幂等键。
@@ -0,0 +1,14 @@
1
+ agent_core_multi_agent/__init__.py,sha256=OVZYpu5RVZZAH0rXqI5dNK9pwEKI4H02P4o_rkMokrs,1869
2
+ agent_core_multi_agent/adapters.py,sha256=fbmtBwVeU_gHFuiYK0dYgesa3d5hhNg1woa8pXh_59o,4582
3
+ agent_core_multi_agent/errors.py,sha256=0Ikj9rKYGXYNanLvysN411hOknt1h39pAACjvAm-Yag,1025
4
+ agent_core_multi_agent/protocols.py,sha256=3cUYrCJ1y1DMHJyY61HLUCSFe8rqj6s46p680Ktkgkg,1289
5
+ agent_core_multi_agent/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
6
+ agent_core_multi_agent/registry.py,sha256=SZhu1p3g4fxN35Su_KAhU84YpjAdsiRfcO1wQRyHJzE,4834
7
+ agent_core_multi_agent/routing.py,sha256=8q2IqDc5F2wNejW5d-bQWcw88Neh6fk2SBV_YJnKR9U,4893
8
+ agent_core_multi_agent/storage.py,sha256=y6-4zLgpdF9cSWXb25PgQZqiUo8Kbbuceqa_jv9stlM,4267
9
+ agent_core_multi_agent/supervisor.py,sha256=j60TomQ_I16pmmrO2gRPN41WItaTFWpjwxC-2dq9Fz8,22448
10
+ agent_core_multi_agent/types.py,sha256=rQ7o9fsxI8LAffqy3bssKRiUNoYvcaBdyWEi3PJAUfI,18610
11
+ zero_agent_core_multi_agent-0.1.0.dist-info/METADATA,sha256=KzJnSQe5aiRh_cJq3XanrgOy5qQSlDdoAfdSQfhR-YE,2201
12
+ zero_agent_core_multi_agent-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
13
+ zero_agent_core_multi_agent-0.1.0.dist-info/licenses/LICENSE,sha256=qAQIBbXbJKNe_4lmjwAGFnthk5xS-ROfzttb-OMh-Tk,11554
14
+ zero_agent_core_multi_agent-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any