agentseek-api 0.2.1__tar.gz → 0.2.2__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.
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.env.example +1 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.github/workflows/ci.yml +15 -2
- agentseek_api-0.2.2/CHANGELOG.md +88 -0
- agentseek_api-0.2.1/README.md → agentseek_api-0.2.2/PKG-INFO +64 -2
- agentseek_api-0.2.1/PKG-INFO → agentseek_api-0.2.2/README.md +32 -33
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/README.zh-CN.md +1 -1
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/pyproject.toml +7 -6
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-redis-runtime.sh +112 -8
- agentseek_api-0.2.2/scripts/test_minimum_cli_dependencies.py +109 -0
- agentseek_api-0.2.2/scripts/verify_worker_concurrency.py +528 -0
- agentseek_api-0.2.2/src/agentseek_api/__init__.py +1 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/assistants.py +48 -6
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/runs.py +12 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/cli.py +148 -59
- agentseek_api-0.2.2/src/agentseek_api/constants.py +3 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/database.py +12 -1
- agentseek_api-0.2.2/src/agentseek_api/dotenv_adapter.py +69 -0
- agentseek_api-0.2.2/src/agentseek_api/process_supervisor.py +1531 -0
- agentseek_api-0.2.2/src/agentseek_api/runtime_entrypoint.py +59 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/redis_queue.py +18 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/run_executor.py +14 -1
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/run_preparation.py +27 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/settings.py +2 -1
- agentseek_api-0.2.2/src/agentseek_api/worker.py +347 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_langsmith_compat_live.py +3 -3
- agentseek_api-0.2.2/tests/fixtures/runtime_settings_probe/sitecustomize.py +69 -0
- agentseek_api-0.2.2/tests/fixtures/termination_tree.py +67 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_assistants_compat.py +2 -2
- agentseek_api-0.2.2/tests/integration/test_assistants_config_context_sync.py +145 -0
- agentseek_api-0.2.2/tests/integration/test_cli_runtime_processes.py +812 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_langsmith_compat_coverage.py +2 -2
- agentseek_api-0.2.2/tests/integration/test_live_redis_queue.py +69 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_metadata_db_config.py +23 -8
- agentseek_api-0.2.2/tests/integration/test_runs_streaming.py +301 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_assistant_routes_unit.py +4 -4
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_cli.py +689 -80
- agentseek_api-0.2.2/tests/unit/test_dotenv_adapter.py +89 -0
- agentseek_api-0.2.2/tests/unit/test_process_supervisor.py +2860 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_redis_queue.py +26 -0
- agentseek_api-0.2.2/tests/unit/test_redis_runtime_script.py +68 -0
- agentseek_api-0.2.2/tests/unit/test_run_controls_validation.py +27 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_run_executor.py +131 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_run_preparation.py +139 -0
- agentseek_api-0.2.2/tests/unit/test_runtime_entrypoint.py +171 -0
- agentseek_api-0.2.2/tests/unit/test_runtime_environment.py +603 -0
- agentseek_api-0.2.2/tests/unit/test_worker.py +650 -0
- agentseek_api-0.2.2/tests/unit/test_worker_concurrency_probe.py +581 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/uv.lock +8 -6
- agentseek_api-0.2.1/CHANGELOG.md +0 -37
- agentseek_api-0.2.1/src/agentseek_api/__init__.py +0 -1
- agentseek_api-0.2.1/src/agentseek_api/worker.py +0 -103
- agentseek_api-0.2.1/tests/integration/test_runs_streaming.py +0 -142
- agentseek_api-0.2.1/tests/unit/test_worker.py +0 -155
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.dockerignore +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.github/workflows/live-provider-streaming.yml +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.github/workflows/release.yml +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/.gitignore +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/AGENTS.md +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/CONTRIBUTING.md +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/LICENSE +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/Makefile +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/README.md +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/assistant_config/agentseek.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/assistant_config/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/auth/api_key_auth.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/auth/bearer_token_auth.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/auth/custom_backend.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/auth/jwt.md +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/auth/jwt_auth.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/custom_routes/app.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/docker_ci_auth/auth_backend.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/docker_ci_auth/manifest.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/external_graph/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/external_graph/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/external_graph/manifest.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/external_graph/run.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/react_agent/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/react_agent/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/store_memory/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/stress_test/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/stress_test/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/stress_tool_agent/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/stress_tool_agent/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/subgraph_agent/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/subgraph_agent/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/subgraph_hitl_agent/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/graphs/subgraph_hitl_agent/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/live_provider_graphs/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/live_provider_graphs/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/live_provider_graphs/manifest.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/minimal_agentseek/agentseek.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/minimal_agentseek/graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/run_sample_graphs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/examples/sample_graphs_manifest.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/build_live_provider_matrix.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/seekdb_checkpoint_smoke.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/seekdb_embed_launcher.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-checkpoints.sh +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-cli-dev-samples.sh +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-cli-docker.sh +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-live-provider.sh +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test-seekdb.sh +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test_cli_config_autodiscovery.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test_cli_dev_studio_smoke.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test_cli_embed_serve_smoke.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/test_cli_serve_smoke.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/scripts/verify_docker_api.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/a2a_server.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/crons.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/stateless_runs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/store.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/streaming.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/api/threads.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/a2a_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/app_loader.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/auth_deps.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/auth_middleware.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/config_file.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/content_type_fix.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/cors_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/http_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/mcp_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/oceanbase_checkpointer.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/orm.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/runtime_store.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/core/store_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/main.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/mcp_server.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/models/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/models/api.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/models/auth.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/models/protocol.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/scheduler.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/cron_models.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/cron_rrule.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/cron_scheduler.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/cron_service.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/cron_webhooks.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/default_assistants.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/executor.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/langgraph_service.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/run_jobs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/run_state.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/sample_graphs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/sse.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/stream_modes.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/stream_persistence.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/thread_checkpoint_store.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/thread_protocol.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/src/agentseek_api/services/thread_service.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/conftest.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/__init__.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/conftest.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/e2e_inprocess_flow.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/e2e_live_http_flow.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/e2e_live_http_multi_graph.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/e2e_live_http_resume_flow.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/fixtures/langgraph.store-e2e.json +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/live_provider_helpers.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_a2a_live.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_cron_api_live.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_cron_scheduler_live.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_live_provider_api.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_live_provider_mcp.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_mcp_live.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/e2e/test_real_api_flow.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_a2a_endpoint.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_agent_card.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_agents_aliases.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_assistants_crud.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_assistants_ordering.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_auth_coverage_gaps.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_auth_handlers.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_auth_route_enforcement.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_auth_scope_matrix.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_core_api_flow.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_cron_api.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_langsmith_compat_extra.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_live_provider_streaming.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_live_redis_stream_persistence.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_mcp_endpoint.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_protocol_v2_streaming.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_run_cancellation_async.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_compat.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_crud.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_ordering.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_resume.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_streaming_errors.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_validation.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_wait_and_get.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_runs_wait_timeout.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_scheduler_runtime.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_stateless_runs_crud.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_store_api.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_stream_persistence.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_system_endpoints.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_threads_compat.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_threads_crud.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/integration/test_threads_ordering.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_a2a_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_a2a_server.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_app_loader.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_auth.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_auth_deps.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_auth_internals.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_checkpoint_guards.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_content_type_fix.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_cron_rrule.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_cron_service.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_cron_webhooks.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_custom_routers.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_database_manager.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_default_assistants.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_examples.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_executor.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_graph_manifest.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_http_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_langgraph_service.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_live_provider_e2e_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_live_provider_graphs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_live_provider_matrix.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_mcp_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_mcp_server.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_oceanbase_checkpointer.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_openapi_auth_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_run_jobs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_run_state.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_runtime_store.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_sample_graphs.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_scheduler.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_scheduler_process.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_seekdb_checkpoint_smoke.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_seekdb_embed_launcher.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_sse_keepalive.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_store_config.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_stream_modes.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_stream_persistence_helpers.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_thread_checkpoint_store.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_thread_protocol.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_thread_routes_unit.py +0 -0
- {agentseek_api-0.2.1 → agentseek_api-0.2.2}/tests/unit/test_thread_service.py +0 -0
|
@@ -82,6 +82,18 @@ jobs:
|
|
|
82
82
|
uv run python -c
|
|
83
83
|
"from pathlib import Path; import subprocess; out = Path('.tmp/agentseek.Dockerfile'); out.parent.mkdir(exist_ok=True); subprocess.run(['uv', 'run', 'agentseek-api', 'dockerfile', '--config', 'examples/external_graph/manifest.json', str(out)], check=True); text = out.read_text(encoding='utf-8'); assert 'ENV PYTHONPATH=/deps/agent' in text; assert 'ENV AGENTSEEK_GRAPHS=/deps/agent/examples/external_graph/manifest.json' in text"
|
|
84
84
|
|
|
85
|
+
- name: CLI config, host environment, and process tests
|
|
86
|
+
run: >-
|
|
87
|
+
uv run pytest
|
|
88
|
+
tests/unit/test_cli.py
|
|
89
|
+
tests/unit/test_graph_manifest.py
|
|
90
|
+
tests/unit/test_dotenv_adapter.py
|
|
91
|
+
tests/unit/test_runtime_environment.py
|
|
92
|
+
tests/unit/test_runtime_entrypoint.py
|
|
93
|
+
tests/unit/test_process_supervisor.py
|
|
94
|
+
tests/integration/test_cli_runtime_processes.py
|
|
95
|
+
-q
|
|
96
|
+
|
|
85
97
|
- name: Sync embedded SeekDB extra for serve smoke
|
|
86
98
|
if: runner.os == 'Linux' || (runner.os == 'macOS' && runner.arch == 'ARM64')
|
|
87
99
|
run: uv sync --dev --extra embedded
|
|
@@ -90,8 +102,9 @@ jobs:
|
|
|
90
102
|
if: runner.os == 'Linux' || (runner.os == 'macOS' && runner.arch == 'ARM64')
|
|
91
103
|
run: uv run python scripts/test_cli_serve_smoke.py
|
|
92
104
|
|
|
93
|
-
- name:
|
|
94
|
-
|
|
105
|
+
- name: Minimum direct dependency compatibility
|
|
106
|
+
if: runner.os == 'Linux'
|
|
107
|
+
run: uv run python scripts/test_minimum_cli_dependencies.py
|
|
95
108
|
|
|
96
109
|
embedded-seekdb-smoke:
|
|
97
110
|
name: Embedded SeekDB Smoke
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to AgentSeek API are documented in this file.
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.2.2 - 2026-08-16
|
|
8
|
+
|
|
9
|
+
### Highlights
|
|
10
|
+
|
|
11
|
+
- Added bounded parallel Redis job execution within a worker process. Set
|
|
12
|
+
`WORKER_CONCURRENT_JOBS` to control the limit; the default is `10`.
|
|
13
|
+
- Aligned assistant and run `config.configurable` / `context` handling with the
|
|
14
|
+
LangGraph API contract, including assistant defaults and legacy configurable
|
|
15
|
+
access for graphs without a context schema.
|
|
16
|
+
- Defined one deterministic environment-ownership contract for the `dev`,
|
|
17
|
+
`serve`, `worker`, and `scheduler` host runtimes.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Made Redis job acknowledgement conditional on ownership of the active worker
|
|
22
|
+
lease, and stopped scheduling safely when a job fails or the lease is lost.
|
|
23
|
+
- Rejected client requests that provide both non-empty `config.configurable` and
|
|
24
|
+
`context`, mirrored either input into the other representation, and merged
|
|
25
|
+
assistant configuration into run configuration without discarding nested
|
|
26
|
+
defaults.
|
|
27
|
+
- Made inherited host environment keys, including explicit empty strings,
|
|
28
|
+
authoritative over config and CLI dotenv sources.
|
|
29
|
+
- Parsed each dotenv source independently with strict malformed-file handling,
|
|
30
|
+
and distinguished valueless `KEY` from explicit empty `KEY=`.
|
|
31
|
+
- Started `worker` and `scheduler` in fresh child processes so their settings
|
|
32
|
+
are built after the resolved environment is installed.
|
|
33
|
+
- Added bounded signal forwarding and descendant-process cleanup for `serve`,
|
|
34
|
+
`worker`, and `scheduler` across supported platforms.
|
|
35
|
+
- Kept version, help, and Dockerfile rendering independent of runtime settings
|
|
36
|
+
validation.
|
|
37
|
+
- Fell back to an ASCII CLI banner when a legacy Windows console cannot encode
|
|
38
|
+
the Unicode banner.
|
|
39
|
+
|
|
40
|
+
### Upgrade notes
|
|
41
|
+
|
|
42
|
+
- Redis workers now execute up to `10` jobs concurrently by default. Set
|
|
43
|
+
`WORKER_CONCURRENT_JOBS=1` to retain the previous serial behavior.
|
|
44
|
+
- Clients must not send both non-empty `config.configurable` and `context` in
|
|
45
|
+
one assistant or run request; such requests now return HTTP 400. Prefer
|
|
46
|
+
`context` for new integrations.
|
|
47
|
+
- For `dev`, `serve`, `worker`, and `scheduler`, dotenv interpolation is
|
|
48
|
+
supported only against the inherited environment and earlier bindings in the
|
|
49
|
+
same physical file.
|
|
50
|
+
- For those host runtime commands, missing, malformed, and non-UTF-8 dotenv
|
|
51
|
+
sources fail closed with status 2 before a runtime child starts.
|
|
52
|
+
- Dependency resolution now requires SQLAlchemy 2.0.12 or newer, LangGraph
|
|
53
|
+
1.0.6 or newer, LangChain Core 1.2.5 or newer, and MCP 1.27.1 through the 1.x
|
|
54
|
+
series. `python-dotenv` 1.0 through 1.2 is now a direct dependency.
|
|
55
|
+
|
|
56
|
+
## 0.2.1 - 2026-07-14
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- Preserved empty JSON arrays in Redis thread-stream events by avoiding a Lua
|
|
61
|
+
cjson decode/encode round trip, while keeping generated envelope fields
|
|
62
|
+
authoritative.
|
|
63
|
+
- Mirrored completed tool, human, and system messages to `messages-tuple` when
|
|
64
|
+
requested so LangGraph SDK clients receive tool results before final-answer
|
|
65
|
+
streaming completes.
|
|
66
|
+
|
|
67
|
+
### Upgrade notes
|
|
68
|
+
|
|
69
|
+
- No schema or configuration migration is required from 0.2.0.
|
|
70
|
+
|
|
71
|
+
## 0.2.0 - 2026-07-12
|
|
72
|
+
|
|
73
|
+
### Highlights
|
|
74
|
+
|
|
75
|
+
- Expanded the Crons API to align its request, response, filtering, sorting,
|
|
76
|
+
selection, and lifecycle behavior with the LangGraph Platform contract.
|
|
77
|
+
- Moved Redis-worker run and protocol event persistence from SQL to bounded
|
|
78
|
+
Redis Streams, removing metadata-database writes from the streaming hot path.
|
|
79
|
+
- Preserved UTF-8 output across SSE, wait, and A2A JSON responses while keeping
|
|
80
|
+
active thread event retention bounded without dropping live events.
|
|
81
|
+
- Upgraded checkpoint integration to `langchain-oceanbase` 0.6.0.
|
|
82
|
+
|
|
83
|
+
### Upgrade notes
|
|
84
|
+
|
|
85
|
+
- Drain active Redis-worker runs before upgrading. Stream-event rows written to
|
|
86
|
+
SQL by earlier versions are not imported into Redis Streams.
|
|
87
|
+
- Redis stream replay is bounded by `REDIS_STREAM_MAXLEN` and
|
|
88
|
+
`REDIS_STREAM_TTL_SECONDS`; review these settings for long-running workloads.
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agentseek-api
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: AgentSeek API core runtime with OceanBase checkpoints.
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: aiomysql>=0.2.0
|
|
8
|
+
Requires-Dist: aiosqlite>=0.20.0
|
|
9
|
+
Requires-Dist: asyncpg>=0.29.0
|
|
10
|
+
Requires-Dist: cryptography>=45.0.0
|
|
11
|
+
Requires-Dist: fastapi>=0.110.1
|
|
12
|
+
Requires-Dist: greenlet>=3.1.0
|
|
13
|
+
Requires-Dist: langchain-anthropic>=1.0.0
|
|
14
|
+
Requires-Dist: langchain-core>=1.2.5
|
|
15
|
+
Requires-Dist: langchain-oceanbase==0.6.0
|
|
16
|
+
Requires-Dist: langchain-openai>=1.0.0
|
|
17
|
+
Requires-Dist: langchain>=0.3.9
|
|
18
|
+
Requires-Dist: langgraph-sdk>=0.3.5
|
|
19
|
+
Requires-Dist: langgraph>=1.0.6
|
|
20
|
+
Requires-Dist: mcp<2,>=1.27.1
|
|
21
|
+
Requires-Dist: pydantic-settings>=2.4.0
|
|
22
|
+
Requires-Dist: pydantic>=2.8.0
|
|
23
|
+
Requires-Dist: pymysql>=1.1.0
|
|
24
|
+
Requires-Dist: python-dotenv<1.3,>=1.0
|
|
25
|
+
Requires-Dist: redis>=5.0.0
|
|
26
|
+
Requires-Dist: scalar-fastapi>=1.0.3
|
|
27
|
+
Requires-Dist: sqlalchemy>=2.0.12
|
|
28
|
+
Requires-Dist: uvicorn>=0.30.0
|
|
29
|
+
Provides-Extra: embedded
|
|
30
|
+
Requires-Dist: langchain-oceanbase[pyseekdb]==0.6.0; extra == 'embedded'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
1
33
|
# AgentSeek API
|
|
2
34
|
|
|
3
35
|
**English** | [中文](README.zh-CN.md)
|
|
@@ -185,7 +217,7 @@ When the server starts it prints the banner and local URLs:
|
|
|
185
217
|
╠═╣│ ┬├┤ │││ │ ╚═╗├┤ ├┤ ├┴┐
|
|
186
218
|
╩ ╩└─┘└─┘┘└┘ ┴ ╚═╝└─┘└─┘┴ ┴
|
|
187
219
|
|
|
188
|
-
AgentSeek v0.2.
|
|
220
|
+
AgentSeek v0.2.2
|
|
189
221
|
|
|
190
222
|
- 🚀 API: http://localhost:2024
|
|
191
223
|
- 📚 Docs: http://localhost:2024/docs
|
|
@@ -260,7 +292,35 @@ When running from this repository, use `uv run agentseek-api ...`.
|
|
|
260
292
|
|
|
261
293
|
- `-c, --config PATH`: explicit `agentseek.json`, `langgraph.json`, or manifest
|
|
262
294
|
path
|
|
263
|
-
- `--env-file PATH`:
|
|
295
|
+
- `--env-file PATH`: host-runtime dotenv source
|
|
296
|
+
|
|
297
|
+
### Host runtime environment
|
|
298
|
+
|
|
299
|
+
For `dev`, `serve`, `worker`, and `scheduler`, direct assignments are applied in
|
|
300
|
+
this order:
|
|
301
|
+
|
|
302
|
+
1. the dotenv path named by config `env`;
|
|
303
|
+
2. the literal config `env` mapping and `auth.path`;
|
|
304
|
+
3. the CLI `--env-file`;
|
|
305
|
+
4. the environment inherited by `agentseek-api`.
|
|
306
|
+
|
|
307
|
+
The inherited environment is authoritative by key presence. This includes an
|
|
308
|
+
explicit empty value. A lower source can fill an absent key, but cannot replace
|
|
309
|
+
an inherited `KEY=`.
|
|
310
|
+
|
|
311
|
+
Each dotenv file is evaluated independently. It can reference the inherited
|
|
312
|
+
environment and earlier bindings in the same physical file; it cannot reference
|
|
313
|
+
a config mapping or another dotenv file. Later assignment does not recompute an
|
|
314
|
+
earlier interpolated value.
|
|
315
|
+
|
|
316
|
+
In dotenv syntax, a bare `KEY` is valid but contributes no assignment, while
|
|
317
|
+
`KEY=` contributes an explicit empty string. Missing files, invalid UTF-8, and
|
|
318
|
+
malformed syntax stop the command before a runtime child starts.
|
|
319
|
+
|
|
320
|
+
The CLI applies command-owned values after this merge: the selected config path
|
|
321
|
+
becomes `AGENTSEEK_GRAPHS`, and `dev` forces `STUDIO_AUTH_LOCAL_DEV=true`.
|
|
322
|
+
Host and port options are passed as child argv and do not rewrite environment
|
|
323
|
+
keys with similar names.
|
|
264
324
|
|
|
265
325
|
### Common usage
|
|
266
326
|
|
|
@@ -622,6 +682,8 @@ parent api build --config ./langgraph.json -t my-api:dev
|
|
|
622
682
|
- `REDIS_URL=redis://127.0.0.1:6379/0`
|
|
623
683
|
- `REDIS_RUN_QUEUE_KEY=agentseek:runs:pending`
|
|
624
684
|
- `REDIS_RUN_PROCESSING_KEY=agentseek:runs:processing`
|
|
685
|
+
- `WORKER_CONCURRENT_JOBS=10` bounds concurrently executing jobs in one
|
|
686
|
+
worker process
|
|
625
687
|
- `REDIS_WORKER_LOCK_KEY=agentseek:worker:active`
|
|
626
688
|
- `REDIS_WORKER_LOCK_TTL_SECONDS=30`
|
|
627
689
|
- `REDIS_STREAM_MAXLEN=10000`
|
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: agentseek-api
|
|
3
|
-
Version: 0.2.1
|
|
4
|
-
Summary: AgentSeek API core runtime with OceanBase checkpoints.
|
|
5
|
-
License-File: LICENSE
|
|
6
|
-
Requires-Python: >=3.12
|
|
7
|
-
Requires-Dist: aiomysql>=0.2.0
|
|
8
|
-
Requires-Dist: aiosqlite>=0.20.0
|
|
9
|
-
Requires-Dist: asyncpg>=0.29.0
|
|
10
|
-
Requires-Dist: cryptography>=45.0.0
|
|
11
|
-
Requires-Dist: fastapi>=0.110.1
|
|
12
|
-
Requires-Dist: greenlet>=3.1.0
|
|
13
|
-
Requires-Dist: langchain-anthropic>=1.0.0
|
|
14
|
-
Requires-Dist: langchain-core>=1.0.0
|
|
15
|
-
Requires-Dist: langchain-oceanbase==0.6.0
|
|
16
|
-
Requires-Dist: langchain-openai>=1.0.0
|
|
17
|
-
Requires-Dist: langchain>=0.3.9
|
|
18
|
-
Requires-Dist: langgraph-sdk>=0.3.5
|
|
19
|
-
Requires-Dist: langgraph>=1.0.3
|
|
20
|
-
Requires-Dist: mcp>=1.27.1
|
|
21
|
-
Requires-Dist: pydantic-settings>=2.4.0
|
|
22
|
-
Requires-Dist: pydantic>=2.8.0
|
|
23
|
-
Requires-Dist: pymysql>=1.1.0
|
|
24
|
-
Requires-Dist: redis>=5.0.0
|
|
25
|
-
Requires-Dist: scalar-fastapi>=1.0.3
|
|
26
|
-
Requires-Dist: sqlalchemy>=2.0.0
|
|
27
|
-
Requires-Dist: uvicorn>=0.30.0
|
|
28
|
-
Provides-Extra: embedded
|
|
29
|
-
Requires-Dist: langchain-oceanbase[pyseekdb]==0.6.0; extra == 'embedded'
|
|
30
|
-
Description-Content-Type: text/markdown
|
|
31
|
-
|
|
32
1
|
# AgentSeek API
|
|
33
2
|
|
|
34
3
|
**English** | [中文](README.zh-CN.md)
|
|
@@ -216,7 +185,7 @@ When the server starts it prints the banner and local URLs:
|
|
|
216
185
|
╠═╣│ ┬├┤ │││ │ ╚═╗├┤ ├┤ ├┴┐
|
|
217
186
|
╩ ╩└─┘└─┘┘└┘ ┴ ╚═╝└─┘└─┘┴ ┴
|
|
218
187
|
|
|
219
|
-
AgentSeek v0.2.
|
|
188
|
+
AgentSeek v0.2.2
|
|
220
189
|
|
|
221
190
|
- 🚀 API: http://localhost:2024
|
|
222
191
|
- 📚 Docs: http://localhost:2024/docs
|
|
@@ -291,7 +260,35 @@ When running from this repository, use `uv run agentseek-api ...`.
|
|
|
291
260
|
|
|
292
261
|
- `-c, --config PATH`: explicit `agentseek.json`, `langgraph.json`, or manifest
|
|
293
262
|
path
|
|
294
|
-
- `--env-file PATH`:
|
|
263
|
+
- `--env-file PATH`: host-runtime dotenv source
|
|
264
|
+
|
|
265
|
+
### Host runtime environment
|
|
266
|
+
|
|
267
|
+
For `dev`, `serve`, `worker`, and `scheduler`, direct assignments are applied in
|
|
268
|
+
this order:
|
|
269
|
+
|
|
270
|
+
1. the dotenv path named by config `env`;
|
|
271
|
+
2. the literal config `env` mapping and `auth.path`;
|
|
272
|
+
3. the CLI `--env-file`;
|
|
273
|
+
4. the environment inherited by `agentseek-api`.
|
|
274
|
+
|
|
275
|
+
The inherited environment is authoritative by key presence. This includes an
|
|
276
|
+
explicit empty value. A lower source can fill an absent key, but cannot replace
|
|
277
|
+
an inherited `KEY=`.
|
|
278
|
+
|
|
279
|
+
Each dotenv file is evaluated independently. It can reference the inherited
|
|
280
|
+
environment and earlier bindings in the same physical file; it cannot reference
|
|
281
|
+
a config mapping or another dotenv file. Later assignment does not recompute an
|
|
282
|
+
earlier interpolated value.
|
|
283
|
+
|
|
284
|
+
In dotenv syntax, a bare `KEY` is valid but contributes no assignment, while
|
|
285
|
+
`KEY=` contributes an explicit empty string. Missing files, invalid UTF-8, and
|
|
286
|
+
malformed syntax stop the command before a runtime child starts.
|
|
287
|
+
|
|
288
|
+
The CLI applies command-owned values after this merge: the selected config path
|
|
289
|
+
becomes `AGENTSEEK_GRAPHS`, and `dev` forces `STUDIO_AUTH_LOCAL_DEV=true`.
|
|
290
|
+
Host and port options are passed as child argv and do not rewrite environment
|
|
291
|
+
keys with similar names.
|
|
295
292
|
|
|
296
293
|
### Common usage
|
|
297
294
|
|
|
@@ -653,6 +650,8 @@ parent api build --config ./langgraph.json -t my-api:dev
|
|
|
653
650
|
- `REDIS_URL=redis://127.0.0.1:6379/0`
|
|
654
651
|
- `REDIS_RUN_QUEUE_KEY=agentseek:runs:pending`
|
|
655
652
|
- `REDIS_RUN_PROCESSING_KEY=agentseek:runs:processing`
|
|
653
|
+
- `WORKER_CONCURRENT_JOBS=10` bounds concurrently executing jobs in one
|
|
654
|
+
worker process
|
|
656
655
|
- `REDIS_WORKER_LOCK_KEY=agentseek:worker:active`
|
|
657
656
|
- `REDIS_WORKER_LOCK_TTL_SECONDS=30`
|
|
658
657
|
- `REDIS_STREAM_MAXLEN=10000`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "agentseek-api"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "AgentSeek API core runtime with OceanBase checkpoints."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -9,22 +9,23 @@ dependencies = [
|
|
|
9
9
|
"uvicorn>=0.30.0",
|
|
10
10
|
"pydantic>=2.8.0",
|
|
11
11
|
"pydantic-settings>=2.4.0",
|
|
12
|
-
"sqlalchemy>=2.0.
|
|
12
|
+
"sqlalchemy>=2.0.12",
|
|
13
13
|
"greenlet>=3.1.0",
|
|
14
14
|
"asyncpg>=0.29.0",
|
|
15
15
|
"aiomysql>=0.2.0",
|
|
16
16
|
"aiosqlite>=0.20.0",
|
|
17
17
|
"redis>=5.0.0",
|
|
18
|
-
"langgraph>=1.0.
|
|
18
|
+
"langgraph>=1.0.6",
|
|
19
19
|
"langgraph-sdk>=0.3.5",
|
|
20
|
-
"langchain-core>=1.
|
|
20
|
+
"langchain-core>=1.2.5",
|
|
21
21
|
"langchain-openai>=1.0.0",
|
|
22
22
|
"langchain-anthropic>=1.0.0",
|
|
23
23
|
"langchain-oceanbase==0.6.0",
|
|
24
24
|
"cryptography>=45.0.0",
|
|
25
25
|
"pymysql>=1.1.0",
|
|
26
26
|
"langchain>=0.3.9",
|
|
27
|
-
"mcp>=1.27.1",
|
|
27
|
+
"mcp>=1.27.1,<2",
|
|
28
|
+
"python-dotenv>=1.0,<1.3",
|
|
28
29
|
"scalar-fastapi>=1.0.3",
|
|
29
30
|
]
|
|
30
31
|
|
|
@@ -39,7 +40,7 @@ agentseek-api = "agentseek_api.cli:main"
|
|
|
39
40
|
[dependency-groups]
|
|
40
41
|
dev = [
|
|
41
42
|
"pytest>=8.0.0",
|
|
42
|
-
"pytest-asyncio>=0.23.
|
|
43
|
+
"pytest-asyncio>=0.23.5",
|
|
43
44
|
"pytest-cov>=5.0.0",
|
|
44
45
|
"httpx>=0.27.0",
|
|
45
46
|
"ruff>=0.6.0",
|
|
@@ -18,13 +18,23 @@ SEEKDB_DOCKER_IMAGE="${SEEKDB_DOCKER_IMAGE:-}"
|
|
|
18
18
|
OCEANBASE_DOCKER_MODE="${OCEANBASE_DOCKER_MODE:-mini}"
|
|
19
19
|
STATE_DIR="${STATE_DIR:-$ROOT_DIR/.tmp/redis-runtime}"
|
|
20
20
|
RESUME_STATE_FILE="$STATE_DIR/resume-state.json"
|
|
21
|
+
SHUTDOWN_STATE_FILE=""
|
|
22
|
+
REDIS_WORKER_LOCK_KEY="${REDIS_WORKER_LOCK_KEY:-agentseek:worker:active}"
|
|
23
|
+
WORKER_CONCURRENT_JOBS="${WORKER_CONCURRENT_JOBS:-10}"
|
|
21
24
|
|
|
22
25
|
cleanup() {
|
|
23
|
-
|
|
26
|
+
local status=$?
|
|
27
|
+
|
|
28
|
+
trap - EXIT
|
|
29
|
+
stop_worker >/dev/null 2>&1 || true
|
|
24
30
|
docker rm -f "$API_CONTAINER" >/dev/null 2>&1 || true
|
|
25
31
|
docker rm -f "$REDIS_CONTAINER" >/dev/null 2>&1 || true
|
|
26
32
|
docker rm -f "$BACKEND_CONTAINER" >/dev/null 2>&1 || true
|
|
27
33
|
docker network rm "$NETWORK_NAME" >/dev/null 2>&1 || true
|
|
34
|
+
if [[ -n "$SHUTDOWN_STATE_FILE" ]]; then
|
|
35
|
+
rm -f "$SHUTDOWN_STATE_FILE" || true
|
|
36
|
+
fi
|
|
37
|
+
exit "$status"
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
print_logs() {
|
|
@@ -197,19 +207,70 @@ PY
|
|
|
197
207
|
}
|
|
198
208
|
|
|
199
209
|
stop_worker() {
|
|
200
|
-
|
|
201
|
-
|
|
210
|
+
local timeout="${1:-10}"
|
|
211
|
+
local container_id
|
|
212
|
+
local running
|
|
213
|
+
local status
|
|
214
|
+
|
|
215
|
+
if container_id="$(docker ps -aq --filter "name=^/${WORKER_CONTAINER}$")"; then
|
|
216
|
+
:
|
|
217
|
+
else
|
|
218
|
+
status=$?
|
|
219
|
+
print_logs >&2
|
|
220
|
+
return "$status"
|
|
221
|
+
fi
|
|
222
|
+
if [[ -z "$container_id" ]]; then
|
|
223
|
+
return 0
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
if running="$(docker inspect --format '{{.State.Running}}' "$container_id")"; then
|
|
227
|
+
:
|
|
228
|
+
else
|
|
229
|
+
status=$?
|
|
230
|
+
print_logs >&2
|
|
231
|
+
return "$status"
|
|
232
|
+
fi
|
|
233
|
+
if [[ "$running" == "true" ]]; then
|
|
234
|
+
if docker stop -t "$timeout" "$WORKER_CONTAINER" >/dev/null; then
|
|
235
|
+
:
|
|
236
|
+
else
|
|
237
|
+
status=$?
|
|
238
|
+
print_logs >&2
|
|
239
|
+
return "$status"
|
|
240
|
+
fi
|
|
241
|
+
fi
|
|
242
|
+
if docker rm -f "$WORKER_CONTAINER" >/dev/null; then
|
|
243
|
+
:
|
|
244
|
+
else
|
|
245
|
+
status=$?
|
|
246
|
+
print_logs >&2
|
|
247
|
+
return "$status"
|
|
248
|
+
fi
|
|
249
|
+
if docker exec "$REDIS_CONTAINER" redis-cli DEL "$REDIS_WORKER_LOCK_KEY" >/dev/null; then
|
|
250
|
+
return 0
|
|
251
|
+
else
|
|
252
|
+
status=$?
|
|
253
|
+
print_logs >&2
|
|
254
|
+
return "$status"
|
|
202
255
|
fi
|
|
203
|
-
docker rm -f "$WORKER_CONTAINER" >/dev/null 2>&1 || true
|
|
204
256
|
}
|
|
205
257
|
|
|
206
258
|
start_worker() {
|
|
207
|
-
|
|
208
|
-
|
|
259
|
+
local status
|
|
260
|
+
|
|
261
|
+
if stop_worker; then
|
|
262
|
+
:
|
|
263
|
+
else
|
|
264
|
+
status=$?
|
|
265
|
+
return "$status"
|
|
266
|
+
fi
|
|
267
|
+
if docker run -d \
|
|
209
268
|
--name "$WORKER_CONTAINER" \
|
|
210
269
|
--network "$NETWORK_NAME" \
|
|
211
270
|
-e EXECUTOR_BACKEND=redis \
|
|
212
271
|
-e REDIS_URL="redis://${REDIS_CONTAINER}:6379/0" \
|
|
272
|
+
-e REDIS_WORKER_LOCK_KEY="${REDIS_WORKER_LOCK_KEY}" \
|
|
273
|
+
-e WORKER_CONCURRENT_JOBS="${WORKER_CONCURRENT_JOBS}" \
|
|
213
274
|
-e SEEKDB_URL="${SEEKDB_URL}" \
|
|
214
275
|
-e OCEANBASE_HOST="${BACKEND_CONTAINER}" \
|
|
215
276
|
-e OCEANBASE_PORT="${OCEANBASE_PORT}" \
|
|
@@ -217,7 +278,28 @@ start_worker() {
|
|
|
217
278
|
-e OCEANBASE_PASSWORD="${OCEANBASE_PASSWORD}" \
|
|
218
279
|
-e OCEANBASE_DB_NAME="${OCEANBASE_DB_NAME}" \
|
|
219
280
|
"$IMAGE_TAG" \
|
|
220
|
-
python -m agentseek_api.cli worker >/dev/null
|
|
281
|
+
python -m agentseek_api.cli worker >/dev/null; then
|
|
282
|
+
return 0
|
|
283
|
+
else
|
|
284
|
+
status=$?
|
|
285
|
+
print_logs >&2
|
|
286
|
+
return "$status"
|
|
287
|
+
fi
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
run_probe() {
|
|
291
|
+
local status
|
|
292
|
+
|
|
293
|
+
if uv run python scripts/verify_worker_concurrency.py \
|
|
294
|
+
--base-url "$BASE_URL" \
|
|
295
|
+
--redis-url "redis://127.0.0.1:${REDIS_HOST_PORT}/0" \
|
|
296
|
+
"$@"; then
|
|
297
|
+
return 0
|
|
298
|
+
else
|
|
299
|
+
status=$?
|
|
300
|
+
print_logs >&2
|
|
301
|
+
return "$status"
|
|
302
|
+
fi
|
|
221
303
|
}
|
|
222
304
|
|
|
223
305
|
start_backend() {
|
|
@@ -259,6 +341,7 @@ set_backend_defaults "$SEEKDB_DOCKER_BACKEND"
|
|
|
259
341
|
docker network rm "$NETWORK_NAME" >/dev/null 2>&1 || true
|
|
260
342
|
docker network create "$NETWORK_NAME" >/dev/null
|
|
261
343
|
mkdir -p "$STATE_DIR"
|
|
344
|
+
SHUTDOWN_STATE_FILE="$(mktemp "$STATE_DIR/shutdown-state.XXXXXX")"
|
|
262
345
|
|
|
263
346
|
uv run agentseek-api build --config "$CONFIG_PATH" -t "$IMAGE_TAG"
|
|
264
347
|
|
|
@@ -274,7 +357,10 @@ docker run -d \
|
|
|
274
357
|
wait_for_redis
|
|
275
358
|
|
|
276
359
|
if ! AGENTSEEK_TEST_REDIS_URL="redis://127.0.0.1:${REDIS_HOST_PORT}/0" \
|
|
277
|
-
uv run pytest
|
|
360
|
+
uv run pytest \
|
|
361
|
+
tests/integration/test_live_redis_stream_persistence.py \
|
|
362
|
+
tests/integration/test_live_redis_queue.py \
|
|
363
|
+
-q; then
|
|
278
364
|
print_logs
|
|
279
365
|
exit 1
|
|
280
366
|
fi
|
|
@@ -319,3 +405,21 @@ if ! uv run python scripts/verify_docker_api.py --base-url "$BASE_URL" --mode re
|
|
|
319
405
|
print_logs
|
|
320
406
|
exit 1
|
|
321
407
|
fi
|
|
408
|
+
|
|
409
|
+
WORKER_CONCURRENCY_SUITE_STARTED_SECONDS=$SECONDS
|
|
410
|
+
echo "worker concurrency probe suite started" >&2
|
|
411
|
+
|
|
412
|
+
WORKER_CONCURRENT_JOBS=10
|
|
413
|
+
start_worker
|
|
414
|
+
run_probe --mode fanout
|
|
415
|
+
|
|
416
|
+
WORKER_CONCURRENT_JOBS=2
|
|
417
|
+
start_worker
|
|
418
|
+
run_probe --mode bounded
|
|
419
|
+
run_probe --mode failure
|
|
420
|
+
run_probe --mode shutdown-seed >"$SHUTDOWN_STATE_FILE"
|
|
421
|
+
stop_worker 1
|
|
422
|
+
start_worker
|
|
423
|
+
run_probe --mode shutdown-check --state-file "$SHUTDOWN_STATE_FILE"
|
|
424
|
+
|
|
425
|
+
echo "worker concurrency probe suite completed in $((SECONDS - WORKER_CONCURRENCY_SUITE_STARTED_SECONDS))s" >&2
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Verify host environment resolution with all direct dependency floors."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
import tempfile
|
|
9
|
+
import tomllib
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> None:
|
|
14
|
+
repository = Path(__file__).resolve().parents[1]
|
|
15
|
+
project = tomllib.loads((repository / "pyproject.toml").read_text(encoding="utf-8"))
|
|
16
|
+
requirements = list(project["project"]["dependencies"])
|
|
17
|
+
requirements.append("pytest>=8.0.0")
|
|
18
|
+
requirements.append("pytest-asyncio>=0.23.5")
|
|
19
|
+
|
|
20
|
+
with tempfile.TemporaryDirectory(prefix="agentseek-minimum-") as directory:
|
|
21
|
+
environment = Path(directory) / ".venv"
|
|
22
|
+
subprocess.run(
|
|
23
|
+
[
|
|
24
|
+
"uv",
|
|
25
|
+
"venv",
|
|
26
|
+
"--python",
|
|
27
|
+
"3.12",
|
|
28
|
+
str(environment),
|
|
29
|
+
],
|
|
30
|
+
check=True,
|
|
31
|
+
)
|
|
32
|
+
python = environment / (
|
|
33
|
+
"Scripts/python.exe" if sys.platform == "win32" else "bin/python"
|
|
34
|
+
)
|
|
35
|
+
subprocess.run(
|
|
36
|
+
[
|
|
37
|
+
"uv",
|
|
38
|
+
"pip",
|
|
39
|
+
"install",
|
|
40
|
+
"--python",
|
|
41
|
+
str(python),
|
|
42
|
+
"--resolution",
|
|
43
|
+
"lowest-direct",
|
|
44
|
+
*requirements,
|
|
45
|
+
],
|
|
46
|
+
check=True,
|
|
47
|
+
)
|
|
48
|
+
subprocess.run(
|
|
49
|
+
[
|
|
50
|
+
"uv",
|
|
51
|
+
"pip",
|
|
52
|
+
"install",
|
|
53
|
+
"--python",
|
|
54
|
+
str(python),
|
|
55
|
+
"--no-deps",
|
|
56
|
+
"-e",
|
|
57
|
+
str(repository),
|
|
58
|
+
],
|
|
59
|
+
check=True,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
version = subprocess.run(
|
|
63
|
+
[
|
|
64
|
+
str(python),
|
|
65
|
+
"-c",
|
|
66
|
+
(
|
|
67
|
+
"import importlib.metadata; "
|
|
68
|
+
"print(importlib.metadata.version('python-dotenv'))"
|
|
69
|
+
),
|
|
70
|
+
],
|
|
71
|
+
check=True,
|
|
72
|
+
capture_output=True,
|
|
73
|
+
text=True,
|
|
74
|
+
)
|
|
75
|
+
assert version.stdout.strip() == "1.0.0"
|
|
76
|
+
|
|
77
|
+
cli_env = dict(os.environ)
|
|
78
|
+
cli_env.pop("PYTHONPATH", None)
|
|
79
|
+
cli_env["PORT"] = "not-an-integer"
|
|
80
|
+
version_result = subprocess.run(
|
|
81
|
+
[str(python), "-m", "agentseek_api.cli", "version"],
|
|
82
|
+
cwd=repository,
|
|
83
|
+
env=cli_env,
|
|
84
|
+
check=True,
|
|
85
|
+
capture_output=True,
|
|
86
|
+
text=True,
|
|
87
|
+
)
|
|
88
|
+
expected_version = project["project"]["version"]
|
|
89
|
+
assert version_result.stdout.strip() == f"agentseek-api {expected_version}"
|
|
90
|
+
|
|
91
|
+
test_env = dict(os.environ)
|
|
92
|
+
test_env.pop("PYTHONPATH", None)
|
|
93
|
+
subprocess.run(
|
|
94
|
+
[
|
|
95
|
+
str(python),
|
|
96
|
+
"-m",
|
|
97
|
+
"pytest",
|
|
98
|
+
"tests/unit/test_dotenv_adapter.py",
|
|
99
|
+
"tests/unit/test_runtime_environment.py",
|
|
100
|
+
"-q",
|
|
101
|
+
],
|
|
102
|
+
cwd=repository,
|
|
103
|
+
env=test_env,
|
|
104
|
+
check=True,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
main()
|