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,400 @@
1
+ /**
2
+ * Admin User Detail JavaScript
3
+ * Handles loading user details, token verification, credits, and blocking
4
+ */
5
+
6
+ (function() {
7
+ 'use strict';
8
+
9
+ // Use shared utilities
10
+ const { apiCall, formatDateTime, formatCredits, timeAgo, showAlert, showConfirm } = AdminUtils;
11
+
12
+ const userId = window.TARGET_USER_ID;
13
+ let userData = null;
14
+
15
+ // Format wallet with more characters for detail view
16
+ function formatWallet(address) {
17
+ if (!address) return '-';
18
+ return `${address.slice(0, 10)}...${address.slice(-8)}`;
19
+ }
20
+
21
+ // Load user details
22
+ async function loadUserDetails() {
23
+ try {
24
+ const user = await apiCall(`/admin/users/${userId}`);
25
+ userData = user;
26
+
27
+ // Update header
28
+ document.getElementById('user-wallet').textContent = formatWallet(user.wallet_address);
29
+ document.getElementById('user-id-display').textContent = `User ID: ${user.user_id}`;
30
+
31
+ // Update badges
32
+ let badges = `
33
+ <span class="badge badge-tier tier-${user.tier}">${user.tier}</span>
34
+ <span class="badge badge-role role-${user.role}">${user.role}</span>
35
+ `;
36
+ document.getElementById('user-badges').innerHTML = badges;
37
+
38
+ // Update identity info
39
+ document.getElementById('info-email').textContent = user.email || '-';
40
+ document.getElementById('info-chain').textContent = user.current_wallet_chain || 'ethereum';
41
+ document.getElementById('info-created').textContent = formatDateTime(user.created_at);
42
+
43
+ // Update role/tier dropdowns
44
+ document.getElementById('select-role').value = user.role;
45
+ document.getElementById('select-tier').value = user.tier;
46
+
47
+ } catch (error) {
48
+ console.error('Failed to load user:', error);
49
+ alert('Failed to load user: ' + error.message);
50
+ }
51
+ }
52
+
53
+ // Load user credits
54
+ async function loadCredits() {
55
+ try {
56
+ const credits = await apiCall(`/admin/users/${userId}/credits`);
57
+
58
+ document.getElementById('info-balance').textContent = formatCredits(credits.balance);
59
+ document.getElementById('info-lifetime-earned').textContent = formatCredits(credits.lifetime_earned);
60
+ document.getElementById('info-lifetime-spent').textContent = formatCredits(credits.lifetime_spent);
61
+
62
+ // Render transactions
63
+ const tbody = document.getElementById('transactions-tbody');
64
+ if (!credits.recent_transactions || credits.recent_transactions.length === 0) {
65
+ tbody.innerHTML = '<tr><td colspan="4" class="empty-state">No transactions</td></tr>';
66
+ return;
67
+ }
68
+
69
+ let html = '';
70
+ for (const tx of credits.recent_transactions.slice(0, 10)) {
71
+ const amountClass = tx.amount > 0 ? 'amount-positive' : 'amount-negative';
72
+ const amountPrefix = tx.amount > 0 ? '+' : '';
73
+ html += `
74
+ <tr>
75
+ <td>${formatDateTime(tx.timestamp)}</td>
76
+ <td class="${amountClass}">${amountPrefix}${formatCredits(tx.amount)}</td>
77
+ <td>${tx.transaction_type}</td>
78
+ <td>${tx.reason || '-'}</td>
79
+ </tr>
80
+ `;
81
+ }
82
+ tbody.innerHTML = html;
83
+
84
+ } catch (error) {
85
+ console.error('Failed to load credits:', error);
86
+ }
87
+ }
88
+
89
+ // Load block status
90
+ async function loadBlockStatus() {
91
+ try {
92
+ const status = await apiCall(`/admin/users/${userId}/block-status`);
93
+
94
+ const container = document.getElementById('block-status');
95
+ const btn = document.getElementById('btn-block');
96
+
97
+ if (status.is_blocked) {
98
+ container.classList.add('blocked');
99
+ container.innerHTML = `
100
+ <span style="color: var(--accent-red);">BLOCKED</span>
101
+ <div class="block-reason">Reason: ${status.blocked_reason || 'Not specified'}</div>
102
+ <div class="block-reason">Blocked at: ${formatDateTime(status.blocked_at)}</div>
103
+ <div class="block-reason">By: ${status.blocked_by || 'Unknown'}</div>
104
+ `;
105
+ btn.textContent = 'Unblock User';
106
+ btn.classList.remove('btn-danger');
107
+ btn.classList.add('btn-success');
108
+
109
+ // Add blocked badge
110
+ const badges = document.getElementById('user-badges');
111
+ if (!badges.querySelector('.badge-blocked')) {
112
+ badges.innerHTML += '<span class="badge badge-blocked">BLOCKED</span>';
113
+ }
114
+ } else {
115
+ container.classList.remove('blocked');
116
+ container.innerHTML = '<span style="color: var(--accent-green);">Not blocked</span>';
117
+ btn.textContent = 'Block User';
118
+ btn.classList.remove('btn-success');
119
+ btn.classList.add('btn-danger');
120
+ }
121
+
122
+ } catch (error) {
123
+ console.error('Failed to load block status:', error);
124
+ }
125
+ }
126
+
127
+ // Load sessions summary
128
+ async function loadSessions() {
129
+ try {
130
+ const sessions = await apiCall(`/admin/users/${userId}/sessions?limit=10`);
131
+
132
+ document.getElementById('sessions-total').textContent = formatCredits(sessions.total_sessions);
133
+ document.getElementById('sessions-spent').textContent = formatCredits(sessions.total_spent);
134
+ document.getElementById('info-total-sessions').textContent = formatCredits(sessions.total_sessions);
135
+
136
+ } catch (error) {
137
+ console.error('Failed to load sessions:', error);
138
+ }
139
+ }
140
+
141
+ // Load audit trail
142
+ async function loadAuditTrail() {
143
+ try {
144
+ const events = await apiCall(`/admin/users/${userId}/audit?limit=20`);
145
+
146
+ const container = document.getElementById('audit-list');
147
+
148
+ if (!events || events.length === 0) {
149
+ container.innerHTML = '<div class="empty-state">No audit events</div>';
150
+ return;
151
+ }
152
+
153
+ let html = '';
154
+ for (const event of events) {
155
+ html += `
156
+ <div class="audit-item">
157
+ <span class="audit-time">${formatDateTime(event.timestamp)}</span>
158
+ <span class="audit-type ${event.event_type}">${event.event_type.replace('_', ' ')}</span>
159
+ <span class="audit-action">${event.action}</span>
160
+ </div>
161
+ `;
162
+ }
163
+ container.innerHTML = html;
164
+
165
+ } catch (error) {
166
+ console.error('Failed to load audit trail:', error);
167
+ document.getElementById('audit-list').innerHTML = '<div class="empty-state">Failed to load audit trail</div>';
168
+ }
169
+ }
170
+
171
+ // Verify token
172
+ async function verifyToken() {
173
+ const btn = document.getElementById('btn-verify-token');
174
+ btn.disabled = true;
175
+ btn.textContent = 'Verifying...';
176
+
177
+ try {
178
+ const result = await apiCall(`/admin/users/${userId}/verify-token`, {
179
+ method: 'POST'
180
+ });
181
+
182
+ // Update token status display
183
+ const container = document.getElementById('token-status');
184
+ const icon = document.getElementById('token-icon');
185
+ const count = document.getElementById('token-count');
186
+ const verified = document.getElementById('token-verified');
187
+ const tokenIds = document.getElementById('token-ids');
188
+
189
+ if (result.new_count > 0) {
190
+ container.classList.add('has-token');
191
+ container.classList.remove('no-token');
192
+ icon.textContent = '✓';
193
+ count.textContent = `${result.new_count} DEN Token(s)`;
194
+ } else {
195
+ container.classList.remove('has-token');
196
+ container.classList.add('no-token');
197
+ icon.textContent = '✗';
198
+ count.textContent = 'No DEN Tokens';
199
+ }
200
+
201
+ verified.textContent = `Last verified: ${formatDateTime(result.verified_at)}`;
202
+
203
+ if (result.token_ids && result.token_ids.length > 0) {
204
+ tokenIds.textContent = `Token IDs: ${result.token_ids.join(', ')}`;
205
+ } else {
206
+ tokenIds.textContent = '';
207
+ }
208
+
209
+ // Show result message
210
+ let message = `Token verification complete.\n`;
211
+ message += `Previous: ${result.previous_count} -> New: ${result.new_count}\n`;
212
+ if (result.tier_changed) {
213
+ message += `Tier changed: ${result.previous_tier} -> ${result.new_tier}\n`;
214
+ }
215
+ if (result.bonuses_granted > 0) {
216
+ message += `Bonuses granted: ${result.bonuses_granted}\n`;
217
+ }
218
+ if (result.bonuses_already_claimed > 0) {
219
+ message += `Bonuses already claimed: ${result.bonuses_already_claimed}`;
220
+ }
221
+ alert(message);
222
+
223
+ // Reload data
224
+ loadUserDetails();
225
+ loadCredits();
226
+
227
+ } catch (error) {
228
+ console.error('Token verification failed:', error);
229
+ alert('Token verification failed: ' + error.message);
230
+ } finally {
231
+ btn.disabled = false;
232
+ btn.textContent = 'Verify Token';
233
+ }
234
+ }
235
+
236
+ // Save role
237
+ async function saveRole() {
238
+ const newRole = document.getElementById('select-role').value;
239
+ try {
240
+ await apiCall(`/admin/users/${userId}/role`, {
241
+ method: 'POST',
242
+ body: JSON.stringify({ role: newRole })
243
+ });
244
+ alert('Role updated successfully');
245
+ loadUserDetails();
246
+ loadAuditTrail();
247
+ } catch (error) {
248
+ alert('Failed to update role: ' + error.message);
249
+ }
250
+ }
251
+
252
+ // Save tier
253
+ async function saveTier() {
254
+ const newTier = document.getElementById('select-tier').value;
255
+ try {
256
+ await apiCall(`/admin/users/${userId}/tier`, {
257
+ method: 'POST',
258
+ body: JSON.stringify({ tier: newTier })
259
+ });
260
+ alert('Tier updated successfully');
261
+ loadUserDetails();
262
+ loadAuditTrail();
263
+ } catch (error) {
264
+ alert('Failed to update tier: ' + error.message);
265
+ }
266
+ }
267
+
268
+ // Add credits
269
+ async function addCredits() {
270
+ const amount = parseInt(document.getElementById('credits-amount').value);
271
+ const reason = document.getElementById('credits-reason').value;
272
+
273
+ if (!amount || amount <= 0) {
274
+ alert('Please enter a valid amount');
275
+ return;
276
+ }
277
+
278
+ try {
279
+ await apiCall(`/admin/users/${userId}/credits/add`, {
280
+ method: 'POST',
281
+ body: JSON.stringify({
282
+ amount: amount,
283
+ reason: reason || 'Admin grant',
284
+ transaction_type: 'admin_grant'
285
+ })
286
+ });
287
+ alert(`Added ${amount} credits successfully`);
288
+ document.getElementById('credits-amount').value = '';
289
+ document.getElementById('credits-reason').value = '';
290
+ loadCredits();
291
+ loadAuditTrail();
292
+ } catch (error) {
293
+ alert('Failed to add credits: ' + error.message);
294
+ }
295
+ }
296
+
297
+ // Deduct credits
298
+ async function deductCredits() {
299
+ const amount = parseInt(document.getElementById('credits-amount').value);
300
+ const reason = document.getElementById('credits-reason').value;
301
+
302
+ if (!amount || amount <= 0) {
303
+ alert('Please enter a valid amount');
304
+ return;
305
+ }
306
+
307
+ try {
308
+ await apiCall(`/admin/users/${userId}/credits/deduct`, {
309
+ method: 'POST',
310
+ body: JSON.stringify({
311
+ amount: amount,
312
+ reason: reason || 'Admin deduction',
313
+ transaction_type: 'admin_deduct'
314
+ })
315
+ });
316
+ alert(`Deducted ${amount} credits successfully`);
317
+ document.getElementById('credits-amount').value = '';
318
+ document.getElementById('credits-reason').value = '';
319
+ loadCredits();
320
+ loadAuditTrail();
321
+ } catch (error) {
322
+ alert('Failed to deduct credits: ' + error.message);
323
+ }
324
+ }
325
+
326
+ // Block/unblock user
327
+ async function toggleBlock() {
328
+ const status = await apiCall(`/admin/users/${userId}/block-status`);
329
+
330
+ if (status.is_blocked) {
331
+ // Unblock
332
+ if (confirm('Are you sure you want to unblock this user?')) {
333
+ try {
334
+ await apiCall(`/admin/users/${userId}/unblock`, { method: 'POST' });
335
+ alert('User unblocked successfully');
336
+ loadBlockStatus();
337
+ loadAuditTrail();
338
+ } catch (error) {
339
+ alert('Failed to unblock user: ' + error.message);
340
+ }
341
+ }
342
+ } else {
343
+ // Show block modal
344
+ document.getElementById('block-modal').classList.remove('hidden');
345
+ }
346
+ }
347
+
348
+ // Confirm block
349
+ async function confirmBlock() {
350
+ const reason = document.getElementById('block-reason').value.trim();
351
+ if (!reason) {
352
+ alert('Please enter a reason for blocking');
353
+ return;
354
+ }
355
+
356
+ try {
357
+ await apiCall(`/admin/users/${userId}/block`, {
358
+ method: 'POST',
359
+ body: JSON.stringify({ reason: reason })
360
+ });
361
+ document.getElementById('block-modal').classList.add('hidden');
362
+ document.getElementById('block-reason').value = '';
363
+ alert('User blocked successfully');
364
+ loadBlockStatus();
365
+ loadAuditTrail();
366
+ } catch (error) {
367
+ alert('Failed to block user: ' + error.message);
368
+ }
369
+ }
370
+
371
+ // Setup event listeners
372
+ function setupEventListeners() {
373
+ document.getElementById('btn-verify-token').addEventListener('click', verifyToken);
374
+ document.getElementById('btn-save-role').addEventListener('click', saveRole);
375
+ document.getElementById('btn-save-tier').addEventListener('click', saveTier);
376
+ document.getElementById('btn-add-credits').addEventListener('click', addCredits);
377
+ document.getElementById('btn-deduct-credits').addEventListener('click', deductCredits);
378
+ document.getElementById('btn-block').addEventListener('click', toggleBlock);
379
+
380
+ // Modal controls
381
+ document.getElementById('modal-close').addEventListener('click', () => {
382
+ document.getElementById('block-modal').classList.add('hidden');
383
+ });
384
+ document.getElementById('btn-cancel-block').addEventListener('click', () => {
385
+ document.getElementById('block-modal').classList.add('hidden');
386
+ });
387
+ document.getElementById('btn-confirm-block').addEventListener('click', confirmBlock);
388
+ }
389
+
390
+ // Initialize
391
+ document.addEventListener('DOMContentLoaded', () => {
392
+ setupEventListeners();
393
+ loadUserDetails();
394
+ loadCredits();
395
+ loadBlockStatus();
396
+ loadSessions();
397
+ loadAuditTrail();
398
+ });
399
+
400
+ })();
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Admin Users List JavaScript
3
+ * Handles user search, filtering, and pagination
4
+ */
5
+
6
+ (function() {
7
+ 'use strict';
8
+
9
+ // Use shared utilities
10
+ const { apiCall, formatWallet, formatDate, formatCredits } = AdminUtils;
11
+
12
+ // State
13
+ let currentPage = 0;
14
+ let pageSize = 50;
15
+ let totalUsers = 0;
16
+ let currentFilters = {
17
+ q: '',
18
+ field: 'all',
19
+ tier: '',
20
+ role: ''
21
+ };
22
+
23
+ // Load users
24
+ async function loadUsers() {
25
+ const tbody = document.getElementById('users-tbody');
26
+ tbody.innerHTML = '<tr><td colspan="7" class="loading">Loading users</td></tr>';
27
+
28
+ try {
29
+ let endpoint;
30
+ const offset = currentPage * pageSize;
31
+
32
+ if (currentFilters.q) {
33
+ // Use search endpoint
34
+ const params = new URLSearchParams({
35
+ q: currentFilters.q,
36
+ field: currentFilters.field,
37
+ limit: pageSize,
38
+ offset: offset
39
+ });
40
+ endpoint = `/admin/users/search?${params}`;
41
+ } else {
42
+ // Use list endpoint with filters
43
+ const params = new URLSearchParams({
44
+ limit: pageSize,
45
+ offset: offset
46
+ });
47
+ if (currentFilters.tier) params.append('tier', currentFilters.tier);
48
+ if (currentFilters.role) params.append('role', currentFilters.role);
49
+ endpoint = `/admin/users?${params}`;
50
+ }
51
+
52
+ const users = await apiCall(endpoint);
53
+
54
+ if (!users || users.length === 0) {
55
+ tbody.innerHTML = '<tr><td colspan="7" class="empty-state">No users found</td></tr>';
56
+ updatePagination(0);
57
+ return;
58
+ }
59
+
60
+ let html = '';
61
+ for (const user of users) {
62
+ const blockedClass = user.is_blocked ? 'blocked-indicator' : '';
63
+ html += `
64
+ <tr>
65
+ <td class="wallet ${blockedClass}">
66
+ ${user.is_blocked ? '[B] ' : ''}${formatWallet(user.wallet_address)}
67
+ </td>
68
+ <td>
69
+ <span class="tier tier-${user.tier}">${user.tier}</span>
70
+ </td>
71
+ <td>
72
+ <span class="role role-${user.role}">${user.role}</span>
73
+ </td>
74
+ <td class="credits">${formatCredits(user.balance)}</td>
75
+ <td>
76
+ <span class="token-count">
77
+ ${user.den_token_count > 0 ? '&#10004;' : '&#10008;'} ${user.den_token_count || 0}
78
+ </span>
79
+ </td>
80
+ <td>${formatDate(user.created_at)}</td>
81
+ <td class="actions">
82
+ <a href="/admin/users/${user.user_id}" class="btn-view">View</a>
83
+ </td>
84
+ </tr>
85
+ `;
86
+ }
87
+ tbody.innerHTML = html;
88
+
89
+ // Update pagination (estimate total based on results)
90
+ totalUsers = users.length < pageSize ? (currentPage * pageSize + users.length) : ((currentPage + 2) * pageSize);
91
+ updatePagination(users.length);
92
+
93
+ } catch (error) {
94
+ console.error('Failed to load users:', error);
95
+ tbody.innerHTML = `<tr><td colspan="7" class="empty-state">Error: ${error.message}</td></tr>`;
96
+ }
97
+ }
98
+
99
+ // Update pagination
100
+ function updatePagination(resultsCount) {
101
+ const startNum = currentPage * pageSize + 1;
102
+ const endNum = currentPage * pageSize + resultsCount;
103
+
104
+ document.getElementById('pagination-info').textContent =
105
+ `Showing ${startNum}-${endNum} users`;
106
+
107
+ const btnPrev = document.getElementById('btn-prev');
108
+ const btnNext = document.getElementById('btn-next');
109
+
110
+ btnPrev.disabled = currentPage === 0;
111
+ btnNext.disabled = resultsCount < pageSize;
112
+ }
113
+
114
+ // Setup event listeners
115
+ function setupEventListeners() {
116
+ // Search button
117
+ document.getElementById('btn-search').addEventListener('click', () => {
118
+ currentFilters.q = document.getElementById('search-input').value.trim();
119
+ currentFilters.field = document.getElementById('search-field').value;
120
+ currentFilters.tier = document.getElementById('filter-tier').value;
121
+ currentFilters.role = document.getElementById('filter-role').value;
122
+ currentPage = 0;
123
+ loadUsers();
124
+ });
125
+
126
+ // Search on Enter
127
+ document.getElementById('search-input').addEventListener('keypress', (e) => {
128
+ if (e.key === 'Enter') {
129
+ document.getElementById('btn-search').click();
130
+ }
131
+ });
132
+
133
+ // Filter changes
134
+ ['filter-tier', 'filter-role'].forEach(id => {
135
+ document.getElementById(id).addEventListener('change', () => {
136
+ currentFilters.tier = document.getElementById('filter-tier').value;
137
+ currentFilters.role = document.getElementById('filter-role').value;
138
+ currentPage = 0;
139
+ loadUsers();
140
+ });
141
+ });
142
+
143
+ // Pagination
144
+ document.getElementById('btn-prev').addEventListener('click', () => {
145
+ if (currentPage > 0) {
146
+ currentPage--;
147
+ loadUsers();
148
+ }
149
+ });
150
+
151
+ document.getElementById('btn-next').addEventListener('click', () => {
152
+ currentPage++;
153
+ loadUsers();
154
+ });
155
+ }
156
+
157
+ // Check for URL params on load
158
+ function checkUrlParams() {
159
+ const params = new URLSearchParams(window.location.search);
160
+ if (params.has('q')) {
161
+ const query = params.get('q');
162
+ document.getElementById('search-input').value = query;
163
+ currentFilters.q = query;
164
+ }
165
+ }
166
+
167
+ // Initialize
168
+ document.addEventListener('DOMContentLoaded', () => {
169
+ checkUrlParams();
170
+ setupEventListeners();
171
+ loadUsers();
172
+ });
173
+
174
+ })();