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.
- emdash_core/agent/agents.py +93 -23
- emdash_core/agent/background.py +481 -0
- emdash_core/agent/hooks.py +419 -0
- emdash_core/agent/inprocess_subagent.py +114 -10
- emdash_core/agent/mcp/config.py +78 -2
- emdash_core/agent/prompts/main_agent.py +88 -1
- emdash_core/agent/prompts/plan_mode.py +65 -44
- emdash_core/agent/prompts/subagents.py +96 -8
- emdash_core/agent/prompts/workflow.py +215 -50
- emdash_core/agent/providers/models.py +1 -1
- emdash_core/agent/providers/openai_provider.py +10 -0
- emdash_core/agent/research/researcher.py +154 -45
- emdash_core/agent/runner/agent_runner.py +157 -19
- emdash_core/agent/runner/context.py +28 -9
- emdash_core/agent/runner/sdk_runner.py +29 -2
- emdash_core/agent/skills.py +81 -1
- emdash_core/agent/toolkit.py +87 -11
- emdash_core/agent/toolkits/__init__.py +117 -18
- emdash_core/agent/toolkits/base.py +87 -2
- emdash_core/agent/toolkits/explore.py +18 -0
- emdash_core/agent/toolkits/plan.py +18 -0
- emdash_core/agent/tools/__init__.py +2 -0
- emdash_core/agent/tools/coding.py +344 -52
- emdash_core/agent/tools/lsp.py +361 -0
- emdash_core/agent/tools/skill.py +21 -1
- emdash_core/agent/tools/task.py +27 -23
- emdash_core/agent/tools/task_output.py +262 -32
- emdash_core/agent/verifier/__init__.py +11 -0
- emdash_core/agent/verifier/manager.py +295 -0
- emdash_core/agent/verifier/models.py +97 -0
- emdash_core/{swarm/worktree_manager.py → agent/worktree.py} +19 -1
- emdash_core/api/agent.py +451 -5
- emdash_core/api/research.py +3 -3
- emdash_core/api/router.py +0 -4
- emdash_core/context/longevity.py +197 -0
- emdash_core/context/providers/explored_areas.py +83 -39
- emdash_core/context/reranker.py +35 -144
- emdash_core/context/simple_reranker.py +500 -0
- emdash_core/context/tool_relevance.py +84 -0
- emdash_core/core/config.py +8 -0
- emdash_core/graph/__init__.py +8 -1
- emdash_core/graph/connection.py +24 -3
- emdash_core/graph/writer.py +7 -1
- emdash_core/ingestion/repository.py +17 -198
- emdash_core/models/agent.py +14 -0
- emdash_core/server.py +1 -6
- emdash_core/sse/stream.py +16 -1
- emdash_core/utils/__init__.py +0 -2
- emdash_core/utils/git.py +103 -0
- emdash_core/utils/image.py +147 -160
- {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/METADATA +7 -5
- {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/RECORD +54 -58
- emdash_core/api/swarm.py +0 -223
- emdash_core/db/__init__.py +0 -67
- emdash_core/db/auth.py +0 -134
- emdash_core/db/models.py +0 -91
- emdash_core/db/provider.py +0 -222
- emdash_core/db/providers/__init__.py +0 -5
- emdash_core/db/providers/supabase.py +0 -452
- emdash_core/swarm/__init__.py +0 -17
- emdash_core/swarm/merge_agent.py +0 -383
- emdash_core/swarm/session_manager.py +0 -274
- emdash_core/swarm/swarm_runner.py +0 -226
- emdash_core/swarm/task_definition.py +0 -137
- emdash_core/swarm/worker_spawner.py +0 -319
- {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/WHEEL +0 -0
- {emdash_core-0.1.33.dist-info → emdash_core-0.1.60.dist-info}/entry_points.txt +0 -0
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
emdash_core/__init__.py,sha256=2VnFDN5zmKekKBa5rHZY9nz2Dhv2lB_O6dTcz-wyF8s,226
|
|
2
2
|
emdash_core/agent/__init__.py,sha256=rGY5MXggrv6TLHqNMp3v1oDldL_KErvLIoHARimlNbk,1195
|
|
3
|
-
emdash_core/agent/agents.py,sha256=
|
|
3
|
+
emdash_core/agent/agents.py,sha256=r1ZnEgA5_LI4zonhrcbJ6LoUqRDFehSZG-fRXZxdkSM,8330
|
|
4
|
+
emdash_core/agent/background.py,sha256=4lXNW8NHkfZuOFmMAamYypNIcnuphu27Wy_JjNBOLIc,15367
|
|
4
5
|
emdash_core/agent/code_reviewer.py,sha256=oUXcDbk773kwYtcCsUNEjb_ipS9rLeCKIv_IEUiUA9k,16467
|
|
5
6
|
emdash_core/agent/compaction.py,sha256=_smuIjmzaiblr6viRFByQCekRzoZDTetcaXRLQol8CI,4102
|
|
6
7
|
emdash_core/agent/context_manager.py,sha256=3HBQFRwsq1bBx6R7FQp7xFsiW0zPLPnOF-8Ox4Y6K44,3676
|
|
7
8
|
emdash_core/agent/events.py,sha256=Qw6s6jzBFXIlsDNpPBiIwNB72tnjbAJNt6hhcblOslg,11930
|
|
8
9
|
emdash_core/agent/handlers.py,sha256=3zo76GT3cTfYayK1qvP2NFo14AXHfA36X-yaa7Xm3T0,7135
|
|
9
|
-
emdash_core/agent/
|
|
10
|
+
emdash_core/agent/hooks.py,sha256=zpKsbcR5X0iZo65VULMsoE84nfdArwDz1uULlgbZATM,13635
|
|
11
|
+
emdash_core/agent/inprocess_subagent.py,sha256=lsW6DWrAt51PuyX1wMc_o86dA1h-CrLgsnsQHuRI-Kk,20652
|
|
10
12
|
emdash_core/agent/mcp/__init__.py,sha256=qzQMJJOgOYVb6X2uyJxTIGgV5x35Dn7H3IglZxToX_c,1081
|
|
11
13
|
emdash_core/agent/mcp/client.py,sha256=_ae6CWRnJfG_mcCcIYZJYbWjajpZC-WmZgsZsRaahco,9753
|
|
12
|
-
emdash_core/agent/mcp/config.py,sha256=
|
|
14
|
+
emdash_core/agent/mcp/config.py,sha256=Z48JK26qZvywfvD3m7wvtR6axz4zYA40FQhDAYeBntk,11584
|
|
13
15
|
emdash_core/agent/mcp/manager.py,sha256=i4OIJyAwfBAw0E8fe6NIOvT-UTf1_hmDbEtIjtAhRjc,15382
|
|
14
16
|
emdash_core/agent/mcp/tool_factory.py,sha256=jtQJ2TW7KdGVSg3fUp9-rm7MbHjiwWmy0yLfwr0H4qc,6410
|
|
15
17
|
emdash_core/agent/prompts/__init__.py,sha256=BuCvF0XLJdhXSWNz0NoJI6dBnomLzRcfZxdBWmkh8tg,987
|
|
16
|
-
emdash_core/agent/prompts/main_agent.py,sha256=
|
|
17
|
-
emdash_core/agent/prompts/plan_mode.py,sha256=
|
|
18
|
-
emdash_core/agent/prompts/subagents.py,sha256
|
|
19
|
-
emdash_core/agent/prompts/workflow.py,sha256=
|
|
18
|
+
emdash_core/agent/prompts/main_agent.py,sha256=t5HtT4AzifBqO6lcR6oCar8qWPEUm1oMiVx2udAdfaw,7213
|
|
19
|
+
emdash_core/agent/prompts/plan_mode.py,sha256=u52k12bQiFlxnUnN9Rh-samMfS9TGQRmsoT0-QIvW8U,9351
|
|
20
|
+
emdash_core/agent/prompts/subagents.py,sha256=FDgWmSwAMq3AabdMWwTjP_17n9NjrQrdc8l7VSN__IY,9622
|
|
21
|
+
emdash_core/agent/prompts/workflow.py,sha256=2suHrohQdJO5PRUVrsVy46pp5Kb8OYwiz5vNEYZ6MmA,18362
|
|
20
22
|
emdash_core/agent/providers/__init__.py,sha256=q58ektAl1zwuS3z36ctHfLB8XruYghT97aq_oj1T_G0,776
|
|
21
23
|
emdash_core/agent/providers/base.py,sha256=m1Vuac2Gtr191YDkefG_3qD64iIT9Ps2WoZC1LWmfJU,4351
|
|
22
24
|
emdash_core/agent/providers/factory.py,sha256=UgPVNQupa73dKugyG_JqFgVdj4y5YJIGbcGXEbzx_1c,3213
|
|
23
|
-
emdash_core/agent/providers/models.py,sha256=
|
|
24
|
-
emdash_core/agent/providers/openai_provider.py,sha256=
|
|
25
|
+
emdash_core/agent/providers/models.py,sha256=Tyt175fU0fy1YDSHgFEjcH5ABgPJUzvH7xSh4N94t4A,8756
|
|
26
|
+
emdash_core/agent/providers/openai_provider.py,sha256=cS44BX1sUQ1mjkGJt9RpNHzgrfK7QQbjs9ELMrk3uMg,21580
|
|
25
27
|
emdash_core/agent/providers/transformers_provider.py,sha256=USSzYIcZrcTAKDKwiNobYUDS024ZVZ34WAuYWGbs9Nk,7167
|
|
26
28
|
emdash_core/agent/research/__init__.py,sha256=4LU9Skk3sxsDy8GzfOxCjNxxqaxOm94hV5cH-Nyqn7g,1992
|
|
27
29
|
emdash_core/agent/research/agent.py,sha256=dGjSZL2rsuJmSRpa8060R5gIvX8rIj57Zs21LsBJ-1U,3819
|
|
@@ -29,50 +31,55 @@ emdash_core/agent/research/controller.py,sha256=fWR8dXW68PCPqspyEjeJolJtDOKwaxeo
|
|
|
29
31
|
emdash_core/agent/research/critic.py,sha256=99PAP-Acr2AegDib0FOP3sgt1oHdKbiicONkkYyssf4,13317
|
|
30
32
|
emdash_core/agent/research/macros.py,sha256=3EM-7_zbetCbd2QeyDwG6NOt3i_OTIWF1nY75nh-OT4,15152
|
|
31
33
|
emdash_core/agent/research/planner.py,sha256=2TjWKqbLg-fv5bEfc6-g729v0kQ5vs7FT-VIhxTG4HM,14333
|
|
32
|
-
emdash_core/agent/research/researcher.py,sha256=
|
|
34
|
+
emdash_core/agent/research/researcher.py,sha256=AMRMVUHPS_xEKDOeflFSQwXNcy7ArYLVM_tkmxLg7B8,18184
|
|
33
35
|
emdash_core/agent/research/state.py,sha256=P44YUTUhMrAmt--xsj8Hi0SzbDmrLXKPEf83HF2mqZs,18010
|
|
34
36
|
emdash_core/agent/research/synthesizer.py,sha256=j4UvH8JxUjo7RF-h69tpRERgN6pHSb8qNBOoKrH2Qro,19016
|
|
35
37
|
emdash_core/agent/reviewer_profile.py,sha256=RkJ_Mk5vbp2U-e0UBWB-k59cHsTzLj0aro22KJVCbss,16075
|
|
36
38
|
emdash_core/agent/rules.py,sha256=GVwfM6YlRxrPXLZ0h2cZFOx4l_mPPl0Bdwt8oxfMBLI,3014
|
|
37
39
|
emdash_core/agent/runner/__init__.py,sha256=FK3FUSsdKImso-QATYam5OnQhpCCHyXnXYRtmoLdQ80,1384
|
|
38
|
-
emdash_core/agent/runner/agent_runner.py,sha256=
|
|
39
|
-
emdash_core/agent/runner/context.py,sha256=
|
|
40
|
+
emdash_core/agent/runner/agent_runner.py,sha256=SohKzZaDUAaPhosXBN-Gg3CciWMalW_CnFclzxlwe7Y,37168
|
|
41
|
+
emdash_core/agent/runner/context.py,sha256=U8tLUtBWgU1yD3j8XDquDEQNEM70HcxkIMRAOsfJP8c,15099
|
|
40
42
|
emdash_core/agent/runner/factory.py,sha256=SXtfgD4F8R8cUDR4Tt-3LPHSDjyJwkyEAbxflXgjkqc,3288
|
|
41
43
|
emdash_core/agent/runner/plan.py,sha256=WMra-xpWeNJ0YtdnQMsd2aak5BhryrzUP_OtZMhlzeA,7336
|
|
42
|
-
emdash_core/agent/runner/sdk_runner.py,sha256=
|
|
44
|
+
emdash_core/agent/runner/sdk_runner.py,sha256=c9NKQyeEpXCEa5-Tc6lWinDCfsEwWHlBb3LdTYSgQTc,11741
|
|
43
45
|
emdash_core/agent/runner/utils.py,sha256=1feF3-rYA9x3Inh7pKdtPSGpMzNM5bBV5s6CJVCqqJQ,1826
|
|
44
46
|
emdash_core/agent/session.py,sha256=Zr7m8IK4-J6CDIMmN2QiSqpDT_O2S-SXu3Qmy9w6dk8,8517
|
|
45
|
-
emdash_core/agent/skills.py,sha256=
|
|
47
|
+
emdash_core/agent/skills.py,sha256=u3IH1y2D8no2E_LT4YS6ilfCQ_83pQZ4-ZcOScMBXb8,13665
|
|
46
48
|
emdash_core/agent/spec_schema.py,sha256=tmTCrO4zKXkOblW6gRyrQ3_ZdYU-ehnLE8YmZbhPHWQ,1429
|
|
47
49
|
emdash_core/agent/specification.py,sha256=b1nUQiGT4NiRv42hDkYAXVX_RtsKcHrf4Ae1dx0UVnc,19105
|
|
48
50
|
emdash_core/agent/subagent.py,sha256=zIlhbHOCUEgYtYLYwiQ7dkSleqI60emyBA-5XLPaH_k,12150
|
|
49
51
|
emdash_core/agent/subagent_prompts.py,sha256=pJJPXh4FlnE8bt9d-Ruquz6j8W-BS9pMCbXRqpgwq4g,407
|
|
50
|
-
emdash_core/agent/toolkit.py,sha256=
|
|
51
|
-
emdash_core/agent/toolkits/__init__.py,sha256=
|
|
52
|
-
emdash_core/agent/toolkits/base.py,sha256=
|
|
53
|
-
emdash_core/agent/toolkits/explore.py,sha256=
|
|
54
|
-
emdash_core/agent/toolkits/plan.py,sha256=
|
|
55
|
-
emdash_core/agent/tools/__init__.py,sha256=
|
|
52
|
+
emdash_core/agent/toolkit.py,sha256=elQRVzKf8Z95M-zuPpEA3AmvLqHukD0d6Gc488Q6mN0,23080
|
|
53
|
+
emdash_core/agent/toolkits/__init__.py,sha256=HPU7krOJ2zIdKT7ykH-k9h3CBH2YOizxkMCIU8r-kNs,5050
|
|
54
|
+
emdash_core/agent/toolkits/base.py,sha256=rQNKsrIMvtyfa_8YprZ-Vo8Khmkl5TgHXapol1UXCp8,5634
|
|
55
|
+
emdash_core/agent/toolkits/explore.py,sha256=5_f6q7x_nf7SkHb1osqQTrss4V-aFmmwR-gBtbCKhO0,1937
|
|
56
|
+
emdash_core/agent/toolkits/plan.py,sha256=ExDlf4dEN_eu41G40pABAvghPUxCnVF35j6lGN7bjIE,2205
|
|
57
|
+
emdash_core/agent/tools/__init__.py,sha256=kh7fVcUt2dBBHNK46bhmrUrnwNJc5jHc7IV8pxj0Kb4,3004
|
|
56
58
|
emdash_core/agent/tools/analytics.py,sha256=tEP_RWFpKGfFW_Yc5inMMjAkDFzpDQ77Ui_Ca7LQu60,14837
|
|
57
59
|
emdash_core/agent/tools/base.py,sha256=3clLKgR7Og5eDijZJLEcpJS1YV8u1rW_pXr_iwHdxTo,3349
|
|
58
|
-
emdash_core/agent/tools/coding.py,sha256=
|
|
60
|
+
emdash_core/agent/tools/coding.py,sha256=hw48My5DygGJyw3ti_jINB8J9jHFxfinvabMHfAIZPg,28216
|
|
59
61
|
emdash_core/agent/tools/github_mcp.py,sha256=D4fu_z9j-rL8SHD8TA2tO-ED-8Q4QB_RHQoqsh7Bjy8,16870
|
|
60
62
|
emdash_core/agent/tools/history.py,sha256=Zaers4Aul9-hrlMaGRcQHwfU2xb7yCjHFHSDtfMe3c4,423
|
|
63
|
+
emdash_core/agent/tools/lsp.py,sha256=8x3zhH9JYebqrLmuyjYU4Jti-pn0TQCFiCM7uONM92o,12480
|
|
61
64
|
emdash_core/agent/tools/modes.py,sha256=g82igKjpBeC23HgYRgULCNbjCRZQ6C-rmMMbNEGNbEk,10587
|
|
62
65
|
emdash_core/agent/tools/plan.py,sha256=RRvZsDHcvvDv6uyDSGhTYIoImZmI_7CCxCarkeSZjbQ,7922
|
|
63
66
|
emdash_core/agent/tools/plan_write.py,sha256=o4EEHTUr1hRfH3WSjrh3-QTfaJuUhjsQ5bJNBPD_j5Q,4417
|
|
64
67
|
emdash_core/agent/tools/search.py,sha256=aq5_jc8YT3R3oZtulgvKwmz1oljJom20NfF_q60o60Q,14353
|
|
65
|
-
emdash_core/agent/tools/skill.py,sha256=
|
|
68
|
+
emdash_core/agent/tools/skill.py,sha256=phrsvWXxNsXY8iQO_D32XD7LcdA6BBhirCgRMQYkiik,7025
|
|
66
69
|
emdash_core/agent/tools/spec.py,sha256=R9Ib-1epCVrgbOB6C9qYkwvgut94x3P2g4_FM_tMd2M,10022
|
|
67
|
-
emdash_core/agent/tools/task.py,sha256=
|
|
68
|
-
emdash_core/agent/tools/task_output.py,sha256=
|
|
70
|
+
emdash_core/agent/tools/task.py,sha256=kAogDNSyOVB_SJRcyYav0INJ3MzlSlwhmv-9ArRqsZc,11133
|
|
71
|
+
emdash_core/agent/tools/task_output.py,sha256=fKeNajN-KWw06u80bDsu0y3BzmU5thX2wV-oEInZ72s,13868
|
|
69
72
|
emdash_core/agent/tools/tasks.py,sha256=VT-oLFKzswmKu02H1hc_ercJ1blbseCo0Q0qRBh0DjM,11844
|
|
70
73
|
emdash_core/agent/tools/traversal.py,sha256=qQvHkledo_rT9q9kxk07pijY8XqkR4WWB5pFWVmG01I,20249
|
|
71
74
|
emdash_core/agent/tools/web.py,sha256=cqm4eiiBzeGCOmQE---uT9zlgsQUX9WY_YYz7wQbK1U,5521
|
|
75
|
+
emdash_core/agent/verifier/__init__.py,sha256=iav1bDKP4P-6xnv0f9V__HAbKys2TFIkVrZ6DvQABBw,280
|
|
76
|
+
emdash_core/agent/verifier/manager.py,sha256=MfVD1aNQGndCXnjzUL6PzH3D1uGCItyVxKEfEidG60g,10089
|
|
77
|
+
emdash_core/agent/verifier/models.py,sha256=JlwMeCILnmDOpmUE3DECbYIDj_58rqo9yw9n_Z_RWq8,2832
|
|
78
|
+
emdash_core/agent/worktree.py,sha256=IHUiNZyrlnumRjZipzM04U61gnR4cf36Bf1jodNuFxg,8946
|
|
72
79
|
emdash_core/analytics/__init__.py,sha256=5ky2djAly3-3lbQmUuNJlJTmBDaXjN2lOUw-OP2F1Zk,98
|
|
73
80
|
emdash_core/analytics/engine.py,sha256=f1go7SNnSlM_sFUEvmHrD4PTY9G39REBC7w01xdh3as,47738
|
|
74
81
|
emdash_core/api/__init__.py,sha256=L11AeV6gaCJjlZ8DU_q-lcuZYH9WV3BV4GYq8JF8BuI,92
|
|
75
|
-
emdash_core/api/agent.py,sha256
|
|
82
|
+
emdash_core/api/agent.py,sha256=-79xlAZB53iAwMgUK7ZJnrNGV4wcCcPKLjoFGcL2JA0,41644
|
|
76
83
|
emdash_core/api/agents.py,sha256=kInkI6iGnQuRxz5wS9w_Owq-4iceUJgugIOrWGDLkGA,3673
|
|
77
84
|
emdash_core/api/analyze.py,sha256=cR6wWzqSvp_5cNyUg0qACNF7DYdrcNkzhmRqgaqnd78,7593
|
|
78
85
|
emdash_core/api/auth.py,sha256=vnhH_xcsoTDYrCDBDytlm0LOV9yDoar04NL5FZKI8JU,4832
|
|
@@ -85,14 +92,13 @@ emdash_core/api/index.py,sha256=7FtyfTvB6K5Yh1mQZ3qlYWQ492QqCA4aTBbdeZBdfb4,5269
|
|
|
85
92
|
emdash_core/api/plan.py,sha256=k5b-nhSpo18Y-HI4RAqmabJWvLXTx9tt0cR3PNj9ewQ,3350
|
|
86
93
|
emdash_core/api/projectmd.py,sha256=KJmLpiTNwXK75_ADdUIWl2OfPLZU-WQaffsV1I5F8ZY,6105
|
|
87
94
|
emdash_core/api/query.py,sha256=90HuhYGRiPtolYMBdlYcgW8DV_SvYo0H2xZ_YUWVPRw,10188
|
|
88
|
-
emdash_core/api/research.py,sha256=
|
|
95
|
+
emdash_core/api/research.py,sha256=nOSu33me3_HrOYOBz08v4t2AZ-mZIoS26LWDuS-3iUI,3500
|
|
89
96
|
emdash_core/api/review.py,sha256=zOGrwwThZP_himnFyBKCl4mo4gjniuEaWGNWqcKajb0,4766
|
|
90
|
-
emdash_core/api/router.py,sha256=
|
|
97
|
+
emdash_core/api/router.py,sha256=Q3jY-oV91KrK2pjKAwy5X8xIiV-tzMSb4I8GiJW6UMw,1463
|
|
91
98
|
emdash_core/api/rules.py,sha256=BbIE_RKX8VGlUqxny0OK-tKoTK58bDBFXBf_1x3yN7g,3242
|
|
92
99
|
emdash_core/api/search.py,sha256=qPVVTNRExbyG4Ri3X3F5uGpILhlvtH99dHBv7ZVkRIw,3696
|
|
93
100
|
emdash_core/api/skills.py,sha256=8hF7IkM--aMMaNEaa16DoHl-8fBVx8oYCBnnqgsFkuE,6422
|
|
94
101
|
emdash_core/api/spec.py,sha256=ub09u1mkqpcF-z0Q1YU9FAkJb0LDyV_eG0_KXYLFmuk,2912
|
|
95
|
-
emdash_core/api/swarm.py,sha256=-CNY-NCVnwes0MlHV5yq_ZUie8pJxt0Fdg4g5R94dKo,6561
|
|
96
102
|
emdash_core/api/tasks.py,sha256=kyrhSc46wfwM3csOT26Gsx9SNjKSTwC9BQ5qMqe1uaY,3160
|
|
97
103
|
emdash_core/api/team.py,sha256=nHdsTIQ-ZDlpByNIVpSl4Ahf4q51A_HwQTnnmBq6agA,3308
|
|
98
104
|
emdash_core/auth/__init__.py,sha256=NpcoEyqtqYwUTKKFwNGKgroPOGtXS5rUpH2D9t2_4TY,290
|
|
@@ -105,26 +111,23 @@ emdash_core/checkpoint/models.py,sha256=0xfpeNHmLgVVzMzSo-C1dm-1bEWBAZvFED_1Du-R
|
|
|
105
111
|
emdash_core/checkpoint/storage.py,sha256=AKUwxeMA05hmxwdRPFivwqv0GWGYgCBlV4m9auzlxpk,5970
|
|
106
112
|
emdash_core/config.py,sha256=i2M9iRxiZQiKlkc1I0goXwI7ac6ABEdku58u_mGbWbA,2216
|
|
107
113
|
emdash_core/context/__init__.py,sha256=_6hqH8FtCi4Q3OpuC9zDPDEXuBitLxrY20CdookRTsY,1496
|
|
114
|
+
emdash_core/context/longevity.py,sha256=5i2cYxXXE3tDNer9ZQGvIXTetL1cIYVpJ9qnNkDvT1M,6123
|
|
108
115
|
emdash_core/context/models.py,sha256=eQdjaea5M6iQ-9ZxJ5IVQgiQEPbZz81Xe2B186GuSYI,1304
|
|
109
116
|
emdash_core/context/providers/__init__.py,sha256=cWokJwYatvihXoyhqM6BHbG4JQeImgWzyjLdj60BqS4,261
|
|
110
117
|
emdash_core/context/providers/base.py,sha256=AtWkQcigXeG4rX6WcGkXGrML5QeRUusn2FPvy4nCzLA,2234
|
|
111
|
-
emdash_core/context/providers/explored_areas.py,sha256=
|
|
118
|
+
emdash_core/context/providers/explored_areas.py,sha256=8lB_mvtEQGuWx7x91bjMHFobgLiQk6vCPk31MeiUiLY,8760
|
|
112
119
|
emdash_core/context/providers/touched_areas.py,sha256=BLnPkYsQSS9InW9rDUDTlOhoE6QldteWYxpMeU73if8,12858
|
|
113
120
|
emdash_core/context/registry.py,sha256=p_F0APYsLTDbZbcNkVzw2ET0AMg5UdySUKstxML8jUA,2273
|
|
114
|
-
emdash_core/context/reranker.py,sha256=
|
|
121
|
+
emdash_core/context/reranker.py,sha256=r3CXpjl93JKXFg9RQ8lahCJF03y_nsniVlnr-m_strE,2832
|
|
115
122
|
emdash_core/context/service.py,sha256=vTSCUoXdNGTTs0ZtMHInX3uG5Wbol-lpCXEn4ICNCDo,9438
|
|
116
123
|
emdash_core/context/session.py,sha256=XqDELflx7TGosraTU3mBJcZLwD1Ihv2DtuFjeoxjF7A,12424
|
|
124
|
+
emdash_core/context/simple_reranker.py,sha256=0JqmXWvax40fDZwkpfM_gCtO9WaSVKji5Swi5PXUymw,15849
|
|
125
|
+
emdash_core/context/tool_relevance.py,sha256=otjbxR2QWXun8j2Yqy1HeG3ZdXjooSc21E7m4bnvdRo,2403
|
|
117
126
|
emdash_core/core/__init__.py,sha256=KW97frnmqf5PWHIvYpdZN7aaAPaUXWfsLEEicdZ3g80,1987
|
|
118
|
-
emdash_core/core/config.py,sha256=
|
|
127
|
+
emdash_core/core/config.py,sha256=dgaZR8jmNtdzyVZGuLD124ReuVBq3VFYRle1EGKzn2k,16304
|
|
119
128
|
emdash_core/core/exceptions.py,sha256=LA4bsgEmPJUKQiBmrMpbPT6Iatu4xQLdenGMceMD2Yk,1186
|
|
120
129
|
emdash_core/core/models.py,sha256=U2achHuaaP9Qr2qZEqBvdzpbxNN2z-SJWjjGpBBiCu4,7810
|
|
121
130
|
emdash_core/core/review_config.py,sha256=pP8d_0D6mzKg2iYLjrbF9XcI8FIPLwZa0onUDUTvgkM,1455
|
|
122
|
-
emdash_core/db/__init__.py,sha256=hGJeI4MqisrE5adATeXZxB9I0GZOArPs7kw2jgOcs8Y,1478
|
|
123
|
-
emdash_core/db/auth.py,sha256=pfIbbjbf4txhvdSMFFSdW1pEFxkP-Sc2fMY5X4KJAJ8,3999
|
|
124
|
-
emdash_core/db/models.py,sha256=JdVmYC19DZ6yAOMgCRYCvd1QNTT1bS6knIXzNOjdYv8,2057
|
|
125
|
-
emdash_core/db/provider.py,sha256=Ip99Lk8cSpRDvxYtnCTaYGAM3BYjHWzZKUD6PcqSs8I,6561
|
|
126
|
-
emdash_core/db/providers/__init__.py,sha256=QxhyPLTJMeMcHY2aIgQB1ezEoCiP3D3sp5R3b5jZhO4,113
|
|
127
|
-
emdash_core/db/providers/supabase.py,sha256=t2RWZbPiusPZT2JZm4J-0meF7fdGdhMe_jH51tz8xVo,16083
|
|
128
131
|
emdash_core/embeddings/__init__.py,sha256=NnmjaDSVOxX_H9yGQxTlaoBa97HMY_8Lv1pmIFta-6M,635
|
|
129
132
|
emdash_core/embeddings/indexer.py,sha256=_LNZyNP6mjSJTeCbsOfSzAHUqEZJQ1TO7EThGBSaUt0,19947
|
|
130
133
|
emdash_core/embeddings/models.py,sha256=YLiJW7TFJ5roomw2AxAnB8SG4ywY33haJHXZsrU_rWs,6457
|
|
@@ -134,11 +137,11 @@ emdash_core/embeddings/providers/fireworks.py,sha256=WEJq1nzQIhECLzxgqnVHtOlkzDd
|
|
|
134
137
|
emdash_core/embeddings/providers/openai.py,sha256=sMHk7uG3Xt7hPjtOGGPkSxaFBF15PN2azPp9eOGbJfU,3287
|
|
135
138
|
emdash_core/embeddings/registry.py,sha256=me9G8xRCpA8XK2U84X-a2auie-VsOmVuQuPwMhQmLwc,5193
|
|
136
139
|
emdash_core/embeddings/service.py,sha256=nvSpMsqzoEnZA7iwLHwTWMqR3YzeFnbGFrL1RmN9F38,6649
|
|
137
|
-
emdash_core/graph/__init__.py,sha256=
|
|
140
|
+
emdash_core/graph/__init__.py,sha256=FGa4qq-YBWngNxywQBlKwH4-G6BNsgw_IymVgcVn4QU,735
|
|
138
141
|
emdash_core/graph/builder.py,sha256=INh81gubFgmow25eNm2Z139p9VAmZhRx9pyylOhJxgw,4531
|
|
139
|
-
emdash_core/graph/connection.py,sha256=
|
|
142
|
+
emdash_core/graph/connection.py,sha256=zXHp9kqyF82nO6ONUaEvrk42QHaie_9x49nk6klxcQ0,22691
|
|
140
143
|
emdash_core/graph/schema.py,sha256=sKjW1GS3tutpFNeXF7TVMA17iOMEdnyfLGG3hbEigXA,13281
|
|
141
|
-
emdash_core/graph/writer.py,sha256=
|
|
144
|
+
emdash_core/graph/writer.py,sha256=Dg4-tt2deLmk8i4nq37SXd1ByL6DNJ2SCXIRbJK0CZA,26358
|
|
142
145
|
emdash_core/ingestion/__init__.py,sha256=hyGLUPT04C9RXj7zaJF_389-8KA6xQN8zCX8l2v_NZ0,276
|
|
143
146
|
emdash_core/ingestion/change_detector.py,sha256=LOAODz_apk4ZRfAINz4lf2gCEq1zqQk0bkRnfRrn9oM,5312
|
|
144
147
|
emdash_core/ingestion/git/__init__.py,sha256=WI754ZInqIQ1JW057Hym1qXUTejhsVdmZ-LTWHXSeLk,113
|
|
@@ -157,9 +160,9 @@ emdash_core/ingestion/parsers/python_parser.py,sha256=n4yc9FwE91DCjqI_BOM4EK2NR_
|
|
|
157
160
|
emdash_core/ingestion/parsers/registry.py,sha256=fgq-dWfEUpACuWFCPxbcQYH4gQSYqDYJnvJXFNAwb8M,2074
|
|
158
161
|
emdash_core/ingestion/parsers/ts_ast_parser.js,sha256=bvFEl97bzI-UItTvYkyT5D0rxXWqSGYlCF-Ph5FdMoI,9744
|
|
159
162
|
emdash_core/ingestion/parsers/typescript_parser.py,sha256=UHEuKUwaEkrscZ7NEisBWcZxJ1Ltn7pUvsdTdccqMGY,10928
|
|
160
|
-
emdash_core/ingestion/repository.py,sha256=
|
|
163
|
+
emdash_core/ingestion/repository.py,sha256=oeHbIHhkomONtLKJWgqba7FKd_dYZHv2nT_JnYaP6dk,4828
|
|
161
164
|
emdash_core/models/__init__.py,sha256=zTsIg4Sy2o2eTWGIpYP9rb_yFdR-DFZ1BSWF9DcrHqU,625
|
|
162
|
-
emdash_core/models/agent.py,sha256=
|
|
165
|
+
emdash_core/models/agent.py,sha256=1h5iCS3066de8mO0iJIjHmlq_bHiHXARW6VWIDqvpJs,2326
|
|
163
166
|
emdash_core/models/index.py,sha256=1dohTHOYvtOLmphGUELwgGH7DkMbhK_ykFn2_YmOtag,2207
|
|
164
167
|
emdash_core/models/query.py,sha256=3ZRTUzZoBr9IRrniXNLq2egUkg3k5tb9BXyu4xPB2DY,3480
|
|
165
168
|
emdash_core/planning/__init__.py,sha256=6db3V1maLCicMlRuG3JfGCnH84MxcdRrwBsGddlxVCg,267
|
|
@@ -170,17 +173,10 @@ emdash_core/planning/feature_expander.py,sha256=ADNv3qsbRqPtXKRVDSZIf4lcaf_hxdGc
|
|
|
170
173
|
emdash_core/planning/llm_explainer.py,sha256=jJlgO5_u5_7TCl_6F-0qoJWtpeY3FTXnR5vvHcqa0Dc,7150
|
|
171
174
|
emdash_core/planning/similarity.py,sha256=j3jiSWoTqlakHZGa-TxVJYknru7DzRaWlIOow2NG02o,18876
|
|
172
175
|
emdash_core/planning/team_focus.py,sha256=fv3rCyh_8sHk4w_yjzuw36KlKPAJLPZPgVOo762aneU,32405
|
|
173
|
-
emdash_core/server.py,sha256=
|
|
176
|
+
emdash_core/server.py,sha256=_VGLi0aOWxpsmc77tj9oQ8iQwToKjaWdC1cXPt60q0Y,4989
|
|
174
177
|
emdash_core/skills/frontend-design/SKILL.md,sha256=fdqIqRS8J_pTH_9h5D-ZUdvYAqor9-xTl2FEYrDAOKA,4338
|
|
175
178
|
emdash_core/sse/__init__.py,sha256=q6nfbsqvEX7uYTuLwRMb4E73hW-o_Cuv63APod_Kluw,129
|
|
176
|
-
emdash_core/sse/stream.py,sha256=
|
|
177
|
-
emdash_core/swarm/__init__.py,sha256=EyL9U64ByQCCcL19ntwu2OU7labME3i3dSpSF25X6Mo,448
|
|
178
|
-
emdash_core/swarm/merge_agent.py,sha256=Fp0rqdHsd0m0swoAApq46QuBNDw5ejDk4dRddc1cD-E,13038
|
|
179
|
-
emdash_core/swarm/session_manager.py,sha256=RyLGpfXw-qFXJuQBP3Acw4w7LC_ZIhlPaDDkqjm-ycU,8999
|
|
180
|
-
emdash_core/swarm/swarm_runner.py,sha256=em-omxFHp1OBQyuucN6OqnMEy4NVdispo059M_QAbBQ,6747
|
|
181
|
-
emdash_core/swarm/task_definition.py,sha256=tplZCA9esV8RQELE45LKsGuasxXxc2Ina9tRFqxtgqU,4364
|
|
182
|
-
emdash_core/swarm/worker_spawner.py,sha256=jTZo1CqAumef6wbX8evIacUS5prtr_otWzYa6Uo2N3k,10461
|
|
183
|
-
emdash_core/swarm/worktree_manager.py,sha256=C5pk5g8dfi1luw6aecR8lu83CNVT3qdL_wEUMOGagns,8415
|
|
179
|
+
emdash_core/sse/stream.py,sha256=Vt4NPH__63w0eCuV0gg8dcVuUxw2vjw0bx3_ONmR9wI,5878
|
|
184
180
|
emdash_core/templates/__init__.py,sha256=rVF1ZlAiFfFTzJKfANFHbifC7c2HoFTvDVxAuOoHur0,256
|
|
185
181
|
emdash_core/templates/defaults/agent-builder.md.template,sha256=LLbd0IFEBT5Gw1LToDXoyT-EC4RHcGrENdterrPN3xk,2187
|
|
186
182
|
emdash_core/templates/defaults/focus.md.template,sha256=wj9AIwbUaZ7ANZO1zx_ZUlZ7kg_NxqGwmmJSGLefWwg,3366
|
|
@@ -194,11 +190,11 @@ emdash_core/templates/defaults/reviewer.md.template,sha256=_RbULDB78fEuPA3DBbQfA
|
|
|
194
190
|
emdash_core/templates/defaults/spec.md.template,sha256=0ftXTYyhftoTZsGkUXP5HgUOXeVmsVcG_VnjBAVjExU,1139
|
|
195
191
|
emdash_core/templates/defaults/tasks.md.template,sha256=LMZ6PRek0_0s3o-i8zRP-hwipgp_8F2qNgwnLAI3v5w,2093
|
|
196
192
|
emdash_core/templates/loader.py,sha256=G_6ITQqWSMYcgA_fgjKQsd_3BBNt-LuhQE8VyC2ouj0,9796
|
|
197
|
-
emdash_core/utils/__init__.py,sha256=
|
|
198
|
-
emdash_core/utils/git.py,sha256=
|
|
199
|
-
emdash_core/utils/image.py,sha256=
|
|
193
|
+
emdash_core/utils/__init__.py,sha256=8SmXbLfHafDW5LxbDp5j0VTPa-dWo9_FH1XjdY4L9c8,898
|
|
194
|
+
emdash_core/utils/git.py,sha256=Qit9h35GZ5ZkP7E5_2JrJ4kNYrDcTgJryq-GMdtFDN4,5161
|
|
195
|
+
emdash_core/utils/image.py,sha256=7Qz2Cbe-3sPRaLsBTKxuf5MS8jzxjFn59TyyhKvGu2M,14566
|
|
200
196
|
emdash_core/utils/logger.py,sha256=iLaMA5vkUvxCfWsvZ7WZSDQWv4Gh5gJHeYbAB6urDio,1473
|
|
201
|
-
emdash_core-0.1.
|
|
202
|
-
emdash_core-0.1.
|
|
203
|
-
emdash_core-0.1.
|
|
204
|
-
emdash_core-0.1.
|
|
197
|
+
emdash_core-0.1.60.dist-info/METADATA,sha256=_GiCIcH6coX4j26WdHokzU2esYeI2izbRQ9MP_UWBLc,1504
|
|
198
|
+
emdash_core-0.1.60.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
199
|
+
emdash_core-0.1.60.dist-info/entry_points.txt,sha256=WgC9h0Bcsh0VaLfDv4hAKaY5krcT2Ati4UyoIJNavdk,105
|
|
200
|
+
emdash_core-0.1.60.dist-info/RECORD,,
|
emdash_core/api/swarm.py
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
"""Swarm (multi-agent) endpoints with SSE streaming."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from fastapi import APIRouter, HTTPException
|
|
8
|
-
from fastapi.responses import StreamingResponse
|
|
9
|
-
from pydantic import BaseModel, Field
|
|
10
|
-
|
|
11
|
-
from ..sse.stream import SSEHandler, EventType
|
|
12
|
-
|
|
13
|
-
router = APIRouter(prefix="/swarm", tags=["swarm"])
|
|
14
|
-
|
|
15
|
-
_executor = ThreadPoolExecutor(max_workers=1)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class SwarmRequest(BaseModel):
|
|
19
|
-
"""Request to run swarm."""
|
|
20
|
-
tasks: list[str] = Field(..., description="List of tasks to run in parallel")
|
|
21
|
-
model: Optional[str] = Field(default=None, description="LLM model")
|
|
22
|
-
workers: int = Field(default=3, description="Number of parallel workers")
|
|
23
|
-
timeout: int = Field(default=300, description="Timeout per task in seconds")
|
|
24
|
-
base_branch: Optional[str] = Field(default=None, description="Base branch")
|
|
25
|
-
auto_merge: bool = Field(default=True, description="Auto-merge completed branches")
|
|
26
|
-
llm_merge: bool = Field(default=False, description="Use LLM for merge conflicts")
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class SwarmStatus(BaseModel):
|
|
30
|
-
"""Status of swarm execution."""
|
|
31
|
-
is_running: bool
|
|
32
|
-
tasks_total: int
|
|
33
|
-
tasks_completed: int
|
|
34
|
-
tasks_failed: int
|
|
35
|
-
current_tasks: list[str]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class SwarmSession(BaseModel):
|
|
39
|
-
"""An active swarm session."""
|
|
40
|
-
id: str
|
|
41
|
-
task: str
|
|
42
|
-
status: str # running, completed, failed
|
|
43
|
-
branch: Optional[str] = None
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def _run_swarm_sync(
|
|
47
|
-
tasks: list[str],
|
|
48
|
-
model: Optional[str],
|
|
49
|
-
workers: int,
|
|
50
|
-
sse_handler: SSEHandler,
|
|
51
|
-
):
|
|
52
|
-
"""Run swarm synchronously."""
|
|
53
|
-
import sys
|
|
54
|
-
from pathlib import Path
|
|
55
|
-
|
|
56
|
-
repo_root = Path(__file__).parent.parent.parent.parent.parent
|
|
57
|
-
if str(repo_root) not in sys.path:
|
|
58
|
-
sys.path.insert(0, str(repo_root))
|
|
59
|
-
|
|
60
|
-
try:
|
|
61
|
-
from ..swarm.swarm_runner import SwarmRunner
|
|
62
|
-
from ..agent.events import AgentEventEmitter
|
|
63
|
-
|
|
64
|
-
class SSEBridge:
|
|
65
|
-
def __init__(self, handler):
|
|
66
|
-
self._handler = handler
|
|
67
|
-
|
|
68
|
-
def handle(self, event):
|
|
69
|
-
self._handler.handle(event)
|
|
70
|
-
|
|
71
|
-
emitter = AgentEventEmitter(agent_name="Swarm")
|
|
72
|
-
emitter.add_handler(SSEBridge(sse_handler))
|
|
73
|
-
|
|
74
|
-
runner = SwarmRunner(
|
|
75
|
-
repo_root=repo_root,
|
|
76
|
-
model=model or "gpt-4o-mini",
|
|
77
|
-
max_workers=workers,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
sse_handler.emit(EventType.PROGRESS, {
|
|
81
|
-
"step": f"Starting {len(tasks)} tasks with {workers} workers",
|
|
82
|
-
"percent": 0,
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
state = runner.run(tasks)
|
|
86
|
-
|
|
87
|
-
# Count results from swarm state
|
|
88
|
-
from ..swarm.task_definition import TaskStatus
|
|
89
|
-
completed = sum(1 for t in state.tasks if t.status == TaskStatus.COMPLETED)
|
|
90
|
-
failed = sum(1 for t in state.tasks if t.status == TaskStatus.FAILED)
|
|
91
|
-
|
|
92
|
-
sse_handler.emit(EventType.RESPONSE, {
|
|
93
|
-
"completed": completed,
|
|
94
|
-
"failed": failed,
|
|
95
|
-
"results": [{"slug": t.slug, "status": t.status.value} for t in state.tasks],
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
except Exception as e:
|
|
99
|
-
sse_handler.emit(EventType.ERROR, {"message": str(e)})
|
|
100
|
-
finally:
|
|
101
|
-
sse_handler.close()
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@router.post("/run")
|
|
105
|
-
async def run_swarm(request: SwarmRequest):
|
|
106
|
-
"""Run multiple agents in parallel on separate tasks.
|
|
107
|
-
|
|
108
|
-
Each task runs in its own git worktree branch.
|
|
109
|
-
"""
|
|
110
|
-
if not request.tasks:
|
|
111
|
-
raise HTTPException(status_code=400, detail="No tasks provided")
|
|
112
|
-
|
|
113
|
-
sse_handler = SSEHandler(agent_name="Swarm")
|
|
114
|
-
|
|
115
|
-
sse_handler.emit(EventType.SESSION_START, {
|
|
116
|
-
"agent_name": "Swarm",
|
|
117
|
-
"task_count": len(request.tasks),
|
|
118
|
-
"workers": request.workers,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
async def run():
|
|
122
|
-
loop = asyncio.get_event_loop()
|
|
123
|
-
await loop.run_in_executor(
|
|
124
|
-
_executor,
|
|
125
|
-
_run_swarm_sync,
|
|
126
|
-
request.tasks,
|
|
127
|
-
request.model,
|
|
128
|
-
request.workers,
|
|
129
|
-
sse_handler,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
asyncio.create_task(run())
|
|
133
|
-
|
|
134
|
-
return StreamingResponse(
|
|
135
|
-
sse_handler,
|
|
136
|
-
media_type="text/event-stream",
|
|
137
|
-
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
@router.get("/status", response_model=SwarmStatus)
|
|
142
|
-
async def get_swarm_status():
|
|
143
|
-
"""Get status of current swarm execution."""
|
|
144
|
-
# TODO: Implement actual status tracking
|
|
145
|
-
return SwarmStatus(
|
|
146
|
-
is_running=False,
|
|
147
|
-
tasks_total=0,
|
|
148
|
-
tasks_completed=0,
|
|
149
|
-
tasks_failed=0,
|
|
150
|
-
current_tasks=[],
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
@router.get("/sessions")
|
|
155
|
-
async def get_swarm_sessions():
|
|
156
|
-
"""List active swarm sessions."""
|
|
157
|
-
# TODO: Implement session tracking
|
|
158
|
-
return {"sessions": []}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@router.post("/cleanup")
|
|
162
|
-
async def cleanup_swarm(force: bool = False):
|
|
163
|
-
"""Clean up all swarm worktrees and branches."""
|
|
164
|
-
try:
|
|
165
|
-
from pathlib import Path
|
|
166
|
-
from ..swarm.swarm_runner import SwarmRunner
|
|
167
|
-
|
|
168
|
-
repo_root = Path(__file__).parent.parent.parent.parent.parent
|
|
169
|
-
runner = SwarmRunner.load(repo_root)
|
|
170
|
-
|
|
171
|
-
if runner:
|
|
172
|
-
cleaned = runner.cleanup()
|
|
173
|
-
else:
|
|
174
|
-
# No active swarm, just cleanup orphaned worktrees
|
|
175
|
-
from ..swarm.worktree_manager import WorktreeManager
|
|
176
|
-
manager = WorktreeManager(repo_root)
|
|
177
|
-
cleaned = manager.cleanup_all()
|
|
178
|
-
|
|
179
|
-
return {
|
|
180
|
-
"success": True,
|
|
181
|
-
"cleaned_worktrees": cleaned,
|
|
182
|
-
}
|
|
183
|
-
except Exception as e:
|
|
184
|
-
raise HTTPException(status_code=500, detail=str(e))
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
@router.post("/merge")
|
|
188
|
-
async def merge_swarm_branches(
|
|
189
|
-
llm_merge: bool = False,
|
|
190
|
-
target: Optional[str] = None,
|
|
191
|
-
):
|
|
192
|
-
"""Merge all completed task branches."""
|
|
193
|
-
try:
|
|
194
|
-
from pathlib import Path
|
|
195
|
-
from ..swarm.swarm_runner import SwarmRunner
|
|
196
|
-
|
|
197
|
-
repo_root = Path(__file__).parent.parent.parent.parent.parent
|
|
198
|
-
runner = SwarmRunner.load(repo_root)
|
|
199
|
-
|
|
200
|
-
if not runner:
|
|
201
|
-
return {
|
|
202
|
-
"success": False,
|
|
203
|
-
"error": "No active swarm found",
|
|
204
|
-
"merged_branches": [],
|
|
205
|
-
"conflicts": [],
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
results = runner.merge_completed(
|
|
209
|
-
use_llm=llm_merge,
|
|
210
|
-
target_branch=target,
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
merged = [r.task_id for r in results if r.success]
|
|
214
|
-
failed = [{"task_id": r.task_id, "conflicts": r.conflicts, "error": r.error_message}
|
|
215
|
-
for r in results if not r.success]
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
"success": len(failed) == 0,
|
|
219
|
-
"merged_tasks": merged,
|
|
220
|
-
"failed": failed,
|
|
221
|
-
}
|
|
222
|
-
except Exception as e:
|
|
223
|
-
raise HTTPException(status_code=500, detail=str(e))
|
emdash_core/db/__init__.py
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""Database layer for EmDash.
|
|
2
|
-
|
|
3
|
-
Provides an abstraction over database backends with Supabase as the default implementation.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
from typing import Optional
|
|
8
|
-
|
|
9
|
-
from .models import (
|
|
10
|
-
Feature,
|
|
11
|
-
FeatureAssignee,
|
|
12
|
-
FeaturePR,
|
|
13
|
-
FeatureStatus,
|
|
14
|
-
PRStatus,
|
|
15
|
-
Project,
|
|
16
|
-
TeamMember,
|
|
17
|
-
)
|
|
18
|
-
from .provider import DatabaseProvider
|
|
19
|
-
from .providers.supabase import SupabaseProvider
|
|
20
|
-
from .auth import AuthProvider, User, get_auth
|
|
21
|
-
|
|
22
|
-
__all__ = [
|
|
23
|
-
# Models
|
|
24
|
-
"Feature",
|
|
25
|
-
"FeatureAssignee",
|
|
26
|
-
"FeaturePR",
|
|
27
|
-
"FeatureStatus",
|
|
28
|
-
"PRStatus",
|
|
29
|
-
"Project",
|
|
30
|
-
"TeamMember",
|
|
31
|
-
"User",
|
|
32
|
-
# Provider
|
|
33
|
-
"DatabaseProvider",
|
|
34
|
-
"SupabaseProvider",
|
|
35
|
-
# Auth
|
|
36
|
-
"AuthProvider",
|
|
37
|
-
"get_auth",
|
|
38
|
-
# Factory
|
|
39
|
-
"get_provider",
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
_provider_instance: Optional[DatabaseProvider] = None
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def get_provider() -> DatabaseProvider:
|
|
46
|
-
"""Get the configured database provider instance.
|
|
47
|
-
|
|
48
|
-
Returns a singleton instance of the database provider.
|
|
49
|
-
Currently only supports Supabase.
|
|
50
|
-
|
|
51
|
-
Returns:
|
|
52
|
-
DatabaseProvider instance
|
|
53
|
-
|
|
54
|
-
Raises:
|
|
55
|
-
ValueError: If required environment variables are not set
|
|
56
|
-
"""
|
|
57
|
-
global _provider_instance
|
|
58
|
-
|
|
59
|
-
if _provider_instance is None:
|
|
60
|
-
provider_type = os.getenv("EMDASH_DB_PROVIDER", "supabase")
|
|
61
|
-
|
|
62
|
-
if provider_type == "supabase":
|
|
63
|
-
_provider_instance = SupabaseProvider()
|
|
64
|
-
else:
|
|
65
|
-
raise ValueError(f"Unknown database provider: {provider_type}")
|
|
66
|
-
|
|
67
|
-
return _provider_instance
|
emdash_core/db/auth.py
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"""Supabase authentication with GitHub OAuth."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
from dataclasses import dataclass
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
|
-
from supabase import create_client, Client
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@dataclass
|
|
11
|
-
class User:
|
|
12
|
-
"""Authenticated user from Supabase Auth."""
|
|
13
|
-
|
|
14
|
-
id: str
|
|
15
|
-
email: Optional[str]
|
|
16
|
-
github_handle: Optional[str]
|
|
17
|
-
avatar_url: Optional[str]
|
|
18
|
-
access_token: Optional[str] = None
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class AuthProvider:
|
|
22
|
-
"""Handle Supabase authentication with GitHub OAuth."""
|
|
23
|
-
|
|
24
|
-
def __init__(self, url: Optional[str] = None, key: Optional[str] = None):
|
|
25
|
-
self.url = url or os.getenv("SUPABASE_URL")
|
|
26
|
-
self.key = key or os.getenv("SUPABASE_KEY")
|
|
27
|
-
|
|
28
|
-
if not self.url or not self.key:
|
|
29
|
-
raise ValueError("SUPABASE_URL and SUPABASE_KEY must be set")
|
|
30
|
-
|
|
31
|
-
self.client: Client = create_client(self.url, self.key)
|
|
32
|
-
|
|
33
|
-
def get_github_login_url(self, redirect_to: Optional[str] = None) -> str:
|
|
34
|
-
"""Get the GitHub OAuth login URL.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
redirect_to: URL to redirect after login (for web apps)
|
|
38
|
-
|
|
39
|
-
Returns:
|
|
40
|
-
GitHub OAuth URL to redirect user to
|
|
41
|
-
"""
|
|
42
|
-
options = {}
|
|
43
|
-
if redirect_to:
|
|
44
|
-
options["redirect_to"] = redirect_to
|
|
45
|
-
|
|
46
|
-
response = self.client.auth.sign_in_with_oauth(
|
|
47
|
-
{"provider": "github", "options": options}
|
|
48
|
-
)
|
|
49
|
-
return response.url
|
|
50
|
-
|
|
51
|
-
def sign_in_with_github_token(self, access_token: str) -> Optional[User]:
|
|
52
|
-
"""Sign in with an existing GitHub access token.
|
|
53
|
-
|
|
54
|
-
Args:
|
|
55
|
-
access_token: GitHub OAuth access token
|
|
56
|
-
|
|
57
|
-
Returns:
|
|
58
|
-
User if successful, None otherwise
|
|
59
|
-
"""
|
|
60
|
-
try:
|
|
61
|
-
response = self.client.auth.sign_in_with_id_token(
|
|
62
|
-
{"provider": "github", "token": access_token}
|
|
63
|
-
)
|
|
64
|
-
return self._session_to_user(response)
|
|
65
|
-
except Exception:
|
|
66
|
-
return None
|
|
67
|
-
|
|
68
|
-
def get_session(self) -> Optional[User]:
|
|
69
|
-
"""Get the current authenticated user from session.
|
|
70
|
-
|
|
71
|
-
Returns:
|
|
72
|
-
User if authenticated, None otherwise
|
|
73
|
-
"""
|
|
74
|
-
try:
|
|
75
|
-
response = self.client.auth.get_session()
|
|
76
|
-
if response and response.user:
|
|
77
|
-
return self._response_to_user(response)
|
|
78
|
-
return None
|
|
79
|
-
except Exception:
|
|
80
|
-
return None
|
|
81
|
-
|
|
82
|
-
def sign_out(self) -> bool:
|
|
83
|
-
"""Sign out the current user.
|
|
84
|
-
|
|
85
|
-
Returns:
|
|
86
|
-
True if successful
|
|
87
|
-
"""
|
|
88
|
-
try:
|
|
89
|
-
self.client.auth.sign_out()
|
|
90
|
-
return True
|
|
91
|
-
except Exception:
|
|
92
|
-
return False
|
|
93
|
-
|
|
94
|
-
def _session_to_user(self, session) -> Optional[User]:
|
|
95
|
-
"""Convert Supabase session to User model."""
|
|
96
|
-
if not session or not session.user:
|
|
97
|
-
return None
|
|
98
|
-
|
|
99
|
-
user_meta = session.user.user_metadata or {}
|
|
100
|
-
|
|
101
|
-
return User(
|
|
102
|
-
id=session.user.id,
|
|
103
|
-
email=session.user.email,
|
|
104
|
-
github_handle=user_meta.get("user_name") or user_meta.get("preferred_username"),
|
|
105
|
-
avatar_url=user_meta.get("avatar_url"),
|
|
106
|
-
access_token=session.access_token if hasattr(session, "access_token") else None,
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
def _response_to_user(self, response) -> Optional[User]:
|
|
110
|
-
"""Convert Supabase auth response to User model."""
|
|
111
|
-
if not response or not response.user:
|
|
112
|
-
return None
|
|
113
|
-
|
|
114
|
-
user_meta = response.user.user_metadata or {}
|
|
115
|
-
|
|
116
|
-
return User(
|
|
117
|
-
id=response.user.id,
|
|
118
|
-
email=response.user.email,
|
|
119
|
-
github_handle=user_meta.get("user_name") or user_meta.get("preferred_username"),
|
|
120
|
-
avatar_url=user_meta.get("avatar_url"),
|
|
121
|
-
access_token=response.session.access_token if response.session else None,
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# Singleton instance
|
|
126
|
-
_auth_instance: Optional[AuthProvider] = None
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def get_auth() -> AuthProvider:
|
|
130
|
-
"""Get the auth provider instance."""
|
|
131
|
-
global _auth_instance
|
|
132
|
-
if _auth_instance is None:
|
|
133
|
-
_auth_instance = AuthProvider()
|
|
134
|
-
return _auth_instance
|