emdash-core 0.1.33__py3-none-any.whl → 0.1.60__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 (67) hide show
  1. emdash_core/agent/agents.py +93 -23
  2. emdash_core/agent/background.py +481 -0
  3. emdash_core/agent/hooks.py +419 -0
  4. emdash_core/agent/inprocess_subagent.py +114 -10
  5. emdash_core/agent/mcp/config.py +78 -2
  6. emdash_core/agent/prompts/main_agent.py +88 -1
  7. emdash_core/agent/prompts/plan_mode.py +65 -44
  8. emdash_core/agent/prompts/subagents.py +96 -8
  9. emdash_core/agent/prompts/workflow.py +215 -50
  10. emdash_core/agent/providers/models.py +1 -1
  11. emdash_core/agent/providers/openai_provider.py +10 -0
  12. emdash_core/agent/research/researcher.py +154 -45
  13. emdash_core/agent/runner/agent_runner.py +157 -19
  14. emdash_core/agent/runner/context.py +28 -9
  15. emdash_core/agent/runner/sdk_runner.py +29 -2
  16. emdash_core/agent/skills.py +81 -1
  17. emdash_core/agent/toolkit.py +87 -11
  18. emdash_core/agent/toolkits/__init__.py +117 -18
  19. emdash_core/agent/toolkits/base.py +87 -2
  20. emdash_core/agent/toolkits/explore.py +18 -0
  21. emdash_core/agent/toolkits/plan.py +18 -0
  22. emdash_core/agent/tools/__init__.py +2 -0
  23. emdash_core/agent/tools/coding.py +344 -52
  24. emdash_core/agent/tools/lsp.py +361 -0
  25. emdash_core/agent/tools/skill.py +21 -1
  26. emdash_core/agent/tools/task.py +27 -23
  27. emdash_core/agent/tools/task_output.py +262 -32
  28. emdash_core/agent/verifier/__init__.py +11 -0
  29. emdash_core/agent/verifier/manager.py +295 -0
  30. emdash_core/agent/verifier/models.py +97 -0
  31. emdash_core/{swarm/worktree_manager.py → agent/worktree.py} +19 -1
  32. emdash_core/api/agent.py +451 -5
  33. emdash_core/api/research.py +3 -3
  34. emdash_core/api/router.py +0 -4
  35. emdash_core/context/longevity.py +197 -0
  36. emdash_core/context/providers/explored_areas.py +83 -39
  37. emdash_core/context/reranker.py +35 -144
  38. emdash_core/context/simple_reranker.py +500 -0
  39. emdash_core/context/tool_relevance.py +84 -0
  40. emdash_core/core/config.py +8 -0
  41. emdash_core/graph/__init__.py +8 -1
  42. emdash_core/graph/connection.py +24 -3
  43. emdash_core/graph/writer.py +7 -1
  44. emdash_core/ingestion/repository.py +17 -198
  45. emdash_core/models/agent.py +14 -0
  46. emdash_core/server.py +1 -6
  47. emdash_core/sse/stream.py +16 -1
  48. emdash_core/utils/__init__.py +0 -2
  49. emdash_core/utils/git.py +103 -0
  50. emdash_core/utils/image.py +147 -160
  51. {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/METADATA +7 -5
  52. {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/RECORD +54 -58
  53. emdash_core/api/swarm.py +0 -223
  54. emdash_core/db/__init__.py +0 -67
  55. emdash_core/db/auth.py +0 -134
  56. emdash_core/db/models.py +0 -91
  57. emdash_core/db/provider.py +0 -222
  58. emdash_core/db/providers/__init__.py +0 -5
  59. emdash_core/db/providers/supabase.py +0 -452
  60. emdash_core/swarm/__init__.py +0 -17
  61. emdash_core/swarm/merge_agent.py +0 -383
  62. emdash_core/swarm/session_manager.py +0 -274
  63. emdash_core/swarm/swarm_runner.py +0 -226
  64. emdash_core/swarm/task_definition.py +0 -137
  65. emdash_core/swarm/worker_spawner.py +0 -319
  66. {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/WHEEL +0 -0
  67. {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/entry_points.txt +0 -0
emdash_core/db/models.py DELETED
@@ -1,91 +0,0 @@
1
- """Data models for the database layer."""
2
-
3
- from dataclasses import dataclass, field
4
- from datetime import datetime
5
- from enum import Enum
6
- from typing import Optional
7
-
8
-
9
- class FeatureStatus(str, Enum):
10
- """Status of a feature in the workflow."""
11
-
12
- TODO = "todo"
13
- IN_DESIGN_REVIEW = "in_design_review"
14
- IN_PROGRESS = "in_progress"
15
- IN_PR = "in_pr"
16
- DONE = "done"
17
-
18
-
19
- class PRStatus(str, Enum):
20
- """Status of a pull request."""
21
-
22
- OPEN = "open"
23
- MERGED = "merged"
24
- CLOSED = "closed"
25
-
26
-
27
- @dataclass
28
- class Project:
29
- """A project in the system."""
30
-
31
- id: str
32
- name: str
33
- repo_url: Optional[str] = None
34
- owner_id: Optional[str] = None
35
- created_at: Optional[datetime] = None
36
- updated_at: Optional[datetime] = None
37
-
38
-
39
- @dataclass
40
- class TeamMember:
41
- """A team member belonging to a project."""
42
-
43
- id: str
44
- project_id: str
45
- name: str
46
- email: Optional[str] = None
47
- github_handle: Optional[str] = None
48
- role: Optional[str] = None
49
- user_id: Optional[str] = None # Links to auth.users
50
- created_at: Optional[datetime] = None
51
-
52
-
53
- @dataclass
54
- class Feature:
55
- """A feature belonging to a project."""
56
-
57
- id: str
58
- project_id: str
59
- title: str
60
- description: Optional[str] = None
61
- status: FeatureStatus = FeatureStatus.TODO
62
- spec: Optional[str] = None
63
- plan: Optional[str] = None
64
- tasks: Optional[str] = None
65
- created_at: Optional[datetime] = None
66
- updated_at: Optional[datetime] = None
67
- # Populated by joins
68
- assignees: list["TeamMember"] = field(default_factory=list)
69
- prs: list["FeaturePR"] = field(default_factory=list)
70
-
71
-
72
- @dataclass
73
- class FeatureAssignee:
74
- """Junction table for feature-assignee many-to-many relationship."""
75
-
76
- feature_id: str
77
- team_member_id: str
78
- assigned_at: Optional[datetime] = None
79
-
80
-
81
- @dataclass
82
- class FeaturePR:
83
- """A pull request linked to a feature."""
84
-
85
- id: str
86
- feature_id: str
87
- pr_url: str
88
- pr_number: int
89
- title: Optional[str] = None
90
- status: PRStatus = PRStatus.OPEN
91
- created_at: Optional[datetime] = None
@@ -1,222 +0,0 @@
1
- """Abstract database provider interface."""
2
-
3
- from abc import ABC, abstractmethod
4
- from typing import Optional
5
-
6
- from .models import (
7
- Feature,
8
- FeatureAssignee,
9
- FeaturePR,
10
- FeatureStatus,
11
- PRStatus,
12
- Project,
13
- TeamMember,
14
- )
15
-
16
-
17
- class DatabaseProvider(ABC):
18
- """Abstract base class for database providers.
19
-
20
- Implementations must provide all CRUD operations for the data models.
21
- """
22
-
23
- # -------------------------------------------------------------------------
24
- # Projects
25
- # -------------------------------------------------------------------------
26
-
27
- @abstractmethod
28
- async def create_project(
29
- self, name: str, repo_url: Optional[str] = None, owner_id: Optional[str] = None
30
- ) -> Project:
31
- """Create a new project.
32
-
33
- Args:
34
- name: Project name
35
- repo_url: GitHub repository URL
36
- owner_id: Auth user ID of the project owner
37
- """
38
- pass
39
-
40
- @abstractmethod
41
- async def get_project(self, project_id: str) -> Optional[Project]:
42
- """Get a project by ID."""
43
- pass
44
-
45
- @abstractmethod
46
- async def get_project_by_name(self, name: str) -> Optional[Project]:
47
- """Get a project by name."""
48
- pass
49
-
50
- @abstractmethod
51
- async def list_projects(self) -> list[Project]:
52
- """List all projects."""
53
- pass
54
-
55
- @abstractmethod
56
- async def update_project(
57
- self, project_id: str, name: Optional[str] = None, repo_url: Optional[str] = None
58
- ) -> Optional[Project]:
59
- """Update a project."""
60
- pass
61
-
62
- @abstractmethod
63
- async def delete_project(self, project_id: str) -> bool:
64
- """Delete a project and all related data."""
65
- pass
66
-
67
- # -------------------------------------------------------------------------
68
- # Team Members
69
- # -------------------------------------------------------------------------
70
-
71
- @abstractmethod
72
- async def create_team_member(
73
- self,
74
- project_id: str,
75
- name: str,
76
- email: Optional[str] = None,
77
- github_handle: Optional[str] = None,
78
- role: Optional[str] = None,
79
- user_id: Optional[str] = None,
80
- ) -> TeamMember:
81
- """Create a new team member.
82
-
83
- Args:
84
- project_id: Project this member belongs to
85
- name: Display name
86
- email: Email address
87
- github_handle: GitHub username
88
- role: Role in the project
89
- user_id: Auth user ID (links to Supabase auth.users)
90
- """
91
- pass
92
-
93
- @abstractmethod
94
- async def get_team_member(self, member_id: str) -> Optional[TeamMember]:
95
- """Get a team member by ID."""
96
- pass
97
-
98
- @abstractmethod
99
- async def list_team_members(self, project_id: str) -> list[TeamMember]:
100
- """List all team members for a project."""
101
- pass
102
-
103
- @abstractmethod
104
- async def update_team_member(
105
- self,
106
- member_id: str,
107
- name: Optional[str] = None,
108
- email: Optional[str] = None,
109
- github_handle: Optional[str] = None,
110
- role: Optional[str] = None,
111
- ) -> Optional[TeamMember]:
112
- """Update a team member."""
113
- pass
114
-
115
- @abstractmethod
116
- async def delete_team_member(self, member_id: str) -> bool:
117
- """Delete a team member."""
118
- pass
119
-
120
- # -------------------------------------------------------------------------
121
- # Features
122
- # -------------------------------------------------------------------------
123
-
124
- @abstractmethod
125
- async def create_feature(
126
- self,
127
- project_id: str,
128
- title: str,
129
- description: Optional[str] = None,
130
- status: FeatureStatus = FeatureStatus.TODO,
131
- spec: Optional[str] = None,
132
- plan: Optional[str] = None,
133
- tasks: Optional[str] = None,
134
- ) -> Feature:
135
- """Create a new feature."""
136
- pass
137
-
138
- @abstractmethod
139
- async def get_feature(self, feature_id: str, include_relations: bool = True) -> Optional[Feature]:
140
- """Get a feature by ID, optionally including assignees and PRs."""
141
- pass
142
-
143
- @abstractmethod
144
- async def list_features(
145
- self, project_id: str, status: Optional[FeatureStatus] = None, include_relations: bool = False
146
- ) -> list[Feature]:
147
- """List features for a project, optionally filtered by status."""
148
- pass
149
-
150
- @abstractmethod
151
- async def update_feature(
152
- self,
153
- feature_id: str,
154
- title: Optional[str] = None,
155
- description: Optional[str] = None,
156
- status: Optional[FeatureStatus] = None,
157
- spec: Optional[str] = None,
158
- plan: Optional[str] = None,
159
- tasks: Optional[str] = None,
160
- ) -> Optional[Feature]:
161
- """Update a feature."""
162
- pass
163
-
164
- @abstractmethod
165
- async def delete_feature(self, feature_id: str) -> bool:
166
- """Delete a feature and all related data."""
167
- pass
168
-
169
- # -------------------------------------------------------------------------
170
- # Feature Assignees
171
- # -------------------------------------------------------------------------
172
-
173
- @abstractmethod
174
- async def assign_feature(self, feature_id: str, team_member_id: str) -> FeatureAssignee:
175
- """Assign a team member to a feature."""
176
- pass
177
-
178
- @abstractmethod
179
- async def unassign_feature(self, feature_id: str, team_member_id: str) -> bool:
180
- """Remove a team member from a feature."""
181
- pass
182
-
183
- @abstractmethod
184
- async def get_feature_assignees(self, feature_id: str) -> list[TeamMember]:
185
- """Get all assignees for a feature."""
186
- pass
187
-
188
- # -------------------------------------------------------------------------
189
- # Feature PRs
190
- # -------------------------------------------------------------------------
191
-
192
- @abstractmethod
193
- async def add_feature_pr(
194
- self,
195
- feature_id: str,
196
- pr_url: str,
197
- pr_number: int,
198
- title: Optional[str] = None,
199
- status: PRStatus = PRStatus.OPEN,
200
- ) -> FeaturePR:
201
- """Add a PR to a feature."""
202
- pass
203
-
204
- @abstractmethod
205
- async def update_feature_pr(
206
- self,
207
- pr_id: str,
208
- title: Optional[str] = None,
209
- status: Optional[PRStatus] = None,
210
- ) -> Optional[FeaturePR]:
211
- """Update a feature PR."""
212
- pass
213
-
214
- @abstractmethod
215
- async def remove_feature_pr(self, pr_id: str) -> bool:
216
- """Remove a PR from a feature."""
217
- pass
218
-
219
- @abstractmethod
220
- async def get_feature_prs(self, feature_id: str) -> list[FeaturePR]:
221
- """Get all PRs for a feature."""
222
- pass
@@ -1,5 +0,0 @@
1
- """Database provider implementations."""
2
-
3
- from .supabase import SupabaseProvider
4
-
5
- __all__ = ["SupabaseProvider"]