apsimo 1.3.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 (614) hide show
  1. apsimo/__init__.py +38 -0
  2. apsimo/__main__.py +6 -0
  3. apsimo/agent/__init__.py +6 -0
  4. apsimo/agent/client.py +276 -0
  5. apsimo/agent/models.py +46 -0
  6. apsimo/agents/__init__.py +20 -0
  7. apsimo/agents/models.py +264 -0
  8. apsimo/agents/store.py +861 -0
  9. apsimo/agents/websocket.py +522 -0
  10. apsimo/api/__init__.py +1 -0
  11. apsimo/api/auth_telemetry.py +287 -0
  12. apsimo/api/authority.py +1203 -0
  13. apsimo/api/contact_grants.py +347 -0
  14. apsimo/api/middleware.py +483 -0
  15. apsimo/api/routers/__init__.py +1 -0
  16. apsimo/api/routers/commitment_work.py +265 -0
  17. apsimo/api/routers/context_gate.py +123 -0
  18. apsimo/api/routers/executions.py +140 -0
  19. apsimo/api/routers/followup_plans.py +147 -0
  20. apsimo/api/routers/governed_actions.py +162 -0
  21. apsimo/api/routers/host.py +14473 -0
  22. apsimo/api/routers/initiative_work.py +115 -0
  23. apsimo/api/routers/mining.py +104 -0
  24. apsimo/api/routers/observations.py +110 -0
  25. apsimo/api/routers/social_state.py +225 -0
  26. apsimo/api/routers/task_queue.py +2715 -0
  27. apsimo/api/routers/temporal_followups.py +251 -0
  28. apsimo/api/routers/transport.py +110 -0
  29. apsimo/api/routers/transport_ingress_api.py +240 -0
  30. apsimo/api/schemas/__init__.py +1 -0
  31. apsimo/api/schemas/host.py +1949 -0
  32. apsimo/autonomy/cli.py +110 -0
  33. apsimo/autonomy/condition_worker.py +437 -0
  34. apsimo/autonomy/config.py +424 -0
  35. apsimo/autonomy/loop.py +4316 -0
  36. apsimo/autonomy/registry.py +339 -0
  37. apsimo/autonomy/scheduler.py +1822 -0
  38. apsimo/autonomy/synthesis.py +449 -0
  39. apsimo/backup.py +962 -0
  40. apsimo/beliefs/__init__.py +23 -0
  41. apsimo/beliefs/contradictions.py +109 -0
  42. apsimo/beliefs/decay.py +61 -0
  43. apsimo/beliefs/engine.py +479 -0
  44. apsimo/beliefs/models.py +67 -0
  45. apsimo/beliefs/promotion.py +41 -0
  46. apsimo/beliefs/resolve.py +58 -0
  47. apsimo/beliefs/source_claims.py +690 -0
  48. apsimo/beliefs/source_projection.py +883 -0
  49. apsimo/beliefs/source_time.py +208 -0
  50. apsimo/beliefs/store.py +133 -0
  51. apsimo/briefings/aggregators.py +824 -0
  52. apsimo/briefings/composer.py +420 -0
  53. apsimo/briefings/config.py +55 -0
  54. apsimo/briefings/delivery.py +439 -0
  55. apsimo/briefings/engagement.py +97 -0
  56. apsimo/briefings/engine.py +274 -0
  57. apsimo/briefings/enhancer.py +99 -0
  58. apsimo/briefings/models.py +183 -0
  59. apsimo/briefings/scheduler.py +382 -0
  60. apsimo/briefings/store.py +435 -0
  61. apsimo/chain/__init__.py +48 -0
  62. apsimo/chain/block.py +100 -0
  63. apsimo/chain/cli.py +704 -0
  64. apsimo/chain/genesis.py +443 -0
  65. apsimo/chain/identity.py +416 -0
  66. apsimo/chain/keys.py +1025 -0
  67. apsimo/chain/local_keys.py +187 -0
  68. apsimo/chain/manager.py +290 -0
  69. apsimo/chain/node.py +163 -0
  70. apsimo/chain/plugin_transactions.py +371 -0
  71. apsimo/chain/protocol.py +220 -0
  72. apsimo/chain/state_machine.py +676 -0
  73. apsimo/chain/storage.py +503 -0
  74. apsimo/chain/transactions.py +250 -0
  75. apsimo/chain/validation.py +397 -0
  76. apsimo/channels/__init__.py +1 -0
  77. apsimo/channels/manifest.py +31 -0
  78. apsimo/channels/migrations/001_channels_schema.sql +12 -0
  79. apsimo/channels/phone_gateways.py +42 -0
  80. apsimo/channels/presence.py +188 -0
  81. apsimo/channels/router.py +235 -0
  82. apsimo/channels/store.py +231 -0
  83. apsimo/cli.py +2688 -0
  84. apsimo/cognition/__init__.py +11 -0
  85. apsimo/cognition/charter.py +398 -0
  86. apsimo/cognition/drive_governance.py +3530 -0
  87. apsimo/cognition/evidence_pipeline.py +1627 -0
  88. apsimo/cognition/external_events.py +932 -0
  89. apsimo/cognition/goal_spine.py +3488 -0
  90. apsimo/cognition/introspection.py +214 -0
  91. apsimo/cognition/prompt.py +150 -0
  92. apsimo/cognition/runtime.py +108 -0
  93. apsimo/cognition/trigger.py +154 -0
  94. apsimo/commitments/__init__.py +18 -0
  95. apsimo/commitments/local_work.py +355 -0
  96. apsimo/commitments/store.py +1052 -0
  97. apsimo/commitments/work.py +91 -0
  98. apsimo/compat.py +53 -0
  99. apsimo/compression/__init__.py +467 -0
  100. apsimo/connectors/__init__.py +21 -0
  101. apsimo/connectors/base.py +152 -0
  102. apsimo/connectors/caldav_calendar.py +125 -0
  103. apsimo/connectors/fs_documents.py +85 -0
  104. apsimo/connectors/imap_email.py +138 -0
  105. apsimo/connectors/manager.py +218 -0
  106. apsimo/connectors/webhook_pull.py +88 -0
  107. apsimo/contacts/__init__.py +33 -0
  108. apsimo/contacts/comms.py +357 -0
  109. apsimo/contacts/config.py +79 -0
  110. apsimo/contacts/exporters/__init__.py +1 -0
  111. apsimo/contacts/exporters/vcard.py +71 -0
  112. apsimo/contacts/identity_links.py +251 -0
  113. apsimo/contacts/importer.py +280 -0
  114. apsimo/contacts/importers/__init__.py +1 -0
  115. apsimo/contacts/importers/batch.py +43 -0
  116. apsimo/contacts/importers/macos_contacts.py +101 -0
  117. apsimo/contacts/migrations/001_contacts_schema.sql +141 -0
  118. apsimo/contacts/migrations/002_trust_scopes.sql +36 -0
  119. apsimo/contacts/migrations/003_open_gateway_enum.sql +32 -0
  120. apsimo/contacts/migrations/004_contact_provision_operations.sql +18 -0
  121. apsimo/contacts/migrations/005_identity_links.sql +27 -0
  122. apsimo/contacts/models.py +308 -0
  123. apsimo/contacts/scoring.py +16 -0
  124. apsimo/contacts/store.py +1623 -0
  125. apsimo/contacts/transport_ingress.py +252 -0
  126. apsimo/contacts/world_bridge.py +314 -0
  127. apsimo/contextgate/__init__.py +69 -0
  128. apsimo/contextgate/chunker.py +169 -0
  129. apsimo/contextgate/estimate.py +54 -0
  130. apsimo/contextgate/gate.py +313 -0
  131. apsimo/contextgate/retrieve.py +115 -0
  132. apsimo/delivery/__init__.py +16 -0
  133. apsimo/delivery/bridge.py +1260 -0
  134. apsimo/delivery/channels.py +526 -0
  135. apsimo/delivery/classification.py +50 -0
  136. apsimo/delivery/rate_limiter.py +268 -0
  137. apsimo/delivery/reachout_policy.py +206 -0
  138. apsimo/directed/__init__.py +22 -0
  139. apsimo/directed/audit.py +167 -0
  140. apsimo/directed/intake.py +95 -0
  141. apsimo/directed/models.py +191 -0
  142. apsimo/directed/service.py +509 -0
  143. apsimo/directives/__init__.py +25 -0
  144. apsimo/directives/evidence.py +87 -0
  145. apsimo/directives/extractor.py +188 -0
  146. apsimo/directives/guard.py +364 -0
  147. apsimo/directives/models.py +206 -0
  148. apsimo/directives/service.py +372 -0
  149. apsimo/directives/store.py +167 -0
  150. apsimo/doctor.py +2173 -0
  151. apsimo/environment.py +43 -0
  152. apsimo/events/__init__.py +33 -0
  153. apsimo/events/broadcaster.py +98 -0
  154. apsimo/events/bus.py +217 -0
  155. apsimo/events/journal.py +863 -0
  156. apsimo/events/stream.py +131 -0
  157. apsimo/events/types.py +150 -0
  158. apsimo/execution_results.py +357 -0
  159. apsimo/feedback/__init__.py +5 -0
  160. apsimo/feedback/store.py +76 -0
  161. apsimo/feeds/__init__.py +19 -0
  162. apsimo/feeds/cli.py +84 -0
  163. apsimo/feeds/engine.py +437 -0
  164. apsimo/feeds/example-feed.yaml +77 -0
  165. apsimo/feeds/hermes_cron.py +126 -0
  166. apsimo/feeds/manager.py +235 -0
  167. apsimo/feeds/spec.py +250 -0
  168. apsimo/feeds/template.py +202 -0
  169. apsimo/gate/__init__.py +18 -0
  170. apsimo/gate/audit.py +61 -0
  171. apsimo/gate/communication_policy.py +166 -0
  172. apsimo/gate/config.py +72 -0
  173. apsimo/gate/context_provenance.py +170 -0
  174. apsimo/gate/env_risk.py +226 -0
  175. apsimo/gate/guard_audit.py +353 -0
  176. apsimo/gate/layers/__init__.py +1 -0
  177. apsimo/gate/layers/base.py +15 -0
  178. apsimo/gate/layers/l1_recipient.py +66 -0
  179. apsimo/gate/layers/l2_pii.py +134 -0
  180. apsimo/gate/layers/l3_cross_context.py +50 -0
  181. apsimo/gate/layers/l4_trust_tier.py +78 -0
  182. apsimo/gate/layers/l5_injection.py +199 -0
  183. apsimo/gate/layers/l6_review.py +86 -0
  184. apsimo/gate/layers/l7_delay.py +100 -0
  185. apsimo/gate/layers/tom2_epistemic.py +185 -0
  186. apsimo/gate/models.py +64 -0
  187. apsimo/gate/pending_dispatch.py +5 -0
  188. apsimo/gate/pipeline.py +206 -0
  189. apsimo/gate/rejection.py +259 -0
  190. apsimo/gate/response_guard.py +700 -0
  191. apsimo/gate/rulesets/injection_v1.yaml +51 -0
  192. apsimo/gate/surface_policy.py +189 -0
  193. apsimo/gate/taint.py +226 -0
  194. apsimo/genesis.json +9 -0
  195. apsimo/goals/__init__.py +100 -0
  196. apsimo/goals/config.py +38 -0
  197. apsimo/goals/decomposer.py +421 -0
  198. apsimo/goals/engine.py +617 -0
  199. apsimo/goals/inference.py +354 -0
  200. apsimo/goals/models.py +302 -0
  201. apsimo/goals/priority.py +270 -0
  202. apsimo/goals/queue_bridge.py +149 -0
  203. apsimo/goals/replan.py +450 -0
  204. apsimo/goals/schema.sql +89 -0
  205. apsimo/goals/store.py +692 -0
  206. apsimo/governed_actions.py +1708 -0
  207. apsimo/harness_integration/__init__.py +45 -0
  208. apsimo/harness_integration/context.py +41 -0
  209. apsimo/harness_integration/skills.py +231 -0
  210. apsimo/identity/__init__.py +26 -0
  211. apsimo/identity/participants.py +181 -0
  212. apsimo/identity/resolver.py +329 -0
  213. apsimo/identity_bootstrap/__init__.py +5 -0
  214. apsimo/identity_bootstrap/builder.py +208 -0
  215. apsimo/identity_bootstrap/corpus.py +443 -0
  216. apsimo/identity_bootstrap/models.py +54 -0
  217. apsimo/identity_bootstrap/runner.py +353 -0
  218. apsimo/identity_bootstrap/seeders/__init__.py +25 -0
  219. apsimo/identity_bootstrap/seeders/briefings.py +109 -0
  220. apsimo/identity_bootstrap/seeders/chain.py +57 -0
  221. apsimo/identity_bootstrap/seeders/goals.py +128 -0
  222. apsimo/identity_bootstrap/seeders/memory.py +191 -0
  223. apsimo/identity_bootstrap/seeders/neo4j_cognition.py +79 -0
  224. apsimo/identity_bootstrap/seeders/relationship.py +152 -0
  225. apsimo/identity_bootstrap/seeders/sessions.py +67 -0
  226. apsimo/identity_bootstrap/seeders/skills.py +92 -0
  227. apsimo/identity_bootstrap/seeders/task_queue.py +72 -0
  228. apsimo/identity_bootstrap/seeders/world_model.py +143 -0
  229. apsimo/identity_bootstrap/self_query.py +92 -0
  230. apsimo/identity_bootstrap/self_reflection.py +155 -0
  231. apsimo/identity_bootstrap/skill.py +37 -0
  232. apsimo/identity_bootstrap/verifier.py +436 -0
  233. apsimo/initiatives/__init__.py +20 -0
  234. apsimo/initiatives/action_registry.py +454 -0
  235. apsimo/initiatives/approval_authority.py +2105 -0
  236. apsimo/initiatives/approval_policy.py +123 -0
  237. apsimo/initiatives/assignment.py +263 -0
  238. apsimo/initiatives/backup_evidence.py +100 -0
  239. apsimo/initiatives/context_freshness.py +103 -0
  240. apsimo/initiatives/models.py +318 -0
  241. apsimo/initiatives/native_work.py +270 -0
  242. apsimo/initiatives/standing_approvals.py +232 -0
  243. apsimo/initiatives/store.py +1081 -0
  244. apsimo/initiatives/temporal_followup.py +410 -0
  245. apsimo/intelligence/__init__.py +1 -0
  246. apsimo/intelligence/cognition/__init__.py +24 -0
  247. apsimo/intelligence/cognition/gap_detector.py +148 -0
  248. apsimo/intelligence/cognition/metalearner.py +547 -0
  249. apsimo/intelligence/cognition/metrics_collector.py +217 -0
  250. apsimo/intelligence/cognition/performance_index.py +299 -0
  251. apsimo/intelligence/cognition/registry.py +192 -0
  252. apsimo/intelligence/cognition/strategy_adjuster.py +222 -0
  253. apsimo/intelligence/cognition/types.py +16 -0
  254. apsimo/intelligence/components/__init__.py +66 -0
  255. apsimo/intelligence/components/anomaly_detector.py +413 -0
  256. apsimo/intelligence/components/initiative_engine.py +2643 -0
  257. apsimo/intelligence/components/preference_learner.py +521 -0
  258. apsimo/intelligence/components/research_orchestrator.py +358 -0
  259. apsimo/intelligence/components/self_directed_thinker.py +221 -0
  260. apsimo/intelligence/components/self_reflector.py +252 -0
  261. apsimo/intelligence/components/session_continuity.py +154 -0
  262. apsimo/intelligence/components/task_planner.py +320 -0
  263. apsimo/intelligence/components/tool_learner.py +217 -0
  264. apsimo/intelligence/graph/__init__.py +79 -0
  265. apsimo/intelligence/graph/client.py +2483 -0
  266. apsimo/intelligence/graph/consolidator.py +405 -0
  267. apsimo/intelligence/graph/distiller.py +312 -0
  268. apsimo/intelligence/graph/migrations.py +129 -0
  269. apsimo/intelligence/graph/queries.py +248 -0
  270. apsimo/intelligence/graph/recall.py +281 -0
  271. apsimo/intelligence/graph/reconciler.py +144 -0
  272. apsimo/intelligence/graph/schema.py +337 -0
  273. apsimo/intelligence/graph/selection.py +252 -0
  274. apsimo/intelligence/learning/__init__.py +17 -0
  275. apsimo/intelligence/learning/continuous_learner.py +245 -0
  276. apsimo/intelligence/learning/feedback_store.py +321 -0
  277. apsimo/intelligence/mind_model/__init__.py +1 -0
  278. apsimo/intelligence/mind_model/graph_baseline.py +136 -0
  279. apsimo/intelligence/mind_model/signal_collector.py +361 -0
  280. apsimo/intelligence/relationships/__init__.py +11 -0
  281. apsimo/intelligence/relationships/profiler.py +389 -0
  282. apsimo/intelligence/relationships/scorer.py +560 -0
  283. apsimo/intelligence/relationships/signal_floor.py +66 -0
  284. apsimo/intelligence/relationships/trust_tiers.py +300 -0
  285. apsimo/intelligence/synthesis/__init__.py +40 -0
  286. apsimo/intelligence/synthesis/connection_discoverer.py +379 -0
  287. apsimo/intelligence/synthesis/cross_domain_analyzer.py +287 -0
  288. apsimo/intelligence/synthesis/insight_deliverer.py +171 -0
  289. apsimo/intelligence/synthesis/insight_store.py +79 -0
  290. apsimo/intelligence/synthesis/insight_validator.py +183 -0
  291. apsimo/intelligence/synthesis/novelty_scorer.py +267 -0
  292. apsimo/intelligence/turn_middleware/__init__.py +15 -0
  293. apsimo/intelligence/turn_middleware/memory_sync.py +119 -0
  294. apsimo/mcp/__init__.py +41 -0
  295. apsimo/mcp/__main__.py +6 -0
  296. apsimo/mcp/config.py +287 -0
  297. apsimo/mcp/server.py +501 -0
  298. apsimo/migrations.py +187 -0
  299. apsimo/mining/__init__.py +27 -0
  300. apsimo/mining/corpus.py +239 -0
  301. apsimo/mining/escalations.py +289 -0
  302. apsimo/mining/models.py +169 -0
  303. apsimo/mining/store.py +210 -0
  304. apsimo/models/__init__.py +30 -0
  305. apsimo/models/memory.py +80 -0
  306. apsimo/models/mesh.py +72 -0
  307. apsimo/models/person.py +104 -0
  308. apsimo/models/signal.py +108 -0
  309. apsimo/observations/__init__.py +15 -0
  310. apsimo/observations/store.py +277 -0
  311. apsimo/patterns/__init__.py +6 -0
  312. apsimo/patterns/extract.py +187 -0
  313. apsimo/patterns/store.py +227 -0
  314. apsimo/persona/__init__.py +1 -0
  315. apsimo/persona/engine.py +611 -0
  316. apsimo/persona/manifest.py +140 -0
  317. apsimo/projects/__init__.py +28 -0
  318. apsimo/projects/engine.py +1681 -0
  319. apsimo/projects/event_outbox.py +188 -0
  320. apsimo/projects/models.py +216 -0
  321. apsimo/projects/planner.py +181 -0
  322. apsimo/projects/store.py +1446 -0
  323. apsimo/proposals/__init__.py +12 -0
  324. apsimo/proposals/engine.py +114 -0
  325. apsimo/proposals/models.py +207 -0
  326. apsimo/qualification/__init__.py +1 -0
  327. apsimo/qualification/cases.py +75 -0
  328. apsimo/qualification/cli.py +51 -0
  329. apsimo/qualification/memory_cases.py +209 -0
  330. apsimo/qualification/records.py +92 -0
  331. apsimo/qualification/report.py +87 -0
  332. apsimo/qualification/runner.py +311 -0
  333. apsimo/qualification/structured_cases.py +131 -0
  334. apsimo/reasoning/__init__.py +13 -0
  335. apsimo/reasoning/executor.py +506 -0
  336. apsimo/reasoning/loop.py +373 -0
  337. apsimo/reasoning/native_tools/__init__.py +16 -0
  338. apsimo/reasoning/native_tools/calculate.py +141 -0
  339. apsimo/reasoning/native_tools/file_ops.py +150 -0
  340. apsimo/reasoning/native_tools/web_search.py +49 -0
  341. apsimo/reasoning/tool_policy.py +182 -0
  342. apsimo/redact/__init__.py +176 -0
  343. apsimo/repos/__init__.py +5 -0
  344. apsimo/repos/mirrors.py +204 -0
  345. apsimo/research/__init__.py +41 -0
  346. apsimo/research/artifact.py +482 -0
  347. apsimo/research/gatherer.py +387 -0
  348. apsimo/research/pipeline.py +513 -0
  349. apsimo/research/search/__init__.py +7 -0
  350. apsimo/research/search/base.py +41 -0
  351. apsimo/research/search/brave.py +59 -0
  352. apsimo/research/search/cache.py +51 -0
  353. apsimo/research/search/duckduckgo.py +103 -0
  354. apsimo/research/search/orchestrator.py +119 -0
  355. apsimo/research/search/serpapi.py +59 -0
  356. apsimo/research/search/tavily.py +59 -0
  357. apsimo/research/synthesizer.py +309 -0
  358. apsimo/router/__init__.py +30 -0
  359. apsimo/router/complexity_scorer.py +148 -0
  360. apsimo/router/endpoints.py +153 -0
  361. apsimo/router/fallback.py +58 -0
  362. apsimo/router/functions.py +243 -0
  363. apsimo/router/native_policy.py +52 -0
  364. apsimo/router/router.py +762 -0
  365. apsimo/router/self_learning.py +174 -0
  366. apsimo/router/tiers.py +677 -0
  367. apsimo/sandbox/__init__.py +21 -0
  368. apsimo/sandbox/backend.py +195 -0
  369. apsimo/sandbox/manager.py +173 -0
  370. apsimo/scope_bounds.py +7 -0
  371. apsimo/secrets/__init__.py +6 -0
  372. apsimo/secrets/backends/__init__.py +8 -0
  373. apsimo/secrets/backends/base.py +42 -0
  374. apsimo/secrets/backends/env.py +110 -0
  375. apsimo/secrets/backends/keyring.py +72 -0
  376. apsimo/secrets/backends/onepassword.py +232 -0
  377. apsimo/secrets/cli.py +191 -0
  378. apsimo/secrets/manager.py +160 -0
  379. apsimo/secrets/migration.py +101 -0
  380. apsimo/secrets/types.py +98 -0
  381. apsimo/seed.py +41 -0
  382. apsimo/self_model/__init__.py +37 -0
  383. apsimo/self_model/appraisals.py +673 -0
  384. apsimo/self_model/benchmark.py +1314 -0
  385. apsimo/self_model/brief.py +40 -0
  386. apsimo/self_model/event_concerns.py +1128 -0
  387. apsimo/self_model/execution_forecasts.py +353 -0
  388. apsimo/self_model/expectations.py +1595 -0
  389. apsimo/self_model/experiments.py +1150 -0
  390. apsimo/self_model/journal.py +148 -0
  391. apsimo/self_model/judgments.py +705 -0
  392. apsimo/self_model/native_outcomes.py +55 -0
  393. apsimo/self_model/params.py +220 -0
  394. apsimo/self_model/perspective.py +246 -0
  395. apsimo/self_model/reconcile.py +183 -0
  396. apsimo/self_model/reply_forecasts.py +381 -0
  397. apsimo/self_model/runtime_forecasts.py +296 -0
  398. apsimo/self_model/runtime_models.py +67 -0
  399. apsimo/self_model/settlement.py +207 -0
  400. apsimo/self_model/situation.py +1731 -0
  401. apsimo/self_model/store.py +883 -0
  402. apsimo/self_model/supervised.py +137 -0
  403. apsimo/self_model/thinker.py +99 -0
  404. apsimo/self_model/trust.py +388 -0
  405. apsimo/self_model/workspace.py +2388 -0
  406. apsimo/server.py +4197 -0
  407. apsimo/services/__init__.py +1 -0
  408. apsimo/services/agent_bridge.py +474 -0
  409. apsimo/services/initiative_executor.py +914 -0
  410. apsimo/services/instance.py +297 -0
  411. apsimo/sessions/__init__.py +22 -0
  412. apsimo/sessions/config.py +13 -0
  413. apsimo/sessions/context_loader.py +88 -0
  414. apsimo/sessions/federation_session.py +75 -0
  415. apsimo/sessions/isolated_session.py +98 -0
  416. apsimo/sessions/reports.py +84 -0
  417. apsimo/sessions/store.py +148 -0
  418. apsimo/setup.py +2818 -0
  419. apsimo/setup_hermes.py +879 -0
  420. apsimo/setup_local_work.py +218 -0
  421. apsimo/setup_native_goals.py +134 -0
  422. apsimo/setup_native_reviews.py +115 -0
  423. apsimo/skills/__init__.py +10 -0
  424. apsimo/skills/base.py +108 -0
  425. apsimo/skills/budget.py +28 -0
  426. apsimo/skills/executor.py +493 -0
  427. apsimo/skills/executors/__init__.py +1 -0
  428. apsimo/skills/executors/behavioral_correction.py +75 -0
  429. apsimo/skills/executors/capability_gap.py +38 -0
  430. apsimo/skills/executors/data_quality.py +163 -0
  431. apsimo/skills/executors/knowledge_acquisition.py +41 -0
  432. apsimo/skills/executors/operational_hygiene.py +185 -0
  433. apsimo/skills/executors/subsystem_health.py +169 -0
  434. apsimo/skills/hermes_export.py +431 -0
  435. apsimo/skills/index.py +123 -0
  436. apsimo/skills/learning/__init__.py +21 -0
  437. apsimo/skills/learning/novelty_detector.py +206 -0
  438. apsimo/skills/learning/pattern_extractor.py +199 -0
  439. apsimo/skills/learning/triggers.py +159 -0
  440. apsimo/skills/loader.py +246 -0
  441. apsimo/skills/migrations/002_progressive_loading.sql +6 -0
  442. apsimo/skills/migrations/backfill_triggers.py +20 -0
  443. apsimo/skills/models.py +202 -0
  444. apsimo/skills/packager.py +128 -0
  445. apsimo/skills/protocols.py +70 -0
  446. apsimo/skills/registry.py +191 -0
  447. apsimo/skills/runtime.py +58 -0
  448. apsimo/skills/sandbox_runner.py +229 -0
  449. apsimo/skills/scheduler.py +129 -0
  450. apsimo/skills/schema.py +79 -0
  451. apsimo/skills/security/__init__.py +12 -0
  452. apsimo/skills/security/guards.py +53 -0
  453. apsimo/skills/security/scanner.py +223 -0
  454. apsimo/skills_memory/__init__.py +26 -0
  455. apsimo/skills_memory/distill.py +159 -0
  456. apsimo/skills_memory/models.py +85 -0
  457. apsimo/skills_memory/retrieve.py +62 -0
  458. apsimo/skills_memory/store.py +172 -0
  459. apsimo/surprise/__init__.py +6 -0
  460. apsimo/surprise/accumulation.py +57 -0
  461. apsimo/surprise/scorer.py +102 -0
  462. apsimo/surprise/store.py +203 -0
  463. apsimo/task_queue/__init__.py +69 -0
  464. apsimo/task_queue/action_receipts.py +148 -0
  465. apsimo/task_queue/approval_relay_canary.py +108 -0
  466. apsimo/task_queue/config.py +85 -0
  467. apsimo/task_queue/contract.py +361 -0
  468. apsimo/task_queue/events.py +130 -0
  469. apsimo/task_queue/governor.py +1031 -0
  470. apsimo/task_queue/handlers/__init__.py +16 -0
  471. apsimo/task_queue/handlers/base.py +37 -0
  472. apsimo/task_queue/handlers/inference.py +640 -0
  473. apsimo/task_queue/handlers/monitoring.py +116 -0
  474. apsimo/task_queue/handlers/registry.py +75 -0
  475. apsimo/task_queue/handlers/subtask_handler.py +173 -0
  476. apsimo/task_queue/handlers/system_maintenance.py +147 -0
  477. apsimo/task_queue/mesh_integration.py +111 -0
  478. apsimo/task_queue/models.py +317 -0
  479. apsimo/task_queue/queue_manager.py +8286 -0
  480. apsimo/task_queue/routing.py +287 -0
  481. apsimo/task_queue/scheduler.py +252 -0
  482. apsimo/task_queue/schema.sql +197 -0
  483. apsimo/task_queue/work_control.py +342 -0
  484. apsimo/task_queue/worker.py +993 -0
  485. apsimo/telemetry.py +145 -0
  486. apsimo/tom/__init__.py +6 -0
  487. apsimo/tom/affect.py +387 -0
  488. apsimo/tom/approvals.py +171 -0
  489. apsimo/tom/arcs.py +896 -0
  490. apsimo/tom/asymmetry.py +131 -0
  491. apsimo/tom/eligibility.py +248 -0
  492. apsimo/tom/engagement.py +214 -0
  493. apsimo/tom/exposure.py +214 -0
  494. apsimo/tom/extractor.py +306 -0
  495. apsimo/tom/fact_adapters.py +144 -0
  496. apsimo/tom/facts.py +326 -0
  497. apsimo/tom/integration.py +592 -0
  498. apsimo/tom/leveled.py +118 -0
  499. apsimo/tom/levels.py +247 -0
  500. apsimo/tom/recipient_audit.py +995 -0
  501. apsimo/tom/recipient_simulator.py +593 -0
  502. apsimo/tom/source_lineage.py +93 -0
  503. apsimo/tom/tom2.py +277 -0
  504. apsimo/tom/visibility.py +559 -0
  505. apsimo/tom/visibility_store.py +414 -0
  506. apsimo/tools/__init__.py +0 -0
  507. apsimo/tools/definitions.py +740 -0
  508. apsimo/tools/handlers.py +943 -0
  509. apsimo/toolsmith/__init__.py +26 -0
  510. apsimo/toolsmith/authority.py +166 -0
  511. apsimo/toolsmith/engine.py +559 -0
  512. apsimo/toolsmith/integrity.py +100 -0
  513. apsimo/toolsmith/miner.py +145 -0
  514. apsimo/toolsmith/policy.py +110 -0
  515. apsimo/toolsmith/registry.py +635 -0
  516. apsimo/turns/__init__.py +17 -0
  517. apsimo/turns/audio.py +134 -0
  518. apsimo/turns/documents.py +235 -0
  519. apsimo/turns/executions.py +486 -0
  520. apsimo/turns/hermes_history.py +245 -0
  521. apsimo/turns/hermes_kanban.py +268 -0
  522. apsimo/turns/hermes_work.py +96 -0
  523. apsimo/turns/idempotency.py +752 -0
  524. apsimo/turns/local_work.py +115 -0
  525. apsimo/turns/media.py +581 -0
  526. apsimo/turns/reported_workers.py +196 -0
  527. apsimo/turns/source_annotations.py +283 -0
  528. apsimo/turns/source_attribution.py +154 -0
  529. apsimo/turns/source_read.py +351 -0
  530. apsimo/turns/source_vectors.py +263 -0
  531. apsimo/turns/video.py +210 -0
  532. apsimo/util/autonomy_preset.py +220 -0
  533. apsimo/util/instance.py +92 -0
  534. apsimo/util/model_output.py +25 -0
  535. apsimo/util/quiet_hours.py +27 -0
  536. apsimo/util/session_safety.py +37 -0
  537. apsimo/util/temporal.py +343 -0
  538. apsimo/vector/__init__.py +75 -0
  539. apsimo/vector/backfill.py +171 -0
  540. apsimo/vector/caption.py +114 -0
  541. apsimo/vector/collections.py +51 -0
  542. apsimo/vector/config.py +102 -0
  543. apsimo/vector/embedder.py +670 -0
  544. apsimo/vector/image_preprocess.py +406 -0
  545. apsimo/vector/image_store.py +296 -0
  546. apsimo/vector/indexes.py +162 -0
  547. apsimo/vector/migrate.py +334 -0
  548. apsimo/vector/multimodal_provider.py +417 -0
  549. apsimo/vector/multimodal_types.py +87 -0
  550. apsimo/vector/openai_provider.py +119 -0
  551. apsimo/vector/query.py +49 -0
  552. apsimo/vector/reranker.py +565 -0
  553. apsimo/vector/safety_image.py +159 -0
  554. apsimo/vector/scanner.py +197 -0
  555. apsimo/vector/setup.py +289 -0
  556. apsimo/vector/store.py +533 -0
  557. apsimo/vector/tiers.py +263 -0
  558. apsimo/work_orders.py +925 -0
  559. apsimo/workers/__init__.py +21 -0
  560. apsimo/workers/agent_bridge.py +640 -0
  561. apsimo/workers/colony_worker.py +382 -0
  562. apsimo/workers/queue_worker.py +441 -0
  563. apsimo/workers/skills_sync.py +152 -0
  564. apsimo/world_model/__init__.py +71 -0
  565. apsimo/world_model/causal_maintenance.py +131 -0
  566. apsimo/world_model/causal_policy.py +43 -0
  567. apsimo/world_model/causal_query.py +125 -0
  568. apsimo/world_model/confidence.py +54 -0
  569. apsimo/world_model/config.py +64 -0
  570. apsimo/world_model/constants.py +97 -0
  571. apsimo/world_model/entities.py +145 -0
  572. apsimo/world_model/expectation_resolvers.py +177 -0
  573. apsimo/world_model/extraction/__init__.py +7 -0
  574. apsimo/world_model/extraction/base.py +62 -0
  575. apsimo/world_model/extraction/conversation_extractor.py +262 -0
  576. apsimo/world_model/extraction/detector.py +74 -0
  577. apsimo/world_model/extraction/document_extractor.py +78 -0
  578. apsimo/world_model/extraction/formats/__init__.py +24 -0
  579. apsimo/world_model/extraction/formats/csv_fmt.py +68 -0
  580. apsimo/world_model/extraction/formats/html_fmt.py +72 -0
  581. apsimo/world_model/extraction/formats/json_fmt.py +68 -0
  582. apsimo/world_model/extraction/formats/pdf.py +43 -0
  583. apsimo/world_model/extraction/formats/text.py +27 -0
  584. apsimo/world_model/extraction/llm_extractor.py +164 -0
  585. apsimo/world_model/extraction/pipeline.py +73 -0
  586. apsimo/world_model/integrations/__init__.py +5 -0
  587. apsimo/world_model/integrations/mind_model_bridge.py +115 -0
  588. apsimo/world_model/integrations/social_intel_bridge.py +120 -0
  589. apsimo/world_model/jobs/__init__.py +4 -0
  590. apsimo/world_model/jobs/extraction_job.py +168 -0
  591. apsimo/world_model/llm_extract.py +572 -0
  592. apsimo/world_model/neo4j/__init__.py +5 -0
  593. apsimo/world_model/neo4j/backend.py +654 -0
  594. apsimo/world_model/observations.py +155 -0
  595. apsimo/world_model/populator.py +307 -0
  596. apsimo/world_model/postgres/__init__.py +1 -0
  597. apsimo/world_model/postgres/backend.py +683 -0
  598. apsimo/world_model/relationships.py +25 -0
  599. apsimo/world_model/resolution/__init__.py +13 -0
  600. apsimo/world_model/resolution/entity_resolver.py +232 -0
  601. apsimo/world_model/resolution/merge_audit.py +16 -0
  602. apsimo/world_model/resolution/merge_workflow.py +117 -0
  603. apsimo/world_model/source_reports.py +121 -0
  604. apsimo/world_model/sqlite/__init__.py +4 -0
  605. apsimo/world_model/sqlite/backend.py +855 -0
  606. apsimo/world_model/sqlite/schema.sql +132 -0
  607. apsimo/world_model/store.py +545 -0
  608. apsimo-1.3.0.dist-info/METADATA +78 -0
  609. apsimo-1.3.0.dist-info/RECORD +614 -0
  610. apsimo-1.3.0.dist-info/WHEEL +5 -0
  611. apsimo-1.3.0.dist-info/entry_points.txt +11 -0
  612. apsimo-1.3.0.dist-info/licenses/LICENSE +21 -0
  613. apsimo-1.3.0.dist-info/top_level.txt +2 -0
  614. colony_sidecar/__init__.py +4 -0
