polyrob 0.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 (745) hide show
  1. agents/README.md +453 -0
  2. agents/__init__.py +164 -0
  3. agents/base_agent.py +743 -0
  4. agents/personality/character.py +119 -0
  5. agents/personality/character_manager.py +309 -0
  6. agents/personality/characters/rob.character.json +56 -0
  7. agents/personality/characters/trump.character.json +63 -0
  8. agents/personality/persona_render.py +78 -0
  9. agents/personality/persona_resolver.py +115 -0
  10. agents/prompt/__init__.py +58 -0
  11. agents/prompt/base_prompt.py +92 -0
  12. agents/prompt/system.py +417 -0
  13. agents/task/README_PATH_MANAGEMENT.md +141 -0
  14. agents/task/__init__.py +162 -0
  15. agents/task/agent/__init__.py +70 -0
  16. agents/task/agent/agent_state.py +408 -0
  17. agents/task/agent/async_delegation.py +274 -0
  18. agents/task/agent/autonomy_state.py +275 -0
  19. agents/task/agent/conversation.py +75 -0
  20. agents/task/agent/core/__init__.py +6 -0
  21. agents/task/agent/core/aux_metering.py +61 -0
  22. agents/task/agent/core/background_review.py +157 -0
  23. agents/task/agent/core/construction.py +1179 -0
  24. agents/task/agent/core/conversational_exit.py +49 -0
  25. agents/task/agent/core/correspondent_gate.py +227 -0
  26. agents/task/agent/core/curator.py +246 -0
  27. agents/task/agent/core/episodic_digest.py +103 -0
  28. agents/task/agent/core/error_recovery.py +480 -0
  29. agents/task/agent/core/history_io.py +257 -0
  30. agents/task/agent/core/llm_provisioning.py +287 -0
  31. agents/task/agent/core/llm_runner.py +547 -0
  32. agents/task/agent/core/logging_io.py +276 -0
  33. agents/task/agent/core/loop_detection.py +262 -0
  34. agents/task/agent/core/memory_prefetch.py +325 -0
  35. agents/task/agent/core/memory_writer.py +667 -0
  36. agents/task/agent/core/model_introspection.py +82 -0
  37. agents/task/agent/core/model_swap.py +177 -0
  38. agents/task/agent/core/next_action_internal.py +1331 -0
  39. agents/task/agent/core/output_validation.py +303 -0
  40. agents/task/agent/core/project_context.py +272 -0
  41. agents/task/agent/core/resources.py +93 -0
  42. agents/task/agent/core/result_processing.py +389 -0
  43. agents/task/agent/core/run_loop.py +661 -0
  44. agents/task/agent/core/safety_lifecycle.py +228 -0
  45. agents/task/agent/core/secret_guard.py +293 -0
  46. agents/task/agent/core/self_wake.py +280 -0
  47. agents/task/agent/core/session_metadata.py +104 -0
  48. agents/task/agent/core/step.py +781 -0
  49. agents/task/agent/core/step_execution.py +398 -0
  50. agents/task/agent/core/step_telemetry.py +222 -0
  51. agents/task/agent/core/test_aux_metering.py +50 -0
  52. agents/task/agent/core/test_billing_failover.py +68 -0
  53. agents/task/agent/core/test_fatal_error_classifier.py +38 -0
  54. agents/task/agent/core/test_judge_validation.py +275 -0
  55. agents/task/agent/core/test_model_swap.py +190 -0
  56. agents/task/agent/core/test_reflection_offload.py +54 -0
  57. agents/task/agent/core/turn_input.py +8 -0
  58. agents/task/agent/core/untrusted_wrap.py +103 -0
  59. agents/task/agent/core/user_ingress.py +228 -0
  60. agents/task/agent/hitl_manager.py +396 -0
  61. agents/task/agent/log_sanitize.py +36 -0
  62. agents/task/agent/message_manager/config.py +97 -0
  63. agents/task/agent/message_manager/service.py +758 -0
  64. agents/task/agent/message_manager/tests.py +305 -0
  65. agents/task/agent/message_manager/tool_call_builder.py +539 -0
  66. agents/task/agent/message_manager/tool_message_repair.py +364 -0
  67. agents/task/agent/message_manager/views.py +143 -0
  68. agents/task/agent/messages/__init__.py +8 -0
  69. agents/task/agent/messages/builders.py +309 -0
  70. agents/task/agent/messages/compactor.py +611 -0
  71. agents/task/agent/messages/context_references.py +271 -0
  72. agents/task/agent/messages/filters.py +333 -0
  73. agents/task/agent/messages/guidance.py +328 -0
  74. agents/task/agent/messages/persistence.py +448 -0
  75. agents/task/agent/messages/retrieval.py +506 -0
  76. agents/task/agent/messages/sqlite_persistence.py +85 -0
  77. agents/task/agent/messages/test_compaction_upgrade.py +349 -0
  78. agents/task/agent/messages/test_persistence_subdir_fix.py +28 -0
  79. agents/task/agent/messages/test_sqlite_persistence.py +54 -0
  80. agents/task/agent/messages/token_counter.py +532 -0
  81. agents/task/agent/orchestrator.py +776 -0
  82. agents/task/agent/profile_manager.py +105 -0
  83. agents/task/agent/profile_registry.py +173 -0
  84. agents/task/agent/prompts.py +1090 -0
  85. agents/task/agent/scenario_registry.py +226 -0
  86. agents/task/agent/service.py +509 -0
  87. agents/task/agent/session.py +984 -0
  88. agents/task/agent/skill_discovery.py +110 -0
  89. agents/task/agent/skill_frontmatter.py +94 -0
  90. agents/task/agent/skill_manager.py +1201 -0
  91. agents/task/agent/skill_store.py +627 -0
  92. agents/task/agent/skill_validation.py +56 -0
  93. agents/task/agent/skill_writer.py +492 -0
  94. agents/task/agent/sub_agent_manager.py +1137 -0
  95. agents/task/agent/test_session_disk_recovery.py +34 -0
  96. agents/task/agent/tests.py +513 -0
  97. agents/task/agent/tool_call_tracker.py +511 -0
  98. agents/task/agent/views.py +469 -0
  99. agents/task/config.py +432 -0
  100. agents/task/constants.py +1384 -0
  101. agents/task/flag_defaults.py +63 -0
  102. agents/task/goals/__init__.py +1 -0
  103. agents/task/goals/autonomy_marker.py +28 -0
  104. agents/task/goals/board.py +690 -0
  105. agents/task/goals/completion_judge.py +247 -0
  106. agents/task/goals/context.py +62 -0
  107. agents/task/goals/dispatcher.py +848 -0
  108. agents/task/goals/escalation.py +102 -0
  109. agents/task/goals/planner.py +114 -0
  110. agents/task/logging_config.py +155 -0
  111. agents/task/path.py +991 -0
  112. agents/task/robust_parse_config.py +400 -0
  113. agents/task/runtime/__init__.py +0 -0
  114. agents/task/runtime/run_as_session.py +130 -0
  115. agents/task/runtime_safety.py +308 -0
  116. agents/task/session/__init__.py +5 -0
  117. agents/task/session/browser_pool.py +130 -0
  118. agents/task/session/cleanup.py +612 -0
  119. agents/task/session/execution.py +397 -0
  120. agents/task/session/feed.py +200 -0
  121. agents/task/session/hitl_ingress.py +201 -0
  122. agents/task/session/hooks.py +83 -0
  123. agents/task/session/multi_agent.py +243 -0
  124. agents/task/session/workspace.py +91 -0
  125. agents/task/session_registry.py +91 -0
  126. agents/task/session_route.py +35 -0
  127. agents/task/sqlite_session_registry.py +261 -0
  128. agents/task/surface_config.py +185 -0
  129. agents/task/telemetry/__init__.py +58 -0
  130. agents/task/telemetry/event_log.py +180 -0
  131. agents/task/telemetry/formatters.py +642 -0
  132. agents/task/telemetry/manager.py +571 -0
  133. agents/task/telemetry/memory_events.py +66 -0
  134. agents/task/telemetry/self_events.py +53 -0
  135. agents/task/telemetry/sequence.py +160 -0
  136. agents/task/telemetry/service.py +1265 -0
  137. agents/task/telemetry/views.py +882 -0
  138. agents/task/templates.py +98 -0
  139. agents/task/test_aux_chain.py +151 -0
  140. agents/task/test_aux_router.py +41 -0
  141. agents/task/tests/test_parse_robustness.py +170 -0
  142. agents/task/tool_defaults.py +110 -0
  143. agents/task/utils.py +762 -0
  144. agents/task/utils_json.py +768 -0
  145. agents/task/utils_webview.py +86 -0
  146. agents/task/workspace_context.py +229 -0
  147. agents/task_agent_lite.py +2398 -0
  148. api/README.md +683 -0
  149. api/TASK_API_DOCS.md +151 -0
  150. api/__init__.py +0 -0
  151. api/a2a/__init__.py +37 -0
  152. api/a2a/agent_card.py +337 -0
  153. api/a2a/client.py +657 -0
  154. api/a2a/endpoints.py +375 -0
  155. api/a2a/models.py +268 -0
  156. api/a2a/streaming.py +419 -0
  157. api/a2a/task_handler.py +929 -0
  158. api/admin_endpoints.py +1584 -0
  159. api/app.py +923 -0
  160. api/auth_constants.py +28 -0
  161. api/auth_endpoints.py +402 -0
  162. api/auth_state.py +36 -0
  163. api/chat_via_task.py +42 -0
  164. api/conversation_manager.py +231 -0
  165. api/dependencies.py +186 -0
  166. api/eip8004_endpoints.py +452 -0
  167. api/hyperliquid_models.py +174 -0
  168. api/hyperliquid_routes.py +450 -0
  169. api/interfaces.py +207 -0
  170. api/jwt_middleware.py +83 -0
  171. api/kb/__init__.py +1 -0
  172. api/kb/endpoints.py +314 -0
  173. api/mcp_models.py +279 -0
  174. api/mcp_routes.py +438 -0
  175. api/middleware.py +526 -0
  176. api/models.py +176 -0
  177. api/openai_compat/__init__.py +0 -0
  178. api/openai_compat/model_map.py +25 -0
  179. api/openai_compat/models.py +59 -0
  180. api/openai_compat/router.py +140 -0
  181. api/payment_endpoints.py +444 -0
  182. api/payment_verification.py +138 -0
  183. api/polymarket_models.py +155 -0
  184. api/polymarket_routes.py +501 -0
  185. api/pricing_endpoints.py +89 -0
  186. api/session_routing.py +54 -0
  187. api/skill_endpoints.py +453 -0
  188. api/task_http_api.py +1856 -0
  189. api/webhooks.py +52 -0
  190. api/x402_endpoints.py +280 -0
  191. avatar/README.md +44 -0
  192. avatar/__init__.py +1 -0
  193. avatar/config/rob.json +7 -0
  194. avatar/mindprint.js +395 -0
  195. avatar/renders/rob.meta.json +20 -0
  196. avatar/renders/rob.png +0 -0
  197. avatar/studio.html +373 -0
  198. avatar/webview/avatar-live.js +44 -0
  199. cli/README.md +89 -0
  200. cli/__init__.py +0 -0
  201. cli/cli_surface.py +67 -0
  202. cli/commands/__init__.py +0 -0
  203. cli/commands/_bootstrap.py +49 -0
  204. cli/commands/_errors.py +53 -0
  205. cli/commands/chat.py +973 -0
  206. cli/commands/config.py +100 -0
  207. cli/commands/dashboard.py +103 -0
  208. cli/commands/doctor.py +222 -0
  209. cli/commands/email.py +174 -0
  210. cli/commands/gateway.py +346 -0
  211. cli/commands/goals.py +509 -0
  212. cli/commands/init.py +276 -0
  213. cli/commands/journey.py +30 -0
  214. cli/commands/kb.py +280 -0
  215. cli/commands/model.py +107 -0
  216. cli/commands/owner.py +431 -0
  217. cli/commands/pfp.py +232 -0
  218. cli/commands/run.py +414 -0
  219. cli/commands/serve.py +41 -0
  220. cli/commands/session.py +684 -0
  221. cli/commands/skill_install.py +786 -0
  222. cli/commands/skills.py +128 -0
  223. cli/commands/subagents.py +100 -0
  224. cli/commands/surface.py +81 -0
  225. cli/commands/telegram.py +185 -0
  226. cli/commands/todos.py +209 -0
  227. cli/commands/tools.py +102 -0
  228. cli/commands/update.py +316 -0
  229. cli/commands/whatsapp.py +175 -0
  230. cli/config_store.py +276 -0
  231. cli/gitignore.py +43 -0
  232. cli/inventory.py +46 -0
  233. cli/keys.py +101 -0
  234. cli/persona.py +17 -0
  235. cli/polyrob.py +137 -0
  236. cli/ui/__init__.py +64 -0
  237. cli/ui/activity.py +141 -0
  238. cli/ui/app.py +538 -0
  239. cli/ui/banner.py +233 -0
  240. cli/ui/blocks.py +534 -0
  241. cli/ui/bootstrap_notice.py +47 -0
  242. cli/ui/commands/__init__.py +41 -0
  243. cli/ui/commands/h_cron.py +64 -0
  244. cli/ui/commands/h_journey.py +164 -0
  245. cli/ui/commands/h_kb.py +121 -0
  246. cli/ui/commands/h_learn.py +100 -0
  247. cli/ui/commands/h_mcp.py +215 -0
  248. cli/ui/commands/h_self.py +113 -0
  249. cli/ui/commands/h_skills.py +314 -0
  250. cli/ui/commands/handlers.py +1672 -0
  251. cli/ui/commands/registry.py +426 -0
  252. cli/ui/dialog.py +425 -0
  253. cli/ui/event_registry.py +110 -0
  254. cli/ui/event_specs.py +45 -0
  255. cli/ui/events.py +433 -0
  256. cli/ui/identity.py +15 -0
  257. cli/ui/lifecycle.py +159 -0
  258. cli/ui/live_hooks.py +43 -0
  259. cli/ui/model_selector.py +532 -0
  260. cli/ui/persistent_loop.py +181 -0
  261. cli/ui/pick.py +113 -0
  262. cli/ui/plain_renderer.py +351 -0
  263. cli/ui/renderer.py +384 -0
  264. cli/ui/rich_renderer.py +533 -0
  265. cli/ui/secrets.py +115 -0
  266. cli/ui/state.py +376 -0
  267. cli/ui/statusbar.py +231 -0
  268. cli/ui/streaming.py +254 -0
  269. cli/ui/terminal_render.py +105 -0
  270. cli/ui/theme.py +132 -0
  271. cli/update/__init__.py +6 -0
  272. cli/update/context.py +121 -0
  273. cli/update/detect.py +176 -0
  274. cli/update/engine.py +95 -0
  275. cli/update/migrate_guarded.py +55 -0
  276. cli/update/process_guard.py +215 -0
  277. cli/update/runners.py +78 -0
  278. cli/update/snapshot.py +270 -0
  279. cli/update/versions.py +205 -0
  280. core/README.md +377 -0
  281. core/__init__.py +174 -0
  282. core/assets.py +87 -0
  283. core/async_bridge.py +76 -0
  284. core/autonomy_runtime.py +259 -0
  285. core/base_component.py +302 -0
  286. core/bootstrap.py +681 -0
  287. core/bot.py +310 -0
  288. core/config.py +833 -0
  289. core/constants.py +126 -0
  290. core/container.py +462 -0
  291. core/db_manifest.py +101 -0
  292. core/embedding.py +57 -0
  293. core/env.py +39 -0
  294. core/exceptions.py +287 -0
  295. core/flags.py +144 -0
  296. core/flags_catalog.py +345 -0
  297. core/home_migration.py +62 -0
  298. core/identity.py +118 -0
  299. core/initialization.py +1004 -0
  300. core/instance.py +537 -0
  301. core/interactive_gate.py +96 -0
  302. core/logging.py +436 -0
  303. core/owner_doc_writer.py +176 -0
  304. core/pairing.py +193 -0
  305. core/path_safety.py +20 -0
  306. core/paths.py +27 -0
  307. core/payment_config.py +21 -0
  308. core/permissions.py +322 -0
  309. core/runtime_config.py +96 -0
  310. core/runtime_paths.py +135 -0
  311. core/seams.py +35 -0
  312. core/secret_scan.py +25 -0
  313. core/secret_scrub.py +71 -0
  314. core/secrets.py +35 -0
  315. core/security_logging_filter.py +148 -0
  316. core/self_context_writer.py +333 -0
  317. core/self_evolution.py +294 -0
  318. core/session_context.py +47 -0
  319. core/sqlite_util.py +59 -0
  320. core/surfaces/__init__.py +16 -0
  321. core/surfaces/access.py +118 -0
  322. core/surfaces/binding.py +88 -0
  323. core/surfaces/bootstrap.py +78 -0
  324. core/surfaces/circuit.py +168 -0
  325. core/surfaces/continuity.py +77 -0
  326. core/surfaces/correspondents.py +228 -0
  327. core/surfaces/dispatcher.py +216 -0
  328. core/surfaces/envelopes.py +75 -0
  329. core/surfaces/gc.py +30 -0
  330. core/surfaces/idempotency.py +57 -0
  331. core/surfaces/inbound_webhook.py +124 -0
  332. core/surfaces/media.py +32 -0
  333. core/surfaces/message_router.py +91 -0
  334. core/surfaces/outbound_allowlist.py +80 -0
  335. core/surfaces/outbound_dispatcher.py +110 -0
  336. core/surfaces/outbound_mirror.py +37 -0
  337. core/surfaces/outbound_queue.py +107 -0
  338. core/surfaces/outbound_target.py +12 -0
  339. core/surfaces/owner_admin.py +29 -0
  340. core/surfaces/proactive.py +78 -0
  341. core/surfaces/progress.py +108 -0
  342. core/surfaces/rate_bucket.py +21 -0
  343. core/surfaces/registry.py +51 -0
  344. core/surfaces/rendering.py +53 -0
  345. core/surfaces/send_policy.py +14 -0
  346. core/surfaces/serialize.py +24 -0
  347. core/surfaces/session_chat_registry.py +112 -0
  348. core/surfaces/session_policy.py +60 -0
  349. core/surfaces/surface.py +288 -0
  350. core/surfaces/transcription.py +88 -0
  351. core/surfaces/voice_echo.py +26 -0
  352. core/surfaces/voice_guard.py +23 -0
  353. core/tickers.py +174 -0
  354. core/tool_catalog.py +192 -0
  355. core/version.py +75 -0
  356. core/wallet/__init__.py +5 -0
  357. core/wallet/agent_wallet.py +59 -0
  358. core/wallet/audit_sink.py +61 -0
  359. core/wallet/config.py +70 -0
  360. core/wallet/factory.py +87 -0
  361. core/wallet/policy.py +104 -0
  362. core/wallet/signer.py +51 -0
  363. cron/README.md +65 -0
  364. cron/__init__.py +0 -0
  365. cron/delivery.py +277 -0
  366. cron/digest.py +124 -0
  367. cron/jobs.py +207 -0
  368. cron/runner.py +297 -0
  369. cron/schedule.py +194 -0
  370. cron/scheduler.py +201 -0
  371. cron/service.py +57 -0
  372. cron/wake_gate.py +223 -0
  373. data/__init__.py +1 -0
  374. data/prompts/autov2_prompts.json +87 -0
  375. data/prompts/skills/browser-automation/SKILL.md +43 -0
  376. data/prompts/skills/coding-workflow/SKILL.md +36 -0
  377. data/prompts/skills/crypto-trading-safety/SKILL.md +53 -0
  378. data/prompts/skills/document-writing/SKILL.md +33 -0
  379. data/prompts/skills/email-comms/SKILL.md +33 -0
  380. data/prompts/skills/file-data-ops/SKILL.md +35 -0
  381. data/prompts/skills/hyperliquid-account-review/SKILL.md +48 -0
  382. data/prompts/skills/hyperliquid-market-data/SKILL.md +52 -0
  383. data/prompts/skills/hyperliquid-trading/SKILL.md +59 -0
  384. data/prompts/skills/lead-research/SKILL.md +86 -0
  385. data/prompts/skills/market-research-brief/SKILL.md +104 -0
  386. data/prompts/skills/person-analyzer/SKILL.md +124 -0
  387. data/prompts/skills/polymarket-market-research/SKILL.md +54 -0
  388. data/prompts/skills/polymarket-portfolio-review/SKILL.md +50 -0
  389. data/prompts/skills/polymarket-trading/SKILL.md +55 -0
  390. data/prompts/skills/presentation-creator/SKILL.md +36 -0
  391. data/prompts/skills/project-analyzer/SKILL.md +169 -0
  392. data/prompts/skills/rules.json +268 -0
  393. data/prompts/skills/secret-handling/SKILL.md +20 -0
  394. data/prompts/skills/skill-authoring/SKILL.md +31 -0
  395. data/prompts/skills/skill-security-review/SKILL.md +27 -0
  396. data/prompts/skills/social-discovery/SKILL.md +57 -0
  397. data/prompts/skills/task-planning/SKILL.md +33 -0
  398. data/prompts/skills/web-research/SKILL.md +39 -0
  399. data/prompts/skills/web-scraping/SKILL.md +73 -0
  400. data/prompts/skills/x-engagement/SKILL.md +69 -0
  401. data/prompts/system_prompts.json +4 -0
  402. data/subscription_channels.json +5 -0
  403. modules/README.md +503 -0
  404. modules/__init__.py +124 -0
  405. modules/auth/__init__.py +13 -0
  406. modules/auth/api_key_manager.py +157 -0
  407. modules/auth/identity_mapper.py +380 -0
  408. modules/auth/siwe_auth.py +273 -0
  409. modules/auth/tier_manager.py +173 -0
  410. modules/base_module.py +190 -0
  411. modules/credits/__init__.py +29 -0
  412. modules/credits/balance_manager.py +237 -0
  413. modules/credits/cost_utils.py +129 -0
  414. modules/credits/pricing.py +139 -0
  415. modules/credits/unified_ledger.py +148 -0
  416. modules/credits/usage_meter.py +310 -0
  417. modules/credits/usage_tracker.py +674 -0
  418. modules/database/__init__.py +33 -0
  419. modules/database/audit_log.py +322 -0
  420. modules/database/auth_tables.py +276 -0
  421. modules/database/connection.py +644 -0
  422. modules/database/connection_pool.py +305 -0
  423. modules/database/conversation_contexts.py +446 -0
  424. modules/database/database_manager.py +237 -0
  425. modules/database/hyperliquid.py +375 -0
  426. modules/database/polymarket.py +574 -0
  427. modules/database/user_mcp_servers.py +728 -0
  428. modules/database/user_profiles.py +562 -0
  429. modules/database/utils.py +107 -0
  430. modules/database/x402_tables.py +92 -0
  431. modules/eip8004/README.md +1069 -0
  432. modules/eip8004/__init__.py +65 -0
  433. modules/eip8004/contracts.py +498 -0
  434. modules/eip8004/models.py +271 -0
  435. modules/eip8004/registration.py +148 -0
  436. modules/eip8004/reputation.py +367 -0
  437. modules/eip8004/validation.py +277 -0
  438. modules/llm/__init__.py +97 -0
  439. modules/llm/adapters.py +963 -0
  440. modules/llm/anthropic_client.py +831 -0
  441. modules/llm/available_models.py +106 -0
  442. modules/llm/brain_scrubber.py +137 -0
  443. modules/llm/cache_hints.py +162 -0
  444. modules/llm/deepseek_client.py +562 -0
  445. modules/llm/gemini_client.py +1367 -0
  446. modules/llm/llm_client.py +1139 -0
  447. modules/llm/llm_client_registry.py +188 -0
  448. modules/llm/llm_factory.py +237 -0
  449. modules/llm/llm_manager.py +1036 -0
  450. modules/llm/messages.py +374 -0
  451. modules/llm/model_registry.py +1935 -0
  452. modules/llm/nvidia_client.py +125 -0
  453. modules/llm/openai_client.py +800 -0
  454. modules/llm/openrouter_client.py +969 -0
  455. modules/llm/profiles.py +178 -0
  456. modules/llm/test_anthropic_cache_capture.py +35 -0
  457. modules/llm/test_cached_pricing_derivation.py +24 -0
  458. modules/llm/think_scrubber.py +444 -0
  459. modules/llm/token_counter.py +268 -0
  460. modules/memory/__init__.py +35 -0
  461. modules/memory/backend_factory.py +83 -0
  462. modules/memory/cache_manager.py +186 -0
  463. modules/memory/episodic.py +108 -0
  464. modules/memory/local_vector_memory_provider.py +552 -0
  465. modules/memory/memory_manager.py +225 -0
  466. modules/memory/models.py +312 -0
  467. modules/memory/provider.py +210 -0
  468. modules/memory/registry.py +205 -0
  469. modules/memory/sqlite_memory_provider.py +767 -0
  470. modules/memory/task/__init__.py +52 -0
  471. modules/memory/task/compaction_manager.py +157 -0
  472. modules/memory/task/context_retriever.py +809 -0
  473. modules/memory/task/hierarchical_memory.py +1002 -0
  474. modules/memory/task/lexical_retriever.py +71 -0
  475. modules/memory/task/null_context_manager.py +213 -0
  476. modules/memory/task/phase_manager.py +625 -0
  477. modules/memory/task/reflection_service.py +157 -0
  478. modules/memory/task/semantic_retriever.py +218 -0
  479. modules/memory/task/task_context_manager.py +1165 -0
  480. modules/memory/task/test_forgetting_engages.py +24 -0
  481. modules/memory/task/test_reflection_llm.py +39 -0
  482. modules/memory/task/test_threat_scan.py +53 -0
  483. modules/memory/task/threat_scan.py +90 -0
  484. modules/memory/test_sqlite_memory_provider.py +106 -0
  485. modules/memory/user_profile_manager.py +527 -0
  486. modules/payments/__init__.py +11 -0
  487. modules/payments/deposit_monitor.py +478 -0
  488. modules/payments/price_oracle.py +70 -0
  489. modules/payments/treasury_sweeper.py +401 -0
  490. modules/payments/wallet_generator.py +145 -0
  491. modules/pfp/__init__.py +1 -0
  492. modules/pfp/config.py +92 -0
  493. modules/pfp/mesh.py +565 -0
  494. modules/pfp/push.py +69 -0
  495. modules/pfp/renderer.py +85 -0
  496. modules/pfp/store.py +82 -0
  497. modules/skills/__init__.py +1 -0
  498. modules/skills/skill_usage.py +248 -0
  499. modules/transcription/__init__.py +24 -0
  500. modules/transcription/base.py +20 -0
  501. modules/transcription/faster_whisper_transcriber.py +55 -0
  502. modules/x402/README.md +249 -0
  503. modules/x402/__init__.py +22 -0
  504. modules/x402/invoicing.py +416 -0
  505. modules/x402/middleware.py +364 -0
  506. modules/x402/settlement_watcher.py +145 -0
  507. modules/x402/x402_integration.py +344 -0
  508. polyrob-0.5.0.dist-info/METADATA +482 -0
  509. polyrob-0.5.0.dist-info/RECORD +745 -0
  510. polyrob-0.5.0.dist-info/WHEEL +5 -0
  511. polyrob-0.5.0.dist-info/entry_points.txt +2 -0
  512. polyrob-0.5.0.dist-info/licenses/LICENSE +21 -0
  513. polyrob-0.5.0.dist-info/top_level.txt +12 -0
  514. surfaces/README.md +70 -0
  515. surfaces/__init__.py +0 -0
  516. surfaces/email/__init__.py +0 -0
  517. surfaces/email/dedup.py +44 -0
  518. surfaces/email/harness.py +187 -0
  519. surfaces/email/inbound.py +159 -0
  520. surfaces/email/seed.py +60 -0
  521. surfaces/email/surface.py +105 -0
  522. surfaces/telegram/__init__.py +0 -0
  523. surfaces/telegram/dedup.py +83 -0
  524. surfaces/telegram/harness.py +886 -0
  525. surfaces/telegram/inbound.py +145 -0
  526. surfaces/telegram/interactive_tools.py +49 -0
  527. surfaces/telegram/markdown.py +347 -0
  528. surfaces/telegram/rate_limit.py +167 -0
  529. surfaces/telegram/surface.py +187 -0
  530. surfaces/telegram/voice.py +52 -0
  531. surfaces/whatsapp/__init__.py +0 -0
  532. surfaces/whatsapp/client.py +51 -0
  533. surfaces/whatsapp/harness.py +62 -0
  534. surfaces/whatsapp/inbound.py +132 -0
  535. surfaces/whatsapp/surface.py +64 -0
  536. surfaces/whatsapp/window.py +34 -0
  537. tools/README.md +578 -0
  538. tools/__init__.py +424 -0
  539. tools/alchemy/__init__.py +5 -0
  540. tools/alchemy/alchemy_tool.py +389 -0
  541. tools/anysite/__init__.py +17 -0
  542. tools/anysite/client.py +88 -0
  543. tools/anysite/tool.py +89 -0
  544. tools/base_tool.py +468 -0
  545. tools/browser/__init__.py +22 -0
  546. tools/browser/actions.py +118 -0
  547. tools/browser/browser.py +1457 -0
  548. tools/browser/browser_manager.py +690 -0
  549. tools/browser/context.py +1748 -0
  550. tools/browser/playwright_utils.py +137 -0
  551. tools/browser/views.py +56 -0
  552. tools/code_exec/SANDBOX_SECURITY.md +144 -0
  553. tools/code_exec/__init__.py +178 -0
  554. tools/code_exec/backend.py +73 -0
  555. tools/code_exec/backends/__init__.py +1 -0
  556. tools/code_exec/backends/docker.py +779 -0
  557. tools/code_exec/backends/local_subprocess.py +154 -0
  558. tools/code_exec/env_policy.py +45 -0
  559. tools/code_exec/result.py +42 -0
  560. tools/code_exec/sandbox_guard.py +59 -0
  561. tools/code_exec/tool.py +227 -0
  562. tools/coding/__init__.py +50 -0
  563. tools/coding/edit.py +107 -0
  564. tools/coding/search.py +113 -0
  565. tools/coding/tool.py +353 -0
  566. tools/collabland/__init__.py +5 -0
  567. tools/collabland/collabland_tool.py +471 -0
  568. tools/controller/__init__.py +0 -0
  569. tools/controller/_helpers.py +165 -0
  570. tools/controller/action_registration.py +1765 -0
  571. tools/controller/approval.py +244 -0
  572. tools/controller/approval_interactive.py +90 -0
  573. tools/controller/delegation.py +195 -0
  574. tools/controller/execution.py +797 -0
  575. tools/controller/execution_context.py +141 -0
  576. tools/controller/hooks.py +135 -0
  577. tools/controller/introspection.py +344 -0
  578. tools/controller/mcp_registrar.py +190 -0
  579. tools/controller/message_send.py +31 -0
  580. tools/controller/registry/__init__.py +4 -0
  581. tools/controller/registry/schema_generators.py +395 -0
  582. tools/controller/registry/schema_sanitizer.py +406 -0
  583. tools/controller/registry/service.py +1266 -0
  584. tools/controller/registry/views.py +151 -0
  585. tools/controller/service.py +409 -0
  586. tools/controller/tool_management.py +334 -0
  587. tools/controller/types.py +28 -0
  588. tools/controller/views.py +450 -0
  589. tools/cronjob_tools.py +166 -0
  590. tools/crypto_trade_gate.py +59 -0
  591. tools/descriptors.py +452 -0
  592. tools/dom/__init__.py +0 -0
  593. tools/dom/history_tree_processor/service.py +244 -0
  594. tools/dom/history_tree_processor/view.py +99 -0
  595. tools/dom/service.py +471 -0
  596. tools/dom/views.py +346 -0
  597. tools/email_tool.py +403 -0
  598. tools/exceptions.py +169 -0
  599. tools/filesystem.py +1038 -0
  600. tools/filesystem_docproc.py +331 -0
  601. tools/filesystem_pdf.py +755 -0
  602. tools/git/__init__.py +42 -0
  603. tools/git/tool.py +258 -0
  604. tools/github/__init__.py +33 -0
  605. tools/github/client.py +94 -0
  606. tools/github/tool.py +237 -0
  607. tools/goal_tools.py +309 -0
  608. tools/hyperliquid/__init__.py +56 -0
  609. tools/hyperliquid/models.py +233 -0
  610. tools/hyperliquid/service.py +1680 -0
  611. tools/knowledge_ingest.py +950 -0
  612. tools/mcp/README.md +535 -0
  613. tools/mcp/__init__.py +52 -0
  614. tools/mcp/catalog.py +115 -0
  615. tools/mcp/config.py +337 -0
  616. tools/mcp/mcp_tool.py +1415 -0
  617. tools/mcp/param_coercion.py +289 -0
  618. tools/mcp/protocol.py +1520 -0
  619. tools/mcp/rate_limit.py +50 -0
  620. tools/mcp/security.py +424 -0
  621. tools/mcp/self_install.py +111 -0
  622. tools/mcp/server_manager.py +829 -0
  623. tools/mcp/subscriptions.py +72 -0
  624. tools/mcp/user_mcp_service.py +899 -0
  625. tools/mcp/validation_tracker.py +89 -0
  626. tools/mcp/views.py +346 -0
  627. tools/oauth/__init__.py +17 -0
  628. tools/oauth/manager.py +75 -0
  629. tools/oauth/provider.py +69 -0
  630. tools/oauth/providers/__init__.py +1 -0
  631. tools/oauth/providers/generic_oauth2.py +96 -0
  632. tools/perplexity_tool.py +280 -0
  633. tools/polymarket/__init__.py +41 -0
  634. tools/polymarket/clob_adapter.py +76 -0
  635. tools/polymarket/models.py +182 -0
  636. tools/polymarket/service.py +2082 -0
  637. tools/self_env/__init__.py +61 -0
  638. tools/self_env/tool.py +274 -0
  639. tools/shell/__init__.py +80 -0
  640. tools/shell/backend_pool.py +118 -0
  641. tools/shell/discipline.py +62 -0
  642. tools/shell/executor.py +157 -0
  643. tools/shell/loopback_allow.py +87 -0
  644. tools/shell/process_registry.py +113 -0
  645. tools/shell/process_tool.py +131 -0
  646. tools/shell/state.py +129 -0
  647. tools/shell/tool.py +151 -0
  648. tools/task_tool.py +637 -0
  649. tools/twitter_tool.py +2086 -0
  650. tools/user_directory.py +179 -0
  651. tools/web_fetch/__init__.py +3 -0
  652. tools/web_fetch/fetcher.py +144 -0
  653. tools/web_fetch/render.py +44 -0
  654. tools/web_fetch/tool.py +60 -0
  655. tools/x402/__init__.py +60 -0
  656. tools/x402/client.py +47 -0
  657. tools/x402/invoice_tool.py +143 -0
  658. tools/x402/real_client.py +250 -0
  659. tools/x402/service.py +131 -0
  660. utils/README.md +498 -0
  661. utils/__init__.py +46 -0
  662. utils/auth_utils.py +114 -0
  663. utils/bounded_collections.py +162 -0
  664. utils/circuit_breaker.py +389 -0
  665. utils/gif_utils.py +435 -0
  666. utils/markdown_utils.py +291 -0
  667. utils/message_utils.py +147 -0
  668. utils/metrics.py +36 -0
  669. utils/path_validator.py +227 -0
  670. utils/rate_limit_manager.py +399 -0
  671. utils/result_size.py +296 -0
  672. utils/time_utils.py +206 -0
  673. utils/user_utils.py +188 -0
  674. webview/README.md +111 -0
  675. webview/RENAME_AND_ALIGN_HANDOFF.md +200 -0
  676. webview/__init__.py +8 -0
  677. webview/activity.py +636 -0
  678. webview/owner_auth.py +108 -0
  679. webview/pages.py +448 -0
  680. webview/repair_sessions.py +399 -0
  681. webview/server.py +4323 -0
  682. webview/server_launcher.py +112 -0
  683. webview/static/css/activity.css +89 -0
  684. webview/static/css/chat.css +1772 -0
  685. webview/static/css/components.css +1190 -0
  686. webview/static/css/config-panel.css +651 -0
  687. webview/static/css/pages/admin.css +766 -0
  688. webview/static/css/pages/profile.css +231 -0
  689. webview/static/css/pages/settings.css +297 -0
  690. webview/static/css/pages/signin.css +316 -0
  691. webview/static/css/style.css +4250 -0
  692. webview/static/css/variables.css +147 -0
  693. webview/static/css/workspace-fullwidth-fix.css +109 -0
  694. webview/static/img/favicon.ico +0 -0
  695. webview/static/js/activity.js +394 -0
  696. webview/static/js/admin/activity.js +186 -0
  697. webview/static/js/admin/dashboard.js +163 -0
  698. webview/static/js/admin/user_detail.js +400 -0
  699. webview/static/js/admin/users.js +174 -0
  700. webview/static/js/admin/utils.js +214 -0
  701. webview/static/js/chat.js +3178 -0
  702. webview/static/js/config-panel.js +522 -0
  703. webview/static/js/constants.js +20 -0
  704. webview/static/js/error-handler.js +226 -0
  705. webview/static/js/ethers.min.js +1 -0
  706. webview/static/js/event-filter.js +137 -0
  707. webview/static/js/event-store.js +351 -0
  708. webview/static/js/file-attachments.js +374 -0
  709. webview/static/js/file-loader.js +163 -0
  710. webview/static/js/index.js +103 -0
  711. webview/static/js/performance-utils.js +196 -0
  712. webview/static/js/profile.js +396 -0
  713. webview/static/js/screenshot.js +386 -0
  714. webview/static/js/session.js +1527 -0
  715. webview/static/js/settings.js +1288 -0
  716. webview/static/js/sidebar-data.js +766 -0
  717. webview/static/js/sidebar-toggle.js +296 -0
  718. webview/static/js/socket.io.min.js +7 -0
  719. webview/static/js/stats.js +355 -0
  720. webview/static/js/ui-utils.js +420 -0
  721. webview/static/js/workspace.js +966 -0
  722. webview/stats_service.py +613 -0
  723. webview/templates/__init__.py +1 -0
  724. webview/templates/__pycache__/__init__.cpython-311.pyc +0 -0
  725. webview/templates/activity.html +36 -0
  726. webview/templates/admin/activity.html +122 -0
  727. webview/templates/admin/dashboard.html +112 -0
  728. webview/templates/admin/user_detail.html +228 -0
  729. webview/templates/admin/users.html +105 -0
  730. webview/templates/autonomy.html +60 -0
  731. webview/templates/error.html +133 -0
  732. webview/templates/finance.html +90 -0
  733. webview/templates/identity.html +73 -0
  734. webview/templates/index.html +42 -0
  735. webview/templates/layout.html +125 -0
  736. webview/templates/memory.html +59 -0
  737. webview/templates/owner_login.html +15 -0
  738. webview/templates/profile.html +121 -0
  739. webview/templates/session.html +312 -0
  740. webview/templates/settings.html +534 -0
  741. webview/templates/sidebar.html +112 -0
  742. webview/templates/signin.html +213 -0
  743. webview/templates/status.html +14 -0
  744. webview/templates/system.html +45 -0
  745. webview/webgate.py +196 -0
