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.
- apsimo/__init__.py +38 -0
- apsimo/__main__.py +6 -0
- apsimo/agent/__init__.py +6 -0
- apsimo/agent/client.py +276 -0
- apsimo/agent/models.py +46 -0
- apsimo/agents/__init__.py +20 -0
- apsimo/agents/models.py +264 -0
- apsimo/agents/store.py +861 -0
- apsimo/agents/websocket.py +522 -0
- apsimo/api/__init__.py +1 -0
- apsimo/api/auth_telemetry.py +287 -0
- apsimo/api/authority.py +1203 -0
- apsimo/api/contact_grants.py +347 -0
- apsimo/api/middleware.py +483 -0
- apsimo/api/routers/__init__.py +1 -0
- apsimo/api/routers/commitment_work.py +265 -0
- apsimo/api/routers/context_gate.py +123 -0
- apsimo/api/routers/executions.py +140 -0
- apsimo/api/routers/followup_plans.py +147 -0
- apsimo/api/routers/governed_actions.py +162 -0
- apsimo/api/routers/host.py +14473 -0
- apsimo/api/routers/initiative_work.py +115 -0
- apsimo/api/routers/mining.py +104 -0
- apsimo/api/routers/observations.py +110 -0
- apsimo/api/routers/social_state.py +225 -0
- apsimo/api/routers/task_queue.py +2715 -0
- apsimo/api/routers/temporal_followups.py +251 -0
- apsimo/api/routers/transport.py +110 -0
- apsimo/api/routers/transport_ingress_api.py +240 -0
- apsimo/api/schemas/__init__.py +1 -0
- apsimo/api/schemas/host.py +1949 -0
- apsimo/autonomy/cli.py +110 -0
- apsimo/autonomy/condition_worker.py +437 -0
- apsimo/autonomy/config.py +424 -0
- apsimo/autonomy/loop.py +4316 -0
- apsimo/autonomy/registry.py +339 -0
- apsimo/autonomy/scheduler.py +1822 -0
- apsimo/autonomy/synthesis.py +449 -0
- apsimo/backup.py +962 -0
- apsimo/beliefs/__init__.py +23 -0
- apsimo/beliefs/contradictions.py +109 -0
- apsimo/beliefs/decay.py +61 -0
- apsimo/beliefs/engine.py +479 -0
- apsimo/beliefs/models.py +67 -0
- apsimo/beliefs/promotion.py +41 -0
- apsimo/beliefs/resolve.py +58 -0
- apsimo/beliefs/source_claims.py +690 -0
- apsimo/beliefs/source_projection.py +883 -0
- apsimo/beliefs/source_time.py +208 -0
- apsimo/beliefs/store.py +133 -0
- apsimo/briefings/aggregators.py +824 -0
- apsimo/briefings/composer.py +420 -0
- apsimo/briefings/config.py +55 -0
- apsimo/briefings/delivery.py +439 -0
- apsimo/briefings/engagement.py +97 -0
- apsimo/briefings/engine.py +274 -0
- apsimo/briefings/enhancer.py +99 -0
- apsimo/briefings/models.py +183 -0
- apsimo/briefings/scheduler.py +382 -0
- apsimo/briefings/store.py +435 -0
- apsimo/chain/__init__.py +48 -0
- apsimo/chain/block.py +100 -0
- apsimo/chain/cli.py +704 -0
- apsimo/chain/genesis.py +443 -0
- apsimo/chain/identity.py +416 -0
- apsimo/chain/keys.py +1025 -0
- apsimo/chain/local_keys.py +187 -0
- apsimo/chain/manager.py +290 -0
- apsimo/chain/node.py +163 -0
- apsimo/chain/plugin_transactions.py +371 -0
- apsimo/chain/protocol.py +220 -0
- apsimo/chain/state_machine.py +676 -0
- apsimo/chain/storage.py +503 -0
- apsimo/chain/transactions.py +250 -0
- apsimo/chain/validation.py +397 -0
- apsimo/channels/__init__.py +1 -0
- apsimo/channels/manifest.py +31 -0
- apsimo/channels/migrations/001_channels_schema.sql +12 -0
- apsimo/channels/phone_gateways.py +42 -0
- apsimo/channels/presence.py +188 -0
- apsimo/channels/router.py +235 -0
- apsimo/channels/store.py +231 -0
- apsimo/cli.py +2688 -0
- apsimo/cognition/__init__.py +11 -0
- apsimo/cognition/charter.py +398 -0
- apsimo/cognition/drive_governance.py +3530 -0
- apsimo/cognition/evidence_pipeline.py +1627 -0
- apsimo/cognition/external_events.py +932 -0
- apsimo/cognition/goal_spine.py +3488 -0
- apsimo/cognition/introspection.py +214 -0
- apsimo/cognition/prompt.py +150 -0
- apsimo/cognition/runtime.py +108 -0
- apsimo/cognition/trigger.py +154 -0
- apsimo/commitments/__init__.py +18 -0
- apsimo/commitments/local_work.py +355 -0
- apsimo/commitments/store.py +1052 -0
- apsimo/commitments/work.py +91 -0
- apsimo/compat.py +53 -0
- apsimo/compression/__init__.py +467 -0
- apsimo/connectors/__init__.py +21 -0
- apsimo/connectors/base.py +152 -0
- apsimo/connectors/caldav_calendar.py +125 -0
- apsimo/connectors/fs_documents.py +85 -0
- apsimo/connectors/imap_email.py +138 -0
- apsimo/connectors/manager.py +218 -0
- apsimo/connectors/webhook_pull.py +88 -0
- apsimo/contacts/__init__.py +33 -0
- apsimo/contacts/comms.py +357 -0
- apsimo/contacts/config.py +79 -0
- apsimo/contacts/exporters/__init__.py +1 -0
- apsimo/contacts/exporters/vcard.py +71 -0
- apsimo/contacts/identity_links.py +251 -0
- apsimo/contacts/importer.py +280 -0
- apsimo/contacts/importers/__init__.py +1 -0
- apsimo/contacts/importers/batch.py +43 -0
- apsimo/contacts/importers/macos_contacts.py +101 -0
- apsimo/contacts/migrations/001_contacts_schema.sql +141 -0
- apsimo/contacts/migrations/002_trust_scopes.sql +36 -0
- apsimo/contacts/migrations/003_open_gateway_enum.sql +32 -0
- apsimo/contacts/migrations/004_contact_provision_operations.sql +18 -0
- apsimo/contacts/migrations/005_identity_links.sql +27 -0
- apsimo/contacts/models.py +308 -0
- apsimo/contacts/scoring.py +16 -0
- apsimo/contacts/store.py +1623 -0
- apsimo/contacts/transport_ingress.py +252 -0
- apsimo/contacts/world_bridge.py +314 -0
- apsimo/contextgate/__init__.py +69 -0
- apsimo/contextgate/chunker.py +169 -0
- apsimo/contextgate/estimate.py +54 -0
- apsimo/contextgate/gate.py +313 -0
- apsimo/contextgate/retrieve.py +115 -0
- apsimo/delivery/__init__.py +16 -0
- apsimo/delivery/bridge.py +1260 -0
- apsimo/delivery/channels.py +526 -0
- apsimo/delivery/classification.py +50 -0
- apsimo/delivery/rate_limiter.py +268 -0
- apsimo/delivery/reachout_policy.py +206 -0
- apsimo/directed/__init__.py +22 -0
- apsimo/directed/audit.py +167 -0
- apsimo/directed/intake.py +95 -0
- apsimo/directed/models.py +191 -0
- apsimo/directed/service.py +509 -0
- apsimo/directives/__init__.py +25 -0
- apsimo/directives/evidence.py +87 -0
- apsimo/directives/extractor.py +188 -0
- apsimo/directives/guard.py +364 -0
- apsimo/directives/models.py +206 -0
- apsimo/directives/service.py +372 -0
- apsimo/directives/store.py +167 -0
- apsimo/doctor.py +2173 -0
- apsimo/environment.py +43 -0
- apsimo/events/__init__.py +33 -0
- apsimo/events/broadcaster.py +98 -0
- apsimo/events/bus.py +217 -0
- apsimo/events/journal.py +863 -0
- apsimo/events/stream.py +131 -0
- apsimo/events/types.py +150 -0
- apsimo/execution_results.py +357 -0
- apsimo/feedback/__init__.py +5 -0
- apsimo/feedback/store.py +76 -0
- apsimo/feeds/__init__.py +19 -0
- apsimo/feeds/cli.py +84 -0
- apsimo/feeds/engine.py +437 -0
- apsimo/feeds/example-feed.yaml +77 -0
- apsimo/feeds/hermes_cron.py +126 -0
- apsimo/feeds/manager.py +235 -0
- apsimo/feeds/spec.py +250 -0
- apsimo/feeds/template.py +202 -0
- apsimo/gate/__init__.py +18 -0
- apsimo/gate/audit.py +61 -0
- apsimo/gate/communication_policy.py +166 -0
- apsimo/gate/config.py +72 -0
- apsimo/gate/context_provenance.py +170 -0
- apsimo/gate/env_risk.py +226 -0
- apsimo/gate/guard_audit.py +353 -0
- apsimo/gate/layers/__init__.py +1 -0
- apsimo/gate/layers/base.py +15 -0
- apsimo/gate/layers/l1_recipient.py +66 -0
- apsimo/gate/layers/l2_pii.py +134 -0
- apsimo/gate/layers/l3_cross_context.py +50 -0
- apsimo/gate/layers/l4_trust_tier.py +78 -0
- apsimo/gate/layers/l5_injection.py +199 -0
- apsimo/gate/layers/l6_review.py +86 -0
- apsimo/gate/layers/l7_delay.py +100 -0
- apsimo/gate/layers/tom2_epistemic.py +185 -0
- apsimo/gate/models.py +64 -0
- apsimo/gate/pending_dispatch.py +5 -0
- apsimo/gate/pipeline.py +206 -0
- apsimo/gate/rejection.py +259 -0
- apsimo/gate/response_guard.py +700 -0
- apsimo/gate/rulesets/injection_v1.yaml +51 -0
- apsimo/gate/surface_policy.py +189 -0
- apsimo/gate/taint.py +226 -0
- apsimo/genesis.json +9 -0
- apsimo/goals/__init__.py +100 -0
- apsimo/goals/config.py +38 -0
- apsimo/goals/decomposer.py +421 -0
- apsimo/goals/engine.py +617 -0
- apsimo/goals/inference.py +354 -0
- apsimo/goals/models.py +302 -0
- apsimo/goals/priority.py +270 -0
- apsimo/goals/queue_bridge.py +149 -0
- apsimo/goals/replan.py +450 -0
- apsimo/goals/schema.sql +89 -0
- apsimo/goals/store.py +692 -0
- apsimo/governed_actions.py +1708 -0
- apsimo/harness_integration/__init__.py +45 -0
- apsimo/harness_integration/context.py +41 -0
- apsimo/harness_integration/skills.py +231 -0
- apsimo/identity/__init__.py +26 -0
- apsimo/identity/participants.py +181 -0
- apsimo/identity/resolver.py +329 -0
- apsimo/identity_bootstrap/__init__.py +5 -0
- apsimo/identity_bootstrap/builder.py +208 -0
- apsimo/identity_bootstrap/corpus.py +443 -0
- apsimo/identity_bootstrap/models.py +54 -0
- apsimo/identity_bootstrap/runner.py +353 -0
- apsimo/identity_bootstrap/seeders/__init__.py +25 -0
- apsimo/identity_bootstrap/seeders/briefings.py +109 -0
- apsimo/identity_bootstrap/seeders/chain.py +57 -0
- apsimo/identity_bootstrap/seeders/goals.py +128 -0
- apsimo/identity_bootstrap/seeders/memory.py +191 -0
- apsimo/identity_bootstrap/seeders/neo4j_cognition.py +79 -0
- apsimo/identity_bootstrap/seeders/relationship.py +152 -0
- apsimo/identity_bootstrap/seeders/sessions.py +67 -0
- apsimo/identity_bootstrap/seeders/skills.py +92 -0
- apsimo/identity_bootstrap/seeders/task_queue.py +72 -0
- apsimo/identity_bootstrap/seeders/world_model.py +143 -0
- apsimo/identity_bootstrap/self_query.py +92 -0
- apsimo/identity_bootstrap/self_reflection.py +155 -0
- apsimo/identity_bootstrap/skill.py +37 -0
- apsimo/identity_bootstrap/verifier.py +436 -0
- apsimo/initiatives/__init__.py +20 -0
- apsimo/initiatives/action_registry.py +454 -0
- apsimo/initiatives/approval_authority.py +2105 -0
- apsimo/initiatives/approval_policy.py +123 -0
- apsimo/initiatives/assignment.py +263 -0
- apsimo/initiatives/backup_evidence.py +100 -0
- apsimo/initiatives/context_freshness.py +103 -0
- apsimo/initiatives/models.py +318 -0
- apsimo/initiatives/native_work.py +270 -0
- apsimo/initiatives/standing_approvals.py +232 -0
- apsimo/initiatives/store.py +1081 -0
- apsimo/initiatives/temporal_followup.py +410 -0
- apsimo/intelligence/__init__.py +1 -0
- apsimo/intelligence/cognition/__init__.py +24 -0
- apsimo/intelligence/cognition/gap_detector.py +148 -0
- apsimo/intelligence/cognition/metalearner.py +547 -0
- apsimo/intelligence/cognition/metrics_collector.py +217 -0
- apsimo/intelligence/cognition/performance_index.py +299 -0
- apsimo/intelligence/cognition/registry.py +192 -0
- apsimo/intelligence/cognition/strategy_adjuster.py +222 -0
- apsimo/intelligence/cognition/types.py +16 -0
- apsimo/intelligence/components/__init__.py +66 -0
- apsimo/intelligence/components/anomaly_detector.py +413 -0
- apsimo/intelligence/components/initiative_engine.py +2643 -0
- apsimo/intelligence/components/preference_learner.py +521 -0
- apsimo/intelligence/components/research_orchestrator.py +358 -0
- apsimo/intelligence/components/self_directed_thinker.py +221 -0
- apsimo/intelligence/components/self_reflector.py +252 -0
- apsimo/intelligence/components/session_continuity.py +154 -0
- apsimo/intelligence/components/task_planner.py +320 -0
- apsimo/intelligence/components/tool_learner.py +217 -0
- apsimo/intelligence/graph/__init__.py +79 -0
- apsimo/intelligence/graph/client.py +2483 -0
- apsimo/intelligence/graph/consolidator.py +405 -0
- apsimo/intelligence/graph/distiller.py +312 -0
- apsimo/intelligence/graph/migrations.py +129 -0
- apsimo/intelligence/graph/queries.py +248 -0
- apsimo/intelligence/graph/recall.py +281 -0
- apsimo/intelligence/graph/reconciler.py +144 -0
- apsimo/intelligence/graph/schema.py +337 -0
- apsimo/intelligence/graph/selection.py +252 -0
- apsimo/intelligence/learning/__init__.py +17 -0
- apsimo/intelligence/learning/continuous_learner.py +245 -0
- apsimo/intelligence/learning/feedback_store.py +321 -0
- apsimo/intelligence/mind_model/__init__.py +1 -0
- apsimo/intelligence/mind_model/graph_baseline.py +136 -0
- apsimo/intelligence/mind_model/signal_collector.py +361 -0
- apsimo/intelligence/relationships/__init__.py +11 -0
- apsimo/intelligence/relationships/profiler.py +389 -0
- apsimo/intelligence/relationships/scorer.py +560 -0
- apsimo/intelligence/relationships/signal_floor.py +66 -0
- apsimo/intelligence/relationships/trust_tiers.py +300 -0
- apsimo/intelligence/synthesis/__init__.py +40 -0
- apsimo/intelligence/synthesis/connection_discoverer.py +379 -0
- apsimo/intelligence/synthesis/cross_domain_analyzer.py +287 -0
- apsimo/intelligence/synthesis/insight_deliverer.py +171 -0
- apsimo/intelligence/synthesis/insight_store.py +79 -0
- apsimo/intelligence/synthesis/insight_validator.py +183 -0
- apsimo/intelligence/synthesis/novelty_scorer.py +267 -0
- apsimo/intelligence/turn_middleware/__init__.py +15 -0
- apsimo/intelligence/turn_middleware/memory_sync.py +119 -0
- apsimo/mcp/__init__.py +41 -0
- apsimo/mcp/__main__.py +6 -0
- apsimo/mcp/config.py +287 -0
- apsimo/mcp/server.py +501 -0
- apsimo/migrations.py +187 -0
- apsimo/mining/__init__.py +27 -0
- apsimo/mining/corpus.py +239 -0
- apsimo/mining/escalations.py +289 -0
- apsimo/mining/models.py +169 -0
- apsimo/mining/store.py +210 -0
- apsimo/models/__init__.py +30 -0
- apsimo/models/memory.py +80 -0
- apsimo/models/mesh.py +72 -0
- apsimo/models/person.py +104 -0
- apsimo/models/signal.py +108 -0
- apsimo/observations/__init__.py +15 -0
- apsimo/observations/store.py +277 -0
- apsimo/patterns/__init__.py +6 -0
- apsimo/patterns/extract.py +187 -0
- apsimo/patterns/store.py +227 -0
- apsimo/persona/__init__.py +1 -0
- apsimo/persona/engine.py +611 -0
- apsimo/persona/manifest.py +140 -0
- apsimo/projects/__init__.py +28 -0
- apsimo/projects/engine.py +1681 -0
- apsimo/projects/event_outbox.py +188 -0
- apsimo/projects/models.py +216 -0
- apsimo/projects/planner.py +181 -0
- apsimo/projects/store.py +1446 -0
- apsimo/proposals/__init__.py +12 -0
- apsimo/proposals/engine.py +114 -0
- apsimo/proposals/models.py +207 -0
- apsimo/qualification/__init__.py +1 -0
- apsimo/qualification/cases.py +75 -0
- apsimo/qualification/cli.py +51 -0
- apsimo/qualification/memory_cases.py +209 -0
- apsimo/qualification/records.py +92 -0
- apsimo/qualification/report.py +87 -0
- apsimo/qualification/runner.py +311 -0
- apsimo/qualification/structured_cases.py +131 -0
- apsimo/reasoning/__init__.py +13 -0
- apsimo/reasoning/executor.py +506 -0
- apsimo/reasoning/loop.py +373 -0
- apsimo/reasoning/native_tools/__init__.py +16 -0
- apsimo/reasoning/native_tools/calculate.py +141 -0
- apsimo/reasoning/native_tools/file_ops.py +150 -0
- apsimo/reasoning/native_tools/web_search.py +49 -0
- apsimo/reasoning/tool_policy.py +182 -0
- apsimo/redact/__init__.py +176 -0
- apsimo/repos/__init__.py +5 -0
- apsimo/repos/mirrors.py +204 -0
- apsimo/research/__init__.py +41 -0
- apsimo/research/artifact.py +482 -0
- apsimo/research/gatherer.py +387 -0
- apsimo/research/pipeline.py +513 -0
- apsimo/research/search/__init__.py +7 -0
- apsimo/research/search/base.py +41 -0
- apsimo/research/search/brave.py +59 -0
- apsimo/research/search/cache.py +51 -0
- apsimo/research/search/duckduckgo.py +103 -0
- apsimo/research/search/orchestrator.py +119 -0
- apsimo/research/search/serpapi.py +59 -0
- apsimo/research/search/tavily.py +59 -0
- apsimo/research/synthesizer.py +309 -0
- apsimo/router/__init__.py +30 -0
- apsimo/router/complexity_scorer.py +148 -0
- apsimo/router/endpoints.py +153 -0
- apsimo/router/fallback.py +58 -0
- apsimo/router/functions.py +243 -0
- apsimo/router/native_policy.py +52 -0
- apsimo/router/router.py +762 -0
- apsimo/router/self_learning.py +174 -0
- apsimo/router/tiers.py +677 -0
- apsimo/sandbox/__init__.py +21 -0
- apsimo/sandbox/backend.py +195 -0
- apsimo/sandbox/manager.py +173 -0
- apsimo/scope_bounds.py +7 -0
- apsimo/secrets/__init__.py +6 -0
- apsimo/secrets/backends/__init__.py +8 -0
- apsimo/secrets/backends/base.py +42 -0
- apsimo/secrets/backends/env.py +110 -0
- apsimo/secrets/backends/keyring.py +72 -0
- apsimo/secrets/backends/onepassword.py +232 -0
- apsimo/secrets/cli.py +191 -0
- apsimo/secrets/manager.py +160 -0
- apsimo/secrets/migration.py +101 -0
- apsimo/secrets/types.py +98 -0
- apsimo/seed.py +41 -0
- apsimo/self_model/__init__.py +37 -0
- apsimo/self_model/appraisals.py +673 -0
- apsimo/self_model/benchmark.py +1314 -0
- apsimo/self_model/brief.py +40 -0
- apsimo/self_model/event_concerns.py +1128 -0
- apsimo/self_model/execution_forecasts.py +353 -0
- apsimo/self_model/expectations.py +1595 -0
- apsimo/self_model/experiments.py +1150 -0
- apsimo/self_model/journal.py +148 -0
- apsimo/self_model/judgments.py +705 -0
- apsimo/self_model/native_outcomes.py +55 -0
- apsimo/self_model/params.py +220 -0
- apsimo/self_model/perspective.py +246 -0
- apsimo/self_model/reconcile.py +183 -0
- apsimo/self_model/reply_forecasts.py +381 -0
- apsimo/self_model/runtime_forecasts.py +296 -0
- apsimo/self_model/runtime_models.py +67 -0
- apsimo/self_model/settlement.py +207 -0
- apsimo/self_model/situation.py +1731 -0
- apsimo/self_model/store.py +883 -0
- apsimo/self_model/supervised.py +137 -0
- apsimo/self_model/thinker.py +99 -0
- apsimo/self_model/trust.py +388 -0
- apsimo/self_model/workspace.py +2388 -0
- apsimo/server.py +4197 -0
- apsimo/services/__init__.py +1 -0
- apsimo/services/agent_bridge.py +474 -0
- apsimo/services/initiative_executor.py +914 -0
- apsimo/services/instance.py +297 -0
- apsimo/sessions/__init__.py +22 -0
- apsimo/sessions/config.py +13 -0
- apsimo/sessions/context_loader.py +88 -0
- apsimo/sessions/federation_session.py +75 -0
- apsimo/sessions/isolated_session.py +98 -0
- apsimo/sessions/reports.py +84 -0
- apsimo/sessions/store.py +148 -0
- apsimo/setup.py +2818 -0
- apsimo/setup_hermes.py +879 -0
- apsimo/setup_local_work.py +218 -0
- apsimo/setup_native_goals.py +134 -0
- apsimo/setup_native_reviews.py +115 -0
- apsimo/skills/__init__.py +10 -0
- apsimo/skills/base.py +108 -0
- apsimo/skills/budget.py +28 -0
- apsimo/skills/executor.py +493 -0
- apsimo/skills/executors/__init__.py +1 -0
- apsimo/skills/executors/behavioral_correction.py +75 -0
- apsimo/skills/executors/capability_gap.py +38 -0
- apsimo/skills/executors/data_quality.py +163 -0
- apsimo/skills/executors/knowledge_acquisition.py +41 -0
- apsimo/skills/executors/operational_hygiene.py +185 -0
- apsimo/skills/executors/subsystem_health.py +169 -0
- apsimo/skills/hermes_export.py +431 -0
- apsimo/skills/index.py +123 -0
- apsimo/skills/learning/__init__.py +21 -0
- apsimo/skills/learning/novelty_detector.py +206 -0
- apsimo/skills/learning/pattern_extractor.py +199 -0
- apsimo/skills/learning/triggers.py +159 -0
- apsimo/skills/loader.py +246 -0
- apsimo/skills/migrations/002_progressive_loading.sql +6 -0
- apsimo/skills/migrations/backfill_triggers.py +20 -0
- apsimo/skills/models.py +202 -0
- apsimo/skills/packager.py +128 -0
- apsimo/skills/protocols.py +70 -0
- apsimo/skills/registry.py +191 -0
- apsimo/skills/runtime.py +58 -0
- apsimo/skills/sandbox_runner.py +229 -0
- apsimo/skills/scheduler.py +129 -0
- apsimo/skills/schema.py +79 -0
- apsimo/skills/security/__init__.py +12 -0
- apsimo/skills/security/guards.py +53 -0
- apsimo/skills/security/scanner.py +223 -0
- apsimo/skills_memory/__init__.py +26 -0
- apsimo/skills_memory/distill.py +159 -0
- apsimo/skills_memory/models.py +85 -0
- apsimo/skills_memory/retrieve.py +62 -0
- apsimo/skills_memory/store.py +172 -0
- apsimo/surprise/__init__.py +6 -0
- apsimo/surprise/accumulation.py +57 -0
- apsimo/surprise/scorer.py +102 -0
- apsimo/surprise/store.py +203 -0
- apsimo/task_queue/__init__.py +69 -0
- apsimo/task_queue/action_receipts.py +148 -0
- apsimo/task_queue/approval_relay_canary.py +108 -0
- apsimo/task_queue/config.py +85 -0
- apsimo/task_queue/contract.py +361 -0
- apsimo/task_queue/events.py +130 -0
- apsimo/task_queue/governor.py +1031 -0
- apsimo/task_queue/handlers/__init__.py +16 -0
- apsimo/task_queue/handlers/base.py +37 -0
- apsimo/task_queue/handlers/inference.py +640 -0
- apsimo/task_queue/handlers/monitoring.py +116 -0
- apsimo/task_queue/handlers/registry.py +75 -0
- apsimo/task_queue/handlers/subtask_handler.py +173 -0
- apsimo/task_queue/handlers/system_maintenance.py +147 -0
- apsimo/task_queue/mesh_integration.py +111 -0
- apsimo/task_queue/models.py +317 -0
- apsimo/task_queue/queue_manager.py +8286 -0
- apsimo/task_queue/routing.py +287 -0
- apsimo/task_queue/scheduler.py +252 -0
- apsimo/task_queue/schema.sql +197 -0
- apsimo/task_queue/work_control.py +342 -0
- apsimo/task_queue/worker.py +993 -0
- apsimo/telemetry.py +145 -0
- apsimo/tom/__init__.py +6 -0
- apsimo/tom/affect.py +387 -0
- apsimo/tom/approvals.py +171 -0
- apsimo/tom/arcs.py +896 -0
- apsimo/tom/asymmetry.py +131 -0
- apsimo/tom/eligibility.py +248 -0
- apsimo/tom/engagement.py +214 -0
- apsimo/tom/exposure.py +214 -0
- apsimo/tom/extractor.py +306 -0
- apsimo/tom/fact_adapters.py +144 -0
- apsimo/tom/facts.py +326 -0
- apsimo/tom/integration.py +592 -0
- apsimo/tom/leveled.py +118 -0
- apsimo/tom/levels.py +247 -0
- apsimo/tom/recipient_audit.py +995 -0
- apsimo/tom/recipient_simulator.py +593 -0
- apsimo/tom/source_lineage.py +93 -0
- apsimo/tom/tom2.py +277 -0
- apsimo/tom/visibility.py +559 -0
- apsimo/tom/visibility_store.py +414 -0
- apsimo/tools/__init__.py +0 -0
- apsimo/tools/definitions.py +740 -0
- apsimo/tools/handlers.py +943 -0
- apsimo/toolsmith/__init__.py +26 -0
- apsimo/toolsmith/authority.py +166 -0
- apsimo/toolsmith/engine.py +559 -0
- apsimo/toolsmith/integrity.py +100 -0
- apsimo/toolsmith/miner.py +145 -0
- apsimo/toolsmith/policy.py +110 -0
- apsimo/toolsmith/registry.py +635 -0
- apsimo/turns/__init__.py +17 -0
- apsimo/turns/audio.py +134 -0
- apsimo/turns/documents.py +235 -0
- apsimo/turns/executions.py +486 -0
- apsimo/turns/hermes_history.py +245 -0
- apsimo/turns/hermes_kanban.py +268 -0
- apsimo/turns/hermes_work.py +96 -0
- apsimo/turns/idempotency.py +752 -0
- apsimo/turns/local_work.py +115 -0
- apsimo/turns/media.py +581 -0
- apsimo/turns/reported_workers.py +196 -0
- apsimo/turns/source_annotations.py +283 -0
- apsimo/turns/source_attribution.py +154 -0
- apsimo/turns/source_read.py +351 -0
- apsimo/turns/source_vectors.py +263 -0
- apsimo/turns/video.py +210 -0
- apsimo/util/autonomy_preset.py +220 -0
- apsimo/util/instance.py +92 -0
- apsimo/util/model_output.py +25 -0
- apsimo/util/quiet_hours.py +27 -0
- apsimo/util/session_safety.py +37 -0
- apsimo/util/temporal.py +343 -0
- apsimo/vector/__init__.py +75 -0
- apsimo/vector/backfill.py +171 -0
- apsimo/vector/caption.py +114 -0
- apsimo/vector/collections.py +51 -0
- apsimo/vector/config.py +102 -0
- apsimo/vector/embedder.py +670 -0
- apsimo/vector/image_preprocess.py +406 -0
- apsimo/vector/image_store.py +296 -0
- apsimo/vector/indexes.py +162 -0
- apsimo/vector/migrate.py +334 -0
- apsimo/vector/multimodal_provider.py +417 -0
- apsimo/vector/multimodal_types.py +87 -0
- apsimo/vector/openai_provider.py +119 -0
- apsimo/vector/query.py +49 -0
- apsimo/vector/reranker.py +565 -0
- apsimo/vector/safety_image.py +159 -0
- apsimo/vector/scanner.py +197 -0
- apsimo/vector/setup.py +289 -0
- apsimo/vector/store.py +533 -0
- apsimo/vector/tiers.py +263 -0
- apsimo/work_orders.py +925 -0
- apsimo/workers/__init__.py +21 -0
- apsimo/workers/agent_bridge.py +640 -0
- apsimo/workers/colony_worker.py +382 -0
- apsimo/workers/queue_worker.py +441 -0
- apsimo/workers/skills_sync.py +152 -0
- apsimo/world_model/__init__.py +71 -0
- apsimo/world_model/causal_maintenance.py +131 -0
- apsimo/world_model/causal_policy.py +43 -0
- apsimo/world_model/causal_query.py +125 -0
- apsimo/world_model/confidence.py +54 -0
- apsimo/world_model/config.py +64 -0
- apsimo/world_model/constants.py +97 -0
- apsimo/world_model/entities.py +145 -0
- apsimo/world_model/expectation_resolvers.py +177 -0
- apsimo/world_model/extraction/__init__.py +7 -0
- apsimo/world_model/extraction/base.py +62 -0
- apsimo/world_model/extraction/conversation_extractor.py +262 -0
- apsimo/world_model/extraction/detector.py +74 -0
- apsimo/world_model/extraction/document_extractor.py +78 -0
- apsimo/world_model/extraction/formats/__init__.py +24 -0
- apsimo/world_model/extraction/formats/csv_fmt.py +68 -0
- apsimo/world_model/extraction/formats/html_fmt.py +72 -0
- apsimo/world_model/extraction/formats/json_fmt.py +68 -0
- apsimo/world_model/extraction/formats/pdf.py +43 -0
- apsimo/world_model/extraction/formats/text.py +27 -0
- apsimo/world_model/extraction/llm_extractor.py +164 -0
- apsimo/world_model/extraction/pipeline.py +73 -0
- apsimo/world_model/integrations/__init__.py +5 -0
- apsimo/world_model/integrations/mind_model_bridge.py +115 -0
- apsimo/world_model/integrations/social_intel_bridge.py +120 -0
- apsimo/world_model/jobs/__init__.py +4 -0
- apsimo/world_model/jobs/extraction_job.py +168 -0
- apsimo/world_model/llm_extract.py +572 -0
- apsimo/world_model/neo4j/__init__.py +5 -0
- apsimo/world_model/neo4j/backend.py +654 -0
- apsimo/world_model/observations.py +155 -0
- apsimo/world_model/populator.py +307 -0
- apsimo/world_model/postgres/__init__.py +1 -0
- apsimo/world_model/postgres/backend.py +683 -0
- apsimo/world_model/relationships.py +25 -0
- apsimo/world_model/resolution/__init__.py +13 -0
- apsimo/world_model/resolution/entity_resolver.py +232 -0
- apsimo/world_model/resolution/merge_audit.py +16 -0
- apsimo/world_model/resolution/merge_workflow.py +117 -0
- apsimo/world_model/source_reports.py +121 -0
- apsimo/world_model/sqlite/__init__.py +4 -0
- apsimo/world_model/sqlite/backend.py +855 -0
- apsimo/world_model/sqlite/schema.sql +132 -0
- apsimo/world_model/store.py +545 -0
- apsimo-1.3.0.dist-info/METADATA +78 -0
- apsimo-1.3.0.dist-info/RECORD +614 -0
- apsimo-1.3.0.dist-info/WHEEL +5 -0
- apsimo-1.3.0.dist-info/entry_points.txt +11 -0
- apsimo-1.3.0.dist-info/licenses/LICENSE +21 -0
- apsimo-1.3.0.dist-info/top_level.txt +2 -0
- colony_sidecar/__init__.py +4 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""ConnectorManager -- registers pull connectors and runs the ingest phase
|
|
2
|
+
(cognition item 2, Phase C).
|
|
3
|
+
|
|
4
|
+
Per due connector: poll -> for each Observation, OBSERVE-boundary check the
|
|
5
|
+
subject (a "don't look at X" blackout suppresses ingest of X) -> record to the
|
|
6
|
+
observation store (feeds the initiative engine) -> feed the world-model
|
|
7
|
+
populator (which upserts entities/relationships under its OWN shadow-first
|
|
8
|
+
gate; belief maintenance rides the populator's inline property-audit hook, so
|
|
9
|
+
changed facts are reconciled without a second pass here).
|
|
10
|
+
|
|
11
|
+
Mode (COLONY_CONNECTORS_MODE, default off):
|
|
12
|
+
off -> no polling.
|
|
13
|
+
shadow -> CALIBRATION: poll + normalize + LOG the output and the entities it
|
|
14
|
+
WOULD populate, writing nothing (inspect a source before trusting
|
|
15
|
+
it, same discipline as the world-model populator shadow).
|
|
16
|
+
live -> record observations + feed the populator.
|
|
17
|
+
|
|
18
|
+
Per-connector cadence and enable/credentials are env-only
|
|
19
|
+
(COLONY_CONNECTOR_<NAME>_*). Default off; enable per connector.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import logging
|
|
25
|
+
import os
|
|
26
|
+
import asyncio
|
|
27
|
+
import time
|
|
28
|
+
from typing import Any, Dict, List, Optional
|
|
29
|
+
|
|
30
|
+
from apsimo.connectors.base import Connector, Observation
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def connectors_enabled() -> bool:
|
|
36
|
+
return os.environ.get(
|
|
37
|
+
"COLONY_CONNECTORS_ENABLED", "false").strip().lower() in (
|
|
38
|
+
"1", "true", "yes", "on")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def connectors_mode() -> str:
|
|
42
|
+
from apsimo.util.autonomy_preset import resolve
|
|
43
|
+
return resolve("COLONY_CONNECTORS_MODE", ("off", "shadow", "live"), "off")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ConnectorManager:
|
|
47
|
+
def __init__(self, *, observation_store: Any = None, populator: Any = None,
|
|
48
|
+
directive_manager: Any = None, self_model: Any = None) -> None:
|
|
49
|
+
self._obs = observation_store
|
|
50
|
+
self._populator = populator
|
|
51
|
+
self._directives = directive_manager
|
|
52
|
+
self._self_model = self_model
|
|
53
|
+
self._connectors: List[Connector] = []
|
|
54
|
+
self._last: Dict[str, Dict[str, Any]] = {}
|
|
55
|
+
|
|
56
|
+
# -- registration -----------------------------------------------------
|
|
57
|
+
def register(self, connector: Connector) -> None:
|
|
58
|
+
self._connectors.append(connector)
|
|
59
|
+
|
|
60
|
+
def register_default_connectors(self) -> int:
|
|
61
|
+
"""Register every reference connector that is enabled.
|
|
62
|
+
|
|
63
|
+
Multi-account: a connector's ACCOUNTS key (env
|
|
64
|
+
COLONY_CONNECTOR_<NAME>_ACCOUNTS or secret connector/<name>/accounts,
|
|
65
|
+
comma-separated) expands into one instance per account, each reading
|
|
66
|
+
its own connector/<name>_<account>/* namespace. A listed account is
|
|
67
|
+
enabled by default; without ACCOUNTS the single classic instance is
|
|
68
|
+
used."""
|
|
69
|
+
from apsimo.connectors.base import ConnectorConfig
|
|
70
|
+
from apsimo.connectors.imap_email import IMAPEmailConnector
|
|
71
|
+
from apsimo.connectors.caldav_calendar import CalendarConnector
|
|
72
|
+
from apsimo.connectors.fs_documents import FSDocumentsConnector
|
|
73
|
+
from apsimo.connectors.webhook_pull import WebhookPullConnector
|
|
74
|
+
for cls in (IMAPEmailConnector, CalendarConnector,
|
|
75
|
+
FSDocumentsConnector, WebhookPullConnector):
|
|
76
|
+
try:
|
|
77
|
+
accounts = [a.strip() for a in
|
|
78
|
+
ConnectorConfig(cls.name).get("ACCOUNTS", "")
|
|
79
|
+
.replace(";", ",").split(",") if a.strip()]
|
|
80
|
+
if accounts:
|
|
81
|
+
instances = []
|
|
82
|
+
for a in accounts:
|
|
83
|
+
c = cls(account=a)
|
|
84
|
+
c._default_enabled = True
|
|
85
|
+
instances.append(c)
|
|
86
|
+
else:
|
|
87
|
+
instances = [cls()]
|
|
88
|
+
for c in instances:
|
|
89
|
+
if c.enabled:
|
|
90
|
+
self.register(c)
|
|
91
|
+
except Exception:
|
|
92
|
+
logger.debug("connector %s init failed", cls.__name__,
|
|
93
|
+
exc_info=True)
|
|
94
|
+
return len(self._connectors)
|
|
95
|
+
|
|
96
|
+
# -- boundary gate ----------------------------------------------------
|
|
97
|
+
def _boundary_ok(self, obs: Observation) -> bool:
|
|
98
|
+
"""OBSERVE-capability check: a subject under a perception blackout is
|
|
99
|
+
suppressed. Reads survive an ACT-level "leave X alone"."""
|
|
100
|
+
if self._directives is None:
|
|
101
|
+
return True
|
|
102
|
+
try:
|
|
103
|
+
from apsimo.directives import Action
|
|
104
|
+
subject = " ".join([e.name for e in obs.entities]
|
|
105
|
+
+ [str(obs.payload.get("subject", ""))]).strip()
|
|
106
|
+
return self._directives.check(Action(
|
|
107
|
+
kind="observe", text=subject or obs.domain,
|
|
108
|
+
target=subject)).allowed
|
|
109
|
+
except Exception:
|
|
110
|
+
# Fail CLOSED: a broken boundary check must not convert into
|
|
111
|
+
# permission to ingest — the observation is only delayed until
|
|
112
|
+
# the directive engine answers again.
|
|
113
|
+
logger.warning("connector boundary check failed; withholding "
|
|
114
|
+
"observation this cycle", exc_info=True)
|
|
115
|
+
return False
|
|
116
|
+
|
|
117
|
+
# -- the ingest phase -------------------------------------------------
|
|
118
|
+
async def poll_due(self, now: Optional[float] = None) -> Dict[str, Any]:
|
|
119
|
+
now = now if now is not None else time.time()
|
|
120
|
+
mode = connectors_mode()
|
|
121
|
+
report: Dict[str, Any] = {"mode": mode, "connectors": [],
|
|
122
|
+
"observations": 0, "populated": 0,
|
|
123
|
+
"skipped_boundary": 0}
|
|
124
|
+
if mode == "off" or not self._connectors:
|
|
125
|
+
return report
|
|
126
|
+
|
|
127
|
+
for c in self._connectors:
|
|
128
|
+
if not c.enabled or not c.due(now):
|
|
129
|
+
continue
|
|
130
|
+
try:
|
|
131
|
+
# poll() implementations do blocking I/O (urllib/IMAP/CalDAV
|
|
132
|
+
# with timeouts up to 30s) — off the event loop, or one hung
|
|
133
|
+
# endpoint freezes the whole autonomy tick.
|
|
134
|
+
observations = await asyncio.to_thread(c.poll)
|
|
135
|
+
except Exception:
|
|
136
|
+
logger.debug("connector %s poll failed", c.name, exc_info=True)
|
|
137
|
+
observations = []
|
|
138
|
+
c.mark_polled(now)
|
|
139
|
+
|
|
140
|
+
kept: List[Observation] = []
|
|
141
|
+
for obs in observations:
|
|
142
|
+
if not self._boundary_ok(obs):
|
|
143
|
+
report["skipped_boundary"] += 1
|
|
144
|
+
continue
|
|
145
|
+
kept.append(obs)
|
|
146
|
+
|
|
147
|
+
counts = await self._ingest(c, kept, mode)
|
|
148
|
+
self._last[c.name] = {
|
|
149
|
+
"at": now, "domain": c.domain, "count": len(kept),
|
|
150
|
+
"populated": counts["populated"]}
|
|
151
|
+
report["connectors"].append({
|
|
152
|
+
"name": c.name, "domain": c.domain,
|
|
153
|
+
"observations": len(kept), **counts})
|
|
154
|
+
report["observations"] += len(kept)
|
|
155
|
+
report["populated"] += counts["populated"]
|
|
156
|
+
|
|
157
|
+
if report["observations"] or report["skipped_boundary"]:
|
|
158
|
+
self._journal(report)
|
|
159
|
+
return report
|
|
160
|
+
|
|
161
|
+
async def _ingest(self, connector: Connector, observations: List[Observation],
|
|
162
|
+
mode: str) -> Dict[str, int]:
|
|
163
|
+
populated = 0
|
|
164
|
+
if mode == "shadow":
|
|
165
|
+
# Log the normalized output + would-populate entities; write nothing.
|
|
166
|
+
for obs in observations:
|
|
167
|
+
logger.info("connector[shadow] %s: %s id=%s entities=%s",
|
|
168
|
+
connector.name, obs.domain, obs.external_id,
|
|
169
|
+
[e.name for e in obs.entities][:6])
|
|
170
|
+
return {"recorded": 0, "populated": 0}
|
|
171
|
+
|
|
172
|
+
# live: record observations, then feed the populator.
|
|
173
|
+
recorded = 0
|
|
174
|
+
if self._obs is not None and observations:
|
|
175
|
+
try:
|
|
176
|
+
rows = [o.to_store_row() for o in observations]
|
|
177
|
+
recorded = self._obs.record_batch(
|
|
178
|
+
connector.domain, rows, reported_by=f"connector:{connector.name}")
|
|
179
|
+
except Exception:
|
|
180
|
+
logger.debug("observation record failed", exc_info=True)
|
|
181
|
+
if self._populator is not None:
|
|
182
|
+
for obs in observations:
|
|
183
|
+
if not obs.text:
|
|
184
|
+
continue
|
|
185
|
+
try:
|
|
186
|
+
await self._populator.populate_from_text(
|
|
187
|
+
obs.text, source_id=f"connector:{connector.name}:{obs.external_id}")
|
|
188
|
+
populated += 1
|
|
189
|
+
except Exception:
|
|
190
|
+
logger.debug("populate failed", exc_info=True)
|
|
191
|
+
return {"recorded": recorded, "populated": populated}
|
|
192
|
+
|
|
193
|
+
# -- observability ----------------------------------------------------
|
|
194
|
+
def status(self) -> Dict[str, Any]:
|
|
195
|
+
return {
|
|
196
|
+
"mode": connectors_mode(),
|
|
197
|
+
"enabled": connectors_enabled(),
|
|
198
|
+
"connectors": [
|
|
199
|
+
{"name": c.name, "domain": c.domain, "enabled": c.enabled,
|
|
200
|
+
"poll_secs": c.poll_secs, "last": self._last.get(c.name)}
|
|
201
|
+
for c in self._connectors],
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
def _journal(self, report: Dict[str, Any]) -> None:
|
|
205
|
+
journal = getattr(self._self_model, "journal", None)
|
|
206
|
+
if journal is None:
|
|
207
|
+
return
|
|
208
|
+
try:
|
|
209
|
+
journal.record(
|
|
210
|
+
"connectors",
|
|
211
|
+
f"ingested {report['observations']} observation(s) from "
|
|
212
|
+
f"{len(report['connectors'])} connector(s)",
|
|
213
|
+
reasoning=f"mode={report['mode']}, "
|
|
214
|
+
f"skipped_boundary={report['skipped_boundary']}",
|
|
215
|
+
decision="acted" if report["mode"] == "live" else "held",
|
|
216
|
+
reversibility="reversible")
|
|
217
|
+
except Exception:
|
|
218
|
+
logger.debug("connector journal failed", exc_info=True)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Generic JSON-pull connector (read-only): GETs a metrics/business endpoint
|
|
2
|
+
and normalizes selected fields into "metrics" observations + a Project/Product
|
|
3
|
+
entity carrying those metrics.
|
|
4
|
+
|
|
5
|
+
This is a PULL connector (the sidecar fetches); push-style ingress belongs to
|
|
6
|
+
the host framework's webhook adapter and is deliberately not built here. Config
|
|
7
|
+
env-only (COLONY_CONNECTOR_WEBHOOK_*): URL, AUTH_HEADER + AUTH_VALUE, FIELD_MAP
|
|
8
|
+
(JSON dotted-path map), ID_FIELD, ENTITY_NAME, ENTITY_KIND.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import logging
|
|
15
|
+
import time
|
|
16
|
+
from typing import Any, Dict, List
|
|
17
|
+
|
|
18
|
+
from apsimo.connectors.base import Connector, EntityHint, Observation
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _dig(obj: Any, path: str) -> Any:
|
|
24
|
+
"""Resolve a dotted path (a.b.0.c) against nested dict/list JSON."""
|
|
25
|
+
cur = obj
|
|
26
|
+
for part in path.split("."):
|
|
27
|
+
if isinstance(cur, dict):
|
|
28
|
+
cur = cur.get(part)
|
|
29
|
+
elif isinstance(cur, list):
|
|
30
|
+
try:
|
|
31
|
+
cur = cur[int(part)]
|
|
32
|
+
except (ValueError, IndexError):
|
|
33
|
+
return None
|
|
34
|
+
else:
|
|
35
|
+
return None
|
|
36
|
+
return cur
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class WebhookPullConnector(Connector):
|
|
40
|
+
name = "webhook"
|
|
41
|
+
domain = "metrics"
|
|
42
|
+
default_poll_secs = 3600
|
|
43
|
+
|
|
44
|
+
def normalize(self, data: Any, *, field_map: Dict[str, str],
|
|
45
|
+
entity_name: str, entity_kind: str = "project",
|
|
46
|
+
id_field: str = "") -> List[Observation]:
|
|
47
|
+
"""Pure: map configured fields out of a JSON body into one metrics obs."""
|
|
48
|
+
metrics = {out_key: _dig(data, src) for out_key, src in field_map.items()}
|
|
49
|
+
metrics = {k: v for k, v in metrics.items() if v is not None}
|
|
50
|
+
ext_id = str(_dig(data, id_field) if id_field else entity_name) or entity_name
|
|
51
|
+
kv = ", ".join(f"{k}={v}" for k, v in metrics.items())
|
|
52
|
+
text = f"Metrics for {entity_name}: {kv}" if kv else f"Metrics for {entity_name}"
|
|
53
|
+
entities = [EntityHint(kind=entity_kind, name=entity_name)] if entity_name else []
|
|
54
|
+
return [Observation(
|
|
55
|
+
domain=self.domain, external_id=str(ext_id)[:200], ts=time.time(),
|
|
56
|
+
payload={"entity": entity_name, "metrics": metrics},
|
|
57
|
+
entities=entities, text=text)]
|
|
58
|
+
|
|
59
|
+
def _fetch(self) -> Any:
|
|
60
|
+
import urllib.request
|
|
61
|
+
url = self.config.get("URL")
|
|
62
|
+
if not url:
|
|
63
|
+
return None
|
|
64
|
+
req = urllib.request.Request(url, method="GET")
|
|
65
|
+
header = self.config.get("AUTH_HEADER")
|
|
66
|
+
value = self.config.get("AUTH_VALUE")
|
|
67
|
+
if header and value:
|
|
68
|
+
req.add_header(header, value)
|
|
69
|
+
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
70
|
+
return json.loads(resp.read().decode("utf-8", "replace"))
|
|
71
|
+
|
|
72
|
+
def poll(self) -> List[Observation]:
|
|
73
|
+
try:
|
|
74
|
+
data = self._fetch()
|
|
75
|
+
if data is None:
|
|
76
|
+
return []
|
|
77
|
+
try:
|
|
78
|
+
field_map = json.loads(self.config.get("FIELD_MAP", "{}"))
|
|
79
|
+
except json.JSONDecodeError:
|
|
80
|
+
field_map = {}
|
|
81
|
+
return self.normalize(
|
|
82
|
+
data, field_map=field_map or {},
|
|
83
|
+
entity_name=self.config.get("ENTITY_NAME", "metrics"),
|
|
84
|
+
entity_kind=self.config.get("ENTITY_KIND", "project"),
|
|
85
|
+
id_field=self.config.get("ID_FIELD", ""))
|
|
86
|
+
except Exception:
|
|
87
|
+
logger.debug("webhook pull failed", exc_info=True)
|
|
88
|
+
return []
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Colony Contacts Management System.
|
|
2
|
+
|
|
3
|
+
Provides contact lifecycle management: storage, import, and privacy controls.
|
|
4
|
+
All contacts are Person nodes in the world model.
|
|
5
|
+
|
|
6
|
+
Quick start::
|
|
7
|
+
|
|
8
|
+
from apsimo.contacts import ContactStore
|
|
9
|
+
from apsimo.contacts.store import SQLiteContactStore
|
|
10
|
+
from apsimo.contacts.config import ContactsConfig
|
|
11
|
+
|
|
12
|
+
config = ContactsConfig(sqlite_path=":memory:")
|
|
13
|
+
async with SQLiteContactStore(config) as store:
|
|
14
|
+
contact = await store.create(display_name="Alice Chen", trust_tier="trusted")
|
|
15
|
+
await store.add_handle(contact.contact_id, "email", "alice@example.com")
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from .store import ContactStore, SQLiteContactStore
|
|
19
|
+
from .importer import ContactImporter, SQLiteContactImporter
|
|
20
|
+
from .models import Contact, ContactHandle, MergeProposal, MergeAuditRecord
|
|
21
|
+
from .config import ContactsConfig
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"ContactStore",
|
|
25
|
+
"ContactImporter",
|
|
26
|
+
"SQLiteContactStore",
|
|
27
|
+
"SQLiteContactImporter",
|
|
28
|
+
"Contact",
|
|
29
|
+
"ContactHandle",
|
|
30
|
+
"MergeProposal",
|
|
31
|
+
"MergeAuditRecord",
|
|
32
|
+
"ContactsConfig",
|
|
33
|
+
]
|