simplicio-agent 0.25.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 (1148) hide show
  1. acp_adapter/__init__.py +1 -0
  2. acp_adapter/__main__.py +5 -0
  3. acp_adapter/auth.py +79 -0
  4. acp_adapter/edit_approval.py +338 -0
  5. acp_adapter/entry.py +280 -0
  6. acp_adapter/events.py +279 -0
  7. acp_adapter/permissions.py +175 -0
  8. acp_adapter/provenance.py +127 -0
  9. acp_adapter/server.py +2065 -0
  10. acp_adapter/session.py +627 -0
  11. acp_adapter/tools.py +1329 -0
  12. agent/__init__.py +8 -0
  13. agent/_fastjson.py +167 -0
  14. agent/_hermes_fast.py +182 -0
  15. agent/account_usage.py +890 -0
  16. agent/adapter_contract.py +35 -0
  17. agent/adaptive_controller.py +379 -0
  18. agent/agent_init.py +2182 -0
  19. agent/agent_runtime_helpers.py +3375 -0
  20. agent/ai_memory/__init__.py +1 -0
  21. agent/ai_memory/cross_vendor.py +148 -0
  22. agent/algorithms/__init__.py +0 -0
  23. agent/algorithms/addressing.py +223 -0
  24. agent/anthropic_adapter.py +2790 -0
  25. agent/asolaria_pattern_contract.py +477 -0
  26. agent/async_dag/__init__.py +15 -0
  27. agent/async_dag/executor.py +166 -0
  28. agent/async_dag/uvloop_runner.py +169 -0
  29. agent/async_utils.py +68 -0
  30. agent/attention_schema.py +370 -0
  31. agent/autobiographical_memory.py +218 -0
  32. agent/autonomy_policy.py +315 -0
  33. agent/auxiliary_client.py +7905 -0
  34. agent/azure_identity_adapter.py +555 -0
  35. agent/background_review.py +988 -0
  36. agent/backlog_ref/__init__.py +0 -0
  37. agent/backlog_ref/issue_315_self_mod_kernel.py +122 -0
  38. agent/bedrock_adapter.py +1351 -0
  39. agent/belief_state.py +696 -0
  40. agent/benchmark_manifest.py +59 -0
  41. agent/benchmarks/__init__.py +1 -0
  42. agent/benchmarks/e2e_comparison.py +162 -0
  43. agent/billing_view.py +295 -0
  44. agent/bounded_response.py +148 -0
  45. agent/browser_provider.py +187 -0
  46. agent/browser_provider_contract.py +31 -0
  47. agent/browser_registry.py +192 -0
  48. agent/capability_inventory.py +86 -0
  49. agent/capability_registry.py +574 -0
  50. agent/capability_registry_contract.py +553 -0
  51. agent/chat_completion_helpers.py +3429 -0
  52. agent/closed_loop_controller.py +1381 -0
  53. agent/coarse_graining_contract.py +100 -0
  54. agent/codex_responses_adapter.py +1468 -0
  55. agent/codex_runtime.py +954 -0
  56. agent/coding_context.py +892 -0
  57. agent/computer_use_provider_contract.py +34 -0
  58. agent/context/__init__.py +33 -0
  59. agent/context/incremental.py +61 -0
  60. agent/context/retrieval.py +83 -0
  61. agent/context/token_cache.py +104 -0
  62. agent/context/working_set.py +263 -0
  63. agent/context_breakdown.py +156 -0
  64. agent/context_compressor.py +3455 -0
  65. agent/context_engine.py +238 -0
  66. agent/context_references.py +616 -0
  67. agent/conversation_compression.py +1194 -0
  68. agent/conversation_loop.py +5821 -0
  69. agent/copilot_acp_client.py +751 -0
  70. agent/credential_persistence.py +174 -0
  71. agent/credential_pool.py +2461 -0
  72. agent/credential_sources.py +447 -0
  73. agent/credits_tracker.py +794 -0
  74. agent/cron/__init__.py +5 -0
  75. agent/cron/unified_scheduler.py +247 -0
  76. agent/curator.py +2016 -0
  77. agent/curator_backup.py +711 -0
  78. agent/delivery_certificate.py +599 -0
  79. agent/desktop_first_run_contract.py +567 -0
  80. agent/desktop_layout_contract.py +596 -0
  81. agent/desktop_security_contract.py +571 -0
  82. agent/display.py +1464 -0
  83. agent/distributed/__init__.py +53 -0
  84. agent/distributed/protocol.py +271 -0
  85. agent/distribution/__init__.py +6 -0
  86. agent/distribution/manifest.py +36 -0
  87. agent/distribution/publisher.py +121 -0
  88. agent/env_alias.py +97 -0
  89. agent/error_classifier.py +1621 -0
  90. agent/errors.py +9 -0
  91. agent/event_store.py +360 -0
  92. agent/fanout_governor_contract.py +536 -0
  93. agent/file_safety.py +679 -0
  94. agent/gemini_native_adapter.py +1040 -0
  95. agent/gemini_schema.py +99 -0
  96. agent/goal_contract.py +727 -0
  97. agent/golden_path.py +435 -0
  98. agent/host.py +451 -0
  99. agent/hrm_controller_contract.py +687 -0
  100. agent/hyper_bechs/__init__.py +11 -0
  101. agent/hyper_bechs/host8.py +253 -0
  102. agent/hypothesis_ensemble.py +225 -0
  103. agent/i18n.py +302 -0
  104. agent/image_gen_provider.py +393 -0
  105. agent/image_gen_registry.py +145 -0
  106. agent/image_routing.py +765 -0
  107. agent/insights.py +1080 -0
  108. agent/issue_claim_lease.py +454 -0
  109. agent/iteration_budget.py +95 -0
  110. agent/jiter_preload.py +39 -0
  111. agent/jspace_contract.py +416 -0
  112. agent/kanban_stop.py +108 -0
  113. agent/learn_prompt.py +150 -0
  114. agent/learning_graph.py +328 -0
  115. agent/learning_graph_render.py +659 -0
  116. agent/learning_mutations.py +206 -0
  117. agent/lmstudio_reasoning.py +48 -0
  118. agent/lsp/__init__.py +106 -0
  119. agent/lsp/cli.py +299 -0
  120. agent/lsp/client.py +964 -0
  121. agent/lsp/eventlog.py +213 -0
  122. agent/lsp/install.py +406 -0
  123. agent/lsp/manager.py +639 -0
  124. agent/lsp/protocol.py +196 -0
  125. agent/lsp/range_shift.py +149 -0
  126. agent/lsp/reporter.py +130 -0
  127. agent/lsp/servers.py +1187 -0
  128. agent/lsp/workspace.py +223 -0
  129. agent/manual_compression_feedback.py +49 -0
  130. agent/markdown_tables.py +309 -0
  131. agent/mcp_agent_gateway.py +194 -0
  132. agent/mcp_cli_compatibility_contract.py +388 -0
  133. agent/media_goal_contract.py +35 -0
  134. agent/memory_manager.py +1135 -0
  135. agent/memory_provider.py +315 -0
  136. agent/message_content.py +50 -0
  137. agent/message_sanitization.py +477 -0
  138. agent/metacognition_contract.py +87 -0
  139. agent/moa_loop.py +1176 -0
  140. agent/moa_trace.py +167 -0
  141. agent/model_metadata.py +2352 -0
  142. agent/models_dev.py +725 -0
  143. agent/modes/__init__.py +1 -0
  144. agent/modes/provider_mode.py +85 -0
  145. agent/moonshot_schema.py +238 -0
  146. agent/multirate_scheduler.py +441 -0
  147. agent/net/__init__.py +5 -0
  148. agent/net/http_pool.py +143 -0
  149. agent/nous_rate_guard.py +325 -0
  150. agent/onboarding.py +253 -0
  151. agent/oneshot.py +158 -0
  152. agent/operational_awareness_contract.py +66 -0
  153. agent/operational_cycle.py +180 -0
  154. agent/operational_metrics.py +260 -0
  155. agent/operational_now.py +527 -0
  156. agent/operational_self_model.py +508 -0
  157. agent/perception_action_feedback_contract.py +74 -0
  158. agent/perf_probe.py +102 -0
  159. agent/persistent_run.py +425 -0
  160. agent/pet/__init__.py +51 -0
  161. agent/pet/constants.py +167 -0
  162. agent/pet/generate/__init__.py +29 -0
  163. agent/pet/generate/atlas.py +1183 -0
  164. agent/pet/generate/imagegen.py +251 -0
  165. agent/pet/generate/orchestrate.py +358 -0
  166. agent/pet/generate/prompts.py +183 -0
  167. agent/pet/manifest.py +165 -0
  168. agent/pet/render.py +682 -0
  169. agent/pet/state.py +81 -0
  170. agent/pet/store.py +503 -0
  171. agent/plugin_llm.py +1046 -0
  172. agent/plugins/__init__.py +1 -0
  173. agent/plugins/unified_registry.py +121 -0
  174. agent/portal_tags.py +64 -0
  175. agent/possibility_ledger.py +385 -0
  176. agent/prediction_receipts.py +941 -0
  177. agent/process_bootstrap.py +227 -0
  178. agent/profiles/__init__.py +4 -0
  179. agent/profiles/multi_profile.py +91 -0
  180. agent/project_mapper/__init__.py +16 -0
  181. agent/project_mapper/fingerprint.py +264 -0
  182. agent/prompt_builder.py +2021 -0
  183. agent/prompt_caching.py +132 -0
  184. agent/prompt_economy.py +941 -0
  185. agent/prompt_microkernel.py +309 -0
  186. agent/protocol.py +155 -0
  187. agent/protocol_v1.py +1173 -0
  188. agent/provider_mode.py +160 -0
  189. agent/providers/__init__.py +17 -0
  190. agent/providers/fallback_chain.py +202 -0
  191. agent/providers/router.py +96 -0
  192. agent/providers/runtime.py +504 -0
  193. agent/rate_distortion_context.py +550 -0
  194. agent/rate_limit_tracker.py +246 -0
  195. agent/reactions.py +56 -0
  196. agent/reasoning_timeouts.py +224 -0
  197. agent/redact.py +811 -0
  198. agent/registry/__init__.py +16 -0
  199. agent/registry/lazy_schema.py +85 -0
  200. agent/registry/skill_meta.py +95 -0
  201. agent/release_evidence_contract.py +481 -0
  202. agent/release_handoff_contract.py +357 -0
  203. agent/replay_cleanup.py +317 -0
  204. agent/resource_homeostasis.py +598 -0
  205. agent/restart_recovery.py +578 -0
  206. agent/retry_utils.py +154 -0
  207. agent/reversible_path.py +520 -0
  208. agent/router/__init__.py +21 -0
  209. agent/router/cost_aware.py +213 -0
  210. agent/router/deterministic.py +94 -0
  211. agent/router/fallback.py +54 -0
  212. agent/runtime_bridge.py +65 -0
  213. agent/runtime_bundle_contract.py +431 -0
  214. agent/runtime_cwd.py +62 -0
  215. agent/scientific_integrity_gate.py +181 -0
  216. agent/secret_scope.py +205 -0
  217. agent/secret_sources/__init__.py +41 -0
  218. agent/secret_sources/_cache.py +213 -0
  219. agent/secret_sources/base.py +274 -0
  220. agent/secret_sources/bitwarden.py +729 -0
  221. agent/secret_sources/onepassword.py +643 -0
  222. agent/secret_sources/registry.py +370 -0
  223. agent/security/__init__.py +14 -0
  224. agent/security/unified_auth.py +93 -0
  225. agent/self_model.py +399 -0
  226. agent/serde/__init__.py +19 -0
  227. agent/serde/fast_json.py +111 -0
  228. agent/session.py +255 -0
  229. agent/session_repositories.py +126 -0
  230. agent/shannon/__init__.py +21 -0
  231. agent/shannon/pipeline.py +525 -0
  232. agent/shell_hooks.py +928 -0
  233. agent/simplicio_prompt.py +60 -0
  234. agent/skill_bundles.py +438 -0
  235. agent/skill_commands.py +964 -0
  236. agent/skill_preprocessing.py +144 -0
  237. agent/skill_utils.py +829 -0
  238. agent/software_delivery_contract.py +35 -0
  239. agent/ssl_guard.py +94 -0
  240. agent/ssl_verify.py +63 -0
  241. agent/state_migration.py +670 -0
  242. agent/stream_diag.py +280 -0
  243. agent/subdirectory_hints.py +270 -0
  244. agent/supervisor_registry.py +188 -0
  245. agent/support_bundle_contract.py +484 -0
  246. agent/system_prompt.py +682 -0
  247. agent/task_envelope.py +870 -0
  248. agent/task_envelope_bridge.py +144 -0
  249. agent/telemetry/__init__.py +39 -0
  250. agent/telemetry/dashboard.py +137 -0
  251. agent/telemetry/gain_analytics.py +108 -0
  252. agent/telemetry/lane_readiness.py +278 -0
  253. agent/telemetry/mcp_session.py +361 -0
  254. agent/telemetry/receipts.py +248 -0
  255. agent/telemetry/savings_report.py +321 -0
  256. agent/telemetry/stage_timer.py +126 -0
  257. agent/telemetry/token_savings.py +108 -0
  258. agent/telemetry/tool_replay.py +259 -0
  259. agent/telemetry/turn_metrics.py +164 -0
  260. agent/testing/__init__.py +5 -0
  261. agent/testing/unified_harness.py +183 -0
  262. agent/think_scrubber.py +399 -0
  263. agent/thinking_timeout_guidance.py +136 -0
  264. agent/thread_scoped_output.py +147 -0
  265. agent/tier_rate_limiter.py +262 -0
  266. agent/title_generator.py +204 -0
  267. agent/token_economy.py +338 -0
  268. agent/token_governor.py +248 -0
  269. agent/tokens/__init__.py +17 -0
  270. agent/tokens/fast_estimator.py +146 -0
  271. agent/tokens/message_estimator.py +80 -0
  272. agent/tool_call_json.py +76 -0
  273. agent/tool_dispatch_helpers.py +626 -0
  274. agent/tool_executor.py +1873 -0
  275. agent/tool_guardrails.py +475 -0
  276. agent/tool_invocation_pipeline.py +868 -0
  277. agent/tool_result_classification.py +43 -0
  278. agent/toon_boundary.py +137 -0
  279. agent/toon_codec.py +679 -0
  280. agent/trace_upload.py +398 -0
  281. agent/tracing/__init__.py +19 -0
  282. agent/tracing/spans.py +165 -0
  283. agent/trajectory.py +56 -0
  284. agent/trajectory_skill_contract.py +42 -0
  285. agent/transcription_provider.py +193 -0
  286. agent/transcription_registry.py +124 -0
  287. agent/transports/__init__.py +99 -0
  288. agent/transports/anthropic.py +251 -0
  289. agent/transports/base.py +89 -0
  290. agent/transports/bedrock.py +154 -0
  291. agent/transports/chat_completions.py +796 -0
  292. agent/transports/codex.py +499 -0
  293. agent/transports/codex_app_server.py +413 -0
  294. agent/transports/codex_app_server_session.py +1078 -0
  295. agent/transports/codex_event_projector.py +335 -0
  296. agent/transports/hermes_tools_mcp_server.py +261 -0
  297. agent/transports/types.py +174 -0
  298. agent/trust_boundary.py +812 -0
  299. agent/tts_provider.py +274 -0
  300. agent/tts_registry.py +134 -0
  301. agent/turn_context.py +623 -0
  302. agent/turn_engine.py +140 -0
  303. agent/turn_envelope.py +242 -0
  304. agent/turn_finalizer.py +612 -0
  305. agent/turn_prep.py +72 -0
  306. agent/turn_retry_state.py +80 -0
  307. agent/update_rollback_contract.py +387 -0
  308. agent/usage_pricing.py +1042 -0
  309. agent/uvloop_utils.py +40 -0
  310. agent/value_of_information_contract.py +105 -0
  311. agent/verification_evidence.py +655 -0
  312. agent/verification_stop.py +313 -0
  313. agent/verify_hooks.py +69 -0
  314. agent/vertex_adapter.py +228 -0
  315. agent/video_gen_provider.py +590 -0
  316. agent/video_gen_registry.py +133 -0
  317. agent/web_search_provider.py +211 -0
  318. agent/web_search_registry.py +304 -0
  319. batch_runner.py +1323 -0
  320. cli.py +16505 -0
  321. cron/__init__.py +42 -0
  322. cron/blueprint_catalog.py +713 -0
  323. cron/jobs.py +2341 -0
  324. cron/lifecycle_guard.py +141 -0
  325. cron/scheduler.py +3940 -0
  326. cron/scheduler_provider.py +205 -0
  327. cron/scripts/__init__.py +1 -0
  328. cron/scripts/classify_items.py +264 -0
  329. cron/suggestion_catalog.py +154 -0
  330. cron/suggestions.py +260 -0
  331. gateway/__init__.py +35 -0
  332. gateway/assets/status_phrases.yaml +52 -0
  333. gateway/assets/telegram-botfather-threads-settings.jpg +0 -0
  334. gateway/authz_mixin.py +710 -0
  335. gateway/builtin_hooks/__init__.py +1 -0
  336. gateway/cgroup_cleanup.py +81 -0
  337. gateway/channel_directory.py +497 -0
  338. gateway/code_skew.py +64 -0
  339. gateway/config.py +2321 -0
  340. gateway/cwd_placeholder.py +49 -0
  341. gateway/dead_targets.py +143 -0
  342. gateway/delivery.py +742 -0
  343. gateway/display_config.py +277 -0
  344. gateway/drain_control.py +273 -0
  345. gateway/hooks.py +227 -0
  346. gateway/kanban_watchers.py +1286 -0
  347. gateway/memory_monitor.py +230 -0
  348. gateway/message_timestamps.py +166 -0
  349. gateway/mirror.py +206 -0
  350. gateway/native_bridge.py +500 -0
  351. gateway/pairing.py +661 -0
  352. gateway/platform_registry.py +332 -0
  353. gateway/platforms/__init__.py +45 -0
  354. gateway/platforms/_http_client_limits.py +84 -0
  355. gateway/platforms/api_server.py +4641 -0
  356. gateway/platforms/base.py +5735 -0
  357. gateway/platforms/bluebubbles.py +1048 -0
  358. gateway/platforms/helpers.py +403 -0
  359. gateway/platforms/msgraph_webhook.py +441 -0
  360. gateway/platforms/qqbot/__init__.py +91 -0
  361. gateway/platforms/qqbot/adapter.py +3237 -0
  362. gateway/platforms/qqbot/chunked_upload.py +602 -0
  363. gateway/platforms/qqbot/constants.py +74 -0
  364. gateway/platforms/qqbot/crypto.py +45 -0
  365. gateway/platforms/qqbot/keyboards.py +461 -0
  366. gateway/platforms/qqbot/onboard.py +220 -0
  367. gateway/platforms/qqbot/utils.py +70 -0
  368. gateway/platforms/signal.py +1701 -0
  369. gateway/platforms/signal_format.py +140 -0
  370. gateway/platforms/signal_rate_limit.py +369 -0
  371. gateway/platforms/webhook.py +1266 -0
  372. gateway/platforms/webhook_filters.py +302 -0
  373. gateway/platforms/weixin.py +2380 -0
  374. gateway/platforms/whatsapp_cloud.py +2067 -0
  375. gateway/platforms/whatsapp_common.py +510 -0
  376. gateway/platforms/yuanbao.py +5557 -0
  377. gateway/platforms/yuanbao_media.py +665 -0
  378. gateway/platforms/yuanbao_proto.py +1418 -0
  379. gateway/platforms/yuanbao_sticker.py +558 -0
  380. gateway/profile_routing.py +166 -0
  381. gateway/readiness.py +117 -0
  382. gateway/relay/__init__.py +836 -0
  383. gateway/relay/adapter.py +546 -0
  384. gateway/relay/auth.py +168 -0
  385. gateway/relay/descriptor.py +124 -0
  386. gateway/relay/transport.py +143 -0
  387. gateway/relay/ws_transport.py +809 -0
  388. gateway/response_filters.py +106 -0
  389. gateway/restart.py +492 -0
  390. gateway/restart_loop_guard.py +150 -0
  391. gateway/rich_sent_store.py +83 -0
  392. gateway/run.py +21689 -0
  393. gateway/runtime_footer.py +149 -0
  394. gateway/scale_to_zero.py +124 -0
  395. gateway/session.py +2603 -0
  396. gateway/session_context.py +346 -0
  397. gateway/shutdown_forensics.py +462 -0
  398. gateway/slash_access.py +229 -0
  399. gateway/slash_commands.py +4742 -0
  400. gateway/status.py +1554 -0
  401. gateway/status_phrases.py +227 -0
  402. gateway/sticker_cache.py +124 -0
  403. gateway/stream_consumer.py +1964 -0
  404. gateway/stream_dispatch.py +132 -0
  405. gateway/stream_events.py +171 -0
  406. gateway/whatsapp_identity.py +206 -0
  407. hermes_bootstrap.py +195 -0
  408. hermes_cli/__init__.py +105 -0
  409. hermes_cli/_parser.py +452 -0
  410. hermes_cli/_subprocess_compat.py +234 -0
  411. hermes_cli/active_sessions.py +357 -0
  412. hermes_cli/auth.py +8411 -0
  413. hermes_cli/auth_commands.py +780 -0
  414. hermes_cli/azure_detect.py +408 -0
  415. hermes_cli/backup.py +1376 -0
  416. hermes_cli/banner.py +742 -0
  417. hermes_cli/blueprint_cmd.py +318 -0
  418. hermes_cli/browser_connect.py +349 -0
  419. hermes_cli/build_info.py +51 -0
  420. hermes_cli/bundles.py +229 -0
  421. hermes_cli/callbacks.py +242 -0
  422. hermes_cli/checkpoints.py +244 -0
  423. hermes_cli/claw.py +809 -0
  424. hermes_cli/cli_agent_setup_mixin.py +690 -0
  425. hermes_cli/cli_commands_mixin.py +2738 -0
  426. hermes_cli/cli_output.py +77 -0
  427. hermes_cli/clipboard.py +494 -0
  428. hermes_cli/codex_models.py +220 -0
  429. hermes_cli/codex_runtime_plugin_migration.py +766 -0
  430. hermes_cli/codex_runtime_switch.py +288 -0
  431. hermes_cli/colors.py +38 -0
  432. hermes_cli/commands.py +2148 -0
  433. hermes_cli/completion.py +319 -0
  434. hermes_cli/config.py +7866 -0
  435. hermes_cli/console_engine.py +1876 -0
  436. hermes_cli/container_boot.py +576 -0
  437. hermes_cli/context_switch_guard.py +169 -0
  438. hermes_cli/copilot_auth.py +458 -0
  439. hermes_cli/cron.py +481 -0
  440. hermes_cli/curator.py +698 -0
  441. hermes_cli/curses_ui.py +872 -0
  442. hermes_cli/daemon.py +466 -0
  443. hermes_cli/dashboard_auth/__init__.py +48 -0
  444. hermes_cli/dashboard_auth/audit.py +89 -0
  445. hermes_cli/dashboard_auth/base.py +306 -0
  446. hermes_cli/dashboard_auth/cookies.py +338 -0
  447. hermes_cli/dashboard_auth/login_page.py +534 -0
  448. hermes_cli/dashboard_auth/middleware.py +516 -0
  449. hermes_cli/dashboard_auth/prefix.py +232 -0
  450. hermes_cli/dashboard_auth/public_paths.py +55 -0
  451. hermes_cli/dashboard_auth/registry.py +81 -0
  452. hermes_cli/dashboard_auth/routes.py +644 -0
  453. hermes_cli/dashboard_auth/token_auth.py +194 -0
  454. hermes_cli/dashboard_auth/ws_tickets.py +161 -0
  455. hermes_cli/dashboard_register.py +427 -0
  456. hermes_cli/debug.py +1017 -0
  457. hermes_cli/default_soul.py +161 -0
  458. hermes_cli/dep_ensure.py +163 -0
  459. hermes_cli/diagnostics_upload.py +138 -0
  460. hermes_cli/dingtalk_auth.py +291 -0
  461. hermes_cli/doctor.py +3156 -0
  462. hermes_cli/dump.py +444 -0
  463. hermes_cli/env_loader.py +403 -0
  464. hermes_cli/fallback_cmd.py +354 -0
  465. hermes_cli/fallback_config.py +135 -0
  466. hermes_cli/gateway.py +6847 -0
  467. hermes_cli/gateway_enroll.py +277 -0
  468. hermes_cli/gateway_windows.py +1682 -0
  469. hermes_cli/goals.py +1749 -0
  470. hermes_cli/gui_uninstall.py +285 -0
  471. hermes_cli/hooks.py +394 -0
  472. hermes_cli/input_sanitize.py +70 -0
  473. hermes_cli/inventory.py +627 -0
  474. hermes_cli/journey.py +357 -0
  475. hermes_cli/kanban.py +2845 -0
  476. hermes_cli/kanban_db.py +9135 -0
  477. hermes_cli/kanban_decompose.py +468 -0
  478. hermes_cli/kanban_diagnostics.py +1133 -0
  479. hermes_cli/kanban_specify.py +264 -0
  480. hermes_cli/kanban_swarm.py +278 -0
  481. hermes_cli/local_change_staging.py +574 -0
  482. hermes_cli/logs.py +397 -0
  483. hermes_cli/main.py +13832 -0
  484. hermes_cli/managed_scope.py +214 -0
  485. hermes_cli/managed_uv.py +254 -0
  486. hermes_cli/mcp_catalog.py +796 -0
  487. hermes_cli/mcp_config.py +1104 -0
  488. hermes_cli/mcp_picker.py +322 -0
  489. hermes_cli/mcp_security.py +181 -0
  490. hermes_cli/mcp_startup.py +130 -0
  491. hermes_cli/memory_oauth.py +83 -0
  492. hermes_cli/memory_providers.py +149 -0
  493. hermes_cli/memory_setup.py +518 -0
  494. hermes_cli/middleware.py +313 -0
  495. hermes_cli/migrate.py +115 -0
  496. hermes_cli/moa_cmd.py +141 -0
  497. hermes_cli/moa_config.py +367 -0
  498. hermes_cli/model_catalog.py +430 -0
  499. hermes_cli/model_cost_guard.py +134 -0
  500. hermes_cli/model_normalize.py +473 -0
  501. hermes_cli/model_setup_flows.py +3063 -0
  502. hermes_cli/model_switch.py +2498 -0
  503. hermes_cli/models.py +4210 -0
  504. hermes_cli/nous_account.py +789 -0
  505. hermes_cli/nous_auth_keepalive.py +189 -0
  506. hermes_cli/nous_billing.py +406 -0
  507. hermes_cli/nous_subscription.py +1285 -0
  508. hermes_cli/onepassword_secrets_cli.py +432 -0
  509. hermes_cli/oneshot.py +440 -0
  510. hermes_cli/pairing.py +115 -0
  511. hermes_cli/partial_compress.py +324 -0
  512. hermes_cli/pets.py +502 -0
  513. hermes_cli/platforms.py +84 -0
  514. hermes_cli/plugins.py +2466 -0
  515. hermes_cli/plugins_cmd.py +2017 -0
  516. hermes_cli/portal_cli.py +245 -0
  517. hermes_cli/profile_describer.py +288 -0
  518. hermes_cli/profile_distribution.py +726 -0
  519. hermes_cli/profiles.py +2238 -0
  520. hermes_cli/projects_cmd.py +335 -0
  521. hermes_cli/projects_db.py +727 -0
  522. hermes_cli/prompt_size.py +161 -0
  523. hermes_cli/provider_catalog.py +181 -0
  524. hermes_cli/providers.py +789 -0
  525. hermes_cli/proxy/__init__.py +20 -0
  526. hermes_cli/proxy/adapters/__init__.py +37 -0
  527. hermes_cli/proxy/adapters/base.py +108 -0
  528. hermes_cli/proxy/adapters/nous_portal.py +199 -0
  529. hermes_cli/proxy/adapters/xai.py +145 -0
  530. hermes_cli/proxy/cli.py +141 -0
  531. hermes_cli/proxy/server.py +304 -0
  532. hermes_cli/psutil_android.py +108 -0
  533. hermes_cli/pt_input_extras.py +120 -0
  534. hermes_cli/pty_bridge.py +286 -0
  535. hermes_cli/pty_session.py +195 -0
  536. hermes_cli/relaunch.py +205 -0
  537. hermes_cli/runtime_mcp_matrix.py +466 -0
  538. hermes_cli/runtime_provider.py +2097 -0
  539. hermes_cli/secret_prompt.py +126 -0
  540. hermes_cli/secrets_cli.py +600 -0
  541. hermes_cli/security_advisories.py +453 -0
  542. hermes_cli/security_audit.py +576 -0
  543. hermes_cli/security_audit_startup.py +282 -0
  544. hermes_cli/send_cmd.py +471 -0
  545. hermes_cli/service_manager.py +1123 -0
  546. hermes_cli/session_export.py +317 -0
  547. hermes_cli/session_export_html.py +871 -0
  548. hermes_cli/session_export_md.py +279 -0
  549. hermes_cli/session_filters.py +208 -0
  550. hermes_cli/session_listing.py +113 -0
  551. hermes_cli/session_recap.py +316 -0
  552. hermes_cli/setup.py +3405 -0
  553. hermes_cli/setup_whatsapp_cloud.py +541 -0
  554. hermes_cli/skills_config.py +202 -0
  555. hermes_cli/skills_hub.py +2013 -0
  556. hermes_cli/skin_engine.py +926 -0
  557. hermes_cli/slack_cli.py +224 -0
  558. hermes_cli/sqlite_util.py +49 -0
  559. hermes_cli/staging_activation.py +601 -0
  560. hermes_cli/status.py +622 -0
  561. hermes_cli/stdio.py +251 -0
  562. hermes_cli/subcommands/__init__.py +18 -0
  563. hermes_cli/subcommands/_shared.py +29 -0
  564. hermes_cli/subcommands/acp.py +52 -0
  565. hermes_cli/subcommands/auth.py +98 -0
  566. hermes_cli/subcommands/backup.py +38 -0
  567. hermes_cli/subcommands/claw.py +92 -0
  568. hermes_cli/subcommands/config.py +49 -0
  569. hermes_cli/subcommands/console.py +18 -0
  570. hermes_cli/subcommands/cron.py +163 -0
  571. hermes_cli/subcommands/daemon.py +67 -0
  572. hermes_cli/subcommands/dashboard.py +200 -0
  573. hermes_cli/subcommands/debug.py +100 -0
  574. hermes_cli/subcommands/doctor.py +35 -0
  575. hermes_cli/subcommands/dump.py +28 -0
  576. hermes_cli/subcommands/gateway.py +345 -0
  577. hermes_cli/subcommands/gui.py +63 -0
  578. hermes_cli/subcommands/hooks.py +77 -0
  579. hermes_cli/subcommands/import_cmd.py +31 -0
  580. hermes_cli/subcommands/insights.py +25 -0
  581. hermes_cli/subcommands/login.py +78 -0
  582. hermes_cli/subcommands/logout.py +28 -0
  583. hermes_cli/subcommands/logs.py +78 -0
  584. hermes_cli/subcommands/mcp.py +126 -0
  585. hermes_cli/subcommands/memory.py +53 -0
  586. hermes_cli/subcommands/model.py +62 -0
  587. hermes_cli/subcommands/pairing.py +36 -0
  588. hermes_cli/subcommands/plugins.py +106 -0
  589. hermes_cli/subcommands/postinstall.py +23 -0
  590. hermes_cli/subcommands/profile.py +203 -0
  591. hermes_cli/subcommands/prompt_size.py +36 -0
  592. hermes_cli/subcommands/report.py +50 -0
  593. hermes_cli/subcommands/security.py +62 -0
  594. hermes_cli/subcommands/setup.py +58 -0
  595. hermes_cli/subcommands/skills.py +315 -0
  596. hermes_cli/subcommands/slack.py +77 -0
  597. hermes_cli/subcommands/status.py +28 -0
  598. hermes_cli/subcommands/tools.py +95 -0
  599. hermes_cli/subcommands/uninstall.py +46 -0
  600. hermes_cli/subcommands/update.py +76 -0
  601. hermes_cli/subcommands/version.py +18 -0
  602. hermes_cli/subcommands/webhook.py +83 -0
  603. hermes_cli/subcommands/whatsapp.py +22 -0
  604. hermes_cli/suggestions_cmd.py +153 -0
  605. hermes_cli/telegram_managed_bot.py +358 -0
  606. hermes_cli/timeouts.py +82 -0
  607. hermes_cli/tips.py +485 -0
  608. hermes_cli/tools_config.py +4521 -0
  609. hermes_cli/toolset_validation.py +74 -0
  610. hermes_cli/transactional_updater.py +453 -0
  611. hermes_cli/uninstall.py +962 -0
  612. hermes_cli/update_contract.py +1011 -0
  613. hermes_cli/update_preflight.py +389 -0
  614. hermes_cli/urllib_security.py +139 -0
  615. hermes_cli/voice.py +846 -0
  616. hermes_cli/web_git.py +697 -0
  617. hermes_cli/web_server.py +14270 -0
  618. hermes_cli/webhook.py +306 -0
  619. hermes_cli/win_pty_bridge.py +179 -0
  620. hermes_cli/write_approval_commands.py +209 -0
  621. hermes_cli/xai_retirement.py +256 -0
  622. hermes_constants.py +1333 -0
  623. hermes_logging.py +791 -0
  624. hermes_state.py +7369 -0
  625. hermes_time.py +135 -0
  626. mcp_serve.py +1680 -0
  627. model_tools.py +1410 -0
  628. plugins/__init__.py +1 -0
  629. plugins/browser/browser_use/__init__.py +14 -0
  630. plugins/browser/browser_use/plugin.yaml +7 -0
  631. plugins/browser/browser_use/provider.py +317 -0
  632. plugins/browser/browserbase/__init__.py +15 -0
  633. plugins/browser/browserbase/plugin.yaml +7 -0
  634. plugins/browser/browserbase/provider.py +301 -0
  635. plugins/browser/firecrawl/__init__.py +16 -0
  636. plugins/browser/firecrawl/plugin.yaml +7 -0
  637. plugins/browser/firecrawl/provider.py +171 -0
  638. plugins/context_engine/__init__.py +285 -0
  639. plugins/cron_providers/__init__.py +356 -0
  640. plugins/cron_providers/chronos/__init__.py +241 -0
  641. plugins/cron_providers/chronos/_nas_client.py +123 -0
  642. plugins/cron_providers/chronos/plugin.yaml +9 -0
  643. plugins/cron_providers/chronos/verify.py +145 -0
  644. plugins/dashboard_auth/basic/__init__.py +491 -0
  645. plugins/dashboard_auth/basic/plugin.yaml +7 -0
  646. plugins/dashboard_auth/drain/__init__.py +291 -0
  647. plugins/dashboard_auth/drain/plugin.yaml +7 -0
  648. plugins/dashboard_auth/nous/__init__.py +667 -0
  649. plugins/dashboard_auth/nous/plugin.yaml +7 -0
  650. plugins/dashboard_auth/self_hosted/__init__.py +858 -0
  651. plugins/dashboard_auth/self_hosted/plugin.yaml +8 -0
  652. plugins/disk-cleanup/README.md +51 -0
  653. plugins/disk-cleanup/__init__.py +316 -0
  654. plugins/disk-cleanup/disk_cleanup.py +588 -0
  655. plugins/disk-cleanup/plugin.yaml +7 -0
  656. plugins/google_meet/README.md +131 -0
  657. plugins/google_meet/__init__.py +103 -0
  658. plugins/google_meet/audio_bridge.py +248 -0
  659. plugins/google_meet/cli.py +476 -0
  660. plugins/google_meet/meet_bot.py +858 -0
  661. plugins/google_meet/node/__init__.py +54 -0
  662. plugins/google_meet/node/cli.py +134 -0
  663. plugins/google_meet/node/client.py +107 -0
  664. plugins/google_meet/node/protocol.py +124 -0
  665. plugins/google_meet/node/registry.py +112 -0
  666. plugins/google_meet/node/server.py +200 -0
  667. plugins/google_meet/plugin.yaml +16 -0
  668. plugins/google_meet/process_manager.py +323 -0
  669. plugins/google_meet/realtime/__init__.py +10 -0
  670. plugins/google_meet/realtime/openai_client.py +332 -0
  671. plugins/google_meet/tools.py +348 -0
  672. plugins/hermes-achievements/README.md +150 -0
  673. plugins/hermes-achievements/dashboard/dist/index.js +726 -0
  674. plugins/hermes-achievements/dashboard/dist/style.css +146 -0
  675. plugins/hermes-achievements/dashboard/manifest.json +11 -0
  676. plugins/hermes-achievements/dashboard/plugin_api.py +1061 -0
  677. plugins/hermes-achievements/tests/test_achievement_engine.py +156 -0
  678. plugins/image_gen/deepinfra/__init__.py +335 -0
  679. plugins/image_gen/deepinfra/plugin.yaml +7 -0
  680. plugins/image_gen/fal/__init__.py +211 -0
  681. plugins/image_gen/fal/plugin.yaml +7 -0
  682. plugins/image_gen/krea/__init__.py +743 -0
  683. plugins/image_gen/krea/plugin.yaml +7 -0
  684. plugins/image_gen/openai/__init__.py +417 -0
  685. plugins/image_gen/openai/plugin.yaml +7 -0
  686. plugins/image_gen/openai-codex/__init__.py +641 -0
  687. plugins/image_gen/openai-codex/plugin.yaml +5 -0
  688. plugins/image_gen/openrouter/__init__.py +529 -0
  689. plugins/image_gen/openrouter/plugin.yaml +7 -0
  690. plugins/image_gen/xai/__init__.py +494 -0
  691. plugins/image_gen/xai/plugin.yaml +7 -0
  692. plugins/kanban/dashboard/dist/index.js +4108 -0
  693. plugins/kanban/dashboard/dist/style.css +1592 -0
  694. plugins/kanban/dashboard/manifest.json +14 -0
  695. plugins/kanban/dashboard/plugin_api.py +2499 -0
  696. plugins/memory/__init__.py +461 -0
  697. plugins/memory/byterover/README.md +41 -0
  698. plugins/memory/byterover/__init__.py +449 -0
  699. plugins/memory/byterover/plugin.yaml +9 -0
  700. plugins/memory/hindsight/README.md +147 -0
  701. plugins/memory/hindsight/__init__.py +1968 -0
  702. plugins/memory/hindsight/plugin.yaml +8 -0
  703. plugins/memory/holographic/README.md +36 -0
  704. plugins/memory/holographic/__init__.py +419 -0
  705. plugins/memory/holographic/holographic.py +203 -0
  706. plugins/memory/holographic/plugin.yaml +5 -0
  707. plugins/memory/holographic/retrieval.py +654 -0
  708. plugins/memory/holographic/store.py +644 -0
  709. plugins/memory/honcho/README.md +388 -0
  710. plugins/memory/honcho/__init__.py +1432 -0
  711. plugins/memory/honcho/cli.py +1868 -0
  712. plugins/memory/honcho/client.py +920 -0
  713. plugins/memory/honcho/oauth.py +371 -0
  714. plugins/memory/honcho/oauth_flow.py +431 -0
  715. plugins/memory/honcho/plugin.yaml +7 -0
  716. plugins/memory/honcho/session.py +1344 -0
  717. plugins/memory/mem0/README.md +187 -0
  718. plugins/memory/mem0/__init__.py +627 -0
  719. plugins/memory/mem0/_backend.py +298 -0
  720. plugins/memory/mem0/_oss_providers.py +84 -0
  721. plugins/memory/mem0/_setup.py +981 -0
  722. plugins/memory/mem0/plugin.yaml +5 -0
  723. plugins/memory/openviking/README.md +83 -0
  724. plugins/memory/openviking/__init__.py +3725 -0
  725. plugins/memory/openviking/plugin.yaml +8 -0
  726. plugins/memory/retaindb/README.md +40 -0
  727. plugins/memory/retaindb/__init__.py +771 -0
  728. plugins/memory/retaindb/plugin.yaml +7 -0
  729. plugins/memory/supermemory/README.md +111 -0
  730. plugins/memory/supermemory/__init__.py +1021 -0
  731. plugins/memory/supermemory/plugin.yaml +5 -0
  732. plugins/model-providers/README.md +70 -0
  733. plugins/model-providers/alibaba/__init__.py +13 -0
  734. plugins/model-providers/alibaba/plugin.yaml +5 -0
  735. plugins/model-providers/alibaba-coding-plan/__init__.py +21 -0
  736. plugins/model-providers/alibaba-coding-plan/plugin.yaml +5 -0
  737. plugins/model-providers/anthropic/__init__.py +54 -0
  738. plugins/model-providers/anthropic/plugin.yaml +5 -0
  739. plugins/model-providers/arcee/__init__.py +13 -0
  740. plugins/model-providers/arcee/plugin.yaml +5 -0
  741. plugins/model-providers/azure-foundry/__init__.py +21 -0
  742. plugins/model-providers/azure-foundry/plugin.yaml +5 -0
  743. plugins/model-providers/bedrock/__init__.py +30 -0
  744. plugins/model-providers/bedrock/plugin.yaml +5 -0
  745. plugins/model-providers/copilot/__init__.py +58 -0
  746. plugins/model-providers/copilot/plugin.yaml +5 -0
  747. plugins/model-providers/copilot-acp/__init__.py +35 -0
  748. plugins/model-providers/copilot-acp/plugin.yaml +5 -0
  749. plugins/model-providers/custom/__init__.py +103 -0
  750. plugins/model-providers/custom/plugin.yaml +5 -0
  751. plugins/model-providers/deepinfra/__init__.py +81 -0
  752. plugins/model-providers/deepinfra/plugin.yaml +5 -0
  753. plugins/model-providers/deepseek/__init__.py +100 -0
  754. plugins/model-providers/deepseek/plugin.yaml +5 -0
  755. plugins/model-providers/fireworks/__init__.py +36 -0
  756. plugins/model-providers/fireworks/plugin.yaml +5 -0
  757. plugins/model-providers/gemini/__init__.py +61 -0
  758. plugins/model-providers/gemini/plugin.yaml +5 -0
  759. plugins/model-providers/gmi/__init__.py +31 -0
  760. plugins/model-providers/gmi/plugin.yaml +5 -0
  761. plugins/model-providers/huggingface/__init__.py +20 -0
  762. plugins/model-providers/huggingface/plugin.yaml +5 -0
  763. plugins/model-providers/kilocode/__init__.py +14 -0
  764. plugins/model-providers/kilocode/plugin.yaml +5 -0
  765. plugins/model-providers/kimi-coding/__init__.py +80 -0
  766. plugins/model-providers/kimi-coding/plugin.yaml +5 -0
  767. plugins/model-providers/minimax/__init__.py +97 -0
  768. plugins/model-providers/minimax/plugin.yaml +5 -0
  769. plugins/model-providers/nous/__init__.py +58 -0
  770. plugins/model-providers/nous/plugin.yaml +5 -0
  771. plugins/model-providers/novita/__init__.py +27 -0
  772. plugins/model-providers/novita/plugin.yaml +5 -0
  773. plugins/model-providers/nvidia/__init__.py +21 -0
  774. plugins/model-providers/nvidia/plugin.yaml +5 -0
  775. plugins/model-providers/ollama-cloud/__init__.py +73 -0
  776. plugins/model-providers/ollama-cloud/plugin.yaml +5 -0
  777. plugins/model-providers/openai-codex/__init__.py +15 -0
  778. plugins/model-providers/openai-codex/plugin.yaml +5 -0
  779. plugins/model-providers/opencode-zen/__init__.py +147 -0
  780. plugins/model-providers/opencode-zen/plugin.yaml +5 -0
  781. plugins/model-providers/openrouter/__init__.py +188 -0
  782. plugins/model-providers/openrouter/plugin.yaml +5 -0
  783. plugins/model-providers/qwen-oauth/__init__.py +108 -0
  784. plugins/model-providers/qwen-oauth/plugin.yaml +5 -0
  785. plugins/model-providers/stepfun/__init__.py +14 -0
  786. plugins/model-providers/stepfun/plugin.yaml +5 -0
  787. plugins/model-providers/upstage/__init__.py +115 -0
  788. plugins/model-providers/upstage/plugin.yaml +5 -0
  789. plugins/model-providers/vertex/__init__.py +75 -0
  790. plugins/model-providers/vertex/plugin.yaml +5 -0
  791. plugins/model-providers/xai/__init__.py +15 -0
  792. plugins/model-providers/xai/plugin.yaml +5 -0
  793. plugins/model-providers/xiaomi/__init__.py +16 -0
  794. plugins/model-providers/xiaomi/plugin.yaml +5 -0
  795. plugins/model-providers/zai/__init__.py +127 -0
  796. plugins/model-providers/zai/plugin.yaml +5 -0
  797. plugins/observability/langfuse/README.md +53 -0
  798. plugins/observability/langfuse/__init__.py +1137 -0
  799. plugins/observability/langfuse/plugin.yaml +14 -0
  800. plugins/observability/nemo_relay/README.md +559 -0
  801. plugins/observability/nemo_relay/__init__.py +1238 -0
  802. plugins/observability/nemo_relay/plugin.yaml +20 -0
  803. plugins/platforms/dingtalk/__init__.py +3 -0
  804. plugins/platforms/dingtalk/adapter.py +1707 -0
  805. plugins/platforms/dingtalk/plugin.yaml +39 -0
  806. plugins/platforms/discord/__init__.py +3 -0
  807. plugins/platforms/discord/adapter.py +7805 -0
  808. plugins/platforms/discord/plugin.yaml +34 -0
  809. plugins/platforms/discord/voice_mixer.py +379 -0
  810. plugins/platforms/email/__init__.py +3 -0
  811. plugins/platforms/email/adapter.py +1273 -0
  812. plugins/platforms/email/plugin.yaml +39 -0
  813. plugins/platforms/feishu/__init__.py +3 -0
  814. plugins/platforms/feishu/adapter.py +5673 -0
  815. plugins/platforms/feishu/feishu_comment.py +1382 -0
  816. plugins/platforms/feishu/feishu_comment_rules.py +429 -0
  817. plugins/platforms/feishu/feishu_meeting_invite.py +212 -0
  818. plugins/platforms/feishu/plugin.yaml +44 -0
  819. plugins/platforms/google_chat/__init__.py +3 -0
  820. plugins/platforms/google_chat/adapter.py +3348 -0
  821. plugins/platforms/google_chat/oauth.py +668 -0
  822. plugins/platforms/google_chat/plugin.yaml +39 -0
  823. plugins/platforms/homeassistant/__init__.py +3 -0
  824. plugins/platforms/homeassistant/adapter.py +577 -0
  825. plugins/platforms/homeassistant/plugin.yaml +22 -0
  826. plugins/platforms/irc/__init__.py +3 -0
  827. plugins/platforms/irc/adapter.py +971 -0
  828. plugins/platforms/irc/plugin.yaml +54 -0
  829. plugins/platforms/line/__init__.py +3 -0
  830. plugins/platforms/line/adapter.py +1652 -0
  831. plugins/platforms/line/plugin.yaml +65 -0
  832. plugins/platforms/matrix/__init__.py +3 -0
  833. plugins/platforms/matrix/adapter.py +4623 -0
  834. plugins/platforms/matrix/plugin.yaml +41 -0
  835. plugins/platforms/mattermost/__init__.py +3 -0
  836. plugins/platforms/mattermost/adapter.py +1281 -0
  837. plugins/platforms/mattermost/plugin.yaml +49 -0
  838. plugins/platforms/ntfy/__init__.py +3 -0
  839. plugins/platforms/ntfy/adapter.py +593 -0
  840. plugins/platforms/ntfy/plugin.yaml +56 -0
  841. plugins/platforms/photon/README.md +190 -0
  842. plugins/platforms/photon/__init__.py +4 -0
  843. plugins/platforms/photon/adapter.py +1795 -0
  844. plugins/platforms/photon/auth.py +1046 -0
  845. plugins/platforms/photon/cli.py +440 -0
  846. plugins/platforms/photon/plugin.yaml +88 -0
  847. plugins/platforms/photon/sidecar/README.md +52 -0
  848. plugins/platforms/raft/__init__.py +3 -0
  849. plugins/platforms/raft/adapter.py +850 -0
  850. plugins/platforms/raft/plugin.yaml +19 -0
  851. plugins/platforms/simplex/__init__.py +3 -0
  852. plugins/platforms/simplex/adapter.py +1313 -0
  853. plugins/platforms/simplex/plugin.yaml +56 -0
  854. plugins/platforms/slack/__init__.py +3 -0
  855. plugins/platforms/slack/adapter.py +5148 -0
  856. plugins/platforms/slack/block_kit.py +512 -0
  857. plugins/platforms/slack/plugin.yaml +39 -0
  858. plugins/platforms/sms/__init__.py +3 -0
  859. plugins/platforms/sms/adapter.py +510 -0
  860. plugins/platforms/sms/plugin.yaml +32 -0
  861. plugins/platforms/teams/__init__.py +3 -0
  862. plugins/platforms/teams/adapter.py +1448 -0
  863. plugins/platforms/teams/plugin.yaml +48 -0
  864. plugins/platforms/telegram/__init__.py +3 -0
  865. plugins/platforms/telegram/adapter.py +9108 -0
  866. plugins/platforms/telegram/plugin.yaml +35 -0
  867. plugins/platforms/telegram/telegram_ids.py +51 -0
  868. plugins/platforms/telegram/telegram_network.py +269 -0
  869. plugins/platforms/wecom/__init__.py +3 -0
  870. plugins/platforms/wecom/adapter.py +1889 -0
  871. plugins/platforms/wecom/callback_adapter.py +444 -0
  872. plugins/platforms/wecom/plugin.yaml +52 -0
  873. plugins/platforms/wecom/wecom_crypto.py +142 -0
  874. plugins/platforms/whatsapp/__init__.py +3 -0
  875. plugins/platforms/whatsapp/adapter.py +1795 -0
  876. plugins/platforms/whatsapp/plugin.yaml +33 -0
  877. plugins/plugin_utils.py +135 -0
  878. plugins/security-guidance/README.md +88 -0
  879. plugins/security-guidance/__init__.py +259 -0
  880. plugins/security-guidance/patterns.py +368 -0
  881. plugins/security-guidance/plugin.yaml +7 -0
  882. plugins/simplicio/__init__.py +245 -0
  883. plugins/simplicio/plugin.yaml +9 -0
  884. plugins/simplicio/skill_recall.py +233 -0
  885. plugins/spotify/__init__.py +66 -0
  886. plugins/spotify/client.py +435 -0
  887. plugins/spotify/plugin.yaml +13 -0
  888. plugins/spotify/tools.py +454 -0
  889. plugins/teams_pipeline/__init__.py +23 -0
  890. plugins/teams_pipeline/cli.py +470 -0
  891. plugins/teams_pipeline/meetings.py +333 -0
  892. plugins/teams_pipeline/models.py +350 -0
  893. plugins/teams_pipeline/pipeline.py +699 -0
  894. plugins/teams_pipeline/plugin.yaml +9 -0
  895. plugins/teams_pipeline/runtime.py +135 -0
  896. plugins/teams_pipeline/store.py +193 -0
  897. plugins/teams_pipeline/subscriptions.py +249 -0
  898. plugins/token_saver/__init__.py +42 -0
  899. plugins/token_saver/plugin.yaml +7 -0
  900. plugins/token_saver/token_saver.py +228 -0
  901. plugins/video_gen/deepinfra/__init__.py +90 -0
  902. plugins/video_gen/deepinfra/plugin.yaml +7 -0
  903. plugins/video_gen/fal/__init__.py +620 -0
  904. plugins/video_gen/fal/plugin.yaml +7 -0
  905. plugins/video_gen/xai/__init__.py +925 -0
  906. plugins/video_gen/xai/plugin.yaml +7 -0
  907. plugins/web/__init__.py +7 -0
  908. plugins/web/brave_free/__init__.py +14 -0
  909. plugins/web/brave_free/plugin.yaml +7 -0
  910. plugins/web/brave_free/provider.py +141 -0
  911. plugins/web/ddgs/__init__.py +15 -0
  912. plugins/web/ddgs/plugin.yaml +7 -0
  913. plugins/web/ddgs/provider.py +158 -0
  914. plugins/web/exa/__init__.py +15 -0
  915. plugins/web/exa/plugin.yaml +7 -0
  916. plugins/web/exa/provider.py +216 -0
  917. plugins/web/firecrawl/__init__.py +28 -0
  918. plugins/web/firecrawl/plugin.yaml +7 -0
  919. plugins/web/firecrawl/provider.py +617 -0
  920. plugins/web/parallel/__init__.py +16 -0
  921. plugins/web/parallel/plugin.yaml +7 -0
  922. plugins/web/parallel/provider.py +297 -0
  923. plugins/web/searxng/__init__.py +15 -0
  924. plugins/web/searxng/plugin.yaml +7 -0
  925. plugins/web/searxng/provider.py +153 -0
  926. plugins/web/tavily/__init__.py +10 -0
  927. plugins/web/tavily/plugin.yaml +7 -0
  928. plugins/web/tavily/provider.py +224 -0
  929. plugins/web/xai/__init__.py +14 -0
  930. plugins/web/xai/plugin.yaml +7 -0
  931. plugins/web/xai/provider.py +557 -0
  932. providers/__init__.py +191 -0
  933. providers/base.py +232 -0
  934. run_agent.py +5734 -0
  935. simplicio_agent/__init__.py +44 -0
  936. simplicio_agent/__init__.pyi +10 -0
  937. simplicio_agent/__main__.py +12 -0
  938. simplicio_agent/asolaria.py +158 -0
  939. simplicio_agent/attention_schema.py +88 -0
  940. simplicio_agent/compat.py +39 -0
  941. simplicio_agent/compat.pyi +6 -0
  942. simplicio_agent/entry.py +15 -0
  943. simplicio_agent/product_identity.py +39 -0
  944. simplicio_agent/public_contract.py +85 -0
  945. simplicio_agent/py.typed +1 -0
  946. simplicio_agent-0.25.0.data/data/locales/af.yaml +408 -0
  947. simplicio_agent-0.25.0.data/data/locales/de.yaml +408 -0
  948. simplicio_agent-0.25.0.data/data/locales/en.yaml +420 -0
  949. simplicio_agent-0.25.0.data/data/locales/es.yaml +405 -0
  950. simplicio_agent-0.25.0.data/data/locales/fr.yaml +408 -0
  951. simplicio_agent-0.25.0.data/data/locales/ga.yaml +412 -0
  952. simplicio_agent-0.25.0.data/data/locales/hu.yaml +408 -0
  953. simplicio_agent-0.25.0.data/data/locales/it.yaml +408 -0
  954. simplicio_agent-0.25.0.data/data/locales/ja.yaml +408 -0
  955. simplicio_agent-0.25.0.data/data/locales/ko.yaml +408 -0
  956. simplicio_agent-0.25.0.data/data/locales/pt.yaml +408 -0
  957. simplicio_agent-0.25.0.data/data/locales/ru.yaml +408 -0
  958. simplicio_agent-0.25.0.data/data/locales/tr.yaml +408 -0
  959. simplicio_agent-0.25.0.data/data/locales/uk.yaml +408 -0
  960. simplicio_agent-0.25.0.data/data/locales/zh-hant.yaml +408 -0
  961. simplicio_agent-0.25.0.data/data/locales/zh.yaml +408 -0
  962. simplicio_agent-0.25.0.data/data/optional-mcps/linear/manifest.yaml +38 -0
  963. simplicio_agent-0.25.0.data/data/optional-mcps/n8n/manifest.yaml +81 -0
  964. simplicio_agent-0.25.0.data/data/runtime/runtime.lock +22 -0
  965. simplicio_agent-0.25.0.dist-info/METADATA +458 -0
  966. simplicio_agent-0.25.0.dist-info/RECORD +1148 -0
  967. simplicio_agent-0.25.0.dist-info/WHEEL +5 -0
  968. simplicio_agent-0.25.0.dist-info/entry_points.txt +6 -0
  969. simplicio_agent-0.25.0.dist-info/licenses/LICENSE +21 -0
  970. simplicio_agent-0.25.0.dist-info/top_level.txt +24 -0
  971. tools/__init__.py +25 -0
  972. tools/_fastjson.py +142 -0
  973. tools/alias_registry.py +490 -0
  974. tools/ansi_strip.py +44 -0
  975. tools/approval.py +3436 -0
  976. tools/async_delegation.py +1037 -0
  977. tools/bench_latency.py +83 -0
  978. tools/benchmark_gate.py +506 -0
  979. tools/benchmark_program.py +474 -0
  980. tools/binary_extensions.py +42 -0
  981. tools/blueprints.py +325 -0
  982. tools/bootstrap_transaction_client.py +181 -0
  983. tools/browser_camofox.py +949 -0
  984. tools/browser_camofox_state.py +47 -0
  985. tools/browser_cdp_tool.py +681 -0
  986. tools/browser_dialog_tool.py +148 -0
  987. tools/browser_interaction_contract.py +104 -0
  988. tools/browser_supervisor.py +1517 -0
  989. tools/browser_tool.py +4805 -0
  990. tools/budget_config.py +114 -0
  991. tools/bundle_manifest.py +128 -0
  992. tools/checkpoint_manager.py +1691 -0
  993. tools/clarify_gateway.py +315 -0
  994. tools/clarify_tool.py +191 -0
  995. tools/cli_surface_contract.py +428 -0
  996. tools/close_terminal_tool.py +71 -0
  997. tools/code_execution_tool.py +1910 -0
  998. tools/command_invocation_manifest.py +457 -0
  999. tools/computer_use/__init__.py +48 -0
  1000. tools/computer_use/backend.py +210 -0
  1001. tools/computer_use/cua_backend.py +2346 -0
  1002. tools/computer_use/doctor.py +288 -0
  1003. tools/computer_use/killswitch.py +65 -0
  1004. tools/computer_use/permissions.py +200 -0
  1005. tools/computer_use/schema.py +238 -0
  1006. tools/computer_use/tool.py +1174 -0
  1007. tools/computer_use/vision_routing.py +204 -0
  1008. tools/computer_use_tool.py +39 -0
  1009. tools/credential_files.py +481 -0
  1010. tools/cronjob_tools.py +1147 -0
  1011. tools/daemon_hot_path.py +538 -0
  1012. tools/daemon_pool.py +64 -0
  1013. tools/debug_helpers.py +105 -0
  1014. tools/delegate_tool.py +3528 -0
  1015. tools/desktop_layout_contract.py +310 -0
  1016. tools/discord_tool.py +1119 -0
  1017. tools/discovery_cache.py +153 -0
  1018. tools/env_passthrough.py +184 -0
  1019. tools/env_probe.py +275 -0
  1020. tools/environments/__init__.py +14 -0
  1021. tools/environments/base.py +1128 -0
  1022. tools/environments/daytona.py +270 -0
  1023. tools/environments/docker.py +1460 -0
  1024. tools/environments/file_sync.py +465 -0
  1025. tools/environments/local.py +1385 -0
  1026. tools/environments/managed_modal.py +282 -0
  1027. tools/environments/modal.py +478 -0
  1028. tools/environments/modal_utils.py +210 -0
  1029. tools/environments/singularity.py +265 -0
  1030. tools/environments/ssh.py +375 -0
  1031. tools/equivalence_gate.py +569 -0
  1032. tools/fal_common.py +163 -0
  1033. tools/feishu_doc_tool.py +138 -0
  1034. tools/feishu_drive_tool.py +431 -0
  1035. tools/file_operations.py +2514 -0
  1036. tools/file_state.py +332 -0
  1037. tools/file_tools.py +1952 -0
  1038. tools/fuzzy_match.py +950 -0
  1039. tools/golden_path.py +371 -0
  1040. tools/homeassistant_tool.py +513 -0
  1041. tools/hook_output_spill.py +236 -0
  1042. tools/identity_scan.py +243 -0
  1043. tools/image_generation_tool.py +1668 -0
  1044. tools/image_source.py +338 -0
  1045. tools/interrupt.py +113 -0
  1046. tools/kanban_tools.py +1681 -0
  1047. tools/kernel_binding.py +1255 -0
  1048. tools/lazy_deps.py +970 -0
  1049. tools/live_commit_attestation.py +303 -0
  1050. tools/locale_contract.py +223 -0
  1051. tools/machine_contracts.py +332 -0
  1052. tools/managed_tool_gateway.py +192 -0
  1053. tools/mcp_capability_matrix.py +83 -0
  1054. tools/mcp_oauth.py +948 -0
  1055. tools/mcp_oauth_manager.py +720 -0
  1056. tools/mcp_stdio_watchdog.py +184 -0
  1057. tools/mcp_tool.py +5832 -0
  1058. tools/memory_tool.py +1153 -0
  1059. tools/microsoft_graph_auth.py +245 -0
  1060. tools/microsoft_graph_client.py +408 -0
  1061. tools/namespace_identity_audit.py +524 -0
  1062. tools/neutts_synth.py +104 -0
  1063. tools/openrouter_client.py +33 -0
  1064. tools/osv_check.py +169 -0
  1065. tools/patch_parser.py +637 -0
  1066. tools/path_security.py +43 -0
  1067. tools/perf_gate/__init__.py +12 -0
  1068. tools/perf_gate/bootstrap_baseline.py +62 -0
  1069. tools/perf_gate/compare.py +163 -0
  1070. tools/perf_gate/runner.py +95 -0
  1071. tools/perf_integration_manifest.py +814 -0
  1072. tools/process_registry.py +2329 -0
  1073. tools/project_tools.py +189 -0
  1074. tools/promotion_controller.py +471 -0
  1075. tools/prompt_microkernel_integration_receipt.py +144 -0
  1076. tools/public_docs_audit.py +563 -0
  1077. tools/read_extract.py +248 -0
  1078. tools/read_terminal_tool.py +94 -0
  1079. tools/registry.py +821 -0
  1080. tools/release_gate.py +897 -0
  1081. tools/release_gate_scan.py +494 -0
  1082. tools/release_handoff.py +107 -0
  1083. tools/release_manifest.py +202 -0
  1084. tools/rename_guard/__init__.py +7 -0
  1085. tools/rename_guard/artifact_scan.py +257 -0
  1086. tools/rename_guard/bootstrap_baseline.py +78 -0
  1087. tools/rename_guard/scanner.py +188 -0
  1088. tools/runtime_handshake.py +256 -0
  1089. tools/runtime_lifecycle.py +589 -0
  1090. tools/runtime_lock_contract.py +212 -0
  1091. tools/runtime_manager.py +1084 -0
  1092. tools/schema_sanitizer.py +501 -0
  1093. tools/self_mutation_kernel.py +298 -0
  1094. tools/send_message_tool.py +1965 -0
  1095. tools/session_search_tool.py +923 -0
  1096. tools/shadow_effects.py +601 -0
  1097. tools/simplicio_bridge.py +716 -0
  1098. tools/simplicio_transport.py +680 -0
  1099. tools/skill_manager_tool.py +1559 -0
  1100. tools/skill_provenance.py +78 -0
  1101. tools/skill_usage.py +947 -0
  1102. tools/skills_ast_audit.py +133 -0
  1103. tools/skills_guard.py +1153 -0
  1104. tools/skills_hub.py +4071 -0
  1105. tools/skills_sync.py +1182 -0
  1106. tools/skills_tool.py +1760 -0
  1107. tools/slash_confirm.py +167 -0
  1108. tools/software_builder_manifest.py +349 -0
  1109. tools/terminal_tool.py +3062 -0
  1110. tools/thread_context.py +120 -0
  1111. tools/threat_patterns.py +284 -0
  1112. tools/tirith_security.py +871 -0
  1113. tools/todo_tool.py +403 -0
  1114. tools/tool_backend_helpers.py +182 -0
  1115. tools/tool_output_limits.py +110 -0
  1116. tools/tool_result_storage.py +254 -0
  1117. tools/tool_search.py +735 -0
  1118. tools/transaction_primitives.py +1085 -0
  1119. tools/transcription_tools.py +1893 -0
  1120. tools/tts_tool.py +3152 -0
  1121. tools/url_safety.py +503 -0
  1122. tools/video_generation_tool.py +575 -0
  1123. tools/vision_tools.py +1897 -0
  1124. tools/voice_mode.py +1218 -0
  1125. tools/wake_word.py +182 -0
  1126. tools/watcher_gate.py +481 -0
  1127. tools/web_tools.py +1240 -0
  1128. tools/website_policy.py +283 -0
  1129. tools/write_approval.py +493 -0
  1130. tools/x_search_tool.py +525 -0
  1131. tools/xai_http.py +277 -0
  1132. tools/xai_video_tools.py +209 -0
  1133. tools/yuanbao_tools.py +737 -0
  1134. toolset_distributions.py +358 -0
  1135. toolsets.py +971 -0
  1136. trajectory_compressor.py +1574 -0
  1137. tui_gateway/__init__.py +0 -0
  1138. tui_gateway/entry.py +381 -0
  1139. tui_gateway/event_publisher.py +126 -0
  1140. tui_gateway/git_probe.py +193 -0
  1141. tui_gateway/loop_noise.py +83 -0
  1142. tui_gateway/project_tree.py +640 -0
  1143. tui_gateway/render.py +49 -0
  1144. tui_gateway/server.py +14516 -0
  1145. tui_gateway/slash_worker.py +179 -0
  1146. tui_gateway/transport.py +219 -0
  1147. tui_gateway/ws.py +466 -0
  1148. utils.py +546 -0