@@ -0,0 +1,450 @@
1
+ """
2
+ Hyperliquid API Routes
3
+
4
+ FastAPI endpoints for Hyperliquid tool configuration and execution.
5
+ """
6
+
7
+ from fastapi import APIRouter, Depends, Request, HTTPException
8
+ from typing import Optional
9
+
10
+ from api.hyperliquid_models import (
11
+ ConfigureHyperliquidRequest,
12
+ UpdateTradingLimitsRequest,
13
+ ExecuteToolRequest,
14
+ SetDemoModeRequest,
15
+ SetEnabledRequest,
16
+ HyperliquidStatusResponse,
17
+ ExecuteToolResponse,
18
+ AvailableToolsResponse,
19
+ AuditLogResponse,
20
+ TradingStatsResponse,
21
+ SuccessResponse,
22
+ )
23
+ from tools.hyperliquid.service import HyperliquidTool
24
+ from tools.hyperliquid.models import TradingLimits, AgentWallet
25
+ from modules.database.hyperliquid import HyperliquidDBHandler
26
+ from core.logging import get_component_logger
27
+ from api.dependencies import get_user_id, get_client_ip
28
+
29
+ router = APIRouter(prefix="/api/hyperliquid", tags=["hyperliquid"])
30
+ logger = get_component_logger("HyperliquidAPI")
31
+
32
+
33
+ def get_hyperliquid_tool(request: Request) -> HyperliquidTool:
34
+ """Get HyperliquidTool from container"""
35
+ container = getattr(request.app.state, "container", None)
36
+ if not container:
37
+ raise HTTPException(status_code=503, detail="Service container not available")
38
+
39
+ tool = container.get_service("hyperliquid")
40
+ if not tool:
41
+ raise HTTPException(status_code=503, detail="Hyperliquid service not available")
42
+ return tool
43
+
44
+
45
+ def get_hyperliquid_db(request: Request) -> HyperliquidDBHandler:
46
+ """Get HyperliquidDBHandler from container"""
47
+ container = getattr(request.app.state, "container", None)
48
+ if not container:
49
+ raise HTTPException(status_code=503, detail="Service container not available")
50
+
51
+ db = container.get_service("hyperliquid_db")
52
+ if not db:
53
+ raise HTTPException(status_code=503, detail="Hyperliquid database not available")
54
+ return db
55
+
56
+
57
+ # =============================================================================
58
+ # Configuration Endpoints
59
+ # =============================================================================
60
+
61
+ @router.post("/configure", response_model=HyperliquidStatusResponse)
62
+ async def configure_hyperliquid(
63
+ request: Request,
64
+ body: ConfigureHyperliquidRequest,
65
+ user_id: str = Depends(get_user_id),
66
+ client_ip: str = Depends(get_client_ip),
67
+ ):
68
+ """Configure Hyperliquid credentials for the user"""
69
+ db = get_hyperliquid_db(request)
70
+
71
+ # Build agent wallet if provided
72
+ agent_wallet = None
73
+ if body.agent_wallet_address and body.agent_wallet_private_key:
74
+ agent_wallet = AgentWallet(
75
+ address=body.agent_wallet_address,
76
+ private_key=body.agent_wallet_private_key,
77
+ name=body.agent_wallet_name,
78
+ )
79
+
80
+ # Build trading limits
81
+ trading_limits = TradingLimits(
82
+ max_order_size_usd=body.max_order_size_usd or 1000.0,
83
+ max_leverage=body.max_leverage or 5,
84
+ enable_autonomous_trading=body.enable_autonomous_trading or False,
85
+ )
86
+
87
+ await db.save_credentials(
88
+ user_id=user_id,
89
+ wallet_address=body.wallet_address,
90
+ private_key=body.private_key,
91
+ agent_wallet=agent_wallet,
92
+ testnet=body.testnet,
93
+ demo_mode=body.demo_mode,
94
+ trading_limits=trading_limits,
95
+ )
96
+
97
+ # Audit
98
+ await db.audit_log(
99
+ user_id=user_id,
100
+ action="configure",
101
+ details={"testnet": body.testnet, "demo_mode": body.demo_mode},
102
+ ip_address=client_ip,
103
+ )
104
+
105
+ # Mask wallet address for response
106
+ masked_wallet = f"{body.wallet_address[:6]}...{body.wallet_address[-4:]}"
107
+ masked_agent = None
108
+ if agent_wallet:
109
+ masked_agent = f"{agent_wallet.address[:6]}...{agent_wallet.address[-4:]}"
110
+
111
+ return HyperliquidStatusResponse(
112
+ configured=True,
113
+ wallet_address=masked_wallet,
114
+ agent_wallet_address=masked_agent,
115
+ testnet=body.testnet,
116
+ demo_mode=body.demo_mode,
117
+ enabled=True,
118
+ trading_limits=trading_limits.to_dict(),
119
+ )
120
+
121
+
122
+ @router.get("/status", response_model=HyperliquidStatusResponse)
123
+ async def get_status(
124
+ request: Request,
125
+ user_id: str = Depends(get_user_id),
126
+ ):
127
+ """Get current Hyperliquid configuration status"""
128
+ db = get_hyperliquid_db(request)
129
+ credentials = await db.get_credentials(user_id)
130
+
131
+ if not credentials:
132
+ return HyperliquidStatusResponse(
133
+ configured=False,
134
+ wallet_address=None,
135
+ testnet=True,
136
+ demo_mode=True,
137
+ enabled=False,
138
+ )
139
+
140
+ # Mask addresses
141
+ masked_wallet = f"{credentials.wallet_address[:6]}...{credentials.wallet_address[-4:]}"
142
+ masked_agent = None
143
+ if credentials.agent_wallet:
144
+ masked_agent = f"{credentials.agent_wallet.address[:6]}...{credentials.agent_wallet.address[-4:]}"
145
+
146
+ return HyperliquidStatusResponse(
147
+ configured=True,
148
+ wallet_address=masked_wallet,
149
+ agent_wallet_address=masked_agent,
150
+ testnet=credentials.testnet,
151
+ demo_mode=credentials.demo_mode,
152
+ enabled=credentials.enabled,
153
+ trading_limits=credentials.trading_limits.to_dict(),
154
+ connection_count=credentials.connection_count,
155
+ last_connected_at=credentials.last_connected_at.isoformat() if credentials.last_connected_at else None,
156
+ last_error=credentials.last_error,
157
+ )
158
+
159
+
160
+ @router.put("/trading-limits", response_model=SuccessResponse)
161
+ async def update_trading_limits(
162
+ request: Request,
163
+ body: UpdateTradingLimitsRequest,
164
+ user_id: str = Depends(get_user_id),
165
+ client_ip: str = Depends(get_client_ip),
166
+ ):
167
+ """Update trading limits"""
168
+ db = get_hyperliquid_db(request)
169
+
170
+ # Get existing credentials
171
+ credentials = await db.get_credentials(user_id)
172
+ if not credentials:
173
+ raise HTTPException(status_code=404, detail="Credentials not configured")
174
+
175
+ # Update limits with provided values
176
+ limits = credentials.trading_limits
177
+ if body.max_order_size_usd is not None:
178
+ limits.max_order_size_usd = body.max_order_size_usd
179
+ if body.max_total_exposure_usd is not None:
180
+ limits.max_total_exposure_usd = body.max_total_exposure_usd
181
+ if body.max_position_per_market_usd is not None:
182
+ limits.max_position_per_market_usd = body.max_position_per_market_usd
183
+ if body.max_leverage is not None:
184
+ limits.max_leverage = body.max_leverage
185
+ if body.max_daily_loss_usd is not None:
186
+ limits.max_daily_loss_usd = body.max_daily_loss_usd
187
+ if body.require_confirmation_above_usd is not None:
188
+ limits.require_confirmation_above_usd = body.require_confirmation_above_usd
189
+ if body.enable_autonomous_trading is not None:
190
+ limits.enable_autonomous_trading = body.enable_autonomous_trading
191
+ if body.allowed_coins is not None:
192
+ limits.allowed_coins = body.allowed_coins
193
+ if body.blocked_coins is not None:
194
+ limits.blocked_coins = body.blocked_coins
195
+
196
+ await db.update_trading_limits(user_id, limits)
197
+
198
+ # Audit
199
+ await db.audit_log(
200
+ user_id=user_id,
201
+ action="update_trading_limits",
202
+ details=body.model_dump(exclude_unset=True),
203
+ ip_address=client_ip,
204
+ )
205
+
206
+ return SuccessResponse(success=True, message="Trading limits updated")
207
+
208
+
209
+ @router.put("/demo-mode", response_model=SuccessResponse)
210
+ async def set_demo_mode(
211
+ request: Request,
212
+ body: SetDemoModeRequest,
213
+ user_id: str = Depends(get_user_id),
214
+ client_ip: str = Depends(get_client_ip),
215
+ ):
216
+ """Set demo mode (read-only or trading)"""
217
+ db = get_hyperliquid_db(request)
218
+
219
+ updated = await db.set_demo_mode(user_id, body.demo_mode)
220
+ if not updated:
221
+ raise HTTPException(status_code=404, detail="Credentials not configured")
222
+
223
+ # Audit
224
+ await db.audit_log(
225
+ user_id=user_id,
226
+ action="set_demo_mode",
227
+ details={"demo_mode": body.demo_mode},
228
+ ip_address=client_ip,
229
+ )
230
+
231
+ mode_str = "read-only" if body.demo_mode else "trading"
232
+ return SuccessResponse(success=True, message=f"Demo mode set to {mode_str}")
233
+
234
+
235
+ @router.put("/enabled", response_model=SuccessResponse)
236
+ async def set_enabled(
237
+ request: Request,
238
+ body: SetEnabledRequest,
239
+ user_id: str = Depends(get_user_id),
240
+ client_ip: str = Depends(get_client_ip),
241
+ ):
242
+ """Enable or disable Hyperliquid integration"""
243
+ db = get_hyperliquid_db(request)
244
+
245
+ updated = await db.set_enabled(user_id, body.enabled)
246
+ if not updated:
247
+ raise HTTPException(status_code=404, detail="Credentials not configured")
248
+
249
+ # Audit
250
+ await db.audit_log(
251
+ user_id=user_id,
252
+ action="set_enabled",
253
+ details={"enabled": body.enabled},
254
+ ip_address=client_ip,
255
+ )
256
+
257
+ status_str = "enabled" if body.enabled else "disabled"
258
+ return SuccessResponse(success=True, message=f"Hyperliquid {status_str}")
259
+
260
+
261
+ @router.delete("/credentials", response_model=SuccessResponse)
262
+ async def delete_credentials(
263
+ request: Request,
264
+ user_id: str = Depends(get_user_id),
265
+ client_ip: str = Depends(get_client_ip),
266
+ ):
267
+ """Permanently delete Hyperliquid credentials"""
268
+ db = get_hyperliquid_db(request)
269
+
270
+ deleted = await db.delete_credentials(user_id)
271
+
272
+ if deleted:
273
+ await db.audit_log(
274
+ user_id=user_id,
275
+ action="delete_credentials",
276
+ ip_address=client_ip,
277
+ )
278
+
279
+ return SuccessResponse(success=deleted, message="Credentials deleted" if deleted else "No credentials found")
280
+
281
+
282
+ # =============================================================================
283
+ # Tool Endpoints
284
+ # =============================================================================
285
+
286
+ @router.get("/tools", response_model=AvailableToolsResponse)
287
+ async def get_available_tools(
288
+ request: Request,
289
+ ):
290
+ """List all available Hyperliquid tools"""
291
+ tool = get_hyperliquid_tool(request)
292
+ tools = tool.get_available_tools()
293
+ return AvailableToolsResponse(tools=tools, count=len(tools))
294
+
295
+
296
+ @router.post("/execute", response_model=ExecuteToolResponse)
297
+ async def execute_tool(
298
+ request: Request,
299
+ body: ExecuteToolRequest,
300
+ user_id: str = Depends(get_user_id),
301
+ client_ip: str = Depends(get_client_ip),
302
+ ):
303
+ """Execute a Hyperliquid tool action"""
304
+ tool = get_hyperliquid_tool(request)
305
+
306
+ # Set user context
307
+ tool.set_user_context(user_id)
308
+
309
+ # Execute action
310
+ result = await tool.execute_action(body.tool_name, body.arguments or {})
311
+
312
+ return ExecuteToolResponse(
313
+ success=result.success,
314
+ data=result.data,
315
+ error=result.error,
316
+ tool_name=result.tool_name,
317
+ execution_time_ms=result.execution_time_ms,
318
+ )
319
+
320
+
321
+ # =============================================================================
322
+ # Convenience Endpoints (direct action access)
323
+ # =============================================================================
324
+
325
+ @router.get("/markets/perpetual")
326
+ async def get_perpetual_markets(
327
+ request: Request,
328
+ user_id: str = Depends(get_user_id),
329
+ ):
330
+ """Get all perpetual markets"""
331
+ tool = get_hyperliquid_tool(request)
332
+ tool.set_user_context(user_id)
333
+ result = await tool.execute_action("get_perpetual_markets", {})
334
+ return result.data if result.success else {"error": result.error}
335
+
336
+
337
+ @router.get("/markets/spot")
338
+ async def get_spot_markets(
339
+ request: Request,
340
+ user_id: str = Depends(get_user_id),
341
+ ):
342
+ """Get all spot markets"""
343
+ tool = get_hyperliquid_tool(request)
344
+ tool.set_user_context(user_id)
345
+ result = await tool.execute_action("get_spot_markets", {})
346
+ return result.data if result.success else {"error": result.error}
347
+
348
+
349
+ @router.get("/price/{coin}")
350
+ async def get_price(
351
+ request: Request,
352
+ coin: str,
353
+ user_id: str = Depends(get_user_id),
354
+ ):
355
+ """Get current price for a coin"""
356
+ tool = get_hyperliquid_tool(request)
357
+ tool.set_user_context(user_id)
358
+ result = await tool.execute_action("get_current_price", {"coin": coin})
359
+ return result.data if result.success else {"error": result.error}
360
+
361
+
362
+ @router.get("/orderbook/{coin}")
363
+ async def get_orderbook(
364
+ request: Request,
365
+ coin: str,
366
+ depth: int = 10,
367
+ user_id: str = Depends(get_user_id),
368
+ ):
369
+ """Get orderbook for a coin"""
370
+ tool = get_hyperliquid_tool(request)
371
+ tool.set_user_context(user_id)
372
+ result = await tool.execute_action("get_orderbook", {"coin": coin, "depth": depth})
373
+ return result.data if result.success else {"error": result.error}
374
+
375
+
376
+ @router.get("/funding/{coin}")
377
+ async def get_funding(
378
+ request: Request,
379
+ coin: str,
380
+ user_id: str = Depends(get_user_id),
381
+ ):
382
+ """Get funding rate for a coin"""
383
+ tool = get_hyperliquid_tool(request)
384
+ tool.set_user_context(user_id)
385
+ result = await tool.execute_action("get_funding_rate", {"coin": coin})
386
+ return result.data if result.success else {"error": result.error}
387
+
388
+
389
+ @router.get("/account")
390
+ async def get_account(
391
+ request: Request,
392
+ user_id: str = Depends(get_user_id),
393
+ ):
394
+ """Get account state"""
395
+ tool = get_hyperliquid_tool(request)
396
+ tool.set_user_context(user_id)
397
+ result = await tool.execute_action("get_account_state", {})
398
+ return result.data if result.success else {"error": result.error}
399
+
400
+
401
+ @router.get("/balances/spot")
402
+ async def get_spot_balances(
403
+ request: Request,
404
+ user_id: str = Depends(get_user_id),
405
+ ):
406
+ """Get spot balances"""
407
+ tool = get_hyperliquid_tool(request)
408
+ tool.set_user_context(user_id)
409
+ result = await tool.execute_action("get_spot_balances", {})
410
+ return result.data if result.success else {"error": result.error}
411
+
412
+
413
+ @router.get("/orders/open")
414
+ async def get_open_orders(
415
+ request: Request,
416
+ user_id: str = Depends(get_user_id),
417
+ ):
418
+ """Get open orders"""
419
+ tool = get_hyperliquid_tool(request)
420
+ tool.set_user_context(user_id)
421
+ result = await tool.execute_action("get_open_orders", {})
422
+ return result.data if result.success else {"error": result.error}
423
+
424
+
425
+ # =============================================================================
426
+ # Audit & Stats Endpoints
427
+ # =============================================================================
428
+
429
+ @router.get("/audit", response_model=AuditLogResponse)
430
+ async def get_audit_log(
431
+ request: Request,
432
+ limit: int = 50,
433
+ action: Optional[str] = None,
434
+ user_id: str = Depends(get_user_id),
435
+ ):
436
+ """Get audit log entries"""
437
+ db = get_hyperliquid_db(request)
438
+ entries = await db.get_audit_log(user_id, limit, action)
439
+ return AuditLogResponse(entries=entries, count=len(entries))
440
+
441
+
442
+ @router.get("/stats", response_model=TradingStatsResponse)
443
+ async def get_trading_stats(
444
+ request: Request,
445
+ user_id: str = Depends(get_user_id),
446
+ ):
447
+ """Get trading statistics"""
448
+ db = get_hyperliquid_db(request)
449
+ stats = await db.get_trading_stats(user_id)
450
+ return TradingStatsResponse(**stats)
api/interfaces.py ADDED
@@ -0,0 +1,207 @@
1
+ """Generic interfaces for API-agent communication.
2
+
3
+ These interfaces provide platform-agnostic abstractions for message handling,
4
+ allowing the system to work with multiple communication channels (HTTP, WebSocket, etc.).
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import Dict, Any, Optional, List, Union
9
+ from dataclasses import dataclass, field
10
+ from datetime import datetime
11
+ from enum import Enum
12
+
13
+
14
+ class MessageType(Enum):
15
+ """Types of messages supported by the system."""
16
+ TEXT = "text"
17
+ COMMAND = "command"
18
+ CALLBACK = "callback"
19
+ MEDIA = "media"
20
+ SYSTEM = "system"
21
+
22
+
23
+ class ResponseFormat(Enum):
24
+ """Response format types."""
25
+ TEXT = "text"
26
+ JSON = "json"
27
+ MARKDOWN = "markdown"
28
+ HTML = "html"
29
+ STREAM = "stream"
30
+
31
+
32
+ @dataclass
33
+ class MessageContext:
34
+ """Context information for a message."""
35
+ user_id: str
36
+ chat_id: str
37
+ message_id: Optional[str] = None
38
+ platform: str = "api" # api, web
39
+ chat_type: str = "private" # private only
40
+ timestamp: datetime = field(default_factory=datetime.now)
41
+ metadata: Dict[str, Any] = field(default_factory=dict)
42
+
43
+ def get_conversation_id(self) -> str:
44
+ """Generate a unique conversation ID."""
45
+ if self.chat_type == "private":
46
+ return f"{self.platform}_{self.user_id}"
47
+ return f"{self.platform}_{self.chat_id}"
48
+
49
+ def to_dict(self) -> Dict[str, Any]:
50
+ """Convert context to dictionary."""
51
+ return {
52
+ "user_id": self.user_id,
53
+ "chat_id": self.chat_id,
54
+ "message_id": self.message_id,
55
+ "platform": self.platform,
56
+ "chat_type": self.chat_type,
57
+ "timestamp": self.timestamp.isoformat(),
58
+ "metadata": self.metadata
59
+ }
60
+
61
+
62
+ @dataclass
63
+ class GenericMessage:
64
+ """Platform-agnostic message representation."""
65
+ content: str
66
+ context: MessageContext
67
+ type: MessageType = MessageType.TEXT
68
+ attachments: List[Dict[str, Any]] = field(default_factory=list)
69
+ reply_to: Optional[str] = None
70
+
71
+ @property
72
+ def is_command(self) -> bool:
73
+ """Check if message is a command."""
74
+ return self.type == MessageType.COMMAND or self.content.startswith("/")
75
+
76
+ def get_command_parts(self) -> tuple[str, str]:
77
+ """Extract command and arguments."""
78
+ if not self.is_command:
79
+ return "", ""
80
+
81
+ text = self.content.strip()
82
+ if text.startswith("/"):
83
+ text = text[1:]
84
+
85
+ parts = text.split(None, 1)
86
+ command = parts[0] if parts else ""
87
+ args = parts[1] if len(parts) > 1 else ""
88
+ return command, args
89
+
90
+ def to_dict(self) -> Dict[str, Any]:
91
+ """Convert message to dictionary."""
92
+ return {
93
+ "content": self.content,
94
+ "type": self.type.value,
95
+ "context": self.context.to_dict(),
96
+ "attachments": self.attachments,
97
+ "reply_to": self.reply_to
98
+ }
99
+
100
+
101
+ @dataclass
102
+ class GenericResponse:
103
+ """Platform-agnostic response representation."""
104
+ content: str
105
+ format: ResponseFormat = ResponseFormat.TEXT
106
+ metadata: Dict[str, Any] = field(default_factory=dict)
107
+ attachments: List[Dict[str, Any]] = field(default_factory=list)
108
+ suggestions: List[str] = field(default_factory=list)
109
+ callback_data: Optional[Dict[str, Any]] = None
110
+
111
+ def to_dict(self) -> Dict[str, Any]:
112
+ """Convert response to dictionary."""
113
+ return {
114
+ "content": self.content,
115
+ "format": self.format.value,
116
+ "metadata": self.metadata,
117
+ "attachments": self.attachments,
118
+ "suggestions": self.suggestions,
119
+ "callback_data": self.callback_data
120
+ }
121
+
122
+
123
+ class IMessageProcessor(ABC):
124
+ """Interface for components that process messages."""
125
+
126
+ @abstractmethod
127
+ async def process_message(self, message: GenericMessage) -> GenericResponse:
128
+ """Process a message and return a response."""
129
+ pass
130
+
131
+ @abstractmethod
132
+ async def can_handle(self, message: GenericMessage) -> bool:
133
+ """Check if this processor can handle the message."""
134
+ pass
135
+
136
+
137
+ class IConversationManager(ABC):
138
+ """Interface for conversation management."""
139
+
140
+ @abstractmethod
141
+ async def get_or_create_conversation(self, context: MessageContext) -> Any:
142
+ """Get or create a conversation for the given context."""
143
+ pass
144
+
145
+ @abstractmethod
146
+ async def add_message(self, conversation_id: str, message: GenericMessage) -> None:
147
+ """Add a message to the conversation."""
148
+ pass
149
+
150
+ @abstractmethod
151
+ async def add_response(self, conversation_id: str, response: GenericResponse) -> None:
152
+ """Add a response to the conversation."""
153
+ pass
154
+
155
+ @abstractmethod
156
+ async def get_history(self, conversation_id: str, limit: int = 10) -> List[Union[GenericMessage, GenericResponse]]:
157
+ """Get conversation history."""
158
+ pass
159
+
160
+ @abstractmethod
161
+ async def clear_conversation(self, conversation_id: str) -> None:
162
+ """Clear a conversation."""
163
+ pass
164
+
165
+
166
+ class IAgent(ABC):
167
+ """Interface for AI agents."""
168
+
169
+ @abstractmethod
170
+ async def process(self, message: GenericMessage, conversation: Any = None) -> GenericResponse:
171
+ """Process a message with optional conversation context."""
172
+ pass
173
+
174
+ @abstractmethod
175
+ async def initialize(self) -> None:
176
+ """Initialize the agent."""
177
+ pass
178
+
179
+ @abstractmethod
180
+ async def shutdown(self) -> None:
181
+ """Shutdown the agent."""
182
+ pass
183
+
184
+ @property
185
+ @abstractmethod
186
+ def capabilities(self) -> List[str]:
187
+ """List of agent capabilities."""
188
+ pass
189
+
190
+
191
+ class IMessageRouter(ABC):
192
+ """Interface for message routing."""
193
+
194
+ @abstractmethod
195
+ async def route(self, message: GenericMessage) -> IAgent:
196
+ """Route a message to the appropriate agent."""
197
+ pass
198
+
199
+ @abstractmethod
200
+ async def register_agent(self, pattern: str, agent: IAgent) -> None:
201
+ """Register an agent for a routing pattern."""
202
+ pass
203
+
204
+ @abstractmethod
205
+ async def unregister_agent(self, pattern: str) -> None:
206
+ """Unregister an agent."""
207
+ pass