voodoo-framework 2.2.0__tar.gz → 2.4.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.
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/PKG-INFO +5 -1
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/pyproject.toml +5 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/__init__.py +1 -1
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/__init__.py +6 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/doctor.py +48 -0
- voodoo_framework-2.4.0/src/voodoo/cli/protocol.py +68 -0
- voodoo_framework-2.4.0/src/voodoo/cli/status.py +73 -0
- voodoo_framework-2.4.0/src/voodoo/cli/workers_cmd.py +71 -0
- voodoo_framework-2.4.0/src/voodoo/protocol/__init__.py +97 -0
- voodoo_framework-2.4.0/src/voodoo/protocol/export.py +75 -0
- voodoo_framework-2.4.0/src/voodoo/protocol/schemas.py +455 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/telemetry/__init__.py +4 -0
- voodoo_framework-2.4.0/src/voodoo/telemetry/otlp.py +108 -0
- voodoo_framework-2.4.0/src/voodoo/telemetry/store.py +355 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/workers/queue.py +9 -2
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/PKG-INFO +5 -1
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/SOURCES.txt +9 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/requires.txt +5 -0
- voodoo_framework-2.4.0/tests/test_observability.py +459 -0
- voodoo_framework-2.4.0/tests/test_protocol.py +399 -0
- voodoo_framework-2.2.0/src/voodoo/telemetry/store.py +0 -200
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/LICENSE +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/README.md +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/setup.cfg +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/adapters/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/adapters/capabilities.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/adapters/registry.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/adapters/tailwind.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/adapters/voodoo_css.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/agent.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/agents/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/agents/models.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/agents/registry.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/agent.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/anthropic.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/gemini.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/mock.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/ollama.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/providers/openai.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/tools/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ai/tools/registry.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/api.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/cookies.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/guards.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/jwt.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/middleware.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/passwords.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/auth/user.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/__main__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/agents.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/ai.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/approvals.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/auth.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/dev.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/executions.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/generate.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/inspect.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/new.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/objects.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/recover.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/routes.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/scaffolding.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/schedules.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/tasks.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/terminal.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/theme.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/cli/version.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/components.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/config.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/app.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/errors.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/events.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/render.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/routing.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/sitemap.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/core/state.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/data/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/data/base.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/data/model.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/i18n.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/mcp/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/mcp/client.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/memory/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/memory/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/memory/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/mesh/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/mesh/client.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/mesh/event_bus.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/capability.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/compute.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/constraint.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/effect.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/intent.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/resource.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/state.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/primitives/time.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/py.typed +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/queue.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/routing/api.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/routing/pages.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/adaptive.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/capability.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/constraint.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/context.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/engine.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/errors.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/execution.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/graph.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/human.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/persistence.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/planner.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/scheduler.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/task.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/runtime/workflow.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/schedule.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/cors.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/csrf.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/headers.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/passwords.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/rate_limit.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/redaction.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/security/secrets.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/seo.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/static/client.js +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/status.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/cache/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/cache/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/cache/memory.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/cache/redis.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/database/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/database/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/database/postgres.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/database/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/events/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/events/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/events/local.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/events/postgres.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/events/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/execution/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/execution/migrations.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/execution/postgres.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/execution/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/manager.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/objects/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/objects/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/objects/local.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/objects/s3.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/interfaces.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/memory.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/postgres.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/redis.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/queue/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/scheduler/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/storage/scheduler/sqlite.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/telemetry/api.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/telemetry/middleware.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/theme.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/tools/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/tools/registry.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/component.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/events.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/library.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/markdown.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/rendering.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/state.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/styles/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/styles/presets.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/ui/styles/theme.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo/workers/__init__.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/dependency_links.txt +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/entry_points.txt +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/src/voodoo_framework.egg-info/top_level.txt +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_agent.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_agent_registry.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_agent_runtime.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_app.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_auth.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_capability_security.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_checkpoint_resume.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_chrome.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_cli.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_cli_inspect.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_components.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_config.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_contract_api.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_data.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_design_system.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_durable_hitl.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_events.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_execution_sqlite_store.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_http_runtime.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_human.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_i18n.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_integration.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_mcp.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_mcp_runtime.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_memory.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_mesh.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_mesh_event_bus.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_model.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_object_store.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_persistence.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_planner_adaptive.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_primitives.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_provider_switching.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_providers.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_queue.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_reactive.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_runtime.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_scheduler.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_security.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_seo.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_state.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_theme.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_theme_presets.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_tools.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_ui.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_websocket.py +0 -0
- {voodoo_framework-2.2.0 → voodoo_framework-2.4.0}/tests/test_workers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voodoo-framework
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: The programmable runtime for adaptive applications and operational systems — web, APIs, agents, workers, human workflows, distributed systems, and physical systems in one runtime.
|
|
5
5
|
Author-email: Helder Perez <contact@helderperez.com>
|
|
6
6
|
Maintainer-email: Helder Perez <contact@helderperez.com>
|
|
@@ -59,6 +59,10 @@ Requires-Dist: boto3>=1.34; extra == "s3"
|
|
|
59
59
|
Requires-Dist: botocore>=1.34; extra == "s3"
|
|
60
60
|
Provides-Extra: redis
|
|
61
61
|
Requires-Dist: redis>=5.0; extra == "redis"
|
|
62
|
+
Provides-Extra: otel
|
|
63
|
+
Requires-Dist: opentelemetry-api>=1.20; extra == "otel"
|
|
64
|
+
Requires-Dist: opentelemetry-sdk>=1.20; extra == "otel"
|
|
65
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.20; extra == "otel"
|
|
62
66
|
Dynamic: license-file
|
|
63
67
|
|
|
64
68
|
<picture>
|
|
@@ -10,12 +10,15 @@ from voodoo.cli import (
|
|
|
10
10
|
generate,
|
|
11
11
|
new,
|
|
12
12
|
objects,
|
|
13
|
+
protocol,
|
|
13
14
|
recover,
|
|
14
15
|
routes,
|
|
15
16
|
schedules,
|
|
17
|
+
status,
|
|
16
18
|
tasks,
|
|
17
19
|
theme,
|
|
18
20
|
version,
|
|
21
|
+
workers_cmd,
|
|
19
22
|
)
|
|
20
23
|
from voodoo.cli.auth import auth_app
|
|
21
24
|
from voodoo.cli.inspect import inspect_app
|
|
@@ -41,10 +44,13 @@ app.add_typer(objects.objects_app, name="objects")
|
|
|
41
44
|
app.add_typer(agents.agents_app, name="agents")
|
|
42
45
|
app.add_typer(approvals.approvals_app, name="approvals")
|
|
43
46
|
app.add_typer(theme.theme_app, name="theme")
|
|
47
|
+
app.add_typer(protocol.protocol_app, name="protocol")
|
|
44
48
|
# Top-level aliases per the Sprint 3 CLI surface: `voodoo execution <id>`
|
|
45
49
|
# (timeline from the journal) and `voodoo events` (recent journal events).
|
|
46
50
|
app.command("execution")(executions.show_execution)
|
|
47
51
|
app.command("events")(executions.list_events)
|
|
52
|
+
app.command()(status.status)
|
|
53
|
+
app.command()(workers_cmd.workers)
|
|
48
54
|
app.command()(version.version)
|
|
49
55
|
app.command()(doctor.doctor)
|
|
50
56
|
app.command()(routes.routes)
|
|
@@ -217,6 +217,54 @@ def doctor(): # noqa: C901
|
|
|
217
217
|
except Exception: # noqa: BLE001 - diagnostics must never crash doctor
|
|
218
218
|
terminal.status("capability matrix", "unavailable")
|
|
219
219
|
|
|
220
|
+
# ── Queue depth ─────────────────────────────────
|
|
221
|
+
terminal.heading("queue")
|
|
222
|
+
try:
|
|
223
|
+
import asyncio
|
|
224
|
+
|
|
225
|
+
async def _check_queue() -> tuple[int, int]:
|
|
226
|
+
from voodoo.workers.queue import _get_queue, _workers
|
|
227
|
+
|
|
228
|
+
depth = 0
|
|
229
|
+
try:
|
|
230
|
+
q = await _get_queue()
|
|
231
|
+
if hasattr(q, "list"):
|
|
232
|
+
tasks = await q.list()
|
|
233
|
+
depth = len(tasks)
|
|
234
|
+
elif hasattr(q, "depth"):
|
|
235
|
+
depth = await q.depth()
|
|
236
|
+
except Exception:
|
|
237
|
+
pass
|
|
238
|
+
return depth, len(_workers)
|
|
239
|
+
|
|
240
|
+
depth, n_workers = asyncio.run(_check_queue())
|
|
241
|
+
terminal.status("depth", str(depth))
|
|
242
|
+
terminal.status("registered workers", str(n_workers))
|
|
243
|
+
except Exception: # noqa: BLE001
|
|
244
|
+
terminal.status("queue", "unavailable")
|
|
245
|
+
|
|
246
|
+
# ── Schedules ───────────────────────────────────
|
|
247
|
+
terminal.heading("schedules")
|
|
248
|
+
try:
|
|
249
|
+
from pathlib import Path as _Path
|
|
250
|
+
|
|
251
|
+
sched_db = _Path(cfg.db_path).parent / "schedules.db"
|
|
252
|
+
if sched_db.exists():
|
|
253
|
+
terminal.status("scheduler db", "present")
|
|
254
|
+
else:
|
|
255
|
+
terminal.status("scheduler db", "not found")
|
|
256
|
+
except Exception: # noqa: BLE001
|
|
257
|
+
terminal.status("schedules", "unavailable")
|
|
258
|
+
|
|
259
|
+
# ── OTLP ────────────────────────────────────────
|
|
260
|
+
terminal.heading("otel")
|
|
261
|
+
try:
|
|
262
|
+
from voodoo.telemetry.otlp import is_available
|
|
263
|
+
|
|
264
|
+
terminal.status("otlp exporter", "active" if is_available() else "off")
|
|
265
|
+
except Exception: # noqa: BLE001
|
|
266
|
+
terminal.status("otlp exporter", "off")
|
|
267
|
+
|
|
220
268
|
# ── AI Kit ──────────────────────────────────────
|
|
221
269
|
terminal.heading("ai kit")
|
|
222
270
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""CLI: ``voodoo protocol export`` — export JSON Schema for protocol entities."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
|
|
10
|
+
from voodoo.protocol import export_json_schemas, schema_for
|
|
11
|
+
|
|
12
|
+
__all__ = ["protocol_app"]
|
|
13
|
+
|
|
14
|
+
protocol_app = typer.Typer(
|
|
15
|
+
name="protocol",
|
|
16
|
+
help="Protocol schema operations.",
|
|
17
|
+
no_args_is_help=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@protocol_app.command("export")
|
|
22
|
+
def export_schemas(
|
|
23
|
+
output: str = typer.Option(
|
|
24
|
+
"",
|
|
25
|
+
"--output",
|
|
26
|
+
"-o",
|
|
27
|
+
help="Output file path (default: stdout).",
|
|
28
|
+
),
|
|
29
|
+
entity: str = typer.Option(
|
|
30
|
+
"",
|
|
31
|
+
"--entity",
|
|
32
|
+
"-e",
|
|
33
|
+
help="Export a single entity by name (e.g. 'Execution').",
|
|
34
|
+
),
|
|
35
|
+
indent: int = typer.Option(2, "--indent", help="JSON indentation."),
|
|
36
|
+
) -> None:
|
|
37
|
+
"""Export JSON Schema for all Voodoo protocol entities."""
|
|
38
|
+
if entity:
|
|
39
|
+
try:
|
|
40
|
+
schema = schema_for(entity)
|
|
41
|
+
except KeyError:
|
|
42
|
+
typer.echo(f"Unknown entity: {entity}", err=True)
|
|
43
|
+
typer.echo(f"Available: {', '.join(sorted(_entity_names()))}", err=True)
|
|
44
|
+
raise typer.Exit(1) from None
|
|
45
|
+
result = json.dumps(schema, indent=indent, default=str)
|
|
46
|
+
else:
|
|
47
|
+
schemas = export_json_schemas()
|
|
48
|
+
result = json.dumps(schemas, indent=indent, default=str)
|
|
49
|
+
|
|
50
|
+
if output:
|
|
51
|
+
Path(output).write_text(result + "\n")
|
|
52
|
+
count = 1 if entity else len(_entity_names())
|
|
53
|
+
typer.echo(f"Exported {count} schema(s) to {output}")
|
|
54
|
+
else:
|
|
55
|
+
typer.echo(result)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@protocol_app.command("list")
|
|
59
|
+
def list_entities() -> None:
|
|
60
|
+
"""List all protocol entity names."""
|
|
61
|
+
for name in sorted(_entity_names()):
|
|
62
|
+
typer.echo(name)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _entity_names() -> list[str]:
|
|
66
|
+
from voodoo.protocol.schemas import PROTOCOL_ENTITIES
|
|
67
|
+
|
|
68
|
+
return list(PROTOCOL_ENTITIES.keys())
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""``voodoo status`` — runtime health overview.
|
|
2
|
+
|
|
3
|
+
Displays a quick snapshot of the runtime: request counts, error rate,
|
|
4
|
+
latency, agent activity, queue depth, and OTel export status.
|
|
5
|
+
Works after a restart because rolling counters are persisted to
|
|
6
|
+
``.voodoo/telemetry_summary.json``.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.table import Table
|
|
14
|
+
|
|
15
|
+
__all__ = ["status"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def status() -> None:
|
|
19
|
+
"""Show runtime health overview."""
|
|
20
|
+
from voodoo.telemetry import telemetry_store
|
|
21
|
+
from voodoo.telemetry.otlp import is_available as otlp_available
|
|
22
|
+
|
|
23
|
+
summary = telemetry_store.get_summary()
|
|
24
|
+
console = Console()
|
|
25
|
+
|
|
26
|
+
# -- header --------------------------------------------------------
|
|
27
|
+
console.print("[bold cyan]Voodoo Runtime Status[/bold cyan]")
|
|
28
|
+
console.print()
|
|
29
|
+
|
|
30
|
+
# -- requests & errors ---------------------------------------------
|
|
31
|
+
tbl = Table(show_header=True, header_style="bold")
|
|
32
|
+
tbl.add_column("Metric", style="dim")
|
|
33
|
+
tbl.add_column("Value", justify="right")
|
|
34
|
+
|
|
35
|
+
total = summary.get("requests_total", 0)
|
|
36
|
+
errors = summary.get("errors_total", 0)
|
|
37
|
+
error_rate = f"{(errors / total * 100):.1f}%" if total else "—"
|
|
38
|
+
avg_lat = summary.get("average_latency_ms", 0.0)
|
|
39
|
+
|
|
40
|
+
tbl.add_row("Requests total", str(total))
|
|
41
|
+
tbl.add_row("Errors total", str(errors))
|
|
42
|
+
tbl.add_row("Error rate", error_rate)
|
|
43
|
+
tbl.add_row("Avg latency", f"{avg_lat:.1f} ms")
|
|
44
|
+
tbl.add_row("DB queries", str(summary.get("db_queries", 0)))
|
|
45
|
+
console.print(tbl)
|
|
46
|
+
console.print()
|
|
47
|
+
|
|
48
|
+
# -- agent activity ------------------------------------------------
|
|
49
|
+
agent_tbl = Table(show_header=True, header_style="bold")
|
|
50
|
+
agent_tbl.add_column("Agent Metric", style="dim")
|
|
51
|
+
agent_tbl.add_column("Value", justify="right")
|
|
52
|
+
|
|
53
|
+
agent_tbl.add_row("Agent runs", str(summary.get("agent_runs", 0)))
|
|
54
|
+
agent_tbl.add_row("Tokens in", str(summary.get("agent_tokens_in", 0)))
|
|
55
|
+
agent_tbl.add_row("Tokens out", str(summary.get("agent_tokens_out", 0)))
|
|
56
|
+
agent_tbl.add_row("Agent cost", f"${summary.get('agent_cost', 0.0):.6f}")
|
|
57
|
+
agent_tbl.add_row("Tool calls", str(summary.get("tool_calls_total", 0)))
|
|
58
|
+
agent_tbl.add_row("Tool errors", str(summary.get("tool_errors", 0)))
|
|
59
|
+
agent_tbl.add_row("Spans recorded", str(summary.get("spans_total", 0)))
|
|
60
|
+
console.print(agent_tbl)
|
|
61
|
+
console.print()
|
|
62
|
+
|
|
63
|
+
# -- infrastructure ------------------------------------------------
|
|
64
|
+
infra_tbl = Table(show_header=True, header_style="bold")
|
|
65
|
+
infra_tbl.add_column("Infrastructure", style="dim")
|
|
66
|
+
infra_tbl.add_column("Status")
|
|
67
|
+
|
|
68
|
+
infra_tbl.add_row("OTLP export", "active" if otlp_available() else "off")
|
|
69
|
+
console.print(infra_tbl)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
app = typer.Typer(name="status", help="Runtime health overview.", no_args_is_help=True)
|
|
73
|
+
app.command()(status)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""``voodoo workers`` — worker state & queue depth.
|
|
2
|
+
|
|
3
|
+
Shows registered background workers, their queue depth, and whether
|
|
4
|
+
the worker loop is running.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
|
|
16
|
+
__all__ = ["workers"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def _gather_worker_info() -> dict[str, Any]:
|
|
20
|
+
"""Collect worker and queue state without side-effects."""
|
|
21
|
+
from voodoo.workers.queue import _get_queue, _worker_tasks, _workers
|
|
22
|
+
|
|
23
|
+
info: dict[str, Any] = {
|
|
24
|
+
"registered": list(_workers.keys()),
|
|
25
|
+
"running_tasks": len([t for t in _worker_tasks if not t.done()]),
|
|
26
|
+
"queue_depth": 0,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
q = await _get_queue()
|
|
31
|
+
if hasattr(q, "list"):
|
|
32
|
+
tasks = await q.list()
|
|
33
|
+
info["queue_depth"] = len(tasks)
|
|
34
|
+
elif hasattr(q, "depth"):
|
|
35
|
+
info["queue_depth"] = await q.depth()
|
|
36
|
+
except Exception:
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
return info
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def workers() -> None:
|
|
43
|
+
"""Show registered workers and queue depth."""
|
|
44
|
+
console = Console()
|
|
45
|
+
info = asyncio.run(_gather_worker_info())
|
|
46
|
+
|
|
47
|
+
console.print("[bold cyan]Voodoo Workers[/bold cyan]")
|
|
48
|
+
console.print()
|
|
49
|
+
|
|
50
|
+
tbl = Table(show_header=True, header_style="bold")
|
|
51
|
+
tbl.add_column("Worker", style="dim")
|
|
52
|
+
tbl.add_column("Status")
|
|
53
|
+
|
|
54
|
+
registered = info["registered"]
|
|
55
|
+
if not registered:
|
|
56
|
+
console.print("[dim]No workers registered.[/dim]")
|
|
57
|
+
else:
|
|
58
|
+
running = info["running_tasks"]
|
|
59
|
+
for name in registered:
|
|
60
|
+
tbl.add_row(name, "running" if running > 0 else "idle")
|
|
61
|
+
console.print(tbl)
|
|
62
|
+
|
|
63
|
+
console.print()
|
|
64
|
+
console.print(f"Queue depth: [bold]{info['queue_depth']}[/bold]")
|
|
65
|
+
console.print(f"Running worker tasks: [bold]{info['running_tasks']}[/bold]")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
app = typer.Typer(
|
|
69
|
+
name="workers", help="Worker state & queue depth.", no_args_is_help=True
|
|
70
|
+
)
|
|
71
|
+
app.command()(workers)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Voodoo protocol — canonical entity schemas for cross-language interop.
|
|
2
|
+
|
|
3
|
+
This package defines the **stable semantic boundary** for the Voodoo runtime.
|
|
4
|
+
Every entity is a Pydantic model with a ``schema_version`` field and full
|
|
5
|
+
JSON Schema export support.
|
|
6
|
+
|
|
7
|
+
Quick start::
|
|
8
|
+
|
|
9
|
+
from voodoo.protocol import Execution, Intent, SCHEMA_VERSION
|
|
10
|
+
|
|
11
|
+
intent = Intent(name="summarize", params={"text": "hello"})
|
|
12
|
+
execution = Execution(
|
|
13
|
+
id="exec-001",
|
|
14
|
+
trace_id="trace-001",
|
|
15
|
+
intent=intent,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Serialize to JSON
|
|
19
|
+
data = execution.model_dump(mode="json")
|
|
20
|
+
|
|
21
|
+
# Round-trip
|
|
22
|
+
restored = Execution.model_validate(data)
|
|
23
|
+
|
|
24
|
+
# Export JSON Schema
|
|
25
|
+
from voodoo.protocol import export_json_schemas
|
|
26
|
+
schemas = export_json_schemas()
|
|
27
|
+
|
|
28
|
+
See ``docs/protocol.md`` for the compatibility policy.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
from .export import export_json_schemas, export_json_schemas_json, schema_for
|
|
34
|
+
from .schemas import (
|
|
35
|
+
PROTOCOL_ENTITIES,
|
|
36
|
+
SCHEMA_VERSION,
|
|
37
|
+
AgentEntity,
|
|
38
|
+
AgentRun,
|
|
39
|
+
Approval,
|
|
40
|
+
ApprovalStatus,
|
|
41
|
+
Capability,
|
|
42
|
+
ComputeKind,
|
|
43
|
+
ComputeSpec,
|
|
44
|
+
Constraint,
|
|
45
|
+
Effect,
|
|
46
|
+
EffectStatus,
|
|
47
|
+
Error,
|
|
48
|
+
Event,
|
|
49
|
+
Execution,
|
|
50
|
+
ExecutionStatus,
|
|
51
|
+
Identity,
|
|
52
|
+
Intent,
|
|
53
|
+
IntentStatus,
|
|
54
|
+
MemoryEntry,
|
|
55
|
+
ObjectRef,
|
|
56
|
+
Resource,
|
|
57
|
+
Task,
|
|
58
|
+
TaskStatus,
|
|
59
|
+
TelemetrySpan,
|
|
60
|
+
TimeSpec,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
# Schema metadata
|
|
65
|
+
"SCHEMA_VERSION",
|
|
66
|
+
"PROTOCOL_ENTITIES",
|
|
67
|
+
# Enums
|
|
68
|
+
"ExecutionStatus",
|
|
69
|
+
"IntentStatus",
|
|
70
|
+
"EffectStatus",
|
|
71
|
+
"TaskStatus",
|
|
72
|
+
"ApprovalStatus",
|
|
73
|
+
"ComputeKind",
|
|
74
|
+
# Core entities
|
|
75
|
+
"Identity",
|
|
76
|
+
"Capability",
|
|
77
|
+
"Constraint",
|
|
78
|
+
"Resource",
|
|
79
|
+
"TimeSpec",
|
|
80
|
+
"ComputeSpec",
|
|
81
|
+
"Intent",
|
|
82
|
+
"Effect",
|
|
83
|
+
"Execution",
|
|
84
|
+
"Task",
|
|
85
|
+
"Event",
|
|
86
|
+
"ObjectRef",
|
|
87
|
+
"Error",
|
|
88
|
+
"TelemetrySpan",
|
|
89
|
+
"Approval",
|
|
90
|
+
"AgentEntity",
|
|
91
|
+
"AgentRun",
|
|
92
|
+
"MemoryEntry",
|
|
93
|
+
# Export
|
|
94
|
+
"export_json_schemas",
|
|
95
|
+
"export_json_schemas_json",
|
|
96
|
+
"schema_for",
|
|
97
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""JSON Schema export for Voodoo protocol entities.
|
|
2
|
+
|
|
3
|
+
Usage::
|
|
4
|
+
|
|
5
|
+
from voodoo.protocol import export_json_schemas
|
|
6
|
+
|
|
7
|
+
# Export all schemas as a dict
|
|
8
|
+
schemas = export_json_schemas()
|
|
9
|
+
|
|
10
|
+
# Write to a file
|
|
11
|
+
import json
|
|
12
|
+
with open("voodoo-protocol.json", "w") as f:
|
|
13
|
+
json.dump(schemas, f, indent=2)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
from .schemas import PROTOCOL_ENTITIES, SCHEMA_VERSION
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"export_json_schemas",
|
|
25
|
+
"export_json_schemas_json",
|
|
26
|
+
"schema_for",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def export_json_schemas() -> dict[str, Any]:
|
|
31
|
+
"""Export JSON Schema for all protocol entities.
|
|
32
|
+
|
|
33
|
+
Returns a dict keyed by entity name, where each value is the
|
|
34
|
+
JSON Schema for that entity (draft 2020-12).
|
|
35
|
+
"""
|
|
36
|
+
schemas: dict[str, Any] = {}
|
|
37
|
+
for name, model in PROTOCOL_ENTITIES.items():
|
|
38
|
+
schema = model.model_json_schema()
|
|
39
|
+
# Add protocol-level metadata
|
|
40
|
+
schema["$schema"] = "https://json-schema.org/draft/2020-12/schema"
|
|
41
|
+
schema["$id"] = f"urn:voodoo:protocol:{name.lower()}:{SCHEMA_VERSION}"
|
|
42
|
+
schema["x-voodoo-schema-version"] = SCHEMA_VERSION
|
|
43
|
+
schemas[name] = schema
|
|
44
|
+
return schemas
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def export_json_schemas_json(indent: int = 2) -> str:
|
|
48
|
+
"""Export all protocol schemas as a JSON string."""
|
|
49
|
+
return json.dumps(export_json_schemas(), indent=indent, default=str)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def schema_for(entity_name: str) -> dict[str, Any]:
|
|
53
|
+
"""Get JSON Schema for a single protocol entity by name.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
entity_name:
|
|
58
|
+
The entity name (e.g. "Execution", "Intent").
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
dict:
|
|
63
|
+
The JSON Schema for the entity.
|
|
64
|
+
|
|
65
|
+
Raises
|
|
66
|
+
------
|
|
67
|
+
KeyError:
|
|
68
|
+
If the entity name is not a known protocol entity.
|
|
69
|
+
"""
|
|
70
|
+
model = PROTOCOL_ENTITIES[entity_name]
|
|
71
|
+
schema = model.model_json_schema()
|
|
72
|
+
schema["$schema"] = "https://json-schema.org/draft/2020-12/schema"
|
|
73
|
+
schema["$id"] = f"urn:voodoo:protocol:{entity_name.lower()}:{SCHEMA_VERSION}"
|
|
74
|
+
schema["x-voodoo-schema-version"] = SCHEMA_VERSION
|
|
75
|
+
return schema
|