aury-agent 0.0.4__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.
Files changed (149) hide show
  1. aury/__init__.py +2 -0
  2. aury/agents/__init__.py +55 -0
  3. aury/agents/a2a/__init__.py +168 -0
  4. aury/agents/backends/__init__.py +196 -0
  5. aury/agents/backends/artifact/__init__.py +9 -0
  6. aury/agents/backends/artifact/memory.py +130 -0
  7. aury/agents/backends/artifact/types.py +133 -0
  8. aury/agents/backends/code/__init__.py +65 -0
  9. aury/agents/backends/file/__init__.py +11 -0
  10. aury/agents/backends/file/local.py +66 -0
  11. aury/agents/backends/file/types.py +40 -0
  12. aury/agents/backends/invocation/__init__.py +8 -0
  13. aury/agents/backends/invocation/memory.py +81 -0
  14. aury/agents/backends/invocation/types.py +110 -0
  15. aury/agents/backends/memory/__init__.py +8 -0
  16. aury/agents/backends/memory/memory.py +179 -0
  17. aury/agents/backends/memory/types.py +136 -0
  18. aury/agents/backends/message/__init__.py +9 -0
  19. aury/agents/backends/message/memory.py +122 -0
  20. aury/agents/backends/message/types.py +124 -0
  21. aury/agents/backends/sandbox.py +275 -0
  22. aury/agents/backends/session/__init__.py +8 -0
  23. aury/agents/backends/session/memory.py +93 -0
  24. aury/agents/backends/session/types.py +124 -0
  25. aury/agents/backends/shell/__init__.py +11 -0
  26. aury/agents/backends/shell/local.py +110 -0
  27. aury/agents/backends/shell/types.py +55 -0
  28. aury/agents/backends/shell.py +209 -0
  29. aury/agents/backends/snapshot/__init__.py +19 -0
  30. aury/agents/backends/snapshot/git.py +95 -0
  31. aury/agents/backends/snapshot/hybrid.py +125 -0
  32. aury/agents/backends/snapshot/memory.py +86 -0
  33. aury/agents/backends/snapshot/types.py +59 -0
  34. aury/agents/backends/state/__init__.py +29 -0
  35. aury/agents/backends/state/composite.py +49 -0
  36. aury/agents/backends/state/file.py +57 -0
  37. aury/agents/backends/state/memory.py +52 -0
  38. aury/agents/backends/state/sqlite.py +262 -0
  39. aury/agents/backends/state/types.py +178 -0
  40. aury/agents/backends/subagent/__init__.py +165 -0
  41. aury/agents/cli/__init__.py +41 -0
  42. aury/agents/cli/chat.py +239 -0
  43. aury/agents/cli/config.py +236 -0
  44. aury/agents/cli/extensions.py +460 -0
  45. aury/agents/cli/main.py +189 -0
  46. aury/agents/cli/session.py +337 -0
  47. aury/agents/cli/workflow.py +276 -0
  48. aury/agents/context_providers/__init__.py +66 -0
  49. aury/agents/context_providers/artifact.py +299 -0
  50. aury/agents/context_providers/base.py +177 -0
  51. aury/agents/context_providers/memory.py +70 -0
  52. aury/agents/context_providers/message.py +130 -0
  53. aury/agents/context_providers/skill.py +50 -0
  54. aury/agents/context_providers/subagent.py +46 -0
  55. aury/agents/context_providers/tool.py +68 -0
  56. aury/agents/core/__init__.py +83 -0
  57. aury/agents/core/base.py +573 -0
  58. aury/agents/core/context.py +797 -0
  59. aury/agents/core/context_builder.py +303 -0
  60. aury/agents/core/event_bus/__init__.py +15 -0
  61. aury/agents/core/event_bus/bus.py +203 -0
  62. aury/agents/core/factory.py +169 -0
  63. aury/agents/core/isolator.py +97 -0
  64. aury/agents/core/logging.py +95 -0
  65. aury/agents/core/parallel.py +194 -0
  66. aury/agents/core/runner.py +139 -0
  67. aury/agents/core/services/__init__.py +5 -0
  68. aury/agents/core/services/file_session.py +144 -0
  69. aury/agents/core/services/message.py +53 -0
  70. aury/agents/core/services/session.py +53 -0
  71. aury/agents/core/signals.py +109 -0
  72. aury/agents/core/state.py +363 -0
  73. aury/agents/core/types/__init__.py +107 -0
  74. aury/agents/core/types/action.py +176 -0
  75. aury/agents/core/types/artifact.py +135 -0
  76. aury/agents/core/types/block.py +736 -0
  77. aury/agents/core/types/message.py +350 -0
  78. aury/agents/core/types/recall.py +144 -0
  79. aury/agents/core/types/session.py +257 -0
  80. aury/agents/core/types/subagent.py +154 -0
  81. aury/agents/core/types/tool.py +205 -0
  82. aury/agents/eval/__init__.py +331 -0
  83. aury/agents/hitl/__init__.py +57 -0
  84. aury/agents/hitl/ask_user.py +242 -0
  85. aury/agents/hitl/compaction.py +230 -0
  86. aury/agents/hitl/exceptions.py +87 -0
  87. aury/agents/hitl/permission.py +617 -0
  88. aury/agents/hitl/revert.py +216 -0
  89. aury/agents/llm/__init__.py +31 -0
  90. aury/agents/llm/adapter.py +367 -0
  91. aury/agents/llm/openai.py +294 -0
  92. aury/agents/llm/provider.py +476 -0
  93. aury/agents/mcp/__init__.py +153 -0
  94. aury/agents/memory/__init__.py +46 -0
  95. aury/agents/memory/compaction.py +394 -0
  96. aury/agents/memory/manager.py +465 -0
  97. aury/agents/memory/processor.py +177 -0
  98. aury/agents/memory/store.py +187 -0
  99. aury/agents/memory/types.py +137 -0
  100. aury/agents/messages/__init__.py +40 -0
  101. aury/agents/messages/config.py +47 -0
  102. aury/agents/messages/raw_store.py +224 -0
  103. aury/agents/messages/store.py +118 -0
  104. aury/agents/messages/types.py +88 -0
  105. aury/agents/middleware/__init__.py +31 -0
  106. aury/agents/middleware/base.py +341 -0
  107. aury/agents/middleware/chain.py +342 -0
  108. aury/agents/middleware/message.py +129 -0
  109. aury/agents/middleware/message_container.py +126 -0
  110. aury/agents/middleware/raw_message.py +153 -0
  111. aury/agents/middleware/truncation.py +139 -0
  112. aury/agents/middleware/types.py +81 -0
  113. aury/agents/plugin.py +162 -0
  114. aury/agents/react/__init__.py +4 -0
  115. aury/agents/react/agent.py +1923 -0
  116. aury/agents/sandbox/__init__.py +23 -0
  117. aury/agents/sandbox/local.py +239 -0
  118. aury/agents/sandbox/remote.py +200 -0
  119. aury/agents/sandbox/types.py +115 -0
  120. aury/agents/skill/__init__.py +16 -0
  121. aury/agents/skill/loader.py +180 -0
  122. aury/agents/skill/types.py +83 -0
  123. aury/agents/tool/__init__.py +39 -0
  124. aury/agents/tool/builtin/__init__.py +23 -0
  125. aury/agents/tool/builtin/ask_user.py +155 -0
  126. aury/agents/tool/builtin/bash.py +107 -0
  127. aury/agents/tool/builtin/delegate.py +726 -0
  128. aury/agents/tool/builtin/edit.py +121 -0
  129. aury/agents/tool/builtin/plan.py +277 -0
  130. aury/agents/tool/builtin/read.py +91 -0
  131. aury/agents/tool/builtin/thinking.py +111 -0
  132. aury/agents/tool/builtin/yield_result.py +130 -0
  133. aury/agents/tool/decorator.py +252 -0
  134. aury/agents/tool/set.py +204 -0
  135. aury/agents/usage/__init__.py +12 -0
  136. aury/agents/usage/tracker.py +236 -0
  137. aury/agents/workflow/__init__.py +85 -0
  138. aury/agents/workflow/adapter.py +268 -0
  139. aury/agents/workflow/dag.py +116 -0
  140. aury/agents/workflow/dsl.py +575 -0
  141. aury/agents/workflow/executor.py +659 -0
  142. aury/agents/workflow/expression.py +136 -0
  143. aury/agents/workflow/parser.py +182 -0
  144. aury/agents/workflow/state.py +145 -0
  145. aury/agents/workflow/types.py +86 -0
  146. aury_agent-0.0.4.dist-info/METADATA +90 -0
  147. aury_agent-0.0.4.dist-info/RECORD +149 -0
  148. aury_agent-0.0.4.dist-info/WHEEL +4 -0
  149. aury_agent-0.0.4.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,176 @@