@@ -0,0 +1,131 @@
1
+ """Causal-edge maintenance primitives (H2.3): contradiction + staleness.
2
+
3
+ Two fabrication controls for the causal layer, consumed by the
4
+ BeliefEngine's periodic run:
5
+
6
+ 1. CONTRADICTION: a positive causal claim (WM_CAUSES / WM_ENABLES) and a
7
+ negative one (WM_BLOCKS / WM_INHIBITS) between the SAME ordered entity
8
+ pair cannot both be right. Opposing pairs become conflict rows + review
9
+ initiatives and are NEVER auto-resolved — not at any trust stage, not in
10
+ live mode. Recency/confidence ordering is how belief conflicts are
11
+ settled, but a causal claim is a model of the world, and silently picking
12
+ a winner would let one confidently-worded fabrication erase a true edge.
13
+ A human (or an explicitly owner-approved flow) closes these.
14
+
15
+ 2. STALENESS: a causal edge that has gone COLONY_CAUSAL_TTL_DAYS (default
16
+ 120) without support (creation or corroboration) loses 0.05 confidence
17
+ per maintenance run, floored at 0.2 — never deleted. Staleness is judged
18
+ by the ``last_support_at`` property (stamped by the extractor on create/
19
+ corroborate) so that the decay write itself cannot reset the clock.
20
+
21
+ This module is pure computation + read-only store access; every WRITE stays
22
+ in the BeliefEngine where it is mode-gated (live/supervised) and journaled.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import logging
28
+ import os
29
+ from datetime import datetime, timezone
30
+ from typing import Any, Dict, List, Tuple
31
+
32
+ from apsimo.world_model.constants import CAUSAL_RELATIONSHIP_TYPES
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+ POSITIVE_CAUSAL = frozenset({"WM_CAUSES", "WM_ENABLES"})
37
+ NEGATIVE_CAUSAL = frozenset({"WM_BLOCKS", "WM_INHIBITS"})
38
+
39
+ CAUSAL_DECAY_STEP = 0.05
40
+ CAUSAL_DECAY_FLOOR = 0.2
41
+
42
+ # The property the extractor stamps on every create/corroborate; the decay
43
+ # clock reads it (falling back to updated_at/created_at for pre-existing
44
+ # edges) and deliberately never advances it on a decay write.
45
+ LAST_SUPPORT_PROP = "last_support_at"
46
+
47
+
48
+ def causal_ttl_days() -> float:
49
+ """COLONY_CAUSAL_TTL_DAYS (default 120): days without support before a
50
+ causal edge starts decaying."""
51
+ try:
52
+ v = float(os.environ.get("COLONY_CAUSAL_TTL_DAYS", "120"))
53
+ return v if v > 0 else 120.0
54
+ except (TypeError, ValueError):
55
+ return 120.0
56
+
57
+
58
+ async def load_causal_edges(store: Any, limit_per_type: int = 500) -> List[Any]:
59
+ """All causal edges, via explicitly-typed queries (the only sanctioned
60
+ read path — causal edges are excluded from generic reads by policy)."""
61
+ out: List[Any] = []
62
+ for rel_type in sorted(CAUSAL_RELATIONSHIP_TYPES):
63
+ try:
64
+ rels = await store.query_relationships(
65
+ relationship_type=rel_type, min_confidence=0.0,
66
+ limit=limit_per_type)
67
+ except Exception:
68
+ logger.debug("causal edge load failed for %s", rel_type,
69
+ exc_info=True)
70
+ continue
71
+ out.extend(rels or [])
72
+ return out
73
+
74
+
75
+ def opposing_pairs(edges: List[Any]) -> List[Tuple[Any, Any]]:
76
+ """(positive_edge, negative_edge) pairs over the same ordered
77
+ (source_id, target_id) — the causal contradictions. Inactive edges
78
+ (valid_to set) are ignored: a closed edge no longer claims anything."""
79
+ by_pair: Dict[Tuple[str, str], Dict[str, List[Any]]] = {}
80
+ for e in edges:
81
+ if getattr(e, "valid_to", None) is not None:
82
+ continue
83
+ rel = str(getattr(e, "relationship_type", "") or "").upper()
84
+ if rel in POSITIVE_CAUSAL:
85
+ polarity = "pos"
86
+ elif rel in NEGATIVE_CAUSAL:
87
+ polarity = "neg"
88
+ else:
89
+ continue
90
+ key = (str(e.source_id), str(e.target_id))
91
+ by_pair.setdefault(key, {"pos": [], "neg": []})[polarity].append(e)
92
+ pairs: List[Tuple[Any, Any]] = []
93
+ for buckets in by_pair.values():
94
+ for pos in buckets["pos"]:
95
+ for neg in buckets["neg"]:
96
+ pairs.append((pos, neg))
97
+ return pairs
98
+
99
+
100
+ def support_timestamp(edge: Any) -> str:
101
+ """The edge's last-support timestamp (ISO8601), preferring the
102
+ extractor-stamped property over store bookkeeping columns."""
103
+ props = getattr(edge, "properties", None) or {}
104
+ return str(props.get(LAST_SUPPORT_PROP)
105
+ or getattr(edge, "updated_at", None)
106
+ or getattr(edge, "created_at", None) or "")
107
+
108
+
109
+ def support_age_days(edge: Any, now: datetime) -> float:
110
+ """Days since the edge was last supported; 0.0 when unparseable (an
111
+ edge we cannot date is never treated as stale — fail toward keeping)."""
112
+ raw = support_timestamp(edge)
113
+ if not raw:
114
+ return 0.0
115
+ try:
116
+ ts = datetime.fromisoformat(raw.replace("Z", "+00:00"))
117
+ if ts.tzinfo is None:
118
+ ts = ts.replace(tzinfo=timezone.utc)
119
+ return max(0.0, (now - ts).total_seconds() / 86400.0)
120
+ except Exception:
121
+ return 0.0
122
+
123
+
124
+ def stale_causal_edges(edges: List[Any], now: datetime = None) -> List[Any]:
125
+ """Causal edges past the TTL that still have confidence to lose."""
126
+ now = now or datetime.now(timezone.utc)
127
+ ttl = causal_ttl_days()
128
+ return [e for e in edges
129
+ if getattr(e, "valid_to", None) is None
130
+ and float(getattr(e, "confidence", 0.0) or 0.0) > CAUSAL_DECAY_FLOOR
131
+ and support_age_days(e, now) > ttl]
@@ -0,0 +1,43 @@
1
+ """Causal-edge policy: causal edges are QUERY-ONLY unless explicitly unlocked.
2
+
3
+ THE INVARIANT
4
+ A causal edge (WM_CAUSES / WM_ENABLES / WM_BLOCKS / WM_INHIBITS, see
5
+ ``CAUSAL_RELATIONSHIP_TYPES``) may be stored, corroborated, decayed and
6
+ read back to answer "why" / "what happens if" questions — but it must
7
+ NEVER, on its own, cause Colony to take or schedule an action. An
8
+ inferred "A causes B" is a belief about the world, not an instruction;
9
+ acting on a fabricated or stale causal edge is exactly the failure mode
10
+ this module exists to prevent.
11
+
12
+ Every consumer that reads causal edges and could turn them into behavior
13
+ (planners, initiative generators, directed actions) MUST gate that path on
14
+ ``causal_edges_actionable()``. The flag COLONY_CAUSAL_ACT defaults to off,
15
+ so the invariant holds by default; flipping it is an explicit owner
16
+ decision, revertible via env alone.
17
+
18
+ This module is intentionally tiny and dependency-free so any layer can
19
+ import it without cycles.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import os
25
+
26
+ from apsimo.world_model.constants import CAUSAL_RELATIONSHIP_TYPES
27
+
28
+ __all__ = ["CAUSAL_RELATIONSHIP_TYPES", "causal_edges_actionable", "is_causal"]
29
+
30
+
31
+ def causal_edges_actionable() -> bool:
32
+ """May causal edges influence ACTIONS (not just answers)? Default no.
33
+
34
+ COLONY_CAUSAL_ACT=1 is the only unlock; anything else (unset, 0, junk)
35
+ keeps causal edges query-only.
36
+ """
37
+ return os.environ.get("COLONY_CAUSAL_ACT", "0").strip().lower() in (
38
+ "1", "true", "yes", "on")
39
+
40
+
41
+ def is_causal(rel_type: str) -> bool:
42
+ """True when ``rel_type`` is one of the causal relationship types."""
43
+ return str(rel_type or "").strip().upper() in CAUSAL_RELATIONSHIP_TYPES
@@ -0,0 +1,125 @@
1
+ """Read-only causal-chain query — the sanctioned way to READ causal edges.
2
+
3
+ Causal edges are query-only by policy (world_model/causal_policy.py) and are
4
+ excluded from every generic graph read path: the ONLY surfaces that return
5
+ them are the /world/causal/* endpoints (built on this module) and
6
+ explicitly-typed relationship queries. This module answers "why" / "what
7
+ happens if" questions by walking causal edges alone; it never writes and
8
+ never feeds an action path.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import logging
14
+ from typing import Any, Dict, List
15
+
16
+ from apsimo.world_model.constants import CAUSAL_RELATIONSHIP_TYPES
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ _DIRECTIONS = ("downstream", "upstream", "both")
21
+
22
+
23
+ def _edge_dict(rel: Any) -> Dict[str, Any]:
24
+ props = getattr(rel, "properties", None) or {}
25
+ return {
26
+ "id": rel.id,
27
+ "source_id": rel.source_id,
28
+ "target_id": rel.target_id,
29
+ "relationship_type": rel.relationship_type,
30
+ "confidence": rel.confidence,
31
+ "is_active": bool(getattr(rel, "is_active", rel.valid_to is None)),
32
+ "evidence": props.get("evidence"),
33
+ }
34
+
35
+
36
+ async def causal_chain(
37
+ store: Any,
38
+ entity_id: str,
39
+ direction: str = "downstream",
40
+ max_hops: int = 3,
41
+ min_confidence: float = 0.0,
42
+ max_edges: int = 100,
43
+ ) -> Dict[str, Any]:
44
+ """BFS over causal edges only (explicitly typed queries, so the generic
45
+ read-path exclusion does not apply here — by construction).
46
+
47
+ direction: downstream = effects of entity_id; upstream = its causes;
48
+ both = the full causal neighborhood.
49
+ """
50
+ if direction not in _DIRECTIONS:
51
+ direction = "downstream"
52
+ max_hops = max(1, min(int(max_hops), 5))
53
+
54
+ edges: Dict[str, Dict[str, Any]] = {}
55
+ visited: Dict[str, int] = {entity_id: 0}
56
+ frontier = [entity_id]
57
+ truncated = False
58
+
59
+ for hop in range(max_hops):
60
+ next_frontier: List[str] = []
61
+ for eid in frontier:
62
+ for rel_type in sorted(CAUSAL_RELATIONSHIP_TYPES):
63
+ queries = []
64
+ if direction in ("downstream", "both"):
65
+ queries.append({"source_id": eid})
66
+ if direction in ("upstream", "both"):
67
+ queries.append({"target_id": eid})
68
+ for q in queries:
69
+ rels = await store.query_relationships(
70
+ relationship_type=rel_type,
71
+ min_confidence=min_confidence, limit=50, **q)
72
+ for rel in rels:
73
+ if rel.id in edges:
74
+ continue
75
+ if len(edges) >= max_edges:
76
+ truncated = True
77
+ break
78
+ edges[rel.id] = _edge_dict(rel)
79
+ other = (rel.target_id if rel.source_id == eid
80
+ else rel.source_id)
81
+ if other not in visited:
82
+ visited[other] = hop + 1
83
+ next_frontier.append(other)
84
+ if truncated:
85
+ break
86
+ if truncated:
87
+ break
88
+ if truncated:
89
+ break
90
+ if truncated or not next_frontier:
91
+ break
92
+ frontier = next_frontier
93
+
94
+ nodes: Dict[str, Dict[str, Any]] = {}
95
+ for eid in visited:
96
+ try:
97
+ ent = await store.get_entity(eid, min_confidence=0.0)
98
+ except Exception:
99
+ ent = None
100
+ if ent is not None:
101
+ nodes[eid] = {"name": ent.name, "entity_type": ent.entity_type,
102
+ "hops": visited[eid]}
103
+
104
+ return {
105
+ "entity_id": entity_id,
106
+ "direction": direction,
107
+ "max_hops": max_hops,
108
+ "edges": list(edges.values()),
109
+ "nodes": nodes,
110
+ "truncated": truncated,
111
+ }
112
+
113
+
114
+ async def causal_edges(store: Any, min_confidence: float = 0.0,
115
+ limit: int = 100) -> List[Dict[str, Any]]:
116
+ """Flat list of causal edges (explicitly typed queries per causal type)."""
117
+ out: List[Dict[str, Any]] = []
118
+ for rel_type in sorted(CAUSAL_RELATIONSHIP_TYPES):
119
+ rels = await store.query_relationships(
120
+ relationship_type=rel_type, min_confidence=min_confidence,
121
+ limit=limit)
122
+ out.extend(_edge_dict(r) for r in rels)
123
+ if len(out) >= limit:
124
+ break
125
+ return out[:limit]
@@ -0,0 +1,54 @@
1
+ """Confidence scoring for World Model entities and properties."""
2
+
3
+ # Confidence initialization rules (entity-level)
4
+ CONFIDENCE_BY_SOURCE = {
5
+ "structured_import": 0.95, # calendar sync, contact import — highly reliable
6
+ "document_extraction": 0.70, # named entity from PDF, email body
7
+ "conversation_ner": 0.55, # NER from message text
8
+ "inferred": 0.30, # deduced from context, not explicitly stated
9
+ "unverified_mention": 0.20, # single passing mention
10
+ }
11
+
12
+ # Confidence boost per corroborating observation
13
+ CORROBORATION_BOOST = 0.05
14
+
15
+ # Confidence ceiling
16
+ MAX_CONFIDENCE = 0.98
17
+
18
+ # Minimum confidence for an entity to appear in query results by default
19
+ DEFAULT_CONFIDENCE_THRESHOLD = 0.30
20
+
21
+ # Minimum confidence for storage
22
+ MIN_CONFIDENCE_FOR_STORAGE = 0.20
23
+
24
+
25
+ def compute_property_confidence(
26
+ extraction_source: str,
27
+ corroboration_count: int = 0,
28
+ ) -> float:
29
+ """Compute property-level confidence from source and corroboration.
30
+
31
+ Args:
32
+ extraction_source: Source type key from CONFIDENCE_BY_SOURCE.
33
+ corroboration_count: Number of additional observations corroborating this value.
34
+
35
+ Returns:
36
+ Confidence in [0.0, MAX_CONFIDENCE].
37
+ """
38
+ base = CONFIDENCE_BY_SOURCE.get(extraction_source, 0.30)
39
+ boosted = base + corroboration_count * CORROBORATION_BOOST
40
+ return min(boosted, MAX_CONFIDENCE)
41
+
42
+
43
+ def boost_confidence(current: float, amount: float = CORROBORATION_BOOST) -> float:
44
+ """Boost confidence by amount, capped at MAX_CONFIDENCE."""
45
+ return min(current + amount, MAX_CONFIDENCE)
46
+
47
+
48
+ def apply_extraction_adjustments(base_confidence: float, adjustments: list[float]) -> float:
49
+ """Apply a list of signed confidence adjustments to a base value.
50
+
51
+ Clamps result to [0.0, MAX_CONFIDENCE].
52
+ """
53
+ result = base_confidence + sum(adjustments)
54
+ return max(0.0, min(result, MAX_CONFIDENCE))
@@ -0,0 +1,64 @@
1
+ """World Model configuration dataclass."""
2
+
3
+ import os
4
+ from dataclasses import dataclass, field
5
+ from typing import List
6
+
7
+
8
+ def _default_sqlite_path() -> str:
9
+ """State-dir-anchored default (env-overridable via
10
+ WORLD_MODEL_SQLITE_PATH). A bare cwd-relative filename made the store
11
+ land wherever the process happened to start (a git checkout, on the
12
+ reference deployment), which is fragile across restarts and updates."""
13
+ explicit = os.environ.get("WORLD_MODEL_SQLITE_PATH", "").strip()
14
+ if explicit:
15
+ return explicit
16
+ state_dir = os.environ.get("COLONY_STATE_DIR", "").strip()
17
+ if state_dir:
18
+ return os.path.join(state_dir, "colony_world_model.db")
19
+ return "colony_world_model.db"
20
+
21
+
22
+ @dataclass
23
+ class WorldModelConfig:
24
+ # ── Feature flags ──────────────────────────────────────────────────
25
+ enabled: bool = True
26
+ auto_extract_conversations: bool = True
27
+ auto_extract_documents: bool = True
28
+ structured_import_enabled: bool = True
29
+ entity_resolution_enabled: bool = True
30
+
31
+ # ── Backend ────────────────────────────────────────────────────────
32
+ # SQLite supports canonical typed observations. Alternate backends retain
33
+ # only the legacy entity/relationship graph, not observation parity.
34
+ backend: str = "sqlite" # "sqlite" | "neo4j" | "postgres"
35
+ neo4j_uri: str = "bolt://localhost:7687"
36
+ neo4j_database: str = "neo4j"
37
+ sqlite_path: str = field(default_factory=_default_sqlite_path)
38
+
39
+ # ── Confidence thresholds ──────────────────────────────────────────
40
+ min_confidence_for_storage: float = 0.20
41
+ min_confidence_for_query: float = 0.30
42
+ auto_merge_confidence_threshold: float = 0.85
43
+ propose_merge_confidence_threshold: float = 0.70
44
+
45
+ # ── Resolution ─────────────────────────────────────────────────────
46
+ string_similarity_auto_merge: float = 0.92
47
+ string_similarity_propose: float = 0.75
48
+
49
+ # ── Extraction ─────────────────────────────────────────────────────
50
+ max_extraction_ms: int = 50 # per-message budget
51
+ min_message_length_for_extraction: int = 20
52
+ extraction_spacy_model: str = "en_core_web_sm"
53
+
54
+ # ── Graph traversal ────────────────────────────────────────────────
55
+ max_graph_hops: int = 5
56
+ default_graph_hops: int = 2
57
+ max_traversal_nodes: int = 200
58
+
59
+ # ── Retention ─────────────────────────────────────────────────────
60
+ low_confidence_entity_ttl_days: int = 90
61
+ merge_proposal_expiry_days: int = 30
62
+
63
+ # ── Briefing limits ────────────────────────────────────────────────
64
+ max_world_model_briefing_items_per_day: int = 3
@@ -0,0 +1,97 @@
1
+ """World Model constants: entity types, relationship types, external ID keys."""
2
+
3
+ # ── Entity Types ──────────────────────────────────────────────────────────────
4
+
5
+ ENTITY_TYPES = frozenset({
6
+ "person",
7
+ "company",
8
+ "project",
9
+ "product",
10
+ "location",
11
+ "event",
12
+ "concept",
13
+ })
14
+
15
+ # ── Relationship Types (WM_ prefixed for Neo4j namespace safety) ──────────────
16
+
17
+ RELATIONSHIP_TYPES = frozenset({
18
+ "WM_WORKS_AT",
19
+ "WM_FOUNDED",
20
+ "WM_OWNS",
21
+ "WM_INVESTED_IN",
22
+ "WM_ADVISES",
23
+ "WM_MANAGES",
24
+ "WM_REPORTS_TO",
25
+ "WM_KNOWS",
26
+ "WM_INTRODUCED_BY", # provenance: who introduced this person to the agent's graph
27
+ "WM_PARTNER_OF",
28
+ "WM_ACQUIRED",
29
+ "WM_PART_OF",
30
+ "WM_LOCATED_IN",
31
+ "WM_MEMBER_OF",
32
+ "WM_ATTENDED",
33
+ "WM_ORGANIZED",
34
+ "WM_PRODUCED",
35
+ "WM_USES",
36
+ "WM_RELATED_TO",
37
+ "WM_TAGGED_WITH",
38
+ "WM_MENTIONS",
39
+ "WM_PREDECESSOR_OF",
40
+ "WM_SUCCESSOR_OF",
41
+ "WM_DEPENDS_ON",
42
+ # Causal vocabulary (query-only; see world_model/causal_policy.py)
43
+ "WM_CAUSES",
44
+ "WM_ENABLES",
45
+ "WM_BLOCKS",
46
+ "WM_INHIBITS",
47
+ })
48
+
49
+ # ── Causal Relationship Types ─────────────────────────────────────────────────
50
+ # The causal subset of RELATIONSHIP_TYPES. Causal edges are QUERY-ONLY by
51
+ # policy: they may inform answers to "why"/"what happens if" questions but
52
+ # must never trigger actions unless world_model.causal_policy explicitly
53
+ # says otherwise (COLONY_CAUSAL_ACT, default off).
54
+
55
+ CAUSAL_RELATIONSHIP_TYPES = frozenset({
56
+ "WM_CAUSES", # A brings about B
57
+ "WM_ENABLES", # A makes B possible (necessary-ish precondition)
58
+ "WM_BLOCKS", # A prevents B outright
59
+ "WM_INHIBITS", # A makes B less likely / weaker
60
+ })
61
+
62
+ # ── External ID Keys ──────────────────────────────────────────────────────────
63
+
64
+ EXTERNAL_ID_KEYS = {
65
+ # People
66
+ "linkedin": "LinkedIn profile URL or ID",
67
+ "email": "Primary email address",
68
+ "phone": "E.164 phone number",
69
+ "twitter": "Twitter/X handle",
70
+
71
+ # Companies
72
+ "crunchbase": "Crunchbase organization slug",
73
+ "linkedin_company": "LinkedIn company ID",
74
+ "ticker": "Stock ticker symbol",
75
+ "domain": "Primary web domain",
76
+ "lei": "Legal Entity Identifier (ISO 17442)",
77
+
78
+ # Events
79
+ "calendar_uid": "iCal UID from calendar source",
80
+ "eventbrite": "Eventbrite event ID",
81
+
82
+ # Products
83
+ "app_store_id": "Apple App Store bundle ID",
84
+ "play_store_id": "Google Play package name",
85
+
86
+ # Locations
87
+ "geonames_id": "GeoNames feature ID",
88
+ "osm_id": "OpenStreetMap node/way/relation ID",
89
+ }
90
+
91
+ # ── ID Prefixes ───────────────────────────────────────────────────────────────
92
+
93
+ ENTITY_ID_PREFIX = "we" # world entity
94
+ RELATIONSHIP_ID_PREFIX = "wr" # world relationship
95
+ OBSERVATION_ID_PREFIX = "wo" # world observation
96
+ MERGE_PROPOSAL_ID_PREFIX = "mp" # merge proposal
97
+ MERGE_AUDIT_ID_PREFIX = "ma" # merge audit record
@@ -0,0 +1,145 @@
1
+ """World Model entity dataclasses.
2
+
3
+ Seven entity types form Colony's world model:
4
+ Person, Company, Project, Product, Location, Event, Concept
5
+
6
+ All share BaseEntity fields. Each adds domain-specific properties.
7
+ """
8
+
9
+ from dataclasses import dataclass, field
10
+ from typing import Any, Dict, List, Optional, Union
11
+ from datetime import datetime
12
+
13
+
14
+ @dataclass
15
+ class BaseEntity:
16
+ """Common properties for all world model entities."""
17
+ id: str # we-<timestamp>-<random7>
18
+ name: str # canonical display name
19
+ entity_type: str # EntityType literal
20
+ aliases: List[str] = field(default_factory=list)
21
+ external_ids: Dict[str, str] = field(default_factory=dict)
22
+ confidence: float = 0.5 # 0.0–1.0 overall entity confidence
23
+ properties: Dict[str, Any] = field(default_factory=dict)
24
+ first_seen: Optional[datetime] = None
25
+ last_seen: Optional[datetime] = None
26
+ created_at: Optional[datetime] = None
27
+ updated_at: Optional[datetime] = None
28
+
29
+
30
+ @dataclass
31
+ class PersonEntity(BaseEntity):
32
+ """A person Colony has encountered or knows about."""
33
+ entity_type: str = "person"
34
+ email: Optional[str] = None
35
+ phone: Optional[str] = None
36
+ title: Optional[str] = None # "CTO", "Engineer"
37
+ bio_summary: Optional[str] = None
38
+ linkedin_url: Optional[str] = None
39
+ twitter_handle: Optional[str] = None
40
+ location_id: Optional[str] = None # FK to LocationEntity
41
+
42
+
43
+ @dataclass
44
+ class CompanyEntity(BaseEntity):
45
+ """An organization of any kind."""
46
+ entity_type: str = "company"
47
+ domain: Optional[str] = None # "acme.com"
48
+ industry: Optional[str] = None # "SaaS", "Healthcare"
49
+ size_range: Optional[str] = None # "1-10", "11-50", "51-200", "201-1000", "1000+"
50
+ founded_year: Optional[int] = None
51
+ headquarters_id: Optional[str] = None # FK to LocationEntity
52
+ linkedin_url: Optional[str] = None
53
+ crunchbase_url: Optional[str] = None
54
+ ticker: Optional[str] = None # "AAPL", "GOOG"
55
+ description: Optional[str] = None
56
+
57
+
58
+ @dataclass
59
+ class ProjectEntity(BaseEntity):
60
+ """A bounded initiative with participants and a goal."""
61
+ entity_type: str = "project"
62
+ description: Optional[str] = None
63
+ status: Optional[str] = None # "active", "completed", "paused", "cancelled"
64
+ start_date: Optional[str] = None # ISO8601
65
+ end_date: Optional[str] = None # ISO8601; None = ongoing
66
+ owner_id: Optional[str] = None # FK to PersonEntity
67
+ company_id: Optional[str] = None # FK to CompanyEntity
68
+
69
+
70
+ @dataclass
71
+ class ProductEntity(BaseEntity):
72
+ """A product, service, or software artifact."""
73
+ entity_type: str = "product"
74
+ category: Optional[str] = None # "SaaS", "hardware", "API"
75
+ version: Optional[str] = None
76
+ url: Optional[str] = None
77
+ company_id: Optional[str] = None # FK to CompanyEntity
78
+ description: Optional[str] = None
79
+
80
+
81
+ @dataclass
82
+ class LocationEntity(BaseEntity):
83
+ """A geographic or virtual place."""
84
+ entity_type: str = "location"
85
+ location_type: Optional[str] = None # "city", "country", "office", "virtual"
86
+ city: Optional[str] = None
87
+ country: Optional[str] = None
88
+ latitude: Optional[float] = None
89
+ longitude: Optional[float] = None
90
+ timezone: Optional[str] = None # "America/Los_Angeles"
91
+
92
+
93
+ @dataclass
94
+ class EventEntity(BaseEntity):
95
+ """A time-bounded occurrence."""
96
+ entity_type: str = "event"
97
+ event_type: Optional[str] = None # "meeting", "conference", "deadline", "launch"
98
+ start_time: Optional[str] = None # ISO8601
99
+ end_time: Optional[str] = None # ISO8601
100
+ location_id: Optional[str] = None
101
+ organizer_id: Optional[str] = None # FK to PersonEntity or CompanyEntity
102
+ url: Optional[str] = None
103
+ description: Optional[str] = None
104
+
105
+
106
+ @dataclass
107
+ class ConceptEntity(BaseEntity):
108
+ """An abstract topic, technology, or category."""
109
+ entity_type: str = "concept"
110
+ concept_type: Optional[str] = None # "technology", "methodology", "regulation", "topic"
111
+ description: Optional[str] = None
112
+ parent_concept_id: Optional[str] = None # for hierarchical concepts
113
+
114
+
115
+ # Type union for all entity types
116
+ EntityType = (
117
+ Union[PersonEntity, CompanyEntity, ProjectEntity,
118
+ ProductEntity, LocationEntity, EventEntity, ConceptEntity]
119
+ )
120
+
121
+ # Map from entity_type string to dataclass
122
+ ENTITY_CLASS_MAP: Dict[str, type] = {
123
+ "person": PersonEntity,
124
+ "company": CompanyEntity,
125
+ "project": ProjectEntity,
126
+ "product": ProductEntity,
127
+ "location": LocationEntity,
128
+ "event": EventEntity,
129
+ "concept": ConceptEntity,
130
+ }
131
+
132
+
133
+ def entity_from_dict(data: Dict[str, Any]) -> BaseEntity:
134
+ """Reconstruct an entity from a flat dict (e.g., from SQLite row).
135
+
136
+ Maps 'entity_type' to the appropriate subclass and constructs it.
137
+ Unknown types fall back to BaseEntity.
138
+ """
139
+ entity_type = data.get("entity_type", "")
140
+ cls = ENTITY_CLASS_MAP.get(entity_type, BaseEntity)
141
+ # Filter data keys to only those accepted by the dataclass
142
+ import dataclasses
143
+ valid_fields = {f.name for f in dataclasses.fields(cls)}
144
+ filtered = {k: v for k, v in data.items() if k in valid_fields}
145
+ return cls(**filtered)