@@ -0,0 +1 @@
1
+ """ACP (Agent Communication Protocol) adapter for hermes-agent."""
@@ -0,0 +1,5 @@
1
+ """Allow running the ACP adapter as ``python -m acp_adapter``."""
2
+
3
+ from .entry import main
4
+
5
+ main()
acp_adapter/auth.py ADDED
@@ -0,0 +1,79 @@
1
+ """ACP auth helpers — detect and advertise Hermes authentication methods."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Optional
6
+
7
+
8
+ TERMINAL_SETUP_AUTH_METHOD_ID = "hermes-setup"
9
+
10
+
11
+ def detect_provider() -> Optional[str]:
12
+ """Resolve the active Hermes runtime provider, or None if unavailable.
13
+
14
+ Treats a ``Callable`` ``api_key`` (Azure Foundry Entra ID bearer
15
+ token provider — see :mod:`agent.azure_identity_adapter`) as a valid
16
+ credential. Without this, ACP sessions for Entra-configured Foundry
17
+ deployments silently default to ``"openrouter"`` and the ACP auth
18
+ handshake rejects the legitimate provider.
19
+ """
20
+ try:
21
+ from hermes_cli.runtime_provider import resolve_runtime_provider
22
+ runtime = resolve_runtime_provider()
23
+ api_key = runtime.get("api_key")
24
+ provider = runtime.get("provider")
25
+ if not isinstance(provider, str) or not provider.strip():
26
+ return None
27
+ is_string_key = isinstance(api_key, str) and api_key.strip()
28
+ is_callable_provider = callable(api_key) and not isinstance(api_key, str)
29
+ if is_string_key or is_callable_provider:
30
+ return provider.strip().lower()
31
+ except Exception:
32
+ return None
33
+ return None
34
+
35
+
36
+ def has_provider() -> bool:
37
+ """Return True if Hermes can resolve any runtime provider credentials."""
38
+ return detect_provider() is not None
39
+
40
+
41
+ def build_auth_methods() -> list[Any]:
42
+ """Return registry-compatible ACP auth methods for Hermes.
43
+
44
+ The official ACP registry validates that agents advertise at least one
45
+ usable auth method during the initial handshake. A fresh Zed install may
46
+ not have Hermes provider credentials configured yet, so Hermes always
47
+ advertises a terminal setup method. When credentials are already present,
48
+ it also advertises the resolved provider as the default agent-managed
49
+ runtime credential method.
50
+ """
51
+ from acp.schema import AuthMethodAgent, TerminalAuthMethod
52
+
53
+ methods: list[Any] = []
54
+ provider = detect_provider()
55
+ if provider:
56
+ methods.append(
57
+ AuthMethodAgent(
58
+ id=provider,
59
+ name=f"{provider} runtime credentials",
60
+ description=(
61
+ "Authenticate Hermes using the currently configured "
62
+ f"{provider} runtime credentials."
63
+ ),
64
+ )
65
+ )
66
+
67
+ methods.append(
68
+ TerminalAuthMethod(
69
+ id=TERMINAL_SETUP_AUTH_METHOD_ID,
70
+ name="Configure Hermes provider",
71
+ description=(
72
+ "Open Hermes' interactive model/provider setup in a terminal. "
73
+ "Use this when Hermes has not been configured on this machine yet."
74
+ ),
75
+ type="terminal",
76
+ args=["--setup"],
77
+ )
78
+ )
79
+ return methods
@@ -0,0 +1,338 @@
1
+ """Pre-execution ACP edit approval helpers.
2
+
3
+ This module is intentionally isolated from the generic tool registry. ACP binds
4
+ an edit approval requester in a ContextVar for the duration of one ACP agent run;
5
+ CLI, gateway, and other sessions leave it unset and therefore bypass this guard.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import asyncio
11
+ import json
12
+ import logging
13
+ import re
14
+ import tempfile
15
+ from concurrent.futures import TimeoutError as FutureTimeout
16
+ from contextvars import ContextVar, Token
17
+ from dataclasses import dataclass
18
+ from itertools import count
19
+ from pathlib import Path
20
+ from typing import Any, Callable
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class EditProposal:
27
+ """A proposed single-file edit that can be shown to an ACP client."""
28
+
29
+ tool_name: str
30
+ path: str
31
+ old_text: str | None
32
+ new_text: str
33
+ arguments: dict[str, Any]
34
+
35
+
36
+ EditApprovalRequester = Callable[[EditProposal], bool]
37
+
38
+ _EDIT_APPROVAL_REQUESTER: ContextVar[EditApprovalRequester | None] = ContextVar(
39
+ "ACP_EDIT_APPROVAL_REQUESTER",
40
+ default=None,
41
+ )
42
+ _PERMISSION_REQUEST_IDS = count(1)
43
+
44
+
45
+ SENSITIVE_AUTO_APPROVE_NAMES = {".env", ".env.local", ".env.production", "id_rsa", "id_ed25519"}
46
+ AUTO_APPROVE_ASK = "ask"
47
+ AUTO_APPROVE_WORKSPACE = "workspace_session"
48
+ AUTO_APPROVE_SESSION = "session"
49
+
50
+
51
+ def set_edit_approval_requester(requester: EditApprovalRequester | None) -> Token:
52
+ """Bind an ACP edit approval requester for the current context."""
53
+
54
+ return _EDIT_APPROVAL_REQUESTER.set(requester)
55
+
56
+
57
+ def reset_edit_approval_requester(token: Token) -> None:
58
+ """Restore a previous edit approval requester binding."""
59
+
60
+ _EDIT_APPROVAL_REQUESTER.reset(token)
61
+
62
+
63
+ def clear_edit_approval_requester() -> None:
64
+ """Clear the current requester; primarily used by tests."""
65
+
66
+ _EDIT_APPROVAL_REQUESTER.set(None)
67
+
68
+
69
+ def get_edit_approval_requester() -> EditApprovalRequester | None:
70
+ return _EDIT_APPROVAL_REQUESTER.get()
71
+
72
+
73
+ def _read_text_if_exists(path: str) -> str | None:
74
+ p = Path(path).expanduser()
75
+ if not p.exists():
76
+ return None
77
+ if not p.is_file():
78
+ raise OSError(f"Cannot edit non-file path: {path}")
79
+ return p.read_text(encoding="utf-8", errors="replace")
80
+
81
+
82
+ def _proposal_for_write_file(arguments: dict[str, Any]) -> EditProposal:
83
+ path = str(arguments.get("path") or "")
84
+ if not path:
85
+ raise ValueError("path required")
86
+ content = arguments.get("content")
87
+ if content is None:
88
+ raise ValueError("content required")
89
+ return EditProposal(
90
+ tool_name="write_file",
91
+ path=path,
92
+ old_text=_read_text_if_exists(path),
93
+ new_text=str(content),
94
+ arguments=dict(arguments),
95
+ )
96
+
97
+
98
+ def _proposal_for_patch_replace(arguments: dict[str, Any]) -> EditProposal:
99
+ path = str(arguments.get("path") or "")
100
+ if not path:
101
+ raise ValueError("path required")
102
+ old_string = arguments.get("old_string")
103
+ new_string = arguments.get("new_string")
104
+ if old_string is None or new_string is None:
105
+ raise ValueError("old_string and new_string required")
106
+
107
+ old_text = _read_text_if_exists(path)
108
+ if old_text is None:
109
+ raise ValueError(f"Failed to read file: {path}")
110
+
111
+ from tools.fuzzy_match import fuzzy_find_and_replace
112
+
113
+ new_text, match_count, _strategy, error = fuzzy_find_and_replace(
114
+ old_text,
115
+ str(old_string),
116
+ str(new_string),
117
+ bool(arguments.get("replace_all", False)),
118
+ )
119
+ if error or match_count == 0:
120
+ raise ValueError(error or f"Could not find match for old_string in {path}")
121
+
122
+ return EditProposal(
123
+ tool_name="patch",
124
+ path=path,
125
+ old_text=old_text,
126
+ new_text=new_text,
127
+ arguments=dict(arguments),
128
+ )
129
+
130
+
131
+ def _extract_v4a_patch_paths(patch_body: str) -> list[str]:
132
+ paths: list[str] = []
133
+ for match in re.finditer(
134
+ r'^\*\*\*\s+(?:Update|Add|Delete)\s+File:\s*(.+)$',
135
+ patch_body,
136
+ re.MULTILINE,
137
+ ):
138
+ path = match.group(1).strip()
139
+ if path:
140
+ paths.append(path)
141
+ for match in re.finditer(
142
+ r'^\*\*\*\s+Move\s+File:\s*(.+?)\s*->\s*(.+)$',
143
+ patch_body,
144
+ re.MULTILINE,
145
+ ):
146
+ src = match.group(1).strip()
147
+ dst = match.group(2).strip()
148
+ if src:
149
+ paths.append(src)
150
+ if dst:
151
+ paths.append(dst)
152
+ return paths
153
+
154
+
155
+ def _proposal_for_patch_v4a(arguments: dict[str, Any]) -> EditProposal:
156
+ patch_body = arguments.get("patch")
157
+ if not isinstance(patch_body, str) or not patch_body:
158
+ raise ValueError("patch content required")
159
+
160
+ paths = _extract_v4a_patch_paths(patch_body)
161
+ if not paths:
162
+ raise ValueError("no file paths found in V4A patch")
163
+
164
+ proposal_path = paths[0] if len(paths) == 1 else ", ".join(paths)
165
+ old_text = _read_text_if_exists(paths[0]) if len(paths) == 1 else None
166
+ return EditProposal(
167
+ tool_name="patch",
168
+ path=proposal_path,
169
+ old_text=old_text,
170
+ # ACP only supports a single diff payload here. Surface the exact V4A
171
+ # patch content before execution so patch-mode calls are permissioned
172
+ # and denied patches cannot mutate.
173
+ new_text=patch_body,
174
+ arguments=dict(arguments),
175
+ )
176
+
177
+
178
+ def build_edit_proposal(tool_name: str, arguments: dict[str, Any]) -> EditProposal | None:
179
+ """Return an edit proposal for supported file mutation calls."""
180
+
181
+ if tool_name == "write_file":
182
+ return _proposal_for_write_file(arguments)
183
+ if tool_name == "patch":
184
+ mode = arguments.get("mode", "replace")
185
+ if mode == "replace":
186
+ return _proposal_for_patch_replace(arguments)
187
+ if mode == "patch":
188
+ return _proposal_for_patch_v4a(arguments)
189
+ return None
190
+
191
+
192
+ def _is_sensitive_auto_approve_path(path: str) -> bool:
193
+ parts = Path(path).expanduser().parts
194
+ lowered = {part.lower() for part in parts}
195
+ if ".git" in lowered or ".ssh" in lowered:
196
+ return True
197
+ return Path(path).name.lower() in SENSITIVE_AUTO_APPROVE_NAMES
198
+
199
+
200
+ def should_auto_approve_edit(proposal: EditProposal, policy: str, cwd: str | None = None) -> bool:
201
+ """Return whether an ACP edit proposal may bypass the prompt for this session.
202
+
203
+ This is intentionally session-scoped and conservative: sensitive paths still
204
+ ask even under autonomous policies.
205
+ """
206
+
207
+ policy = str(policy or AUTO_APPROVE_ASK).strip()
208
+ if policy == AUTO_APPROVE_ASK or _is_sensitive_auto_approve_path(proposal.path):
209
+ return False
210
+ path = Path(proposal.path).expanduser().resolve(strict=False)
211
+ if policy == AUTO_APPROVE_SESSION:
212
+ return True
213
+ if policy == AUTO_APPROVE_WORKSPACE:
214
+ # `/tmp` is the POSIX path but tempfile.gettempdir() is the real one on
215
+ # every platform: `/private/tmp` on macOS (because `/tmp` is a symlink
216
+ # and Path.resolve() follows it) and the per-user Temp dir on Windows.
217
+ tmp_root = Path(tempfile.gettempdir()).resolve(strict=False)
218
+ try:
219
+ path.relative_to(tmp_root)
220
+ return True
221
+ except ValueError:
222
+ pass
223
+ if cwd:
224
+ root = Path(cwd).expanduser().resolve(strict=False)
225
+ try:
226
+ path.relative_to(root)
227
+ return True
228
+ except ValueError:
229
+ return False
230
+ return False
231
+
232
+
233
+ def maybe_require_edit_approval(tool_name: str, arguments: dict[str, Any]) -> str | None:
234
+ """Run ACP edit approval if bound.
235
+
236
+ Returns a JSON tool-error string when the edit must be blocked, otherwise
237
+ ``None`` so dispatch can continue. Requester exceptions deny by default.
238
+ """
239
+
240
+ requester = get_edit_approval_requester()
241
+ if requester is None:
242
+ return None
243
+
244
+ try:
245
+ proposal = build_edit_proposal(tool_name, arguments)
246
+ except Exception as exc:
247
+ logger.warning("Could not build ACP edit approval proposal for %s: %s", tool_name, exc)
248
+ return json.dumps({"error": f"Edit approval denied: could not prepare diff ({exc})"}, ensure_ascii=False)
249
+
250
+ if proposal is None:
251
+ return None
252
+
253
+ try:
254
+ approved = bool(requester(proposal))
255
+ except Exception as exc:
256
+ logger.warning("ACP edit approval requester failed: %s", exc)
257
+ approved = False
258
+
259
+ if approved:
260
+ return None
261
+ return json.dumps({"error": "Edit approval denied by ACP client; file was not modified."}, ensure_ascii=False)
262
+
263
+
264
+ def build_acp_edit_tool_call(proposal: EditProposal):
265
+ """Build the ToolCallUpdate payload for ACP request_permission."""
266
+
267
+ import acp
268
+
269
+ tool_call_id = f"edit-approval-{next(_PERMISSION_REQUEST_IDS)}"
270
+ return acp.update_tool_call(
271
+ tool_call_id,
272
+ title=f"Approve edit: {proposal.path}",
273
+ kind="edit",
274
+ status="pending",
275
+ content=[
276
+ acp.tool_diff_content(
277
+ path=proposal.path,
278
+ old_text=proposal.old_text,
279
+ new_text=proposal.new_text,
280
+ )
281
+ ],
282
+ raw_input={"tool": proposal.tool_name, "arguments": proposal.arguments},
283
+ )
284
+
285
+
286
+ def make_acp_edit_approval_requester(
287
+ request_permission_fn: Callable,
288
+ loop: asyncio.AbstractEventLoop,
289
+ session_id: str,
290
+ timeout: float = 60.0,
291
+ auto_approve_getter: Callable[[], tuple[str, str | None]] | None = None,
292
+ ) -> EditApprovalRequester:
293
+ """Return a sync requester that bridges edit proposals to ACP permissions."""
294
+
295
+ def _requester(proposal: EditProposal) -> bool:
296
+ from acp.schema import PermissionOption
297
+ from agent.async_utils import safe_schedule_threadsafe
298
+
299
+ if auto_approve_getter is not None:
300
+ try:
301
+ policy, cwd = auto_approve_getter()
302
+ if should_auto_approve_edit(proposal, policy, cwd):
303
+ logger.info("Auto-approved ACP edit under policy %s: %s", policy, proposal.path)
304
+ return True
305
+ except Exception:
306
+ logger.debug("ACP edit auto-approval policy check failed", exc_info=True)
307
+
308
+ options = [
309
+ PermissionOption(option_id="allow_once", kind="allow_once", name="Allow edit"),
310
+ PermissionOption(option_id="deny", kind="reject_once", name="Deny"),
311
+ ]
312
+ tool_call = build_acp_edit_tool_call(proposal)
313
+ coro = request_permission_fn(
314
+ session_id=session_id,
315
+ tool_call=tool_call,
316
+ options=options,
317
+ )
318
+ future = safe_schedule_threadsafe(
319
+ coro,
320
+ loop,
321
+ logger=logger,
322
+ log_message="Edit approval request: failed to schedule on loop",
323
+ )
324
+ if future is None:
325
+ return False
326
+ try:
327
+ response = future.result(timeout=timeout)
328
+ except (FutureTimeout, Exception) as exc:
329
+ future.cancel()
330
+ logger.warning("Edit approval request timed out or failed: %s", exc)
331
+ return False
332
+ outcome = getattr(response, "outcome", None)
333
+ return (
334
+ getattr(outcome, "outcome", None) == "selected"
335
+ and getattr(outcome, "option_id", None) == "allow_once"
336
+ )
337
+
338
+ return _requester
acp_adapter/entry.py ADDED
@@ -0,0 +1,280 @@
1
+ """CLI entry point for the hermes-agent ACP adapter.
2
+
3
+ Loads environment variables from ``~/.hermes/.env``, configures logging
4
+ to write to stderr (so stdout is reserved for ACP JSON-RPC transport),
5
+ and starts the ACP agent server.
6
+
7
+ Usage::
8
+
9
+ python -m acp_adapter.entry
10
+ # or
11
+ simplicio-agent acp
12
+ # or
13
+ hermes-acp
14
+ """
15
+
16
+ # IMPORTANT: hermes_bootstrap must be the very first import — UTF-8 stdio
17
+ # on Windows. No-op on POSIX. See hermes_bootstrap.py for full rationale.
18
+ try:
19
+ import hermes_bootstrap # noqa: F401
20
+ except ModuleNotFoundError:
21
+ # Graceful fallback when hermes_bootstrap isn't registered in the venv
22
+ # yet — happens during partial ``simplicio-agent update`` where git-reset landed
23
+ # new code but ``uv pip install -e .`` didn't finish. Missing bootstrap
24
+ # means UTF-8 stdio setup is skipped on Windows; POSIX is unaffected.
25
+ pass
26
+ else:
27
+ # Stop a ``utils/``/``proxy/``/``ui/`` package in the launch directory from
28
+ # shadowing Hermes's own modules — ``simplicio-agent acp`` can be started from any
29
+ # cwd, including a project that has same-named packages on its path.
30
+ hermes_bootstrap.harden_import_path()
31
+
32
+ import argparse
33
+ import asyncio
34
+ import logging
35
+ import sys
36
+ from pathlib import Path
37
+ from hermes_constants import get_hermes_home
38
+
39
+
40
+ # Methods clients send as periodic liveness probes. They are not part of the
41
+ # ACP schema, so the acp router correctly returns JSON-RPC -32601 to the
42
+ # caller — but the supervisor task that dispatches the request then surfaces
43
+ # the raised RequestError via ``logging.exception("Background task failed")``,
44
+ # which dumps a traceback to stderr every probe interval. Clients like
45
+ # acp-bridge already treat the -32601 response as "agent alive", so the
46
+ # traceback is pure noise. We keep the protocol response intact and only
47
+ # silence the stderr noise for this specific benign case.
48
+ _BENIGN_PROBE_METHODS = frozenset({"ping", "health", "healthcheck"})
49
+
50
+
51
+ class _BenignProbeMethodFilter(logging.Filter):
52
+ """Suppress acp 'Background task failed' tracebacks caused by unknown
53
+ liveness-probe methods (e.g. ``ping``) while leaving every other
54
+ background-task error — including method_not_found for any non-probe
55
+ method — visible in stderr.
56
+ """
57
+
58
+ def filter(self, record: logging.LogRecord) -> bool:
59
+ if record.getMessage() != "Background task failed":
60
+ return True
61
+ exc_info = record.exc_info
62
+ if not exc_info:
63
+ return True
64
+ exc = exc_info[1]
65
+ # Imported lazily so this module stays importable when the optional
66
+ # ``agent-client-protocol`` dependency is not installed.
67
+ try:
68
+ from acp.exceptions import RequestError
69
+ except ImportError:
70
+ return True
71
+ if not isinstance(exc, RequestError):
72
+ return True
73
+ if getattr(exc, "code", None) != -32601:
74
+ return True
75
+ data = getattr(exc, "data", None)
76
+ method = data.get("method") if isinstance(data, dict) else None
77
+ return method not in _BENIGN_PROBE_METHODS
78
+
79
+
80
+ def _setup_logging() -> None:
81
+ """Route all logging to stderr so stdout stays clean for ACP stdio."""
82
+ handler = logging.StreamHandler(sys.stderr)
83
+ handler.setFormatter(
84
+ logging.Formatter(
85
+ "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
86
+ datefmt="%Y-%m-%d %H:%M:%S",
87
+ )
88
+ )
89
+ handler.addFilter(_BenignProbeMethodFilter())
90
+ root = logging.getLogger()
91
+ root.handlers.clear()
92
+ root.addHandler(handler)
93
+ root.setLevel(logging.INFO)
94
+
95
+ # Quiet down noisy libraries
96
+ logging.getLogger("httpx").setLevel(logging.WARNING)
97
+ logging.getLogger("httpcore").setLevel(logging.WARNING)
98
+ logging.getLogger("openai").setLevel(logging.WARNING)
99
+
100
+
101
+ def _load_env() -> None:
102
+ """Load .env from HERMES_HOME (default ``~/.hermes``)."""
103
+ from hermes_cli.env_loader import load_hermes_dotenv
104
+
105
+ hermes_home = get_hermes_home()
106
+ loaded = load_hermes_dotenv(hermes_home=hermes_home)
107
+ if loaded:
108
+ for env_file in loaded:
109
+ logging.getLogger(__name__).info("Loaded env from %s", env_file)
110
+ else:
111
+ logging.getLogger(__name__).info(
112
+ "No .env found at %s, using system env", hermes_home / ".env"
113
+ )
114
+
115
+
116
+ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
117
+ parser = argparse.ArgumentParser(
118
+ prog="hermes-acp",
119
+ description="Run Hermes Agent as an ACP stdio server.",
120
+ )
121
+ parser.add_argument("--version", action="store_true", help="Print Hermes version and exit")
122
+ parser.add_argument(
123
+ "--check",
124
+ action="store_true",
125
+ help="Verify ACP dependencies and adapter imports, then exit",
126
+ )
127
+ parser.add_argument(
128
+ "--setup",
129
+ action="store_true",
130
+ help="Run interactive Hermes provider/model setup for ACP terminal auth",
131
+ )
132
+ parser.add_argument(
133
+ "--setup-browser",
134
+ action="store_true",
135
+ help="Install agent-browser + Playwright Chromium into ~/.hermes/node/ "
136
+ "for browser tool support. Idempotent.",
137
+ )
138
+ parser.add_argument(
139
+ "--yes",
140
+ "-y",
141
+ action="store_true",
142
+ dest="assume_yes",
143
+ help="Accept all prompts (currently used by --setup-browser to skip the "
144
+ "~400 MB Chromium download confirmation).",
145
+ )
146
+ return parser.parse_args(argv)
147
+
148
+
149
+ def _print_version() -> None:
150
+ from hermes_cli import __version__ as hermes_version
151
+
152
+ print(hermes_version)
153
+
154
+
155
+ def _run_check() -> None:
156
+ import acp # noqa: F401
157
+ from acp_adapter.server import HermesACPAgent # noqa: F401
158
+
159
+ print("Hermes ACP check OK")
160
+
161
+
162
+ def _run_setup() -> None:
163
+ from hermes_cli.main import main as hermes_main
164
+
165
+ old_argv = sys.argv[:]
166
+ try:
167
+ sys.argv = [old_argv[0] if old_argv else "hermes", "model"]
168
+ hermes_main()
169
+ finally:
170
+ sys.argv = old_argv
171
+
172
+ # Offer browser-tools install as a follow-up. The terminal auth method
173
+ # is the one supported first-run UX for registry installs, so this is
174
+ # the natural moment to ask. Skip silently if stdin isn't a TTY (the
175
+ # answer can't be collected anyway).
176
+ if not sys.stdin.isatty():
177
+ return
178
+ try:
179
+ reply = input(
180
+ "\nInstall browser tools? Downloads agent-browser (npm) and "
181
+ "optionally Playwright Chromium (~400 MB). [y/N] "
182
+ ).strip().lower()
183
+ except (EOFError, KeyboardInterrupt):
184
+ return
185
+ if reply in {"y", "yes"}:
186
+ _run_setup_browser(assume_yes=False)
187
+
188
+
189
+ def _run_setup_browser(assume_yes: bool = False) -> int:
190
+ """Bootstrap agent-browser + Chromium.
191
+
192
+ Routes through dep_ensure -> install.{sh,ps1} --ensure, sharing code
193
+ with ``hermes postinstall`` and the runtime lazy installer.
194
+
195
+ Returns 0 on success, 1 on failure.
196
+ """
197
+ from hermes_cli.dep_ensure import ensure_dependency
198
+
199
+ try:
200
+ node_ok = ensure_dependency("node", interactive=not assume_yes)
201
+ if not node_ok:
202
+ print("Node.js installation failed — cannot proceed with browser tools.",
203
+ file=sys.stderr)
204
+ return 1
205
+
206
+ browser_ok = ensure_dependency("browser", interactive=not assume_yes)
207
+ if not browser_ok:
208
+ print("Browser tools installation failed.", file=sys.stderr)
209
+ return 1
210
+
211
+ return 0
212
+ except OSError as exc:
213
+ print(f"Browser bootstrap failed: {exc}", file=sys.stderr)
214
+ return 1
215
+
216
+
217
+ def main(argv: list[str] | None = None) -> None:
218
+ """Entry point: load env, configure logging, run the ACP agent."""
219
+ args = _parse_args(argv)
220
+ if args.version:
221
+ _print_version()
222
+ return
223
+ if args.check:
224
+ _run_check()
225
+ return
226
+ if args.setup:
227
+ _run_setup()
228
+ return
229
+ if args.setup_browser:
230
+ rc = _run_setup_browser(assume_yes=args.assume_yes)
231
+ if rc != 0:
232
+ sys.exit(rc)
233
+ return
234
+
235
+ _setup_logging()
236
+ _load_env()
237
+
238
+ logger = logging.getLogger(__name__)
239
+ logger.info("Starting hermes-agent ACP adapter")
240
+
241
+ # Ensure the project root is on sys.path so ``from run_agent import AIAgent`` works
242
+ project_root = str(Path(__file__).resolve().parent.parent)
243
+ if project_root not in sys.path:
244
+ sys.path.insert(0, project_root)
245
+
246
+ import acp
247
+ from .server import HermesACPAgent
248
+
249
+ # MCP tool discovery from config.yaml — run before asyncio.run() so
250
+ # it's safe to use blocking waits. (ACP also registers per-session
251
+ # MCP servers dynamically via asyncio.to_thread inside the event
252
+ # loop; that path is unaffected.) Moved from model_tools.py module
253
+ # scope to avoid freezing the gateway's loop on lazy import (#16856).
254
+ try:
255
+ from tools.mcp_tool import discover_mcp_tools
256
+ discover_mcp_tools()
257
+ except Exception:
258
+ logger.debug("MCP tool discovery failed at ACP startup", exc_info=True)
259
+
260
+ agent = HermesACPAgent()
261
+ # Install the faster uvloop event-loop policy when available (no-op on
262
+ # Windows or when the optional dep isn't installed). Must run before the
263
+ # loop is created by asyncio.run(). See agent/uvloop_utils.py.
264
+ try:
265
+ from agent.uvloop_utils import install_uvloop_policy
266
+
267
+ install_uvloop_policy()
268
+ except Exception:
269
+ pass
270
+ try:
271
+ asyncio.run(acp.run_agent(agent, use_unstable_protocol=True))
272
+ except KeyboardInterrupt:
273
+ logger.info("Shutting down (KeyboardInterrupt)")
274
+ except Exception:
275
+ logger.exception("ACP agent crashed")
276
+ sys.exit(1)
277
+
278
+
279
+ if __name__ == "__main__":
280
+ main()