devcopilot 0.2.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.
Files changed (189) hide show
  1. api/__init__.py +17 -0
  2. api/admin_config.py +1303 -0
  3. api/admin_routes.py +287 -0
  4. api/admin_static/admin.css +459 -0
  5. api/admin_static/admin.js +497 -0
  6. api/admin_static/index.html +77 -0
  7. api/admin_urls.py +34 -0
  8. api/app.py +194 -0
  9. api/command_utils.py +164 -0
  10. api/dependencies.py +144 -0
  11. api/detection.py +152 -0
  12. api/gateway_model_ids.py +54 -0
  13. api/model_catalog.py +133 -0
  14. api/model_router.py +125 -0
  15. api/models/__init__.py +45 -0
  16. api/models/anthropic.py +234 -0
  17. api/models/openai_responses.py +28 -0
  18. api/models/responses.py +60 -0
  19. api/optimization_handlers.py +154 -0
  20. api/request_pipeline.py +424 -0
  21. api/routes.py +156 -0
  22. api/runtime.py +334 -0
  23. api/validation_log.py +48 -0
  24. api/web_server_tools.py +22 -0
  25. api/web_tools/__init__.py +17 -0
  26. api/web_tools/constants.py +15 -0
  27. api/web_tools/egress.py +99 -0
  28. api/web_tools/outbound.py +278 -0
  29. api/web_tools/parsers.py +104 -0
  30. api/web_tools/request.py +87 -0
  31. api/web_tools/streaming.py +206 -0
  32. cli/__init__.py +5 -0
  33. cli/claude_env.py +12 -0
  34. cli/entrypoints.py +166 -0
  35. cli/env.example +209 -0
  36. cli/launchers/__init__.py +1 -0
  37. cli/launchers/claude.py +84 -0
  38. cli/launchers/codex.py +204 -0
  39. cli/launchers/codex_model_catalog.py +186 -0
  40. cli/launchers/common.py +93 -0
  41. cli/managed/__init__.py +6 -0
  42. cli/managed/claude.py +215 -0
  43. cli/managed/manager.py +157 -0
  44. cli/managed/session.py +260 -0
  45. cli/process_registry.py +78 -0
  46. config/__init__.py +5 -0
  47. config/constants.py +13 -0
  48. config/logging_config.py +159 -0
  49. config/nim.py +118 -0
  50. config/paths.py +91 -0
  51. config/provider_catalog.py +259 -0
  52. config/provider_ids.py +7 -0
  53. config/settings.py +538 -0
  54. core/__init__.py +1 -0
  55. core/anthropic/__init__.py +46 -0
  56. core/anthropic/content.py +31 -0
  57. core/anthropic/conversion.py +587 -0
  58. core/anthropic/emitted_sse_tracker.py +346 -0
  59. core/anthropic/errors.py +70 -0
  60. core/anthropic/native_messages_request.py +280 -0
  61. core/anthropic/native_sse_block_policy.py +313 -0
  62. core/anthropic/provider_stream_error.py +34 -0
  63. core/anthropic/server_tool_sse.py +14 -0
  64. core/anthropic/sse.py +440 -0
  65. core/anthropic/stream_contracts.py +205 -0
  66. core/anthropic/stream_recovery.py +346 -0
  67. core/anthropic/stream_recovery_session.py +133 -0
  68. core/anthropic/thinking.py +140 -0
  69. core/anthropic/tokens.py +117 -0
  70. core/anthropic/tools.py +212 -0
  71. core/anthropic/utils.py +9 -0
  72. core/openai_responses/__init__.py +5 -0
  73. core/openai_responses/adapter.py +31 -0
  74. core/openai_responses/anthropic_sse.py +59 -0
  75. core/openai_responses/errors.py +22 -0
  76. core/openai_responses/events.py +19 -0
  77. core/openai_responses/ids.py +21 -0
  78. core/openai_responses/input.py +258 -0
  79. core/openai_responses/items.py +37 -0
  80. core/openai_responses/reasoning.py +52 -0
  81. core/openai_responses/stream.py +25 -0
  82. core/openai_responses/stream_state.py +654 -0
  83. core/openai_responses/tools.py +374 -0
  84. core/openai_responses/usage.py +37 -0
  85. core/rate_limit.py +60 -0
  86. core/trace.py +216 -0
  87. devcopilot-0.2.0.dist-info/METADATA +687 -0
  88. devcopilot-0.2.0.dist-info/RECORD +189 -0
  89. devcopilot-0.2.0.dist-info/WHEEL +4 -0
  90. devcopilot-0.2.0.dist-info/entry_points.txt +6 -0
  91. devcopilot-0.2.0.dist-info/licenses/LICENSE +21 -0
  92. messaging/__init__.py +26 -0
  93. messaging/cli_event_constants.py +67 -0
  94. messaging/command_context.py +66 -0
  95. messaging/command_dispatcher.py +37 -0
  96. messaging/commands.py +275 -0
  97. messaging/event_parser.py +181 -0
  98. messaging/limiter.py +300 -0
  99. messaging/models.py +36 -0
  100. messaging/node_event_pipeline.py +127 -0
  101. messaging/node_runner.py +342 -0
  102. messaging/platforms/__init__.py +15 -0
  103. messaging/platforms/base.py +228 -0
  104. messaging/platforms/discord.py +567 -0
  105. messaging/platforms/factory.py +103 -0
  106. messaging/platforms/outbox.py +144 -0
  107. messaging/platforms/telegram.py +688 -0
  108. messaging/platforms/voice_flow.py +295 -0
  109. messaging/rendering/__init__.py +3 -0
  110. messaging/rendering/discord_markdown.py +318 -0
  111. messaging/rendering/markdown_tables.py +49 -0
  112. messaging/rendering/profiles.py +55 -0
  113. messaging/rendering/telegram_markdown.py +327 -0
  114. messaging/safe_diagnostics.py +17 -0
  115. messaging/session.py +334 -0
  116. messaging/transcript.py +581 -0
  117. messaging/transcription.py +164 -0
  118. messaging/trees/__init__.py +15 -0
  119. messaging/trees/data.py +482 -0
  120. messaging/trees/manager.py +433 -0
  121. messaging/trees/processor.py +179 -0
  122. messaging/trees/repository.py +177 -0
  123. messaging/turn_intake.py +235 -0
  124. messaging/ui_updates.py +101 -0
  125. messaging/voice.py +76 -0
  126. messaging/workflow.py +200 -0
  127. providers/__init__.py +31 -0
  128. providers/base.py +152 -0
  129. providers/cerebras/__init__.py +7 -0
  130. providers/cerebras/client.py +31 -0
  131. providers/cerebras/request.py +55 -0
  132. providers/codestral/__init__.py +7 -0
  133. providers/codestral/client.py +34 -0
  134. providers/deepseek/__init__.py +11 -0
  135. providers/deepseek/client.py +51 -0
  136. providers/deepseek/request.py +475 -0
  137. providers/defaults.py +41 -0
  138. providers/error_mapping.py +309 -0
  139. providers/exceptions.py +113 -0
  140. providers/fireworks/__init__.py +5 -0
  141. providers/fireworks/client.py +45 -0
  142. providers/fireworks/request.py +48 -0
  143. providers/gemini/__init__.py +7 -0
  144. providers/gemini/client.py +49 -0
  145. providers/gemini/request.py +199 -0
  146. providers/groq/__init__.py +7 -0
  147. providers/groq/client.py +31 -0
  148. providers/groq/request.py +83 -0
  149. providers/kimi/__init__.py +10 -0
  150. providers/kimi/client.py +53 -0
  151. providers/kimi/request.py +42 -0
  152. providers/llamacpp/__init__.py +3 -0
  153. providers/llamacpp/client.py +16 -0
  154. providers/lmstudio/__init__.py +5 -0
  155. providers/lmstudio/client.py +16 -0
  156. providers/mistral/__init__.py +7 -0
  157. providers/mistral/client.py +31 -0
  158. providers/mistral/request.py +37 -0
  159. providers/model_listing.py +133 -0
  160. providers/nvidia_nim/__init__.py +7 -0
  161. providers/nvidia_nim/client.py +91 -0
  162. providers/nvidia_nim/request.py +430 -0
  163. providers/nvidia_nim/voice.py +95 -0
  164. providers/ollama/__init__.py +7 -0
  165. providers/ollama/client.py +39 -0
  166. providers/open_router/__init__.py +7 -0
  167. providers/open_router/client.py +124 -0
  168. providers/open_router/request.py +42 -0
  169. providers/opencode/__init__.py +11 -0
  170. providers/opencode/client.py +31 -0
  171. providers/opencode/request.py +35 -0
  172. providers/rate_limit.py +300 -0
  173. providers/registry.py +527 -0
  174. providers/transports/__init__.py +1 -0
  175. providers/transports/anthropic_messages/__init__.py +5 -0
  176. providers/transports/anthropic_messages/http.py +118 -0
  177. providers/transports/anthropic_messages/recovery.py +206 -0
  178. providers/transports/anthropic_messages/stream.py +295 -0
  179. providers/transports/anthropic_messages/transport.py +236 -0
  180. providers/transports/openai_chat/__init__.py +5 -0
  181. providers/transports/openai_chat/recovery.py +217 -0
  182. providers/transports/openai_chat/stream.py +384 -0
  183. providers/transports/openai_chat/tool_calls.py +293 -0
  184. providers/transports/openai_chat/transport.py +156 -0
  185. providers/wafer/__init__.py +10 -0
  186. providers/wafer/client.py +50 -0
  187. providers/zai/__init__.py +10 -0
  188. providers/zai/client.py +46 -0
  189. providers/zai/request.py +42 -0
