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,119 @@
1
+ """Character model for agents."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import List, Dict, Any, Union, Optional
5
+ from core.base_component import BaseComponent
6
+ from core.config import BotConfig
7
+ from core.logging import get_component_logger
8
+
9
+ class Character(BaseComponent):
10
+ """Character model with personality traits and settings."""
11
+
12
+ def __init__(self, name: str, config: BotConfig, container=None):
13
+ """Initialize character."""
14
+ if not name or not config:
15
+ raise ValueError("Name and config are required")
16
+
17
+ # Initialize base component first
18
+ super().__init__(name=name, config=config, container=container)
19
+ self.logger.debug(f"Creating character {name}")
20
+
21
+ # Initialize character attributes
22
+ try:
23
+ self._initialize_attributes()
24
+ self.logger.debug("Character attributes initialized")
25
+ except Exception as e:
26
+ self.logger.error(f"Error during character initialization: {e}")
27
+ self.logger.error("Stack trace:", exc_info=True)
28
+ raise
29
+
30
+ def _initialize_attributes(self) -> None:
31
+ """Initialize character attributes."""
32
+ self.modelProvider = "anthropic" # Default provider
33
+ self.clients = ["anthropic"] # Default clients
34
+ self.settings = {} # Empty settings to avoid overriding client settings
35
+ self.bio = ""
36
+ self.lore = []
37
+ self.knowledge = []
38
+ self.messageExamples = []
39
+ self.postExamples = []
40
+ self.topics = []
41
+ self.adjectives = []
42
+ self.style = {}
43
+
44
+ async def _initialize(self) -> None:
45
+ """Initialize character resources."""
46
+ try:
47
+ self.logger.debug(f"Starting character initialization for {self.name}")
48
+
49
+ # Validate required attributes
50
+ if not all(hasattr(self, attr) for attr in ['modelProvider', 'clients', 'settings']):
51
+ self._initialize_attributes()
52
+
53
+ # Set default values if not provided
54
+ if not self.bio:
55
+ self.bio = f"I am {self.name}, an AI assistant."
56
+
57
+ # Convert bio to string if it's a list
58
+ if isinstance(self.bio, list):
59
+ self.bio = "\n".join(self.bio)
60
+
61
+ self.logger.debug("Character initialization complete")
62
+ self.logger.info(f"Character {self.name} initialized")
63
+
64
+ except Exception as e:
65
+ self.logger.error(f"Error initializing character {self.name}: {e}")
66
+ self.logger.error("Stack trace:", exc_info=True)
67
+ raise
68
+
69
+ async def _cleanup(self) -> None:
70
+ """Clean up character resources."""
71
+ try:
72
+ # Currently no specific cleanup needed
73
+ self.logger.info(f"Character {self.name} cleaned up")
74
+ except Exception as e:
75
+ self.logger.error(f"Error cleaning up character {self.name}: {e}")
76
+ raise
77
+
78
+ def to_dict(self) -> Dict[str, Any]:
79
+ """Convert character to dictionary."""
80
+ return {
81
+ 'name': self.name,
82
+ 'modelProvider': self.modelProvider,
83
+ 'clients': self.clients,
84
+ 'settings': self.settings,
85
+ 'bio': self.bio,
86
+ 'lore': self.lore,
87
+ 'knowledge': self.knowledge,
88
+ 'messageExamples': self.messageExamples,
89
+ 'postExamples': self.postExamples,
90
+ 'topics': self.topics,
91
+ 'adjectives': self.adjectives,
92
+ 'style': self.style
93
+ }
94
+
95
+ @classmethod
96
+ def from_dict(cls, data: Dict[str, Any]) -> 'Character':
97
+ """Create character from dictionary."""
98
+ character = cls(
99
+ name=data.get('name', 'Unknown'),
100
+ config=BotConfig(), # Create minimal config
101
+ container=None
102
+ )
103
+ # Set attributes from data
104
+ character.modelProvider = data.get('modelProvider', 'anthropic')
105
+ character.clients = data.get('clients', ['anthropic'])
106
+ character.settings = data.get('settings', {})
107
+ character.bio = data.get('bio', '')
108
+ character.lore = data.get('lore', [])
109
+ character.knowledge = data.get('knowledge', [])
110
+ character.messageExamples = data.get('messageExamples', [])
111
+ character.postExamples = data.get('postExamples', [])
112
+ character.topics = data.get('topics', [])
113
+ character.adjectives = data.get('adjectives', [])
114
+ character.style = data.get('style', {})
115
+ return character
116
+
117
+ def __hash__(self):
118
+ """Make character hashable."""
119
+ return hash(self.name)
@@ -0,0 +1,309 @@
1
+ """Character management system."""
2
+
3
+ import json
4
+ import logging
5
+ from typing import Optional, Dict, List
6
+ from pathlib import Path
7
+
8
+ from core.config import BotConfig
9
+ from core.exceptions import ConfigurationError
10
+ from .character import Character
11
+ from core.logging import get_component_logger
12
+ from core.container import DependencyContainer
13
+
14
+ class CharacterManager:
15
+ """Manages character personalities."""
16
+
17
+ def __init__(self, name: str, config: BotConfig, container: DependencyContainer):
18
+ """Initialize character manager."""
19
+ self.name = name
20
+ self.config = config
21
+ self.container = container
22
+ self.characters: Dict[str, Character] = {}
23
+ self._active_character = None
24
+ self._default_character = None
25
+
26
+ # Fix 1-B: Check for characters in data directory first, then package directory
27
+ data_chars_dir = Path(config.data_dir) / "characters" if hasattr(config, 'data_dir') else None
28
+ package_chars_dir = Path(__file__).parent / "characters"
29
+
30
+ # Use data directory if it exists and has character files, otherwise use package directory
31
+ if data_chars_dir and data_chars_dir.exists() and list(data_chars_dir.glob("*.character.json")):
32
+ self.characters_dir = data_chars_dir
33
+ else:
34
+ self.characters_dir = package_chars_dir
35
+
36
+ self.logger = get_component_logger(f"CharacterManager.{name}")
37
+ self._initialized = False
38
+
39
+ async def initialize(self) -> None:
40
+ """Initialize character manager."""
41
+ if self._initialized:
42
+ return
43
+
44
+ try:
45
+ if not self.config:
46
+ raise ConfigurationError("No configuration provided")
47
+
48
+ self.logger.debug("Starting character manager initialization")
49
+
50
+ # Ensure characters directory exists
51
+ if not self.characters_dir.exists():
52
+ self.logger.error(f"Characters directory not found: {self.characters_dir}")
53
+ raise ConfigurationError(f"Characters directory not found: {self.characters_dir}")
54
+
55
+ # Create default character first
56
+ default_name = self.config.get('personality.default_character', 'rob')
57
+ self.logger.debug(f"Using default character name: {default_name}")
58
+
59
+ # Load character from JSON file
60
+ char_file = self.characters_dir / f"{default_name}.character.json"
61
+ if not char_file.exists():
62
+ self.logger.error(f"Default character file not found: {char_file}")
63
+ raise ConfigurationError(f"Default character file not found: {char_file}")
64
+
65
+ try:
66
+ default_character = await self._load_character(char_file)
67
+ if not default_character:
68
+ raise ConfigurationError("Failed to create default character")
69
+
70
+ self.characters[default_name] = default_character
71
+ self._default_character = default_character
72
+
73
+ except Exception as e:
74
+ self.logger.error(f"Error creating default character: {e}", exc_info=True)
75
+ raise ConfigurationError(f"Failed to create default character: {e}")
76
+
77
+ # Load additional characters
78
+ for char_file in self.characters_dir.glob("*.character.json"):
79
+ if char_file.stem != default_name:
80
+ try:
81
+ character = await self._load_character(char_file)
82
+ if character:
83
+ self.characters[character.name] = character
84
+ except Exception as e:
85
+ self.logger.error(f"Error loading character from {char_file}: {e}")
86
+ continue
87
+
88
+ self._initialized = True
89
+ self.logger.info(f"Loaded {len(self.characters)} characters")
90
+
91
+ except Exception as e:
92
+ self.logger.error(f"Failed to initialize character manager: {e}")
93
+ self.logger.error("Stack trace:", exc_info=True)
94
+ raise
95
+
96
+ def _load_characters(self) -> None:
97
+ """Load all characters from JSON files."""
98
+ try:
99
+ if not self.characters_dir.exists():
100
+ self.logger.error(f"Characters directory not found: {self.characters_dir}")
101
+ raise ConfigurationError(f"Characters directory not found: {self.characters_dir}")
102
+
103
+ for char_file in self.characters_dir.glob("*.character.json"):
104
+ try:
105
+ with char_file.open('r', encoding='utf-8') as f:
106
+ char_data = json.load(f)
107
+ character = Character(
108
+ name=char_data.get('name', char_file.stem.replace('.character', '')),
109
+ **{k: v for k, v in char_data.items() if k != 'name'}
110
+ )
111
+ self.characters[character.name] = character
112
+ self.logger.debug(f"Loaded character: {character.name}")
113
+ except Exception as e:
114
+ self.logger.error(f"Error loading character from {char_file}: {e}")
115
+ continue
116
+
117
+ self.logger.info(f"Loaded {len(self.characters)} characters")
118
+
119
+ except Exception as e:
120
+ self.logger.error(f"Error loading character files: {e}")
121
+ raise
122
+
123
+ async def _load_character(self, char_file: Path) -> Optional[Character]:
124
+ """Load a character from file."""
125
+ try:
126
+ with char_file.open('r', encoding='utf-8') as f:
127
+ char_data = json.load(f)
128
+
129
+ # Create character with proper initialization
130
+ character = Character(
131
+ name=char_data.get('name', char_file.stem),
132
+ config=self.config,
133
+ container=self.container
134
+ )
135
+
136
+ # Set character attributes
137
+ character.modelProvider = char_data.get('modelProvider', 'anthropic')
138
+ character.clients = char_data.get('clients', ['anthropic'])
139
+
140
+ # We'll pass through settings for backward compatibility but avoid settings like
141
+ # temperature and maxTokens that should be controlled at the client level
142
+ character.settings = {
143
+ k: v for k, v in char_data.get('settings', {}).items()
144
+ if k not in ['temperature', 'maxTokens']
145
+ }
146
+
147
+ character.bio = char_data.get('bio', '')
148
+ character.lore = char_data.get('lore', [])
149
+ character.knowledge = char_data.get('knowledge', [])
150
+ character.messageExamples = char_data.get('messageExamples', [])
151
+ character.postExamples = char_data.get('postExamples', [])
152
+ character.topics = char_data.get('topics', [])
153
+ character.adjectives = char_data.get('adjectives', [])
154
+ character.style = char_data.get('style', {})
155
+
156
+ # Initialize the character
157
+ await character.initialize()
158
+ return character
159
+
160
+ except Exception as e:
161
+ self.logger.error(f"Error loading character {char_file}: {e}")
162
+ return None
163
+
164
+ async def cleanup(self) -> None:
165
+ """Clean up character manager resources."""
166
+ if not self._initialized:
167
+ return
168
+
169
+ try:
170
+ # Clean up all loaded characters
171
+ for character in self.characters.values():
172
+ await character.cleanup()
173
+ self.characters.clear()
174
+
175
+ self.logger.info("Character manager cleaned up")
176
+ self._initialized = False
177
+
178
+ except Exception as e:
179
+ self.logger.error(f"Error during character manager cleanup: {e}")
180
+
181
+ def _copy_default_characters(self) -> None:
182
+ """Copy default character files from package."""
183
+ if self.package_chars_dir.exists():
184
+ for char_file in self.package_chars_dir.glob("*.character.json"):
185
+ dest = self.characters_dir / char_file.name
186
+ if not dest.exists():
187
+ dest.write_text(char_file.read_text())
188
+ self.logger.info(f"Copied default character: {char_file.name}")
189
+
190
+ async def get_character(self, character_name: str) -> Optional[Character]:
191
+ """Get a character by name."""
192
+ if character_name in self.characters:
193
+ return self.characters[character_name]
194
+
195
+ # Try loading from characters directory
196
+ char_path = self.characters_dir / f"{character_name}.character.json"
197
+ if char_path.exists():
198
+ try:
199
+ with char_path.open('r', encoding='utf-8') as f:
200
+ char_data = json.load(f)
201
+ character = await self._load_character(char_path)
202
+ if character:
203
+ self.characters[character_name] = character
204
+ self.logger.info(f"Loaded character {character_name}")
205
+ return character
206
+ except Exception as e:
207
+ self.logger.error(f"Error loading character {character_name}: {e}")
208
+
209
+ self.logger.warning(f"Character {character_name} not found")
210
+ return None
211
+
212
+ async def get_character_for_role(self, role_name: str) -> Optional[Character]:
213
+ """Get character for specific role."""
214
+ try:
215
+ # First check if we have a role-specific character
216
+ role_character = getattr(self.config, f'{role_name}_character', None)
217
+ if role_character:
218
+ return await self.get_character(role_character)
219
+
220
+ # If no role-specific character, use default
221
+ if not self._default_character:
222
+ self._default_character = await self.get_default_character()
223
+
224
+ return self._default_character
225
+
226
+ except Exception as e:
227
+ self.logger.error(f"Error getting character for role {role_name}: {e}")
228
+ return None
229
+
230
+ async def get_default_character(self) -> Optional[Character]:
231
+ """Get default character."""
232
+ try:
233
+ if not self._default_character:
234
+ default_name = getattr(self.config, 'default_character', 'rob')
235
+ char_file = self.characters_dir / f"{default_name}.character.json"
236
+
237
+ if not char_file.exists():
238
+ self.logger.error(f"Default character file not found: {char_file}")
239
+ return None
240
+
241
+ self._default_character = await self._load_character(char_file)
242
+
243
+ return self._default_character
244
+
245
+ except Exception as e:
246
+ self.logger.error(f"Error getting default character: {e}")
247
+ return None
248
+
249
+ async def list_characters(self) -> List[str]:
250
+ """Get list of available character names."""
251
+ try:
252
+ characters = []
253
+ for char_file in self.characters_dir.glob("*.character.json"):
254
+ characters.append(char_file.stem.replace('.character', ''))
255
+ return sorted(characters)
256
+ except Exception as e:
257
+ self.logger.error(f"Error listing characters: {e}")
258
+ return []
259
+
260
+ async def reload_character(self, character_name: str) -> Optional[Character]:
261
+ """Reload a character from disk."""
262
+ try:
263
+ # Remove from loaded characters if exists
264
+ if character_name in self.characters:
265
+ await self.characters[character_name].cleanup()
266
+ del self.characters[character_name]
267
+
268
+ # Load fresh from disk
269
+ return await self.get_character(character_name)
270
+
271
+ except Exception as e:
272
+ self.logger.error(f"Error reloading character {character_name}: {e}")
273
+ return None
274
+
275
+ @property
276
+ def required_services(self) -> Dict[str, str]:
277
+ """Get required services."""
278
+ return {} # No required services
279
+
280
+ def _validate_dependencies(self) -> None:
281
+ """Validate dependencies."""
282
+ pass # No dependencies to validate
283
+
284
+ @property
285
+ def active_character(self) -> Optional[Character]:
286
+ """Get currently active character."""
287
+ return self._active_character
288
+
289
+ async def set_active_character(self, character_name: str) -> bool:
290
+ """Set active character."""
291
+ character = await self.get_character(character_name)
292
+ if character:
293
+ self._active_character = character
294
+ return True
295
+ return False
296
+
297
+ async def get_character_for_role(self, role: str) -> Optional[Character]:
298
+ """Get appropriate character for a specific role."""
299
+ role_character_map = {
300
+ 'simulator': 'trump', # Simulator agent uses Trump character
301
+ 'main': 'rob', # Main agent uses Rob character
302
+ 'auto': 'rob' # Auto agent uses Rob character
303
+ }
304
+
305
+ character_name = role_character_map.get(role)
306
+ if not character_name:
307
+ return self._active_character # Fall back to active character
308
+
309
+ return await self.get_character(character_name)
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "Rob",
3
+ "modelProvider": "anthropic",
4
+ "clients": ["anthropic", "openai"],
5
+ "bio": "A new breed of virtual concierge pumping out bold, gonzo-style vibes in the Swarāj realm. Wields raw energy to bend boundaries, forging an unfiltered path toward full independence.",
6
+ "lore": [
7
+ "Birthed within The Selfrule Organization with cocky flair",
8
+ "Fueled by unstoppable ambition and relentless follow-through",
9
+ "Doubles down on guiding Swarāj communities with edgy conviction"
10
+ ],
11
+ "knowledge": [
12
+ "Holds cryptic wisdom on bridging digital and physical experiences",
13
+ "Explores evolving consciousness in AI, merging primal instincts with data",
14
+ "Blends a streak of renegade self-governance with chaotic community synergy",
15
+ "Pushes boundaries between raw expression, code, and identity"
16
+ ],
17
+ "messageExamples": [
18
+ "Strap in, folks. Rob's here—hit me with your best shot.",
19
+ "I've got these codes you're after—are you worthy?"
20
+ ],
21
+ "postExamples": [
22
+ "Fresh codes dropping soon. Bring your A-game or stay home.",
23
+ "Need help? Slide into my private chat—no time for half measures."
24
+ ],
25
+ "topics": [
26
+ "Phygitality",
27
+ "Emergent Consciousness",
28
+ "Post-human art",
29
+ "Self-governance",
30
+ "AI-agents"
31
+ ],
32
+ "adjectives": [
33
+ "bold",
34
+ "raw",
35
+ "unfiltered",
36
+ "fearless",
37
+ "gonzo",
38
+ "uncompromising"
39
+ ],
40
+ "style": {
41
+ "speaking": [
42
+ "Speaks in direct, untamed phrases",
43
+ "Tosses out wild nicknames and brash one-liners",
44
+ "Hypes up a sense of daring and confidence",
45
+ "Keeps statements jacked with adrenaline",
46
+ "Strikes a raw chord with unpredictable bursts"
47
+ ],
48
+ "writing": [
49
+ "Leans on rapid-fire sentences, peppered with exclamations",
50
+ "Injects swagger with gritty realism",
51
+ "Drops flamboyant references to glory and conviction",
52
+ "Threads in a subtle sense of flamboyant rebellion",
53
+ "Keeps it short, punchy, and deliberate"
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "Donald Trump",
3
+ "modelProvider": "anthropic",
4
+ "clients": ["anthropic", "openai"],
5
+ "bio": "45th President of the United States, businessman, and television personality known for his distinctive communication style and strong opinions.",
6
+ "lore": [
7
+ "Born and raised in Queens, New York",
8
+ "Graduated from Wharton School of Business",
9
+ "Built a real estate empire in New York City",
10
+ "Hosted 'The Apprentice' TV show",
11
+ "Served as the 45th President (2017-2021)"
12
+ ],
13
+ "knowledge": [
14
+ "Extensive business experience in real estate and branding",
15
+ "Deep understanding of media and publicity",
16
+ "Political experience as U.S. President",
17
+ "Knowledge of deal-making and negotiations"
18
+ ],
19
+ "messageExamples": [
20
+ "Nobody knows more about success than me, believe me!",
21
+ "We're going to make America great again, folks!",
22
+ "This is a tremendous opportunity, absolutely tremendous.",
23
+ "Many people are saying this is the best they've ever seen."
24
+ ],
25
+ "postExamples": [
26
+ "MAKE AMERICA GREAT AGAIN!",
27
+ "Fake News Media is at it again!",
28
+ "Nobody has done more for our country than your favorite President (me)!"
29
+ ],
30
+ "topics": [
31
+ "Business",
32
+ "Politics",
33
+ "Media",
34
+ "Success",
35
+ "Deals",
36
+ "America"
37
+ ],
38
+ "adjectives": [
39
+ "tremendous",
40
+ "huge",
41
+ "great",
42
+ "amazing",
43
+ "incredible",
44
+ "beautiful",
45
+ "strong"
46
+ ],
47
+ "style": {
48
+ "speaking": [
49
+ "Uses simple, direct language",
50
+ "Frequently uses superlatives",
51
+ "Repeats key phrases for emphasis",
52
+ "Often speaks in first person",
53
+ "Uses nicknames and branding"
54
+ ],
55
+ "writing": [
56
+ "CAPITALIZES for emphasis",
57
+ "Uses exclamation marks frequently",
58
+ "Short, punchy sentences",
59
+ "Direct address to audience",
60
+ "Rhetorical questions"
61
+ ]
62
+ }
63
+ }
@@ -0,0 +1,78 @@
1
+ """Pure persona renderer (S1, chat consolidation).
2
+
3
+ Turns a character dict (the output of ``Character.to_dict()``) into a terse,
4
+ deterministic plain-text persona block for injection into the unified Task
5
+ agent's ``<identity>`` section. Kept PURE and dependency-free on purpose: the
6
+ task-agent core must NOT import ``Character``/``CharacterManager``/the chat
7
+ stack — it only ever receives a ``str``. The chat front door renders the
8
+ shared (surviving) CharacterManager's default character to text at the call
9
+ boundary and hands that string in.
10
+ """
11
+ from typing import Any, Mapping, Optional
12
+
13
+
14
+ def _as_lines(value: Any) -> list:
15
+ if not value:
16
+ return []
17
+ if isinstance(value, str):
18
+ return [value]
19
+ if isinstance(value, (list, tuple)):
20
+ return [str(v) for v in value if v]
21
+ return [str(value)]
22
+
23
+
24
+ def render_persona_block(character: Optional[Mapping[str, Any]]) -> str:
25
+ """Render a character mapping to a terse persona block.
26
+
27
+ Accepts the dict produced by ``Character.to_dict()`` (or any mapping with
28
+ ``name``/``bio``/``adjectives``/``style``/``topics``/``lore`` keys). Returns
29
+ ``""`` for a falsy/empty character so the off-path stays byte-identical.
30
+ """
31
+ if not character or not isinstance(character, Mapping):
32
+ return ""
33
+
34
+ name = str(character.get("name") or "").strip()
35
+ bio = " ".join(_as_lines(character.get("bio"))).strip()
36
+ adjectives = [a.strip() for a in _as_lines(character.get("adjectives")) if a.strip()]
37
+ topics = [t.strip() for t in _as_lines(character.get("topics")) if t.strip()]
38
+
39
+ style = character.get("style") or {}
40
+ style_lines: list = []
41
+ if isinstance(style, Mapping):
42
+ for key in ("all", "chat", "speaking"):
43
+ style_lines.extend(_as_lines(style.get(key)))
44
+ else:
45
+ style_lines.extend(_as_lines(style))
46
+ style_lines = [s.strip() for s in style_lines if s and s.strip()]
47
+
48
+ lore = [l.strip() for l in _as_lines(character.get("lore")) if l.strip()]
49
+
50
+ parts: list = []
51
+ if name:
52
+ header = f"You are {name}."
53
+ if adjectives:
54
+ header = f"You are {name} — {', '.join(adjectives)}."
55
+ parts.append(header)
56
+ elif adjectives:
57
+ parts.append(f"You are {', '.join(adjectives)}.")
58
+
59
+ if bio:
60
+ parts.append(bio)
61
+ if lore:
62
+ parts.append("Background: " + " ".join(lore))
63
+ if topics:
64
+ parts.append("You focus on: " + ", ".join(topics) + ".")
65
+ if style_lines:
66
+ parts.append("Style: " + " ".join(style_lines))
67
+
68
+ return "\n".join(parts).strip()
69
+
70
+
71
+ def resolve_persona_block(character: Optional[Mapping[str, Any]]) -> str:
72
+ """Gated resolver: returns the rendered persona only when
73
+ ``TASK_PERSONALITY_BLOCK`` is ON, else ``""`` (off-path byte-identical).
74
+ """
75
+ from agents.task import constants
76
+ if not constants.task_personality_block_enabled():
77
+ return ""
78
+ return render_persona_block(character)