cognis-executor 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/PKG-INFO +2 -2
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/app.py +100 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/common.py +80 -3
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/executor_runtime.py +39 -7
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/executor_ws.py +5 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/middleware.py +40 -20
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/models.py +238 -26
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/agents.py +435 -75
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/auth.py +150 -51
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/conversations.py +51 -29
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/credentials.py +13 -1
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/executors.py +61 -10
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/images.py +2 -2
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/notifications.py +8 -1
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/schedules.py +242 -18
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/secrets.py +27 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/sessions.py +5 -5
- cognis_executor-0.3.0/cognis/api/routes/settings.py +796 -0
- cognis_executor-0.3.0/cognis/api/routes/skills.py +1002 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/system.py +36 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/tasks.py +340 -62
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/tools.py +314 -29
- cognis_executor-0.3.0/cognis/api/routes/workflows.py +359 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/runtime_support.py +379 -180
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/serializers.py +133 -12
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/sse.py +56 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/websocket.py +268 -31
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/bootstrap.py +292 -31
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/signal.py +41 -6
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/delivery.py +147 -94
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/inbound.py +68 -59
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/cli/admin.py +27 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/config.py +17 -0
- cognis_executor-0.3.0/cognis/core/agent_loop.py +10204 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/agent_registry.py +307 -212
- cognis_executor-0.3.0/cognis/core/anchored_output.py +71 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/attachment_utils.py +30 -4
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/commands.py +298 -54
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/compaction.py +12 -4
- cognis_executor-0.3.0/cognis/core/context.py +2396 -0
- cognis_executor-0.3.0/cognis/core/context_budget.py +69 -0
- cognis_executor-0.3.0/cognis/core/context_projection.py +371 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/decision.py +29 -1
- cognis_executor-0.3.0/cognis/core/errors.py +11 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/events.py +76 -3
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/executor_policy.py +14 -2
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/executor_resolution.py +27 -26
- cognis_executor-0.3.0/cognis/core/harness_guards.py +369 -0
- cognis_executor-0.3.0/cognis/core/immutable_prefix.py +105 -0
- cognis_executor-0.3.0/cognis/core/invariants.py +233 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/management.py +54 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/notifications.py +160 -3
- cognis_executor-0.3.0/cognis/core/project_context.py +122 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/prompts.py +174 -16
- cognis_executor-0.3.0/cognis/core/pruning.py +33 -0
- cognis_executor-0.3.0/cognis/core/remember_queue.py +583 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/runtime.py +1 -0
- cognis_executor-0.3.0/cognis/core/schedule_management.py +102 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/scheduler.py +58 -16
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/session.py +168 -23
- cognis_executor-0.3.0/cognis/core/session_cache.py +1139 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/step_evaluator.py +77 -21
- cognis_executor-0.3.0/cognis/core/step_profiles.py +411 -0
- cognis_executor-0.3.0/cognis/core/system_skills.py +304 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/task_queue.py +403 -54
- cognis_executor-0.3.0/cognis/core/tool_arguments.py +128 -0
- cognis_executor-0.3.0/cognis/core/tool_classification_queue.py +359 -0
- cognis_executor-0.3.0/cognis/core/tool_exposure.py +702 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/tool_output_store.py +273 -40
- cognis_executor-0.3.0/cognis/core/tool_retrieval.py +291 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/tool_router.py +377 -26
- cognis_executor-0.3.0/cognis/core/truncation.py +136 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/turn_scheduler.py +779 -117
- cognis_executor-0.3.0/cognis/core/workflow_composition.py +562 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/workflow_engine.py +991 -158
- cognis_executor-0.3.0/cognis/core/workflow_management.py +429 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/workflow_registry.py +281 -35
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/executor/runner.py +138 -117
- cognis_executor-0.3.0/cognis/json_stream.py +92 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/agent.py +29 -1
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/config.py +40 -5
- cognis_executor-0.3.0/cognis/models/deliverable.py +51 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/schedule.py +5 -2
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/session.py +18 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/skill.py +53 -4
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/task.py +22 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/tool.py +98 -1
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/workflow.py +145 -2
- cognis_executor-0.3.0/cognis/ownership.py +26 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/auth/jwt.py +17 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/base.py +28 -3
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/in_process.py +109 -82
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/websocket.py +15 -5
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/guardrails/intaris.py +133 -21
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/inference_router.py +5 -1
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/litellm.py +1330 -120
- cognis_executor-0.3.0/cognis/providers/llm/reasoning.py +584 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/responses_bridge.py +399 -69
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/memory/mnemory.py +401 -56
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/secrets/encrypted_db.py +8 -6
- cognis_executor-0.3.0/cognis/runtime_context.py +56 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/settings_schema.py +2 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/032_system_asset_overrides.py +67 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/033_system_agent_skill_overrides.py +24 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/033_task_working_directory.py +30 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/034_completion_delivery_policy.py +74 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/035_harness_recovery_tables.py +93 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/036_workflow_deliverables.py +66 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/037_workflow_composition_lifecycle.py +38 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/038_tool_classifications.py +66 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/039_tool_classification_overrides.py +48 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/040_browser_sessions.py +64 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/041_schedule_skill_sources.py +26 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/042_skill_linked_tool_ids.py +30 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/043_agent_grants.py +70 -0
- cognis_executor-0.3.0/cognis/store/migrations/versions/044_step_run_runtime_info.py +26 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/models.py +303 -3
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/queries.py +1254 -97
- cognis_executor-0.3.0/cognis/tools/builtin/artifact_tools.py +1050 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/memory.py +99 -96
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/orchestration.py +167 -15
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/schedule.py +24 -13
- cognis_executor-0.3.0/cognis/tools/builtin/skill_management.py +1662 -0
- cognis_executor-0.3.0/cognis/tools/builtin/tool_output.py +356 -0
- cognis_executor-0.3.0/cognis/tools/builtin/tool_search.py +230 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/workflow.py +77 -2
- cognis_executor-0.3.0/cognis/tools/classification.py +693 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/definitions.py +171 -21
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/filesystem.py +572 -90
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/client.py +75 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/manager.py +104 -0
- cognis_executor-0.3.0/cognis/tools/executor/lsp/tool.py +86 -0
- cognis_executor-0.3.0/cognis/tools/executor/paths.py +79 -0
- cognis_executor-0.3.0/cognis/tools/executor/project_context.py +263 -0
- cognis_executor-0.3.0/cognis/tools/executor/search.py +344 -0
- cognis_executor-0.3.0/cognis/tools/executor/shell.py +443 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/backends/brave.py +15 -15
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/backends/direct.py +12 -14
- cognis_executor-0.3.0/cognis/tools/executor/web/backends/formatting.py +83 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/backends/tavily.py +19 -21
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/definitions.py +119 -8
- cognis_executor-0.3.0/cognis/tools/executor/web/handlers.py +498 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/mcp.py +145 -17
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/registry.py +1 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/skill_parser.py +46 -2
- cognis_executor-0.3.0/cognis/tools/skill_service.py +613 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/skills.py +185 -15
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/pyproject.toml +2 -2
- cognis_executor-0.2.0/cognis/api/routes/settings.py +0 -438
- cognis_executor-0.2.0/cognis/api/routes/skills.py +0 -428
- cognis_executor-0.2.0/cognis/api/routes/workflows.py +0 -160
- cognis_executor-0.2.0/cognis/core/agent_loop.py +0 -4667
- cognis_executor-0.2.0/cognis/core/context.py +0 -1505
- cognis_executor-0.2.0/cognis/core/pruning.py +0 -142
- cognis_executor-0.2.0/cognis/core/remember_queue.py +0 -99
- cognis_executor-0.2.0/cognis/core/session_cache.py +0 -638
- cognis_executor-0.2.0/cognis/core/system_skills.py +0 -149
- cognis_executor-0.2.0/cognis/core/tool_exposure.py +0 -241
- cognis_executor-0.2.0/cognis/core/truncation.py +0 -52
- cognis_executor-0.2.0/cognis/core/workflow_management.py +0 -192
- cognis_executor-0.2.0/cognis/runtime_context.py +0 -27
- cognis_executor-0.2.0/cognis/tools/builtin/skill_management.py +0 -666
- cognis_executor-0.2.0/cognis/tools/builtin/tool_output.py +0 -178
- cognis_executor-0.2.0/cognis/tools/builtin/tool_search.py +0 -85
- cognis_executor-0.2.0/cognis/tools/executor/paths.py +0 -16
- cognis_executor-0.2.0/cognis/tools/executor/search.py +0 -196
- cognis_executor-0.2.0/cognis/tools/executor/shell.py +0 -127
- cognis_executor-0.2.0/cognis/tools/executor/web/handlers.py +0 -211
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/README.md +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/error_sanitizer.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/artifacts.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/channels.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/escalations.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/routes/users.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/api/tool_inventory.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/artifacts/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/artifacts/store.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/bluebubbles.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/discord.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/google_chat.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/irc.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/matrix.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/signal_cli_runtime.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/slack.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/telegram.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/adapters/whatsapp.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/factory.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/formatting.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/manager.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/pairing.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/registry.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/remote.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/channels/signal_formatting.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/cli/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/cli/executor.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/cli/serve.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/artifact_maintenance.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/followups.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/json_utils.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/core/title_policy.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/executor/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/executor/__main__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/executor/channel_handler.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/executor/inference.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/logging.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/main.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/artifact.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/channel.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/credential.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/models/delegation.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/auth/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/auth/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/circuit_breaker.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/credentials/encrypted_db.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/composite.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/executor/subprocess.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/guardrails/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/guardrails/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/llm/retry.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/memory/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/memory/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/registry.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/retry.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/secrets/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/providers/secrets/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/security.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/database.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/alembic.ini +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/env.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/script.py.mako +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/001_initial.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/002_session_lifecycle_fields.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/003_tasks_workflows_schedules.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/004_api_key_last_used_at.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/005_agent_sync_metadata.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/006_provider_is_default.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/007_skills_table.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/008_executors_table.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/009_session_compaction_fields.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/010_task_expected_output.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/011_rename_root_to_active_session_id.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/012_step_run_conversation_id.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/013_user_management_fields.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/014_notifications_table.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/015_conversation_last_read_at.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/016_channel_accounts_contacts.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/017_channel_pairing_requests.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/018_channel_adapter_location.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/019_channel_executor_fk.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/020_agent_avatar_image.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/021_artifact_records.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/022_mcp_servers_table.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/023_executor_runtime_state.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/024_skill_versions.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/025_channel_delivery_outbox.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/026_executor_runtime_metadata.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/027_extend_schedules.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/028_credentials_table.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/029_conversation_title_source.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/030_mcp_http_headers.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/store/migrations/versions/031_skill_is_system.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/argument_normalization.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/datetime_tools.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/image.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/builtin/system.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/browser/definitions.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/browser/handlers.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/browser/install.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/browser/manager.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/document.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/file_freshness.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/diagnostics.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/install.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/runtime.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/servers.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/lsp/types.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/backends/__init__.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/backends/protocol.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/executor/web/headers.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/tools/skill_import.py +0 -0
- {cognis_executor-0.2.0 → cognis_executor-0.3.0}/cognis/ui_assets.py +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cognis-executor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Standalone remote executor for Cognis
|
|
5
5
|
Author-email: Filip Pytloun <filip@pytloun.cz>
|
|
6
6
|
License: TBD
|
|
@@ -18,7 +18,7 @@ Requires-Dist: ddgs>=9.0.0
|
|
|
18
18
|
Requires-Dist: email-validator>=2.0.0
|
|
19
19
|
Requires-Dist: fastapi>=0.115.0
|
|
20
20
|
Requires-Dist: httpx>=0.27.0
|
|
21
|
-
Requires-Dist: litellm>=1.
|
|
21
|
+
Requires-Dist: litellm>=1.82.0
|
|
22
22
|
Requires-Dist: markdown>=3.7
|
|
23
23
|
Requires-Dist: markdownify>=0.14.0
|
|
24
24
|
Requires-Dist: mcp>=1.6.0
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import contextlib
|
|
6
7
|
import hashlib
|
|
7
8
|
import secrets
|
|
8
9
|
import sys
|
|
@@ -43,6 +44,7 @@ from cognis.api.websocket import handle_websocket
|
|
|
43
44
|
from cognis.bootstrap import bootstrap_runtime
|
|
44
45
|
from cognis.config import load_config
|
|
45
46
|
from cognis.core.agent_loop import AgentLoop, PauseWaiter, SessionLock
|
|
47
|
+
from cognis.core.agent_registry import AgentRegistry
|
|
46
48
|
from cognis.core.compaction import CompactionStrategy
|
|
47
49
|
from cognis.core.context import ContextAssembler
|
|
48
50
|
from cognis.core.decision import DecisionEngine
|
|
@@ -52,7 +54,9 @@ from cognis.core.scheduler import Scheduler
|
|
|
52
54
|
from cognis.core.session import SessionManager
|
|
53
55
|
from cognis.core.session_cache import SessionCache
|
|
54
56
|
from cognis.core.step_evaluator import StepEvaluator
|
|
57
|
+
from cognis.core.step_profiles import StepProfileRegistry
|
|
55
58
|
from cognis.core.task_queue import TaskQueue
|
|
59
|
+
from cognis.core.tool_classification_queue import ToolClassificationQueue
|
|
56
60
|
from cognis.core.tool_output_store import ToolOutputStore
|
|
57
61
|
from cognis.core.tool_router import ToolRouter
|
|
58
62
|
from cognis.core.workflow_engine import WorkflowEngine
|
|
@@ -145,8 +149,19 @@ def create_app() -> FastAPI:
|
|
|
145
149
|
config_runtime.jwt_private_key_path, config_runtime.jwt_public_key_path
|
|
146
150
|
)
|
|
147
151
|
providers = build_provider_registry(config_runtime, session_factory, auth_provider)
|
|
148
|
-
|
|
152
|
+
event_bus = EventBus()
|
|
153
|
+
remember_queue = RememberRetryQueue(
|
|
154
|
+
providers.memory,
|
|
155
|
+
session_factory=session_factory,
|
|
156
|
+
event_reader=providers.guardrails,
|
|
157
|
+
event_bus=event_bus,
|
|
158
|
+
)
|
|
149
159
|
await remember_queue.start()
|
|
160
|
+
tool_classification_queue = ToolClassificationQueue(
|
|
161
|
+
session_factory=session_factory,
|
|
162
|
+
llm_provider=providers.llm,
|
|
163
|
+
)
|
|
164
|
+
await tool_classification_queue.start()
|
|
150
165
|
await _print_startup_status(config_runtime, providers, ui_build_dir)
|
|
151
166
|
|
|
152
167
|
async with session_factory() as session:
|
|
@@ -188,14 +203,20 @@ def create_app() -> FastAPI:
|
|
|
188
203
|
)
|
|
189
204
|
sys.stdout.flush()
|
|
190
205
|
|
|
191
|
-
|
|
206
|
+
pause_waiter = PauseWaiter()
|
|
207
|
+
session_lock = SessionLock()
|
|
208
|
+
session_lock_sweeper_task: asyncio.Task[None] | None = None
|
|
192
209
|
session_cache = SessionCache(
|
|
193
210
|
providers.guardrails,
|
|
194
211
|
max_entries=cache_max_entries,
|
|
195
212
|
redis_url=config_runtime.redis_url,
|
|
196
213
|
)
|
|
197
214
|
session_manager = SessionManager(
|
|
198
|
-
session_factory,
|
|
215
|
+
session_factory,
|
|
216
|
+
providers,
|
|
217
|
+
session_cache,
|
|
218
|
+
event_bus=event_bus,
|
|
219
|
+
session_lock=session_lock,
|
|
199
220
|
)
|
|
200
221
|
context_assembler = await ContextAssembler.from_session_factory(
|
|
201
222
|
session_factory=session_factory,
|
|
@@ -215,8 +236,6 @@ def create_app() -> FastAPI:
|
|
|
215
236
|
session_factory=session_factory,
|
|
216
237
|
llm=providers.llm,
|
|
217
238
|
)
|
|
218
|
-
pause_waiter = PauseWaiter()
|
|
219
|
-
session_lock = SessionLock()
|
|
220
239
|
from cognis.core.tool_output_store import (
|
|
221
240
|
FilesystemToolOutputBackend,
|
|
222
241
|
S3ToolOutputBackend,
|
|
@@ -263,6 +282,7 @@ def create_app() -> FastAPI:
|
|
|
263
282
|
)
|
|
264
283
|
|
|
265
284
|
from cognis.core.artifact_maintenance import ArtifactMaintenanceService
|
|
285
|
+
from cognis.store.queries import get_setting_value
|
|
266
286
|
|
|
267
287
|
artifact_maintenance = ArtifactMaintenanceService(
|
|
268
288
|
session_factory=session_factory,
|
|
@@ -273,13 +293,16 @@ def create_app() -> FastAPI:
|
|
|
273
293
|
tool_router = await ToolRouter.from_session_factory(
|
|
274
294
|
providers.guardrails,
|
|
275
295
|
session_factory,
|
|
296
|
+
llm=providers.llm,
|
|
276
297
|
memory=providers.memory,
|
|
277
298
|
credentials_provider=providers.credentials,
|
|
278
299
|
tool_output_store=tool_output_store,
|
|
279
300
|
image_generation_provider=providers.image_generation,
|
|
280
301
|
artifact_store=artifact_store,
|
|
281
302
|
)
|
|
303
|
+
agent_registry = AgentRegistry(session_factory)
|
|
282
304
|
workflow_registry = WorkflowRegistry(session_factory)
|
|
305
|
+
step_profile_registry = await StepProfileRegistry.from_session_factory(session_factory)
|
|
283
306
|
step_evaluator = await StepEvaluator.from_session_factory(
|
|
284
307
|
session_factory=session_factory,
|
|
285
308
|
llm=providers.llm,
|
|
@@ -290,7 +313,14 @@ def create_app() -> FastAPI:
|
|
|
290
313
|
shared_registry=shared_runtime.tool_registry,
|
|
291
314
|
shared_connection=shared_runtime.executor_connection,
|
|
292
315
|
session_factory=session_factory,
|
|
316
|
+
artifact_store=artifact_store,
|
|
293
317
|
)
|
|
318
|
+
async with session_factory() as session:
|
|
319
|
+
step_timeout_seconds = await get_setting_value(
|
|
320
|
+
session,
|
|
321
|
+
"session.step_timeout_seconds",
|
|
322
|
+
3600,
|
|
323
|
+
)
|
|
294
324
|
agent_loop = AgentLoop(
|
|
295
325
|
providers=providers,
|
|
296
326
|
session_manager=session_manager,
|
|
@@ -302,6 +332,12 @@ def create_app() -> FastAPI:
|
|
|
302
332
|
event_bus=event_bus,
|
|
303
333
|
session_lock=session_lock,
|
|
304
334
|
pause_waiter=pause_waiter,
|
|
335
|
+
session_factory=session_factory,
|
|
336
|
+
tool_classification_queue=tool_classification_queue,
|
|
337
|
+
step_profile_registry=step_profile_registry,
|
|
338
|
+
default_step_timeout_seconds=(
|
|
339
|
+
int(step_timeout_seconds) if isinstance(step_timeout_seconds, int) else 3600
|
|
340
|
+
),
|
|
305
341
|
tool_output_store=tool_output_store,
|
|
306
342
|
step_runtime_factory=step_runtime_factory,
|
|
307
343
|
)
|
|
@@ -324,6 +360,7 @@ def create_app() -> FastAPI:
|
|
|
324
360
|
workflow_engine=workflow_engine,
|
|
325
361
|
workflow_registry=workflow_registry,
|
|
326
362
|
event_bus=event_bus,
|
|
363
|
+
agent_registry=agent_registry,
|
|
327
364
|
llm_provider=providers.llm,
|
|
328
365
|
)
|
|
329
366
|
agent_loop.set_task_queue(task_queue)
|
|
@@ -383,6 +420,41 @@ def create_app() -> FastAPI:
|
|
|
383
420
|
recovered_sessions = await session_manager.recover_stale_sessions()
|
|
384
421
|
recovered_tasks = await task_queue.recover_stale_tasks()
|
|
385
422
|
recovered_paused_tasks = await task_queue.recover_paused_tasks()
|
|
423
|
+
recovered_orphaned_step_runs = await task_queue.recover_orphaned_running_step_runs()
|
|
424
|
+
|
|
425
|
+
# System-wide invariant reconciliation. Runs after the focused
|
|
426
|
+
# recovery helpers above so any residual drift (e.g. conversations
|
|
427
|
+
# whose active_session_id still points at a terminal session) is
|
|
428
|
+
# cleaned before the drain loop starts picking tasks. The
|
|
429
|
+
# implementation is idempotent and covered by unit tests.
|
|
430
|
+
from cognis.core.invariants import reconcile_invariants
|
|
431
|
+
|
|
432
|
+
async with session_factory() as recon_session:
|
|
433
|
+
invariant_reports = await reconcile_invariants(recon_session)
|
|
434
|
+
reconciled_invariant_counts = {
|
|
435
|
+
report.category: report.reconciled_count
|
|
436
|
+
for report in invariant_reports
|
|
437
|
+
if report.reconciled_count
|
|
438
|
+
}
|
|
439
|
+
if reconciled_invariant_counts:
|
|
440
|
+
logger.warning(
|
|
441
|
+
"startup: reconciled invariant violations",
|
|
442
|
+
extra={"extra_data": {"counts": reconciled_invariant_counts}},
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
logger.info(
|
|
446
|
+
"startup: recovery summary",
|
|
447
|
+
extra={
|
|
448
|
+
"extra_data": {
|
|
449
|
+
"recovered_sessions": len(recovered_sessions),
|
|
450
|
+
"recovered_tasks": len(recovered_tasks),
|
|
451
|
+
"recovered_paused_tasks": len(recovered_paused_tasks),
|
|
452
|
+
"recovered_orphaned_step_runs": recovered_orphaned_step_runs,
|
|
453
|
+
"invariant_reports": [report.as_dict() for report in invariant_reports],
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
)
|
|
457
|
+
|
|
386
458
|
await task_queue.start()
|
|
387
459
|
|
|
388
460
|
# Scheduler — evaluates cron/interval/one-shot schedules and
|
|
@@ -410,6 +482,7 @@ def create_app() -> FastAPI:
|
|
|
410
482
|
app.state.provider_test_results = {}
|
|
411
483
|
app.state.provider_test_cooldowns = {}
|
|
412
484
|
app.state.remember_queue = remember_queue
|
|
485
|
+
app.state.tool_classification_queue = tool_classification_queue
|
|
413
486
|
app.state.artifact_store = artifact_store
|
|
414
487
|
app.state.artifact_maintenance = artifact_maintenance
|
|
415
488
|
app.state.serve_ui = config_runtime.serve_ui
|
|
@@ -425,7 +498,9 @@ def create_app() -> FastAPI:
|
|
|
425
498
|
app.state.pause_waiter = pause_waiter
|
|
426
499
|
app.state.session_lock = session_lock
|
|
427
500
|
app.state.tool_router = tool_router
|
|
501
|
+
app.state.agent_registry = agent_registry
|
|
428
502
|
app.state.workflow_registry = workflow_registry
|
|
503
|
+
app.state.step_profile_registry = step_profile_registry
|
|
429
504
|
app.state.step_evaluator = step_evaluator
|
|
430
505
|
app.state.agent_loop = agent_loop
|
|
431
506
|
app.state.workflow_engine = workflow_engine
|
|
@@ -438,6 +513,8 @@ def create_app() -> FastAPI:
|
|
|
438
513
|
app.state.recovered_session_ids = frozenset(recovered_sessions)
|
|
439
514
|
app.state.recovered_task_ids = frozenset(recovered_tasks)
|
|
440
515
|
app.state.recovered_paused_task_ids = frozenset(recovered_paused_tasks)
|
|
516
|
+
app.state.recovered_orphaned_step_runs = recovered_orphaned_step_runs
|
|
517
|
+
app.state.startup_invariant_reports = [report.as_dict() for report in invariant_reports]
|
|
441
518
|
|
|
442
519
|
app.state.notification_service = notification_service
|
|
443
520
|
app.state.turn_scheduler = turn_scheduler
|
|
@@ -488,6 +565,7 @@ def create_app() -> FastAPI:
|
|
|
488
565
|
channel_manager_ref=_get_channel_manager,
|
|
489
566
|
turn_scheduler=turn_scheduler,
|
|
490
567
|
)
|
|
568
|
+
workflow_engine._channel_delivery = channel_delivery # noqa: SLF001
|
|
491
569
|
|
|
492
570
|
app.state.channel_manager = channel_manager
|
|
493
571
|
app.state.channel_delivery = channel_delivery
|
|
@@ -506,8 +584,24 @@ def create_app() -> FastAPI:
|
|
|
506
584
|
|
|
507
585
|
await channel_delivery.start()
|
|
508
586
|
|
|
587
|
+
async def _session_lock_sweeper() -> None:
|
|
588
|
+
interval_seconds = 900.0
|
|
589
|
+
idle_seconds = 900.0
|
|
590
|
+
while True:
|
|
591
|
+
await asyncio.sleep(interval_seconds)
|
|
592
|
+
for session_id in session_lock.stale_unlocked_session_ids(
|
|
593
|
+
max_idle_seconds=idle_seconds
|
|
594
|
+
):
|
|
595
|
+
session_lock.evict(session_id, reason="sweeper")
|
|
596
|
+
|
|
597
|
+
session_lock_sweeper_task = asyncio.create_task(_session_lock_sweeper())
|
|
598
|
+
|
|
509
599
|
yield
|
|
510
600
|
|
|
601
|
+
if session_lock_sweeper_task is not None:
|
|
602
|
+
session_lock_sweeper_task.cancel()
|
|
603
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
604
|
+
await session_lock_sweeper_task
|
|
511
605
|
await artifact_maintenance.stop()
|
|
512
606
|
await channel_delivery.stop()
|
|
513
607
|
await channel_manager.stop_all()
|
|
@@ -515,6 +609,7 @@ def create_app() -> FastAPI:
|
|
|
515
609
|
await task_queue.stop()
|
|
516
610
|
await shared_runtime.cleanup()
|
|
517
611
|
await remember_queue.stop()
|
|
612
|
+
await tool_classification_queue.stop()
|
|
518
613
|
await providers.executor.cleanup()
|
|
519
614
|
await session_cache.aclose()
|
|
520
615
|
await providers.memory.client.aclose()
|
|
@@ -6,6 +6,7 @@ import base64
|
|
|
6
6
|
import json
|
|
7
7
|
import re
|
|
8
8
|
from collections.abc import Callable
|
|
9
|
+
from dataclasses import dataclass
|
|
9
10
|
from datetime import datetime
|
|
10
11
|
from typing import Any, cast
|
|
11
12
|
|
|
@@ -14,6 +15,8 @@ from fastapi.responses import JSONResponse
|
|
|
14
15
|
|
|
15
16
|
from cognis.api.middleware import AuthenticatedUser
|
|
16
17
|
from cognis.api.models import ErrorBody, ErrorResponse
|
|
18
|
+
from cognis.ownership import normalize_executor_scope
|
|
19
|
+
from cognis.store.queries import get_active_agent_grant
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
def api_exception(
|
|
@@ -54,15 +57,21 @@ def require_current_user(request: Request) -> AuthenticatedUser:
|
|
|
54
57
|
return user
|
|
55
58
|
|
|
56
59
|
|
|
57
|
-
def
|
|
58
|
-
"""Require a
|
|
60
|
+
def require_session_user(request: Request) -> AuthenticatedUser:
|
|
61
|
+
"""Require a human interactive session authenticated by cookie or bearer."""
|
|
59
62
|
|
|
60
63
|
user = require_current_user(request)
|
|
61
|
-
if user.auth_type
|
|
64
|
+
if user.auth_type not in {"jwt", "session"}:
|
|
62
65
|
raise api_exception(403, "forbidden", "This endpoint requires session authentication")
|
|
63
66
|
return user
|
|
64
67
|
|
|
65
68
|
|
|
69
|
+
def require_jwt_user(request: Request) -> AuthenticatedUser:
|
|
70
|
+
"""Backward-compatible alias for interactive session auth."""
|
|
71
|
+
|
|
72
|
+
return require_session_user(request)
|
|
73
|
+
|
|
74
|
+
|
|
66
75
|
def require_admin(request: Request) -> AuthenticatedUser:
|
|
67
76
|
"""Require the authenticated user to be an admin."""
|
|
68
77
|
user = require_current_user(request)
|
|
@@ -79,6 +88,74 @@ def require_owner_or_admin(request: Request, owner_email: str) -> AuthenticatedU
|
|
|
79
88
|
return user
|
|
80
89
|
|
|
81
90
|
|
|
91
|
+
def require_resource_owner(request: Request, owner_email: str) -> AuthenticatedUser:
|
|
92
|
+
"""Require strict resource ownership with no admin bypass."""
|
|
93
|
+
|
|
94
|
+
user = require_current_user(request)
|
|
95
|
+
if user.email != owner_email:
|
|
96
|
+
raise api_exception(403, "forbidden", "Resource access denied")
|
|
97
|
+
return user
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass(slots=True)
|
|
101
|
+
class AgentAccess:
|
|
102
|
+
"""Resolved caller access to an agent."""
|
|
103
|
+
|
|
104
|
+
user: AuthenticatedUser
|
|
105
|
+
owner_email: str
|
|
106
|
+
is_owner: bool
|
|
107
|
+
grant: Any | None = None
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def granted_permission(self) -> str | None:
|
|
111
|
+
return str(self.grant.permission) if self.grant is not None else None
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def executor_scope(self) -> str | None:
|
|
115
|
+
return normalize_executor_scope(str(self.grant.executor_scope)) if self.grant is not None else None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
async def check_agent_access(request: Request, agent: Any, *, required: str) -> AgentAccess:
|
|
119
|
+
"""Resolve agent access for the caller.
|
|
120
|
+
|
|
121
|
+
``required`` may be ``view``, ``use``, ``edit``, ``delete``, or ``share``.
|
|
122
|
+
Ownership is the only write path; active ``use`` grants permit only
|
|
123
|
+
``view`` and ``use``. Admin role is intentionally ignored here.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
user = require_current_user(request)
|
|
127
|
+
owner_email = str(getattr(agent, "owner_email", "") or "")
|
|
128
|
+
if not owner_email:
|
|
129
|
+
raise api_exception(500, "internal_error", "Agent owner is missing")
|
|
130
|
+
if user.email == owner_email:
|
|
131
|
+
return AgentAccess(user=user, owner_email=owner_email, is_owner=True)
|
|
132
|
+
|
|
133
|
+
if required not in {"view", "use", "edit", "delete", "share"}:
|
|
134
|
+
raise api_exception(500, "internal_error", f"Unsupported agent access requirement: {required}")
|
|
135
|
+
if required not in {"view", "use"}:
|
|
136
|
+
raise api_exception(403, "forbidden", "Resource access denied")
|
|
137
|
+
|
|
138
|
+
session_factory = getattr(request.app.state, "session_factory", None)
|
|
139
|
+
if session_factory is None:
|
|
140
|
+
raise api_exception(500, "internal_error", "Session factory unavailable")
|
|
141
|
+
async with session_factory() as session:
|
|
142
|
+
grant = await get_active_agent_grant(session, str(agent.agent_id), user.email)
|
|
143
|
+
if grant is None:
|
|
144
|
+
raise api_exception(403, "forbidden", "Resource access denied")
|
|
145
|
+
return AgentAccess(user=user, owner_email=owner_email, is_owner=False, grant=grant)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def apply_agent_access_metadata(agent: Any, access: AgentAccess) -> Any:
|
|
149
|
+
"""Annotate an agent row/definition with caller-scoped sharing metadata."""
|
|
150
|
+
|
|
151
|
+
agent.is_shared_with_me = not access.is_owner
|
|
152
|
+
agent.shared_by_email = None if access.is_owner else access.owner_email
|
|
153
|
+
agent.granted_permission = access.granted_permission
|
|
154
|
+
agent.executor_scope = access.executor_scope
|
|
155
|
+
agent.is_readonly_for_caller = not access.is_owner
|
|
156
|
+
return agent
|
|
157
|
+
|
|
158
|
+
|
|
82
159
|
def forbid_mutation_for_viewer(request: Request) -> None:
|
|
83
160
|
"""Reject mutation attempts from viewer accounts."""
|
|
84
161
|
user = require_current_user(request)
|
|
@@ -9,7 +9,7 @@ from typing import Any
|
|
|
9
9
|
|
|
10
10
|
from cognis.logging import get_logger
|
|
11
11
|
from cognis.models.agent import AgentDefinition
|
|
12
|
-
from cognis.models.tool import ExecutorCapabilities
|
|
12
|
+
from cognis.models.tool import ExecutorCapabilities, ToolDefinition
|
|
13
13
|
from cognis.store.queries import get_executor_row, update_executor_runtime_state
|
|
14
14
|
from cognis.tools.skills import resolve_skills_for_agent
|
|
15
15
|
|
|
@@ -247,7 +247,7 @@ async def _persist_runtime_state(
|
|
|
247
247
|
runtime_metadata: dict[str, Any],
|
|
248
248
|
) -> None:
|
|
249
249
|
async with app.state.session_factory() as session:
|
|
250
|
-
await update_executor_runtime_state(
|
|
250
|
+
row = await update_executor_runtime_state(
|
|
251
251
|
session,
|
|
252
252
|
executor_id,
|
|
253
253
|
applied_config_version=applied_config_version,
|
|
@@ -257,6 +257,22 @@ async def _persist_runtime_state(
|
|
|
257
257
|
runtime_state=runtime_state,
|
|
258
258
|
)
|
|
259
259
|
await session.commit()
|
|
260
|
+
queue = getattr(app.state, "tool_classification_queue", None)
|
|
261
|
+
if queue is None or row is None or not observed_tools:
|
|
262
|
+
return
|
|
263
|
+
try:
|
|
264
|
+
tool_defs = [
|
|
265
|
+
ToolDefinition.model_validate(item)
|
|
266
|
+
for item in observed_tools
|
|
267
|
+
if isinstance(item, dict)
|
|
268
|
+
]
|
|
269
|
+
await queue.enqueue_tools(tool_defs, owner_email=getattr(row, "owner_email", None))
|
|
270
|
+
except Exception:
|
|
271
|
+
_logger.warning(
|
|
272
|
+
"executor_runtime: failed to enqueue tool classifications",
|
|
273
|
+
extra={"extra_data": {"executor_id": executor_id, "observed_tools": len(observed_tools)}},
|
|
274
|
+
exc_info=True,
|
|
275
|
+
)
|
|
260
276
|
|
|
261
277
|
|
|
262
278
|
async def _build_configure_payload(
|
|
@@ -266,6 +282,7 @@ async def _build_configure_payload(
|
|
|
266
282
|
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
267
283
|
from cognis.api.executor_ws import _resolve_executor_mcp_payload
|
|
268
284
|
from cognis.api.runtime_support import _resolve_web_config
|
|
285
|
+
from cognis.tools.skills import _qualified_skill_tool_name
|
|
269
286
|
|
|
270
287
|
mcp_servers, scoped_secrets = await _resolve_executor_mcp_payload(row, app.state.providers)
|
|
271
288
|
web_config = await _resolve_web_config(app.state.providers, row.owner_email)
|
|
@@ -287,19 +304,34 @@ async def _build_configure_payload(
|
|
|
287
304
|
"skill_id": skill.skill_id,
|
|
288
305
|
"version_id": skill.version_id,
|
|
289
306
|
"content_hash": skill.content_hash,
|
|
290
|
-
"tools": [
|
|
307
|
+
"tools": [
|
|
308
|
+
{
|
|
309
|
+
**t.model_dump(mode="json"),
|
|
310
|
+
"qualified_name": _qualified_skill_tool_name(skill.skill_id, t.name),
|
|
311
|
+
}
|
|
312
|
+
for t in skill.tools
|
|
313
|
+
],
|
|
291
314
|
"asset_manifest": [a.model_dump(mode="json") for a in skill.asset_manifest],
|
|
292
315
|
}
|
|
293
|
-
artifact_store = getattr(app.state
|
|
316
|
+
artifact_store = getattr(app.state, "artifact_store", None)
|
|
294
317
|
if artifact_store and skill.asset_manifest:
|
|
318
|
+
ttl_seconds = getattr(
|
|
319
|
+
getattr(artifact_store, "_config", None), # noqa: SLF001
|
|
320
|
+
"signed_url_ttl_seconds",
|
|
321
|
+
None,
|
|
322
|
+
)
|
|
295
323
|
for asset_entry in manifest["asset_manifest"]:
|
|
296
324
|
ns = asset_entry.get("artifact_namespace", "skills")
|
|
297
325
|
oid = asset_entry.get("artifact_object_id", "")
|
|
326
|
+
filename = asset_entry.get("filename", "")
|
|
298
327
|
if oid:
|
|
299
328
|
with contextlib.suppress(Exception):
|
|
300
|
-
asset_entry[
|
|
301
|
-
|
|
302
|
-
|
|
329
|
+
asset_entry["url"] = await artifact_store.async_get_public_url(
|
|
330
|
+
ns,
|
|
331
|
+
oid,
|
|
332
|
+
filename,
|
|
333
|
+
ttl_seconds=ttl_seconds,
|
|
334
|
+
)
|
|
303
335
|
skill_manifests.append(manifest)
|
|
304
336
|
except Exception:
|
|
305
337
|
_logger.warning(
|
|
@@ -13,6 +13,7 @@ from cognis.api.executor_runtime import reconcile_executor
|
|
|
13
13
|
from cognis.core.executor_policy import is_executor_type_allowed, load_executor_policy
|
|
14
14
|
from cognis.logging import get_logger
|
|
15
15
|
from cognis.models.tool import MCP_SERVER_IDS_KEY, ExecutorCapabilities, MCPServerConfig
|
|
16
|
+
from cognis.ownership import is_shared_owner_email
|
|
16
17
|
from cognis.providers.executor.websocket import WebSocketExecutorProvider
|
|
17
18
|
from cognis.store.queries import get_executor_row, get_mcp_server, update_executor_runtime_state
|
|
18
19
|
from cognis.tools.mcp import invalid_mcp_config_reason
|
|
@@ -91,6 +92,7 @@ async def handle_executor_websocket(
|
|
|
91
92
|
environment=params.get("environment"),
|
|
92
93
|
platform=params.get("platform") or {},
|
|
93
94
|
status=row.status,
|
|
95
|
+
owner_email=row.owner_email,
|
|
94
96
|
),
|
|
95
97
|
)
|
|
96
98
|
|
|
@@ -251,11 +253,14 @@ def _executor_connection_metadata(
|
|
|
251
253
|
environment: Any,
|
|
252
254
|
platform: dict[str, Any],
|
|
253
255
|
status: str,
|
|
256
|
+
owner_email: str | None,
|
|
254
257
|
) -> dict[str, Any]:
|
|
255
258
|
metadata: dict[str, Any] = {
|
|
256
259
|
"labels": labels,
|
|
257
260
|
"platform": platform,
|
|
258
261
|
"status": status,
|
|
262
|
+
"owner_email": owner_email,
|
|
263
|
+
"shared": is_shared_owner_email(owner_email),
|
|
259
264
|
}
|
|
260
265
|
if isinstance(environment, dict):
|
|
261
266
|
metadata["environment"] = environment
|
|
@@ -14,7 +14,12 @@ from starlette.responses import Response
|
|
|
14
14
|
from cognis.api.models import ErrorBody, ErrorResponse
|
|
15
15
|
from cognis.runtime_context import current_user_email
|
|
16
16
|
from cognis.security import parse_api_key, verify_api_key
|
|
17
|
-
from cognis.store.queries import
|
|
17
|
+
from cognis.store.queries import (
|
|
18
|
+
get_api_key,
|
|
19
|
+
get_browser_session_by_token,
|
|
20
|
+
get_user,
|
|
21
|
+
touch_api_key_last_used,
|
|
22
|
+
)
|
|
18
23
|
|
|
19
24
|
PUBLIC_ROUTES = {
|
|
20
25
|
("GET", "/api/bootstrap-status"),
|
|
@@ -177,20 +182,28 @@ class AuthenticationMiddleware(BaseHTTPMiddleware):
|
|
|
177
182
|
finally:
|
|
178
183
|
current_user_email.reset(context_token)
|
|
179
184
|
|
|
180
|
-
# Fallback: check
|
|
185
|
+
# Fallback: check opaque browser session cookie.
|
|
181
186
|
if cookie_token:
|
|
182
|
-
try:
|
|
183
|
-
claims = auth_provider.verify_jwt(cookie_token, audience=["cognis"])
|
|
184
|
-
except Exception:
|
|
185
|
-
return JSONResponse(
|
|
186
|
-
status_code=401,
|
|
187
|
-
content=ErrorResponse(
|
|
188
|
-
error=ErrorBody(code="unauthorized", message="Invalid session cookie")
|
|
189
|
-
).model_dump(),
|
|
190
|
-
)
|
|
191
|
-
# Check if user is disabled
|
|
192
187
|
async with session_factory() as session:
|
|
193
|
-
|
|
188
|
+
browser_session = await get_browser_session_by_token(session, cookie_token)
|
|
189
|
+
if browser_session is None or browser_session.revoked_at is not None:
|
|
190
|
+
return JSONResponse(
|
|
191
|
+
status_code=401,
|
|
192
|
+
content=ErrorResponse(
|
|
193
|
+
error=ErrorBody(code="unauthorized", message="Invalid session cookie")
|
|
194
|
+
).model_dump(),
|
|
195
|
+
)
|
|
196
|
+
expires_at = browser_session.expires_at
|
|
197
|
+
if expires_at.tzinfo is None:
|
|
198
|
+
expires_at = expires_at.replace(tzinfo=UTC)
|
|
199
|
+
if expires_at < datetime.now(UTC):
|
|
200
|
+
return JSONResponse(
|
|
201
|
+
status_code=401,
|
|
202
|
+
content=ErrorResponse(
|
|
203
|
+
error=ErrorBody(code="unauthorized", message="Session expired")
|
|
204
|
+
).model_dump(),
|
|
205
|
+
)
|
|
206
|
+
user_row = await get_user(session, browser_session.user_email)
|
|
194
207
|
if user_row is not None and not user_row.is_active:
|
|
195
208
|
return JSONResponse(
|
|
196
209
|
status_code=403,
|
|
@@ -198,16 +211,23 @@ class AuthenticationMiddleware(BaseHTTPMiddleware):
|
|
|
198
211
|
error=ErrorBody(code="account_disabled", message="Account disabled")
|
|
199
212
|
).model_dump(),
|
|
200
213
|
)
|
|
201
|
-
|
|
214
|
+
if user_row is None:
|
|
215
|
+
return JSONResponse(
|
|
216
|
+
status_code=401,
|
|
217
|
+
content=ErrorResponse(
|
|
218
|
+
error=ErrorBody(code="unauthorized", message="Unknown session owner")
|
|
219
|
+
).model_dump(),
|
|
220
|
+
)
|
|
221
|
+
context_token = current_user_email.set(user_row.email)
|
|
202
222
|
request.state.user = AuthenticatedUser(
|
|
203
|
-
email=
|
|
204
|
-
role=
|
|
205
|
-
name=
|
|
206
|
-
auth_type="
|
|
223
|
+
email=user_row.email,
|
|
224
|
+
role=user_row.role,
|
|
225
|
+
name=user_row.name,
|
|
226
|
+
auth_type="session",
|
|
207
227
|
)
|
|
208
|
-
request.state.
|
|
228
|
+
request.state.browser_session_id = browser_session.session_id
|
|
209
229
|
if api_rate_limiter is not None and not await api_rate_limiter.allow(
|
|
210
|
-
user_key=
|
|
230
|
+
user_key=user_row.email,
|
|
211
231
|
path=request.url.path,
|
|
212
232
|
method=request.method,
|
|
213
233
|
):
|