@@ -0,0 +1,189 @@
1
+ api/__init__.py,sha256=XzNJK5jqYtIyXDDjKO-IzpxRc7wcIHe-Iy0F8lTuqOE,313
2
+ api/admin_config.py,sha256=Q6uzOnZjZ2ingZwqvrvNr2KFoTN114Sd0se_yd2RJ1k,35791
3
+ api/admin_routes.py,sha256=VmuIFQcfozUrv-BalTEydRZWvOTKD4YArkIepCI5D2Y,9268
4
+ api/admin_urls.py,sha256=1o8J30n-uy6b2kZga9gni69lM376rAdnhFjfObQoEmU,1081
5
+ api/app.py,sha256=ttNYvqL4bekvGi2Rf8POSfyDbkjoa1gkvkc8HQanGCw,6934
6
+ api/command_utils.py,sha256=exQMF7LdTf_bnEPNKLimTtZb7AELT7IGnP9rXe1vylA,4943
7
+ api/dependencies.py,sha256=rgLvdJKAnQgXGr3uIHFMSDceFpLteRlhMRksQZKLDvM,5455
8
+ api/detection.py,sha256=oavLq91jXyzeWRT0EBIZxrFI0-AOTV9m6jQi_qEwodU,5304
9
+ api/gateway_model_ids.py,sha256=XZvJlNW4sjMXwAiRRh0OmJ1r-8sC-i5byxhFyAp605o,1875
10
+ api/model_catalog.py,sha256=utUAgmgOY9nVs-YyER-b5xEAqYyx_M1_81Ynh5KBw78,3855
11
+ api/model_router.py,sha256=p3vjnGmGdVHJ6Ypm9pvh93SfRzyic9TAM2JwdJxXZ-w,4409
12
+ api/optimization_handlers.py,sha256=C079IbPJ_TxI2cdYF04sARMNiJFLXvpKOrzl62xNYf8,4205
13
+ api/request_pipeline.py,sha256=SOkvKoGWJzSaNNicmasmjP6fMB36YSw8i5fS1wYj0FU,16176
14
+ api/routes.py,sha256=twikDVFTDGJE-6WkrV9piwvq3Ct50xG7DsUYh2TiWG0,5479
15
+ api/runtime.py,sha256=_rnTyMhmgEhvQXEZB6-E9S8AR6MQZ_O1KdaaJZW0YjY,13242
16
+ api/validation_log.py,sha256=Tbc13MPfUOGWLJD9-z0PLDVC_g0u5OayQc8CanxrAWs,1757
17
+ api/web_server_tools.py,sha256=DfQtyelA_xtGA4coy30kCCmc4A4S7_3bvjINA4AEnb4,576
18
+ api/admin_static/admin.css,sha256=3PAp2FS9nGKUp8-LmLXJyxjLAg-D-hi9uFDr6pqkhcQ,7134
19
+ api/admin_static/admin.js,sha256=HI-2mZMmpyh609GmaEMqPtAmmF2T1Ql-pHbMWS3TwfY,14967
20
+ api/admin_static/index.html,sha256=zLPzxg9HrzPVnQa4bS4HYlffVM7tfPhIvUn21ix8EbQ,2525
21
+ api/models/__init__.py,sha256=MLjy2bAeJBgBrvNCo8JXSksvf9mG-EwtCsxoSsn0NpU,880
22
+ api/models/anthropic.py,sha256=_tKzV2mOlMzA4FmXdlY-WQHUFpWywaczNZ18U83M3Iw,7150
23
+ api/models/openai_responses.py,sha256=xuHafYP7CjiQX0m6kN_LE7_S_scVTAr5ZXdLDt425uU,820
24
+ api/models/responses.py,sha256=qKH3Cs2yzUwBCfc_uESOmcoE_JaRtTeCBGxgeQtgPm4,1332
25
+ api/web_tools/__init__.py,sha256=KQBltethlopL7e6rEJxyMXxFA-Zj4AL2g5wKrQyqpO0,483
26
+ api/web_tools/constants.py,sha256=-2rIuCpl_8wbu0rVRYMQZ7j_8jjkFWvJ65RW3j-QODA,593
27
+ api/web_tools/egress.py,sha256=d4YqJDMYQg1I5vu62ftRvwnGSeZ6dEyTlbznxiE3glY,3287
28
+ api/web_tools/outbound.py,sha256=Qlm04GVMyerKDk7bXK2oVEB0w0X3Ekv0YdTPDZ8xSKw,8977
29
+ api/web_tools/parsers.py,sha256=zNd-tlTtG2b9MG7mb-w7ulUt89v6dNgxyEs_wuQh_kU,3317
30
+ api/web_tools/request.py,sha256=qT-yba6oGP51b625nqnn4FiO9NJs0W16JhQ5_SPaVW8,3341
31
+ api/web_tools/streaming.py,sha256=i5jHc-eoiCwnjsyT37IQf1Gyxpys6n97Y3kzbjoAGsA,6779
32
+ cli/__init__.py,sha256=XJL7fa8bkq6a2-1My7haXUAwTIVttXCarxpz5iSQANE,210
33
+ cli/claude_env.py,sha256=SJKNX5Dp2fGhH9dL_o5X-f_OMYavNwPkFOouaHc1iRg,377
34
+ cli/entrypoints.py,sha256=nZtBmXsTRW_qyeVXx9UTNblYJ1eC2tvXiQ6iehCNPCQ,5159
35
+ cli/process_registry.py,sha256=J1c56G2g8OVipnb0eAdJHDi7d1m1VdTYPXFT_C4VDqs,2003
36
+ cli/launchers/__init__.py,sha256=TIRUEB7JvSZVqCCKOz4Ler2Se4L3R0rzMPMjdW7xctM,42
37
+ cli/launchers/claude.py,sha256=FPywuCD0EmicMnDZUzcuYWrRNX7MMtG87uCamgUzpKI,2690
38
+ cli/launchers/codex.py,sha256=ICRcl4t8Zhc5I5faPfx9Y0gONobwZkKf6S4v3IXq3G4,6311
39
+ cli/launchers/codex_model_catalog.py,sha256=q9CVqpZaIEtSgOxhrP1CIIXFdfLe-4Z8ea-6d6YGXjY,5938
40
+ cli/launchers/common.py,sha256=4sNnsoHdSYt0M81T7CpAHAlcUXHGNFez-LkdXWNEhEw,2600
41
+ cli/managed/__init__.py,sha256=rrpiWFmO7GJI22KM5Pu7KuwTc66c95dqc3q4srpEpjc,213
42
+ cli/managed/claude.py,sha256=k6yd_kv9U8eYduOMnocb9eIP9TKeGv28epGl0FGD6XU,6281
43
+ cli/managed/manager.py,sha256=fjbbRIG4W8t15xEoNXbF_f8FfmtKlYmQHQhPEL3AJe4,5722
44
+ cli/managed/session.py,sha256=nf2FgXFoOzGOm4XYKFDIzvJCIgaQSzYx59H45V56U-o,10025
45
+ config/__init__.py,sha256=pyF_LSOIJspKGpmdQBWKuz8A00Kr0iOgnDbh46WEo_Y,118
46
+ config/constants.py,sha256=p4Pdqvn8DI6UT0gUyUlQeRahjDwgLcMsZ-yzx3nCCRs,560
47
+ config/logging_config.py,sha256=kcTdUZ2AceP3i3oBd0i6a0TFhAXqLb7HgXZw_QO2hg0,4900
48
+ config/nim.py,sha256=PFmieaANbtEFTSiTIkUbYqHqNCfld_5zw8LE75hzEFg,3915
49
+ config/paths.py,sha256=xGP7EUbHirit646slZBxKB3Mt0MeqJaKapoy_TMOfc0,2039
50
+ config/provider_catalog.py,sha256=anMENxKjVnkyGFfiF--Ej-1G1pcgm3g3ZgbFGyBnsrE,10414
51
+ config/provider_ids.py,sha256=Gad2L5wmz8io3FFJuLH0a1BtAdHcABcQM69Iz_PlyCE,204
52
+ config/settings.py,sha256=w0YkLfpk2c62Ce6c-R-B9tBDQXK5ZIrWbStFhbtBHwI,21660
53
+ core/__init__.py,sha256=OKqvVz77sM92b658yJ3zpTvXYxExh9klMG7hCDMCXgY,39
54
+ core/rate_limit.py,sha256=71zZdwXPuRVdsGPEX2XikUOcKoLLjVz0-daR6pKLBiA,1754
55
+ core/trace.py,sha256=aCqBvG6W_CeWGb3sGUBY0qiCzmnFx0Y0KGyVWc4XGvs,6217
56
+ core/anthropic/__init__.py,sha256=pCBJE1Lz0z6gy2biR6Lw_NFbJeqmZaVlqSxzc5y6ab8,1451
57
+ core/anthropic/content.py,sha256=faHYdUqTxk-Rp3avEnsfp5UIwDRKEsGImaGyB8HXQkI,977
58
+ core/anthropic/conversion.py,sha256=Yit_EVhctUtlt0urnxkIg3-saRoqFBWKB5RFLcMpJac,22564
59
+ core/anthropic/emitted_sse_tracker.py,sha256=nFU667eA3RV3YNBsD2QnwTod5i9sce3ZDEXprUPoL9o,12462
60
+ core/anthropic/errors.py,sha256=HIqrqKeTrabT_2qH3-AR0EETQywm-2nDDLDY3xlXVYE,2647
61
+ core/anthropic/native_messages_request.py,sha256=k__QCGfvCWuPHMkV2UH0iZsqGERDE11EBWsQJsBohnE,8730
62
+ core/anthropic/native_sse_block_policy.py,sha256=s7lVAQIStQWdjhZheYMPh-vSnA_U9FkHJv8K4V9KZeI,10903
63
+ core/anthropic/provider_stream_error.py,sha256=4iFD0LhkDuidqQZ2CrU6taWeW_BrK_8oDgBUNTHGdxo,951
64
+ core/anthropic/server_tool_sse.py,sha256=Xjm9ew4XJ2PMwToGo1yR6glBQsU-ksEc8OuXzkPiYgU,504
65
+ core/anthropic/sse.py,sha256=Yo58mT3fd8AvU_OPPBwwLACZScdDgNtidPaF21XvFqg,15510
66
+ core/anthropic/stream_contracts.py,sha256=kaeH9Oi8vMpST1heONXwTBeWZvcGcrFjR59YDbnAmvQ,6881
67
+ core/anthropic/stream_recovery.py,sha256=wIzAOwp4gXA5ume0bpG57NoW7BayFFHhHxgwAFTxrDg,10975
68
+ core/anthropic/stream_recovery_session.py,sha256=F_07zMjB2XVDTvQfia2phMiXtO_sDCfWgRsu4knGdgY,4179
69
+ core/anthropic/thinking.py,sha256=rWW_8oUvGG8iXLXteWWT7-OUo26UbvyqWx3nzI6Csdg,4615
70
+ core/anthropic/tokens.py,sha256=awD-GikpOKtQlPYZwnQv69eQymVzoK26ynZV0H0eb-g,4642
71
+ core/anthropic/tools.py,sha256=gUP948IO4UINhb831rpbwSHF3SsZl9iIiW6baRiSSwU,7966
72
+ core/anthropic/utils.py,sha256=i3xIQtU-PnHGWavM9-A2-Y8JVZYI91vhARzsLAPuCGk,253
73
+ core/openai_responses/__init__.py,sha256=BCkna3hu2pcGnpnoooldLTYGOfbbvOJMkkOgSr-_mHU,124
74
+ core/openai_responses/adapter.py,sha256=i24r0RCOx8G-k0n2tC-5SVUVIolYIP2PRTwacXEjTZw,1210
75
+ core/openai_responses/anthropic_sse.py,sha256=-Co5O1TLsTfZGfJdOtF7RG6q1Ft6Kn8RlFYvxZxNM74,1728
76
+ core/openai_responses/errors.py,sha256=PewHOi_Gb45l--p5_jdilyr4DCk9D3ezrJWMwnDtofA,556
77
+ core/openai_responses/events.py,sha256=L8x9WgKuzILFxuyzO4AQJZL8ZOnKzEUe-Ih_ZE1QbyU,497
78
+ core/openai_responses/ids.py,sha256=_QhyiE99dhKPBjs-J2Ot-UZHE3YZWLZfDDL3Ov0Hf4Y,393
79
+ core/openai_responses/input.py,sha256=S_gyDvJjRXvVGfAsvSW1BnDU-tw2wDLyYsFOp6WoXy0,8682
80
+ core/openai_responses/items.py,sha256=at0CEY71VcVTDSoarWXnCkyBX_GERrd4rK2F74_e3-8,924
81
+ core/openai_responses/reasoning.py,sha256=izCz1YDfymkU4dBAPN-W3h9UHDCJ3fgnvlpZBbDGgC8,1551
82
+ core/openai_responses/stream.py,sha256=u_IaDZkudyhQdG347nHjHT1BeCrW2YfR2bSQU3XfPbY,811
83
+ core/openai_responses/stream_state.py,sha256=YSrkqYQSX3vRgwK0_UGkaRcUnNn1jjF0ToHh_ItIl6Y,23473
84
+ core/openai_responses/tools.py,sha256=wOVjiHEE53cD2fiGwMJRoSpaIgHMvPaJoDz3TnW56xA,13311
85
+ core/openai_responses/usage.py,sha256=NGJVQe0j1FD4fvVLb8sbGc6WBfRgjS6j1EY3JJwXuXU,854
86
+ messaging/__init__.py,sha256=8uRMCmMNuLUFW984mPwcWBDtll0R9vplBpGJeEtqJJk,692
87
+ messaging/cli_event_constants.py,sha256=4mKe_ELjE7DecoK9UdQ-gjSqhXVYY4ALI4m-zVFeXi0,1930
88
+ messaging/command_context.py,sha256=UOhyvucskv4bqgI73P1wJSb8sBR9J_lELqMNkkByRM4,1979
89
+ messaging/command_dispatcher.py,sha256=2BCuIl4nxpeB5UnOALbEcHwhqkmGwXaURzLivCr3uQw,1181
90
+ messaging/commands.py,sha256=tkQg8nhm4rh0jTNaNw3jf9a3hVUpie6C5kMxNzffpZ8,9825
91
+ messaging/event_parser.py,sha256=wyGzzk1gQPRJSxjv7S2E9EOvtUnGceqVaorrKy554IA,6925
92
+ messaging/limiter.py,sha256=Y-ldY0uVPtzno1B_Cuu49TxpOkNtAVLNcNUlhU3WqNg,11978
93
+ messaging/models.py,sha256=W5OuHHPLoruiDwwRF2_Je6RG7Xbr9uU7qMXu3bk4kgo,1075
94
+ messaging/node_event_pipeline.py,sha256=6avTT96fuTeOnbzELpLqFr9LC90mUYuNwqZonuKTcdc,4447
95
+ messaging/node_runner.py,sha256=UZ9JAal_K4wMn4ZZwtdPnf0kCzhzJZpUwkXFTD99uv8,13078
96
+ messaging/safe_diagnostics.py,sha256=vEeaXWNfe2mAwmEEq36dkK_F6CLALVZ1DscnZlJFGJM,544
97
+ messaging/session.py,sha256=j9yD9kz76RdSuodjY2Rxvah05ey7jim4lPHUnrK0TV4,12326
98
+ messaging/transcript.py,sha256=ICxGkf3E2ES5YUER8SYtpZ221AuBWKH06Ge-E8KCWww,20644
99
+ messaging/transcription.py,sha256=IgSB4wNNYtWCsRUwDnhk1L_EFUR4wwTf2k2g2jIx8IU,5505
100
+ messaging/turn_intake.py,sha256=n0iJWfn5x8tP513fdnH04XdwROK0iA9EG0cKKoa0_y8,8827
101
+ messaging/ui_updates.py,sha256=mdE_KIAA1XIY_UYULbcr2M737eLc3CvdK3B2feFcFes,3504
102
+ messaging/voice.py,sha256=CYIMTxxG1yf0PzLXKrCypA-xrdRTtpSNs2ZDRvqKNYY,2365
103
+ messaging/workflow.py,sha256=_PpJIn-ixblBM9cGjtG2nROKTJh4vHBumFDTxdbXEWU,7637
104
+ messaging/platforms/__init__.py,sha256=D63jPAoLcbTSCprOtuVtUlG98i74sr-GnSmcjdIAU4A,381
105
+ messaging/platforms/base.py,sha256=nfVxnT5D5johil_MeIV8g18qDaW6lVvlZAYZixu4r7g,5831
106
+ messaging/platforms/discord.py,sha256=O5c2LeY9hLYqAiOduP3-Hn10WzeWHfRVEEpJzT4gG7g,18241
107
+ messaging/platforms/factory.py,sha256=sjb0oqaYww29E23XFQCpVtK1MX3PBlykBQY0k_APreo,3663
108
+ messaging/platforms/outbox.py,sha256=QgICxcgE4iOiw1ecFLPI1axmo2FA6gn1pVZsxbNSU8s,4420
109
+ messaging/platforms/telegram.py,sha256=WS3PVsBhvwsolkco7rBW2XIKvjqZVH_SMwT3sseSvZg,23969
110
+ messaging/platforms/voice_flow.py,sha256=YOZeh--c_R-f9LezHcbGnFfPcjWMm8qM9uOpMiP4ywk,10037
111
+ messaging/rendering/__init__.py,sha256=M4_6_ECGJj4HUIIuCo4iumFwAQ8bGA0A-X87WtH5enk,85
112
+ messaging/rendering/discord_markdown.py,sha256=xDjL8zcEvsOiRHX4ht4BWrF0EuvDtD3vP7RMBZhK2kc,11188
113
+ messaging/rendering/markdown_tables.py,sha256=tVhBi4UD03Ep73E9H9BAROBhJUkUeBsDd4swClloW6s,1445
114
+ messaging/rendering/profiles.py,sha256=d8tGgeMih9-erVrSQCY6J-ifNCRAI0lFh7DYocOLfoI,1814
115
+ messaging/rendering/telegram_markdown.py,sha256=tnXXwHVx4Yajrpni7O2QaqCTG7UQhnTj7nhAIxpBj2s,11518
116
+ messaging/trees/__init__.py,sha256=PkKZp_1-V0uXYxBBZFWD-y0KMBvGaBkO9daM4qI5pT0,379
117
+ messaging/trees/data.py,sha256=hT_A0QBk0Nx4a6KE3m0FXvQ8sQ2CZOW1n8TsOCSAYWM,16552
118
+ messaging/trees/manager.py,sha256=0INSTnR1lq6gpurxFB5k1ab6Bw10BosFpNgv9OQKuXI,14945
119
+ messaging/trees/processor.py,sha256=XSoI9WiaKDgGpUNhmpA2SzVm22MYKwjs3WM1FVe3B1U,6446
120
+ messaging/trees/repository.py,sha256=IlpFe4lKQ3ArWBXJufmlO0qBstnG308YU2MxJEpwPXo,6328
121
+ providers/__init__.py,sha256=5rpwdhkS7JVHSS10fTv6vmqfENk6PuI8qeK7ERgvXvE,786
122
+ providers/base.py,sha256=qRmJZN4QvIL3hE8LU_QTp_FG5ixH3oSZ6fMeYZpXkVM,5204
123
+ providers/defaults.py,sha256=y3YaJrOKysMtGKASps8AOnTyuoHDz_GDttJrYRY5Wg4,1080
124
+ providers/error_mapping.py,sha256=hNwjCJKfSdbOa4tPjfWiWFh8Jy_uvjUQhHv489rBGqc,10664
125
+ providers/exceptions.py,sha256=W2WXJ7hms_Z1_94Gk0NVRoFUSNro4BLO2iMwGJOyg58,3103
126
+ providers/model_listing.py,sha256=s29hUmdMks11CDoI4FPhUnL1qvZnO9ngLv3pjnaFyJg,4488
127
+ providers/rate_limit.py,sha256=pwX5A0BuQXmV8oSglkDBBniVPmoDogSG_x7DA9oMFXc,10436
128
+ providers/registry.py,sha256=9XvFEPUhu8BJ6G5oAtwoh5C6KXBZJFqlv10uVkcul48,19466
129
+ providers/cerebras/__init__.py,sha256=RlAEQtP9bjAsEPYJIzF7qZnNsNovAUulowlcGepJKhw,203
130
+ providers/cerebras/client.py,sha256=FHOgBnmtF_tTaM_BAtjSmWludoiB5IBKuvNVBmwFV80,957
131
+ providers/cerebras/request.py,sha256=ts8mkG1-RKVly4e7cRQ5v3rRumQ3yRejLztGtq_-plU,1919
132
+ providers/codestral/__init__.py,sha256=2tj97ODeCBJuF9gk7dv76nlkndg_KGaB4mquiVK1X8M,218
133
+ providers/codestral/client.py,sha256=WH2PKYYVO1MulBlV8lZV0TcFBQRkjhEExjqiWoyjeDk,1167
134
+ providers/deepseek/__init__.py,sha256=8H0OzAtNxTag1XBzPgssqIlZZVwaUQQgbouMR_2Bf-8,265
135
+ providers/deepseek/client.py,sha256=TgOR-z8r_dA8YLVZ8eWwKMvJyod2fYuVJM04bM912g0,1685
136
+ providers/deepseek/request.py,sha256=V6pS9L2ZRgbbpjFp1ARhr0Q8ppsnw1Q0lHAjjnbhpHQ,17137
137
+ providers/fireworks/__init__.py,sha256=c6oiSxlqWZ1XfNM0fhUkCSuRVkOowjML66WbLl1MLOU,151
138
+ providers/fireworks/client.py,sha256=AwuCA8qaBMzAGBc8wOHUj1Y0E_QQrIwfqW3ut0uzWRg,1417
139
+ providers/fireworks/request.py,sha256=xXqFe0MgeYpi5wIoKbezI6av_K10EZhdEQQLbIqVsEU,1493
140
+ providers/gemini/__init__.py,sha256=NPnj5EE2CMRM-z4vtWHmLpr-7E8VMJB060gnbc4VsEM,196
141
+ providers/gemini/client.py,sha256=bJJnLSLSbVlMrWIoM29GsBIP57F3Aw95plVFTqiD_GQ,1726
142
+ providers/gemini/request.py,sha256=vefr7ua7p9jpADX_JDsStptKnCC0rm8AFkflhWtVTx0,6826
143
+ providers/groq/__init__.py,sha256=THfvpnQ2AJDEdeTVTqsICDwXJxF-ei3Lup5he_8jKAM,175
144
+ providers/groq/client.py,sha256=vPSRYIgFquxDf1Lx3myokVldKgWko9lwu3NYqJf26rQ,945
145
+ providers/groq/request.py,sha256=zOPT5R4-LMn-PbRy10SM5J9_oVYPi_32Z8Tth43Z2nI,2739
146
+ providers/kimi/__init__.py,sha256=azS7sGI_JnrMgaylaS9Gz5i8AzDbdtOKEfZuGhSLquI,184
147
+ providers/kimi/client.py,sha256=IrYPE-iuxWw097cgUqTaXaOGNpS5f-W5ZELGpDrNMco,1730
148
+ providers/kimi/request.py,sha256=Hc4Kz2WwZbBwzu4B6UKRniQPOHrUR7Pgy-0UTslWF-I,1315
149
+ providers/llamacpp/__init__.py,sha256=7JkDzGuF0xMqzODo410byyZwS2yC8teTT9KIAhd4U-s,69
150
+ providers/llamacpp/client.py,sha256=Mdbo6_jl3S42DiHCBmzjkribGCBD2VbY9QYuPpKculU,536
151
+ providers/lmstudio/__init__.py,sha256=XthjVFOYGhLvYRuad6iwCJ2JjrZswBzy1tz_eheKePQ,129
152
+ providers/lmstudio/client.py,sha256=7X-jYdGekuhJ4cbaz_0M6CdD7zD4I1ydunYbePL3EDg,536
153
+ providers/mistral/__init__.py,sha256=SjyvNDKTCGHKVXhQO9YsAtog2b40ddOCW7r0lRodKHg,191
154
+ providers/mistral/client.py,sha256=BNIX4deyTM5tLrr_9z1qivd_9AWv6AnXeRu_CrtVv_8,972
155
+ providers/mistral/request.py,sha256=b_6r1_8oo9DN9ccqzT-3QZ64mr8gUDOiAOtbSoRVuh0,1239
156
+ providers/nvidia_nim/__init__.py,sha256=DwE477TXkbtMn-YdbOY8dy3_QcY4X1c8PD_OLBDoJZs,190
157
+ providers/nvidia_nim/client.py,sha256=c9YlY_kd6BxVmP9HBz7UWaLeaaU8Q_lRVYn6DuoYXJU,3319
158
+ providers/nvidia_nim/request.py,sha256=XdSe4gdiC0_zYSX29z_hc1yRdlqpZ1gbTTMBTjDRNoY,15448
159
+ providers/nvidia_nim/voice.py,sha256=C4ae8YvgfgzkqvMNJegk4rGRXWOTKTlxEMAQk98nqzw,3180
160
+ providers/ollama/__init__.py,sha256=jNXAHXYK51BBPgEGEyAbEe44wPGr6RuHN-_FPodNu7Y,172
161
+ providers/ollama/client.py,sha256=Z_LuPSBNZyNXXKhmhK29r5hracV96Y5Pag9X9oFb3Ac,1406
162
+ providers/open_router/__init__.py,sha256=Z8K4ILp8rkxjZgM03e5DSGwCmqpzf6Ug0DR_6ZU_DFw,224
163
+ providers/open_router/client.py,sha256=HO9XuhXRDCgysXxlgh7JDBF1qSFQ34csfF2TTb3LiAk,4243
164
+ providers/open_router/request.py,sha256=fQgyNrJcD3Q4vKXx58IHHh_lbKZrjwD3T1w_0AiQm3M,1306
165
+ providers/opencode/__init__.py,sha256=meZDGOQFR15UiAlZS-Bpg1F00iHgPNMARx2MlpcsHzY,255
166
+ providers/opencode/client.py,sha256=DlyrDk2-ufG8NDDSuIz-mndkO9MKkvL7QRknKeanx14,1014
167
+ providers/opencode/request.py,sha256=UvKQlheIO5YUy4GOxRluezeBda7R227YpErdWgg63jM,1173
168
+ providers/transports/__init__.py,sha256=2vrVU_XSlB2v-EPypKY_MrKVi2S4GwCxHJEZSX6m3a0,35
169
+ providers/transports/anthropic_messages/__init__.py,sha256=4k7MIWgs0B7XQoLAm68Xsl0-UsUqXFVyOfBQfJ0hIgQ,179
170
+ providers/transports/anthropic_messages/http.py,sha256=s1IMGgPqItQaWijSewO_eTAphvQduUjZ7icefGEguRc,3871
171
+ providers/transports/anthropic_messages/recovery.py,sha256=FH9a8WO3SFmqmqtw9J961p3K757__q0wnTu0EhYpyr4,7753
172
+ providers/transports/anthropic_messages/stream.py,sha256=g5RFfG1OggKcMXsLwvvX9IkgPiCOar8Bwgu71EuCqgM,11977
173
+ providers/transports/anthropic_messages/transport.py,sha256=QxbPmpvIZ220pKsxFGVf4h_koX88c7N4rVQCziLfPo0,8668
174
+ providers/transports/openai_chat/__init__.py,sha256=aNN-RA07EzTOHUVU-PlyCGEyGVhYQeDTtCfb46JmVa4,126
175
+ providers/transports/openai_chat/recovery.py,sha256=8PCnEZv9GiPVsGpKbgWWwOeBVQ9Sg5ul9ZqO8_IBUms,8589
176
+ providers/transports/openai_chat/stream.py,sha256=EwcIOQslyMujmrh1wdIbVbNXSbg_-ysNIwZp3VYM9Xk,16175
177
+ providers/transports/openai_chat/tool_calls.py,sha256=iS3Y8sMCuvh_UWfMCrUKFXt3CdiifCNHgYXCb3jF0AU,10768
178
+ providers/transports/openai_chat/transport.py,sha256=Yl_UcngR5EVSHPO8_0rXX4EU2pxamCw7dmHq9hFQvyk,5644
179
+ providers/wafer/__init__.py,sha256=SGqE8xL1eTHsfd3kdcsFrQQnGOUOt6TSlyxmkbRblr8,178
180
+ providers/wafer/client.py,sha256=6dlWMqaAtZdkNbw8TaCrjCEF-TrBW3YAO9wyr_JWf3E,1694
181
+ providers/zai/__init__.py,sha256=Y4Qc2b8XNsFM_a_kq8VKHpCokO0pq0sLXiAkQZjbaK4,169
182
+ providers/zai/client.py,sha256=y9yhtbvCj7RSZ2KTJpN_HRW8uJwqanO_eOxGYb7zOL4,1388
183
+ providers/zai/request.py,sha256=e1cNGuthIFQdTWpgrcX5n7XgeRBCXpJWJFepJEpz-o4,1302
184
+ cli/env.example,sha256=WTR2ttX9Wp7nRfnB-Pfr9L1_z424hW49GB8UlMyeFDQ,6532
185
+ devcopilot-0.2.0.dist-info/METADATA,sha256=vujBQ7gq0DKNIq81dPhqSDs2Lg64j9JuGIgAvooMqMw,33417
186
+ devcopilot-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
187
+ devcopilot-0.2.0.dist-info/entry_points.txt,sha256=luvkgNX4B_dcs0Oj8Kg2P5THjYlt8UIIjWyrgNyA8xc,228
188
+ devcopilot-0.2.0.dist-info/licenses/LICENSE,sha256=h7PJzu9cn76oF5jIq_02sl9NoaUoCvByIoUvVS-TZXI,1068
189
+ devcopilot-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ devcopilot = cli.entrypoints:serve
3
+ devcopilot-claude = cli.launchers.claude:launch
4
+ devcopilot-codex = cli.launchers.codex:launch
5
+ devcopilot-init = cli.entrypoints:init
6
+ devcopilot-server = cli.entrypoints:serve
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ali Khokhar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
messaging/__init__.py ADDED
@@ -0,0 +1,26 @@
1
+ """Platform-agnostic messaging layer."""
2
+
3
+ from .event_parser import parse_cli_event
4
+ from .models import IncomingMessage
5
+ from .platforms.base import (
6
+ ManagedClaudeSessionManagerProtocol,
7
+ ManagedClaudeSessionProtocol,
8
+ MessagingPlatform,
9
+ )
10
+ from .session import SessionStore
11
+ from .trees import MessageNode, MessageState, MessageTree, TreeQueueManager
12
+ from .workflow import MessagingWorkflow
13
+
14
+ __all__ = [
15
+ "IncomingMessage",
16
+ "ManagedClaudeSessionManagerProtocol",
17
+ "ManagedClaudeSessionProtocol",
18
+ "MessageNode",
19
+ "MessageState",
20
+ "MessageTree",
21
+ "MessagingPlatform",
22
+ "MessagingWorkflow",
23
+ "SessionStore",
24
+ "TreeQueueManager",
25
+ "parse_cli_event",
26
+ ]
@@ -0,0 +1,67 @@
1
+ """CLI event types and status-line mapping for transcript / UI updates."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any
5
+
6
+ # Status message prefixes used to filter our own messages (ignore echo)
7
+ STATUS_MESSAGE_PREFIXES = (
8
+ "⏳",
9
+ "💭",
10
+ "🔧",
11
+ "✅",
12
+ "❌",
13
+ "🚀",
14
+ "🤖",
15
+ "📋",
16
+ "📊",
17
+ "🔄",
18
+ )
19
+
20
+ # Event types that update the transcript (frozenset for O(1) membership)
21
+ TRANSCRIPT_EVENT_TYPES = frozenset(
22
+ {
23
+ "thinking_start",
24
+ "thinking_delta",
25
+ "thinking_chunk",
26
+ "thinking_stop",
27
+ "text_start",
28
+ "text_delta",
29
+ "text_chunk",
30
+ "text_stop",
31
+ "tool_use_start",
32
+ "tool_use_delta",
33
+ "tool_use_stop",
34
+ "tool_use",
35
+ "tool_result",
36
+ "block_stop",
37
+ "error",
38
+ }
39
+ )
40
+
41
+ # Event type -> (emoji, label) for status updates (O(1) lookup)
42
+ _EVENT_STATUS_MAP: dict[str, tuple[str, str]] = {
43
+ "thinking_start": ("🧠", "Claude is thinking..."),
44
+ "thinking_delta": ("🧠", "Claude is thinking..."),
45
+ "thinking_chunk": ("🧠", "Claude is thinking..."),
46
+ "text_start": ("🧠", "Claude is working..."),
47
+ "text_delta": ("🧠", "Claude is working..."),
48
+ "text_chunk": ("🧠", "Claude is working..."),
49
+ "tool_result": ("⏳", "Executing tools..."),
50
+ }
51
+
52
+
53
+ def get_status_for_event(
54
+ ptype: str,
55
+ parsed: dict[str, Any],
56
+ format_status_fn: Callable[..., str],
57
+ ) -> str | None:
58
+ """Return status string for event type, or None if no status update needed."""
59
+ entry = _EVENT_STATUS_MAP.get(ptype)
60
+ if entry is not None:
61
+ emoji, label = entry
62
+ return format_status_fn(emoji, label)
63
+ if ptype in ("tool_use_start", "tool_use_delta", "tool_use"):
64
+ if parsed.get("name") == "Task":
65
+ return format_status_fn("🤖", "Subagent working...")
66
+ return format_status_fn("⏳", "Executing tools...")
67
+ return None
@@ -0,0 +1,66 @@
1
+ """Typed dependency surface for messaging slash commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Protocol
6
+
7
+ from .platforms.base import ManagedClaudeSessionManagerProtocol, MessagingPlatform
8
+ from .session import SessionStore
9
+ from .transcript import RenderCtx
10
+ from .trees import MessageNode, MessageTree, TreeQueueManager
11
+
12
+
13
+ class MessagingCommandContext(Protocol):
14
+ """Operations commands need from the messaging workflow."""
15
+
16
+ platform: MessagingPlatform
17
+ cli_manager: ManagedClaudeSessionManagerProtocol
18
+ session_store: SessionStore
19
+
20
+ @property
21
+ def tree_queue(self) -> TreeQueueManager: ...
22
+
23
+ def format_status(self, emoji: str, label: str, suffix: str | None = None) -> str:
24
+ """Format a platform-specific status line."""
25
+ ...
26
+
27
+ def get_render_ctx(self) -> RenderCtx:
28
+ """Return the render context for command output."""
29
+ ...
30
+
31
+ def replace_tree_queue(self, tree_queue: TreeQueueManager) -> None:
32
+ """Replace the active tree queue after global clear/restore."""
33
+ ...
34
+
35
+ async def update_queue_positions(self, tree: MessageTree) -> None:
36
+ """Refresh queued status messages."""
37
+ ...
38
+
39
+ async def mark_node_processing(self, tree: MessageTree, node_id: str) -> None:
40
+ """Mark a dequeued node as processing."""
41
+ ...
42
+
43
+ async def stop_all_tasks(self) -> int:
44
+ """Stop every pending or active messaging task."""
45
+ ...
46
+
47
+ async def stop_task(self, node_id: str) -> int:
48
+ """Stop one pending or active node."""
49
+ ...
50
+
51
+ def record_outgoing_message(
52
+ self,
53
+ platform: str,
54
+ chat_id: str,
55
+ msg_id: str | None,
56
+ kind: str,
57
+ ) -> None:
58
+ """Persist an outgoing platform message ID."""
59
+ ...
60
+
61
+ def update_cancelled_nodes_ui(self, nodes: list[MessageNode]) -> None:
62
+ """Render cancellation status and persist affected trees."""
63
+ ...
64
+
65
+
66
+ __all__ = ["MessagingCommandContext"]
@@ -0,0 +1,37 @@
1
+ """Command parsing and dispatch for messaging handlers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .command_context import MessagingCommandContext
6
+ from .commands import handle_clear_command, handle_stats_command, handle_stop_command
7
+ from .models import IncomingMessage
8
+
9
+
10
+ def parse_command_base(text: str | None) -> str:
11
+ """Return the slash command without bot mention suffix."""
12
+ parts = (text or "").strip().split()
13
+ cmd = parts[0] if parts else ""
14
+ return cmd.split("@", 1)[0] if cmd else ""
15
+
16
+
17
+ def message_kind_for_command(command_base: str) -> str:
18
+ """Return the persistence kind for an incoming message."""
19
+ return "command" if command_base.startswith("/") else "content"
20
+
21
+
22
+ async def dispatch_command(
23
+ context: MessagingCommandContext,
24
+ incoming: IncomingMessage,
25
+ command_base: str,
26
+ ) -> bool:
27
+ """Dispatch a known command and return whether it was handled."""
28
+ commands = {
29
+ "/clear": handle_clear_command,
30
+ "/stop": handle_stop_command,
31
+ "/stats": handle_stats_command,
32
+ }
33
+ command = commands.get(command_base)
34
+ if command is None:
35
+ return False
36
+ await command(context, incoming)
37
+ return True