1
+ """ActionEvent for framework-level state and result passing.
2
+
3
+ Unlike BlockEvent (for UI streaming), ActionEvent is used for:
4
+ - State changes (state_delta)
5
+ - Result passing between agents
6
+ - Framework-level signals
7
+
8
+ ActionEvents can be internal (not sent to external API) or external.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass, field
13
+ from datetime import datetime
14
+ from enum import Enum
15
+ from typing import Any
16
+
17
+ from .session import generate_id
18
+
19
+
20
+ class ActionType(str, Enum):
21
+ """Built-in action types."""
22
+
23
+ # State management
24
+ STATE_DELTA = "state_delta" # Update state with delta
25
+ SET_RESULT = "set_result" # Set agent result (text + structured)
26
+
27
+ # Control flow
28
+ TRANSFER = "transfer" # Transfer to another agent
29
+ END_AGENT = "end_agent" # Agent finished
30
+
31
+ # Progress (can be external)
32
+ PROGRESS = "progress" # Progress update
33
+
34
+
35
+ @dataclass
36
+ class ActionEvent:
37
+ """Action event for framework-level operations.
38
+
39
+ Emitted via ctx.emit() alongside BlockEvents.
40
+ Framework collects these for state management and result passing.
41
+
42
+ Attributes:
43
+ action: Action type (ActionType enum or custom string)
44
+ data: Action payload
45
+ branch: Branch identifier for parallel execution isolation
46
+ internal: If True, not sent to external API (default: True)
47
+ event_id: Unique event identifier
48
+ timestamp: Event timestamp in milliseconds
49
+
50
+ Example:
51
+ # Internal action - framework only
52
+ await ctx.emit(ActionEvent(
53
+ action=ActionType.SET_RESULT,
54
+ data={"text": "报告已完成", "artifact_id": "xxx"},
55
+ branch="report_writer",
56
+ ))
57
+
58
+ # External action - also sent to API
59
+ await ctx.emit(ActionEvent(
60
+ action=ActionType.PROGRESS,
61
+ data={"percent": 50, "message": "生成中..."},
62
+ internal=False,
63
+ ))
64
+ """
65
+
66
+ action: ActionType | str
67
+ data: dict[str, Any] = field(default_factory=dict)
68
+ branch: str | None = None
69
+ internal: bool = True # Default: not sent to external API
70
+
71
+ # Protocol fields
72
+ event_id: str = field(default_factory=lambda: generate_id("act"))
73
+ timestamp: int = field(default_factory=lambda: int(datetime.now().timestamp() * 1000))
74
+
75
+ def to_dict(self) -> dict[str, Any]:
76
+ """Convert to dictionary for serialization."""
77
+ action_value = self.action.value if isinstance(self.action, ActionType) else self.action
78
+ return {
79
+ "type": "action", # Distinguish from BlockEvent
80
+ "action": action_value,
81
+ "data": self.data,
82
+ "branch": self.branch,
83
+ "internal": self.internal,
84
+ "event_id": self.event_id,
85
+ "timestamp": self.timestamp,
86
+ }
87
+
88
+ @classmethod
89
+ def from_dict(cls, data: dict[str, Any]) -> ActionEvent:
90
+ """Create from dictionary."""
91
+ action_str = data["action"]
92
+ try:
93
+ action = ActionType(action_str)
94
+ except ValueError:
95
+ action = action_str # Custom action string
96
+ return cls(
97
+ action=action,
98
+ data=data.get("data", {}),
99
+ branch=data.get("branch"),
100
+ internal=data.get("internal", True),
101
+ event_id=data.get("event_id", ""),
102
+ timestamp=data.get("timestamp", 0),
103
+ )
104
+
105
+
106
+ @dataclass
107
+ class ActionCollector:
108
+ """Collects ActionEvents during agent execution.
109
+
110
+ Used by framework to aggregate actions from agent and sub-agents.
111
+ Supports branch-based isolation for parallel execution.
112
+ """
113
+
114
+ def __init__(self):
115
+ self._actions: list[ActionEvent] = []
116
+ self._branch_results: dict[str, dict[str, Any]] = {}
117
+ self._state_delta: dict[str, Any] = {}
118
+
119
+ def collect(self, event: ActionEvent) -> None:
120
+ """Collect an action event."""
121
+ self._actions.append(event)
122
+
123
+ # Handle specific action types
124
+ if event.action == ActionType.STATE_DELTA:
125
+ self._merge_state_delta(event.data)
126
+ elif event.action == ActionType.SET_RESULT:
127
+ branch = event.branch or "_default"
128
+ self._branch_results[branch] = event.data
129
+
130
+ def _merge_state_delta(self, delta: dict[str, Any]) -> None:
131
+ """Merge state delta into accumulated state."""
132
+ for key, value in delta.items():
133
+ if isinstance(value, dict) and isinstance(self._state_delta.get(key), dict):
134
+ # Deep merge dicts
135
+ self._state_delta[key] = {**self._state_delta[key], **value}
136
+ else:
137
+ self._state_delta[key] = value
138
+
139
+ @property
140
+ def state_delta(self) -> dict[str, Any]:
141
+ """Get accumulated state delta."""
142
+ return self._state_delta
143
+
144
+ @property
145
+ def branch_results(self) -> dict[str, dict[str, Any]]:
146
+ """Get results by branch."""
147
+ return self._branch_results
148
+
149
+ @property
150
+ def actions(self) -> list[ActionEvent]:
151
+ """Get all collected actions."""
152
+ return self._actions
153
+
154
+ def get_results(self) -> list[dict[str, Any]]:
155
+ """Get all SET_RESULT actions as array.
156
+
157
+ Returns list of raw result data, caller handles formatting.
158
+ """
159
+ return list(self._branch_results.values())
160
+
161
+ def get_result(self, branch: str = "_default") -> dict[str, Any] | None:
162
+ """Get result for specific branch."""
163
+ return self._branch_results.get(branch)
164
+
165
+ def clear(self) -> None:
166
+ """Clear all collected actions."""
167
+ self._actions.clear()
168
+ self._branch_results.clear()
169
+ self._state_delta.clear()
170
+
171
+
172
+ __all__ = [
173
+ "ActionType",
174
+ "ActionEvent",
175
+ "ActionCollector",
176
+ ]
@@ -0,0 +1,135 @@
1
+ """Artifact data structures.
2
+
3
+ Artifacts are independent generated objects that:
4
+ - Are stored separately (ArtifactStore by developer)
5
+ - Are referenced in Messages by ID + summary
6
+ - Can be previewed, downloaded, edited by users
7
+ - Have different frontend rendering than ToolResult
8
+
9
+ Artifact can be:
10
+ - Single file (code, markdown, etc.)
11
+ - Package/directory (project with multiple files)
12
+ - Page list (PPT, PDF pages)
13
+ - Item list (search results, resource list)
14
+ - External reference (S3, URLs, etc.)
15
+
16
+ Framework only defines structure, developer implements storage.
17
+ """
18
+ from __future__ import annotations
19
+
20
+ from dataclasses import dataclass, field
21
+ from typing import Any
22
+
23
+ from .session import generate_id
24
+
25
+
26
+ @dataclass
27
+ class Artifact:
28
+ """An artifact (generated content/file/data).
29
+
30
+ Simple structure - framework doesn't dictate storage details.
31
+ Developer implements ArtifactStore to handle persistence.
32
+
33
+ Examples:
34
+ # Single file
35
+ Artifact(kind="file", title="main.py", data={"content": "...", "language": "python"})
36
+
37
+ # Package/directory
38
+ Artifact(kind="package", title="my_project", data={"root": "/path", "files": [...]})
39
+
40
+ # Search results (structured list)
41
+ Artifact(kind="search_results", data=[{"title": "...", "summary": "...", "url": "..."}])
42
+
43
+ # PPT slides
44
+ Artifact(kind="slides", data={"pages": [...], "page_count": 10})
45
+
46
+ # External reference
47
+ Artifact(kind="external", data={"ref": "s3://...", "type": "s3"})
48
+ """
49
+ id: str = field(default_factory=lambda: generate_id("art"))
50
+ kind: str = "file" # Content type (developer-defined)
51
+ renderer: str | None = None # Override default renderer
52
+ title: str | None = None
53
+ summary: str | None = None # For LLM context
54
+ data: Any = None # Content (structure depends on kind)
55
+ session_id: str = ""
56
+ invocation_id: str = ""
57
+
58
+ # Nesting structure (tree relationship)
59
+ parent_artifact_id: str | None = None # Parent artifact (for nested artifacts)
60
+ root_artifact_id: str | None = None # Root artifact of the tree
61
+
62
+ def to_ref(self) -> "ArtifactRef":
63
+ """Create a reference to this artifact."""
64
+ return ArtifactRef(
65
+ artifact_id=self.id,
66
+ kind=self.kind,
67
+ title=self.title,
68
+ summary=self.summary,
69
+ )
70
+
71
+ def to_dict(self) -> dict[str, Any]:
72
+ """Convert to dictionary for serialization."""
73
+ return {
74
+ "id": self.id,
75
+ "kind": self.kind,
76
+ "renderer": self.renderer,
77
+ "title": self.title,
78
+ "summary": self.summary,
79
+ "data": self.data,
80
+ "session_id": self.session_id,
81
+ "invocation_id": self.invocation_id,
82
+ "parent_artifact_id": self.parent_artifact_id,
83
+ "root_artifact_id": self.root_artifact_id,
84
+ }
85
+
86
+ @classmethod
87
+ def from_dict(cls, data: dict[str, Any]) -> "Artifact":
88
+ """Create from dictionary."""
89
+ return cls(
90
+ id=data["id"],
91
+ kind=data.get("kind", "file"),
92
+ renderer=data.get("renderer"),
93
+ title=data.get("title"),
94
+ summary=data.get("summary"),
95
+ data=data.get("data"),
96
+ session_id=data.get("session_id", ""),
97
+ invocation_id=data.get("invocation_id", ""),
98
+ parent_artifact_id=data.get("parent_artifact_id"),
99
+ root_artifact_id=data.get("root_artifact_id"),
100
+ )
101
+
102
+
103
+ @dataclass
104
+ class ArtifactRef:
105
+ """Reference to an artifact (used in Message).
106
+
107
+ Contains only summary info for LLM context.
108
+ Full content fetched from ArtifactStore when needed.
109
+ """
110
+ artifact_id: str
111
+ kind: str = "file"
112
+ title: str | None = None
113
+ summary: str | None = None
114
+
115
+ def to_dict(self) -> dict[str, Any]:
116
+ """Convert to dictionary for serialization."""
117
+ return {
118
+ "artifact_id": self.artifact_id,
119
+ "kind": self.kind,
120
+ "title": self.title,
121
+ "summary": self.summary,
122
+ }
123
+
124
+ @classmethod
125
+ def from_dict(cls, data: dict[str, Any]) -> "ArtifactRef":
126
+ """Create from dictionary."""
127
+ return cls(
128
+ artifact_id=data["artifact_id"],
129
+ kind=data.get("kind", "file"),
130
+ title=data.get("title"),
131
+ summary=data.get("summary"),
132
+ )
133
+
134
+
135
+ __all__ = ["Artifact", "ArtifactRef"]