agentpool 2.1.9__py3-none-any.whl → 2.5.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 (311) hide show
  1. acp/__init__.py +13 -4
  2. acp/acp_requests.py +20 -77
  3. acp/agent/connection.py +8 -0
  4. acp/agent/implementations/debug_server/debug_server.py +6 -2
  5. acp/agent/protocol.py +6 -0
  6. acp/bridge/README.md +15 -2
  7. acp/bridge/__init__.py +3 -2
  8. acp/bridge/__main__.py +60 -19
  9. acp/bridge/ws_server.py +173 -0
  10. acp/bridge/ws_server_cli.py +89 -0
  11. acp/client/connection.py +38 -29
  12. acp/client/implementations/default_client.py +3 -2
  13. acp/client/implementations/headless_client.py +2 -2
  14. acp/connection.py +2 -2
  15. acp/notifications.py +20 -50
  16. acp/schema/__init__.py +2 -0
  17. acp/schema/agent_responses.py +21 -0
  18. acp/schema/client_requests.py +3 -3
  19. acp/schema/session_state.py +63 -29
  20. acp/stdio.py +39 -9
  21. acp/task/supervisor.py +2 -2
  22. acp/transports.py +362 -2
  23. acp/utils.py +17 -4
  24. agentpool/__init__.py +6 -1
  25. agentpool/agents/__init__.py +2 -0
  26. agentpool/agents/acp_agent/acp_agent.py +407 -277
  27. agentpool/agents/acp_agent/acp_converters.py +196 -38
  28. agentpool/agents/acp_agent/client_handler.py +191 -26
  29. agentpool/agents/acp_agent/session_state.py +17 -6
  30. agentpool/agents/agent.py +607 -572
  31. agentpool/agents/agui_agent/__init__.py +0 -2
  32. agentpool/agents/agui_agent/agui_agent.py +176 -110
  33. agentpool/agents/agui_agent/agui_converters.py +0 -131
  34. agentpool/agents/agui_agent/helpers.py +3 -4
  35. agentpool/agents/base_agent.py +632 -17
  36. agentpool/agents/claude_code_agent/FORKING.md +191 -0
  37. agentpool/agents/claude_code_agent/__init__.py +13 -1
  38. agentpool/agents/claude_code_agent/claude_code_agent.py +1058 -291
  39. agentpool/agents/claude_code_agent/converters.py +74 -143
  40. agentpool/agents/claude_code_agent/history.py +474 -0
  41. agentpool/agents/claude_code_agent/models.py +77 -0
  42. agentpool/agents/claude_code_agent/static_info.py +100 -0
  43. agentpool/agents/claude_code_agent/usage.py +242 -0
  44. agentpool/agents/context.py +40 -0
  45. agentpool/agents/events/__init__.py +24 -0
  46. agentpool/agents/events/builtin_handlers.py +67 -1
  47. agentpool/agents/events/event_emitter.py +32 -2
  48. agentpool/agents/events/events.py +104 -3
  49. agentpool/agents/events/infer_info.py +145 -0
  50. agentpool/agents/events/processors.py +254 -0
  51. agentpool/agents/interactions.py +41 -6
  52. agentpool/agents/modes.py +67 -0
  53. agentpool/agents/slashed_agent.py +5 -4
  54. agentpool/agents/tool_call_accumulator.py +213 -0
  55. agentpool/agents/tool_wrapping.py +18 -6
  56. agentpool/common_types.py +56 -21
  57. agentpool/config_resources/__init__.py +38 -1
  58. agentpool/config_resources/acp_assistant.yml +2 -2
  59. agentpool/config_resources/agents.yml +3 -0
  60. agentpool/config_resources/agents_template.yml +1 -0
  61. agentpool/config_resources/claude_code_agent.yml +10 -6
  62. agentpool/config_resources/external_acp_agents.yml +2 -1
  63. agentpool/delegation/base_team.py +4 -30
  64. agentpool/delegation/pool.py +136 -289
  65. agentpool/delegation/team.py +58 -57
  66. agentpool/delegation/teamrun.py +51 -55
  67. agentpool/diagnostics/__init__.py +53 -0
  68. agentpool/diagnostics/lsp_manager.py +1593 -0
  69. agentpool/diagnostics/lsp_proxy.py +41 -0
  70. agentpool/diagnostics/lsp_proxy_script.py +229 -0
  71. agentpool/diagnostics/models.py +398 -0
  72. agentpool/functional/run.py +10 -4
  73. agentpool/mcp_server/__init__.py +0 -2
  74. agentpool/mcp_server/client.py +76 -32
  75. agentpool/mcp_server/conversions.py +54 -13
  76. agentpool/mcp_server/manager.py +34 -54
  77. agentpool/mcp_server/registries/official_registry_client.py +35 -1
  78. agentpool/mcp_server/tool_bridge.py +186 -139
  79. agentpool/messaging/__init__.py +0 -2
  80. agentpool/messaging/compaction.py +72 -197
  81. agentpool/messaging/connection_manager.py +11 -10
  82. agentpool/messaging/event_manager.py +5 -5
  83. agentpool/messaging/message_container.py +6 -30
  84. agentpool/messaging/message_history.py +99 -8
  85. agentpool/messaging/messagenode.py +52 -14
  86. agentpool/messaging/messages.py +54 -35
  87. agentpool/messaging/processing.py +12 -22
  88. agentpool/models/__init__.py +1 -1
  89. agentpool/models/acp_agents/base.py +6 -24
  90. agentpool/models/acp_agents/mcp_capable.py +126 -157
  91. agentpool/models/acp_agents/non_mcp.py +129 -95
  92. agentpool/models/agents.py +98 -76
  93. agentpool/models/agui_agents.py +1 -1
  94. agentpool/models/claude_code_agents.py +144 -19
  95. agentpool/models/file_parsing.py +0 -1
  96. agentpool/models/manifest.py +113 -50
  97. agentpool/prompts/conversion_manager.py +1 -1
  98. agentpool/prompts/prompts.py +5 -2
  99. agentpool/repomap.py +1 -1
  100. agentpool/resource_providers/__init__.py +11 -1
  101. agentpool/resource_providers/aggregating.py +56 -5
  102. agentpool/resource_providers/base.py +70 -4
  103. agentpool/resource_providers/codemode/code_executor.py +72 -5
  104. agentpool/resource_providers/codemode/helpers.py +2 -2
  105. agentpool/resource_providers/codemode/provider.py +64 -12
  106. agentpool/resource_providers/codemode/remote_mcp_execution.py +2 -2
  107. agentpool/resource_providers/codemode/remote_provider.py +9 -12
  108. agentpool/resource_providers/filtering.py +3 -1
  109. agentpool/resource_providers/mcp_provider.py +89 -12
  110. agentpool/resource_providers/plan_provider.py +228 -46
  111. agentpool/resource_providers/pool.py +7 -3
  112. agentpool/resource_providers/resource_info.py +111 -0
  113. agentpool/resource_providers/static.py +4 -2
  114. agentpool/sessions/__init__.py +4 -1
  115. agentpool/sessions/manager.py +33 -5
  116. agentpool/sessions/models.py +59 -6
  117. agentpool/sessions/protocol.py +28 -0
  118. agentpool/sessions/session.py +11 -55
  119. agentpool/skills/registry.py +13 -8
  120. agentpool/storage/manager.py +572 -49
  121. agentpool/talk/registry.py +4 -4
  122. agentpool/talk/talk.py +9 -10
  123. agentpool/testing.py +538 -20
  124. agentpool/tool_impls/__init__.py +6 -0
  125. agentpool/tool_impls/agent_cli/__init__.py +42 -0
  126. agentpool/tool_impls/agent_cli/tool.py +95 -0
  127. agentpool/tool_impls/bash/__init__.py +64 -0
  128. agentpool/tool_impls/bash/helpers.py +35 -0
  129. agentpool/tool_impls/bash/tool.py +171 -0
  130. agentpool/tool_impls/delete_path/__init__.py +70 -0
  131. agentpool/tool_impls/delete_path/tool.py +142 -0
  132. agentpool/tool_impls/download_file/__init__.py +80 -0
  133. agentpool/tool_impls/download_file/tool.py +183 -0
  134. agentpool/tool_impls/execute_code/__init__.py +55 -0
  135. agentpool/tool_impls/execute_code/tool.py +163 -0
  136. agentpool/tool_impls/grep/__init__.py +80 -0
  137. agentpool/tool_impls/grep/tool.py +200 -0
  138. agentpool/tool_impls/list_directory/__init__.py +73 -0
  139. agentpool/tool_impls/list_directory/tool.py +197 -0
  140. agentpool/tool_impls/question/__init__.py +42 -0
  141. agentpool/tool_impls/question/tool.py +127 -0
  142. agentpool/tool_impls/read/__init__.py +104 -0
  143. agentpool/tool_impls/read/tool.py +305 -0
  144. agentpool/tools/__init__.py +2 -1
  145. agentpool/tools/base.py +114 -34
  146. agentpool/tools/manager.py +57 -1
  147. agentpool/ui/base.py +2 -2
  148. agentpool/ui/mock_provider.py +2 -2
  149. agentpool/ui/stdlib_provider.py +2 -2
  150. agentpool/utils/file_watcher.py +269 -0
  151. agentpool/utils/identifiers.py +121 -0
  152. agentpool/utils/pydantic_ai_helpers.py +46 -0
  153. agentpool/utils/streams.py +616 -2
  154. agentpool/utils/subprocess_utils.py +155 -0
  155. agentpool/utils/token_breakdown.py +461 -0
  156. agentpool/vfs_registry.py +7 -2
  157. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/METADATA +41 -27
  158. agentpool-2.5.0.dist-info/RECORD +579 -0
  159. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/WHEEL +1 -1
  160. agentpool_cli/__main__.py +24 -0
  161. agentpool_cli/create.py +1 -1
  162. agentpool_cli/serve_acp.py +100 -21
  163. agentpool_cli/serve_agui.py +87 -0
  164. agentpool_cli/serve_opencode.py +119 -0
  165. agentpool_cli/ui.py +557 -0
  166. agentpool_commands/__init__.py +42 -5
  167. agentpool_commands/agents.py +75 -2
  168. agentpool_commands/history.py +62 -0
  169. agentpool_commands/mcp.py +176 -0
  170. agentpool_commands/models.py +56 -3
  171. agentpool_commands/pool.py +260 -0
  172. agentpool_commands/session.py +1 -1
  173. agentpool_commands/text_sharing/__init__.py +119 -0
  174. agentpool_commands/text_sharing/base.py +123 -0
  175. agentpool_commands/text_sharing/github_gist.py +80 -0
  176. agentpool_commands/text_sharing/opencode.py +462 -0
  177. agentpool_commands/text_sharing/paste_rs.py +59 -0
  178. agentpool_commands/text_sharing/pastebin.py +116 -0
  179. agentpool_commands/text_sharing/shittycodingagent.py +112 -0
  180. agentpool_commands/tools.py +57 -0
  181. agentpool_commands/utils.py +80 -30
  182. agentpool_config/__init__.py +30 -2
  183. agentpool_config/agentpool_tools.py +498 -0
  184. agentpool_config/builtin_tools.py +77 -22
  185. agentpool_config/commands.py +24 -1
  186. agentpool_config/compaction.py +258 -0
  187. agentpool_config/converters.py +1 -1
  188. agentpool_config/event_handlers.py +42 -0
  189. agentpool_config/events.py +1 -1
  190. agentpool_config/forward_targets.py +1 -4
  191. agentpool_config/jinja.py +3 -3
  192. agentpool_config/mcp_server.py +132 -6
  193. agentpool_config/nodes.py +1 -1
  194. agentpool_config/observability.py +44 -0
  195. agentpool_config/session.py +0 -3
  196. agentpool_config/storage.py +82 -38
  197. agentpool_config/task.py +3 -3
  198. agentpool_config/tools.py +11 -22
  199. agentpool_config/toolsets.py +109 -233
  200. agentpool_server/a2a_server/agent_worker.py +307 -0
  201. agentpool_server/a2a_server/server.py +23 -18
  202. agentpool_server/acp_server/acp_agent.py +234 -181
  203. agentpool_server/acp_server/commands/acp_commands.py +151 -156
  204. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +18 -17
  205. agentpool_server/acp_server/event_converter.py +651 -0
  206. agentpool_server/acp_server/input_provider.py +53 -10
  207. agentpool_server/acp_server/server.py +24 -90
  208. agentpool_server/acp_server/session.py +173 -331
  209. agentpool_server/acp_server/session_manager.py +8 -34
  210. agentpool_server/agui_server/server.py +3 -1
  211. agentpool_server/mcp_server/server.py +5 -2
  212. agentpool_server/opencode_server/.rules +95 -0
  213. agentpool_server/opencode_server/ENDPOINTS.md +401 -0
  214. agentpool_server/opencode_server/OPENCODE_UI_TOOLS_COMPLETE.md +202 -0
  215. agentpool_server/opencode_server/__init__.py +19 -0
  216. agentpool_server/opencode_server/command_validation.py +172 -0
  217. agentpool_server/opencode_server/converters.py +975 -0
  218. agentpool_server/opencode_server/dependencies.py +24 -0
  219. agentpool_server/opencode_server/input_provider.py +421 -0
  220. agentpool_server/opencode_server/models/__init__.py +250 -0
  221. agentpool_server/opencode_server/models/agent.py +53 -0
  222. agentpool_server/opencode_server/models/app.py +72 -0
  223. agentpool_server/opencode_server/models/base.py +26 -0
  224. agentpool_server/opencode_server/models/common.py +23 -0
  225. agentpool_server/opencode_server/models/config.py +37 -0
  226. agentpool_server/opencode_server/models/events.py +821 -0
  227. agentpool_server/opencode_server/models/file.py +88 -0
  228. agentpool_server/opencode_server/models/mcp.py +44 -0
  229. agentpool_server/opencode_server/models/message.py +179 -0
  230. agentpool_server/opencode_server/models/parts.py +323 -0
  231. agentpool_server/opencode_server/models/provider.py +81 -0
  232. agentpool_server/opencode_server/models/pty.py +43 -0
  233. agentpool_server/opencode_server/models/question.py +56 -0
  234. agentpool_server/opencode_server/models/session.py +111 -0
  235. agentpool_server/opencode_server/routes/__init__.py +29 -0
  236. agentpool_server/opencode_server/routes/agent_routes.py +473 -0
  237. agentpool_server/opencode_server/routes/app_routes.py +202 -0
  238. agentpool_server/opencode_server/routes/config_routes.py +302 -0
  239. agentpool_server/opencode_server/routes/file_routes.py +571 -0
  240. agentpool_server/opencode_server/routes/global_routes.py +94 -0
  241. agentpool_server/opencode_server/routes/lsp_routes.py +319 -0
  242. agentpool_server/opencode_server/routes/message_routes.py +761 -0
  243. agentpool_server/opencode_server/routes/permission_routes.py +63 -0
  244. agentpool_server/opencode_server/routes/pty_routes.py +300 -0
  245. agentpool_server/opencode_server/routes/question_routes.py +128 -0
  246. agentpool_server/opencode_server/routes/session_routes.py +1276 -0
  247. agentpool_server/opencode_server/routes/tui_routes.py +139 -0
  248. agentpool_server/opencode_server/server.py +475 -0
  249. agentpool_server/opencode_server/state.py +151 -0
  250. agentpool_server/opencode_server/time_utils.py +8 -0
  251. agentpool_storage/__init__.py +12 -0
  252. agentpool_storage/base.py +184 -2
  253. agentpool_storage/claude_provider/ARCHITECTURE.md +433 -0
  254. agentpool_storage/claude_provider/__init__.py +42 -0
  255. agentpool_storage/claude_provider/provider.py +1089 -0
  256. agentpool_storage/file_provider.py +278 -15
  257. agentpool_storage/memory_provider.py +193 -12
  258. agentpool_storage/models.py +3 -0
  259. agentpool_storage/opencode_provider/ARCHITECTURE.md +386 -0
  260. agentpool_storage/opencode_provider/__init__.py +16 -0
  261. agentpool_storage/opencode_provider/helpers.py +414 -0
  262. agentpool_storage/opencode_provider/provider.py +895 -0
  263. agentpool_storage/project_store.py +325 -0
  264. agentpool_storage/session_store.py +26 -6
  265. agentpool_storage/sql_provider/__init__.py +4 -2
  266. agentpool_storage/sql_provider/models.py +48 -0
  267. agentpool_storage/sql_provider/sql_provider.py +269 -3
  268. agentpool_storage/sql_provider/utils.py +12 -13
  269. agentpool_storage/zed_provider/__init__.py +16 -0
  270. agentpool_storage/zed_provider/helpers.py +281 -0
  271. agentpool_storage/zed_provider/models.py +130 -0
  272. agentpool_storage/zed_provider/provider.py +442 -0
  273. agentpool_storage/zed_provider.py +803 -0
  274. agentpool_toolsets/__init__.py +0 -2
  275. agentpool_toolsets/builtin/__init__.py +2 -12
  276. agentpool_toolsets/builtin/code.py +96 -57
  277. agentpool_toolsets/builtin/debug.py +118 -48
  278. agentpool_toolsets/builtin/execution_environment.py +115 -230
  279. agentpool_toolsets/builtin/file_edit/file_edit.py +115 -7
  280. agentpool_toolsets/builtin/skills.py +9 -4
  281. agentpool_toolsets/builtin/subagent_tools.py +64 -51
  282. agentpool_toolsets/builtin/workers.py +4 -2
  283. agentpool_toolsets/composio_toolset.py +2 -2
  284. agentpool_toolsets/entry_points.py +3 -1
  285. agentpool_toolsets/fsspec_toolset/__init__.py +13 -1
  286. agentpool_toolsets/fsspec_toolset/diagnostics.py +860 -73
  287. agentpool_toolsets/fsspec_toolset/grep.py +99 -7
  288. agentpool_toolsets/fsspec_toolset/helpers.py +3 -2
  289. agentpool_toolsets/fsspec_toolset/image_utils.py +161 -0
  290. agentpool_toolsets/fsspec_toolset/toolset.py +500 -95
  291. agentpool_toolsets/mcp_discovery/__init__.py +5 -0
  292. agentpool_toolsets/mcp_discovery/data/mcp_servers.parquet +0 -0
  293. agentpool_toolsets/mcp_discovery/toolset.py +511 -0
  294. agentpool_toolsets/mcp_run_toolset.py +87 -12
  295. agentpool_toolsets/notifications.py +33 -33
  296. agentpool_toolsets/openapi.py +3 -1
  297. agentpool_toolsets/search_toolset.py +3 -1
  298. agentpool-2.1.9.dist-info/RECORD +0 -474
  299. agentpool_config/resources.py +0 -33
  300. agentpool_server/acp_server/acp_tools.py +0 -43
  301. agentpool_server/acp_server/commands/spawn.py +0 -210
  302. agentpool_storage/text_log_provider.py +0 -275
  303. agentpool_toolsets/builtin/agent_management.py +0 -239
  304. agentpool_toolsets/builtin/chain.py +0 -288
  305. agentpool_toolsets/builtin/history.py +0 -36
  306. agentpool_toolsets/builtin/integration.py +0 -85
  307. agentpool_toolsets/builtin/tool_management.py +0 -90
  308. agentpool_toolsets/builtin/user_interaction.py +0 -52
  309. agentpool_toolsets/semantic_memory_toolset.py +0 -536
  310. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/entry_points.txt +0 -0
  311. {agentpool-2.1.9.dist-info → agentpool-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,119 @@
1
+ """Text sharing services for sharing content via paste services."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal, assert_never, overload
6
+
7
+ from agentpool_commands.text_sharing.base import ShareResult, TextSharer, Visibility
8
+ from agentpool_commands.text_sharing.github_gist import GistSharer
9
+ from agentpool_commands.text_sharing.opencode import OpenCodeSharer
10
+ from agentpool_commands.text_sharing.paste_rs import PasteRsSharer
11
+ from agentpool_commands.text_sharing.pastebin import PastebinSharer
12
+ from agentpool_commands.text_sharing.shittycodingagent import ShittyCodingAgentSharer
13
+
14
+
15
+ TextSharerStr = Literal["gist", "pastebin", "paste_rs", "opencode", "shittycodingagent"]
16
+
17
+
18
+ @overload
19
+ def get_sharer(
20
+ provider: Literal["gist"],
21
+ *,
22
+ token: str | None = None,
23
+ ) -> GistSharer: ...
24
+
25
+
26
+ @overload
27
+ def get_sharer(
28
+ provider: Literal["pastebin"],
29
+ *,
30
+ api_key: str | None = None,
31
+ ) -> PastebinSharer: ...
32
+
33
+
34
+ @overload
35
+ def get_sharer(
36
+ provider: Literal["paste_rs"],
37
+ ) -> PasteRsSharer: ...
38
+
39
+
40
+ @overload
41
+ def get_sharer(
42
+ provider: Literal["opencode"],
43
+ *,
44
+ api_url: str | None = None,
45
+ ) -> OpenCodeSharer: ...
46
+
47
+
48
+ @overload
49
+ def get_sharer(
50
+ provider: Literal["shittycodingagent"],
51
+ *,
52
+ token: str | None = None,
53
+ ) -> ShittyCodingAgentSharer: ...
54
+
55
+
56
+ def get_sharer(
57
+ provider: TextSharerStr,
58
+ **kwargs: str | None,
59
+ ) -> TextSharer:
60
+ """Get a text sharer based on provider name.
61
+
62
+ Args:
63
+ provider: The text sharing provider to use
64
+ **kwargs: Keyword arguments to pass to the provider constructor
65
+
66
+ Returns:
67
+ An instance of the specified text sharer
68
+
69
+ Example:
70
+ ```python
71
+ # GitHub Gist (reads GITHUB_TOKEN/GH_TOKEN from env)
72
+ sharer = get_sharer("gist")
73
+
74
+ # GitHub Gist with explicit token
75
+ sharer = get_sharer("gist", token="ghp_...")
76
+
77
+ # Pastebin (reads PASTEBIN_API_KEY from env)
78
+ sharer = get_sharer("pastebin")
79
+
80
+ # Pastebin with explicit key
81
+ sharer = get_sharer("pastebin", api_key="...")
82
+
83
+ # paste.rs (no auth needed)
84
+ sharer = get_sharer("paste_rs")
85
+
86
+ # OpenCode (no auth needed)
87
+ sharer = get_sharer("opencode")
88
+
89
+ # OpenCode with custom API URL
90
+ sharer = get_sharer("opencode", api_url="https://api.dev.opencode.ai")
91
+ ```
92
+ """
93
+ match provider:
94
+ case "gist":
95
+ return GistSharer(**kwargs)
96
+ case "pastebin":
97
+ return PastebinSharer(**kwargs)
98
+ case "paste_rs":
99
+ return PasteRsSharer()
100
+ case "opencode":
101
+ return OpenCodeSharer(**kwargs) # type: ignore[arg-type]
102
+ case "shittycodingagent":
103
+ return ShittyCodingAgentSharer(**kwargs)
104
+ case _ as unreachable:
105
+ assert_never(unreachable)
106
+
107
+
108
+ __all__ = [
109
+ "GistSharer",
110
+ "OpenCodeSharer",
111
+ "PasteRsSharer",
112
+ "PastebinSharer",
113
+ "ShareResult",
114
+ "ShittyCodingAgentSharer",
115
+ "TextSharer",
116
+ "TextSharerStr",
117
+ "Visibility",
118
+ "get_sharer",
119
+ ]
@@ -0,0 +1,123 @@
1
+ """Base class for text sharing services."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import abc
6
+ from dataclasses import dataclass
7
+ from typing import TYPE_CHECKING, Literal
8
+
9
+
10
+ if TYPE_CHECKING:
11
+ from agentpool.messaging.message_history import MessageHistory
12
+
13
+
14
+ Visibility = Literal["public", "unlisted", "private"]
15
+
16
+
17
+ @dataclass
18
+ class ShareResult:
19
+ """Result of a text sharing operation."""
20
+
21
+ url: str
22
+ """URL to access the shared content."""
23
+
24
+ raw_url: str | None = None
25
+ """Direct URL to raw content, if available."""
26
+
27
+ delete_url: str | None = None
28
+ """URL to delete the content, if available."""
29
+
30
+ id: str | None = None
31
+ """Provider-specific ID of the shared content."""
32
+
33
+
34
+ class TextSharer(abc.ABC):
35
+ """Base class for text sharing services."""
36
+
37
+ @property
38
+ @abc.abstractmethod
39
+ def name(self) -> str:
40
+ """Name of the sharing service."""
41
+
42
+ @abc.abstractmethod
43
+ async def share(
44
+ self,
45
+ content: str,
46
+ *,
47
+ title: str | None = None,
48
+ syntax: str | None = None,
49
+ visibility: Visibility = "unlisted",
50
+ expires_in: int | None = None,
51
+ ) -> ShareResult:
52
+ """Share text content.
53
+
54
+ Args:
55
+ content: The text content to share
56
+ title: Optional title/filename for the content
57
+ syntax: Syntax highlighting hint (e.g. "python", "markdown")
58
+ visibility: Visibility level (not all providers support all levels)
59
+ expires_in: Expiration time in seconds (not supported by all providers)
60
+
61
+ Returns:
62
+ ShareResult with URL and metadata
63
+ """
64
+
65
+ async def share_conversation(
66
+ self,
67
+ conversation: MessageHistory,
68
+ *,
69
+ title: str | None = None,
70
+ visibility: Visibility = "unlisted",
71
+ expires_in: int | None = None,
72
+ num_messages: int | None = None,
73
+ ) -> ShareResult:
74
+ """Share a conversation in structured format.
75
+
76
+ Default implementation formats conversation as text and calls share().
77
+ Providers that support structured conversations (e.g., OpenCode)
78
+ should override this method.
79
+
80
+ Args:
81
+ conversation: MessageHistory object to share
82
+ title: Optional title for the conversation
83
+ visibility: Visibility level
84
+ expires_in: Expiration time in seconds
85
+ num_messages: Number of messages to include (None = all)
86
+
87
+ Returns:
88
+ ShareResult with URL and metadata
89
+ """
90
+ # Default: format as plain text
91
+ content = await conversation.format_history(
92
+ num_messages=num_messages,
93
+ )
94
+ return await self.share(
95
+ content,
96
+ title=title,
97
+ syntax="markdown",
98
+ visibility=visibility,
99
+ expires_in=expires_in,
100
+ )
101
+
102
+ def share_sync(
103
+ self,
104
+ content: str,
105
+ *,
106
+ title: str | None = None,
107
+ syntax: str | None = None,
108
+ visibility: Visibility = "unlisted",
109
+ expires_in: int | None = None,
110
+ ) -> ShareResult:
111
+ """Synchronous version of share."""
112
+ from anyenv import run_sync
113
+
114
+ async def wrapper() -> ShareResult:
115
+ return await self.share(
116
+ content,
117
+ title=title,
118
+ syntax=syntax,
119
+ visibility=visibility,
120
+ expires_in=expires_in,
121
+ )
122
+
123
+ return run_sync(wrapper())
@@ -0,0 +1,80 @@
1
+ """GitHub Gist text sharing provider."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ from agentpool_commands.text_sharing.base import ShareResult, TextSharer
9
+
10
+
11
+ if TYPE_CHECKING:
12
+ from agentpool_commands.text_sharing.base import Visibility
13
+
14
+
15
+ class GistSharer(TextSharer):
16
+ """Share text via GitHub Gists."""
17
+
18
+ def __init__(self, token: str | None = None) -> None:
19
+ """Initialize the GitHub Gist sharer.
20
+
21
+ Args:
22
+ token: GitHub personal access token. If not provided,
23
+ reads from GITHUB_TOKEN environment variable.
24
+ """
25
+ self._token = token or os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
26
+ if not self._token:
27
+ msg = "GitHub token required. Set GITHUB_TOKEN/GH_TOKEN or pass token parameter."
28
+ raise ValueError(msg)
29
+
30
+ @property
31
+ def name(self) -> str:
32
+ """Name of the sharing service."""
33
+ return "GitHub Gist"
34
+
35
+ async def share(
36
+ self,
37
+ content: str,
38
+ *,
39
+ title: str | None = None,
40
+ syntax: str | None = None,
41
+ visibility: Visibility = "unlisted",
42
+ expires_in: int | None = None,
43
+ ) -> ShareResult:
44
+ """Share content as a GitHub Gist.
45
+
46
+ Args:
47
+ content: The text content to share
48
+ title: Filename for the gist (defaults to "shared.txt" or "shared.{syntax}")
49
+ syntax: File extension hint (e.g. "py", "md")
50
+ visibility: "public" or "unlisted" (private not supported)
51
+ expires_in: Ignored (gists don't expire)
52
+ """
53
+ import anyenv
54
+
55
+ filename = title or f"shared.{syntax or 'txt'}"
56
+ public = visibility == "public"
57
+ payload: dict[str, Any] = {"files": {filename: {"content": content}}, "public": public}
58
+ headers = {
59
+ "Authorization": f"Bearer {self._token}",
60
+ "Accept": "application/vnd.github+json",
61
+ "X-GitHub-Api-Version": "2022-11-28",
62
+ }
63
+ url = "https://api.github.com/gists"
64
+ response: dict[str, Any] = await anyenv.post_json(url, payload, headers=headers)
65
+ raw_url = response["files"][filename]["raw_url"]
66
+ return ShareResult(url=response["html_url"], raw_url=raw_url, id=response["id"])
67
+
68
+
69
+ if __name__ == "__main__":
70
+ import asyncio
71
+
72
+ async def main() -> None:
73
+ """Example usage of the GistSharer class."""
74
+ sharer = GistSharer()
75
+ result = await sharer.share("# Test Gist!", title="test.md", syntax="md")
76
+ print(f"URL: {result.url}")
77
+ print(f"Raw: {result.raw_url}")
78
+ print(f"ID: {result.id}")
79
+
80
+ asyncio.run(main())