selectools 1.0.1__tar.gz → 1.1.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.
- {selectools-1.0.1/src/selectools.egg-info → selectools-1.1.0}/PKG-INFO +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/pyproject.toml +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/__init__.py +2 -1
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/_provider_caller.py +77 -27
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/config.py +8 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/config_groups.py +28 -1
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/core.py +315 -104
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/cache.py +4 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/anthropic.py +0 -10
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/cohere.py +0 -10
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/gemini.py +0 -10
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/openai.py +0 -10
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/provider.py +6 -2
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/pipeline.py +68 -2
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/_openai_compat.py +45 -8
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/anthropic_provider.py +131 -108
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/gemini_provider.py +103 -127
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/openai_provider.py +2 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/sessions.py +37 -104
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/structured.py +19 -1
- {selectools-1.0.1 → selectools-1.1.0/src/selectools.egg-info}/PKG-INFO +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_bug_hunt_batch1_core.py +0 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_bug_hunt_batch1_security.py +0 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_bug_hunt_batch1_tools.py +1 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_bug_hunt_regression.py +1 -10
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_checkpoint_postgres.py +3 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_coherence.py +1 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_concurrency_smoke.py +1 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_consolidation_regression.py +2 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_coverage_orchestration.py +7 -14
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_document_loaders_extended.py +0 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_e2e_multimodal.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_entity_memory.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals.py +0 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_advanced.py +2 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_cli.py +5 -7
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_e2e.py +3 -11
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_final.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_hardening.py +0 -8
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_html_report.py +0 -6
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_new_evaluators.py +2 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_ralph_bugs.py +2 -7
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_release.py +1 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_serve.py +0 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_v017_features.py +1 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_evals_v0191.py +1 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_features_in_graph.py +7 -12
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_final_coverage_a.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_final_coverage_b.py +10 -14
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_guardrails.py +100 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_hardening.py +1 -7
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge.py +1 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_backend.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_backend_redis.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_backend_supabase.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_graph.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_stores.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_stores_error_handling.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_mcp.py +2 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_mcp_coverage.py +1 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_memory_boundary.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_memory_integration.py +0 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_multi_agent_edge_cases.py +2 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_multimodal.py +0 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_checkpoint.py +4 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_evals.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_graph.py +3 -9
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_integration.py +0 -9
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_supervisor.py +5 -6
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_patterns.py +5 -11
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_phase1_design_patterns.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_pipeline.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_pipeline_coverage.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_prompt_compression.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_property_based.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_remaining_coverage.py +4 -9
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_results.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_security.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_semantic_cache.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_serve_app_coverage.py +7 -11
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_serve_cli.py +0 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions_dynamodb.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions_edge_cases.py +1 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions_redis.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions_supabase.py +4 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_starlette_app.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_structured_config.py +0 -10
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_structured_tool_results.py +1 -1
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_summarize_on_trim.py +2 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_terminal_actions.py +1 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_token_estimation.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_trace.py +0 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_trace_html.py +0 -4
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_trace_store.py +1 -5
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_v016_regression.py +0 -2
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_v019_features.py +2 -3
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_visual_builder.py +3 -17
- {selectools-1.0.1 → selectools-1.1.0}/LICENSE +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/README.md +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/setup.cfg +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/_async_utils.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/_json_utils.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/_ssrf.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/_time.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/a2a/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/a2a/client.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/a2a/server.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/a2a/types.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/_lifecycle.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/_memory_manager.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/_planning.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/agent/_tool_executor.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/analytics.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/audit.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/cache_redis.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/cache_semantic.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/cancellation.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/checkpoint_postgres.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/coherence.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/compose.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/embeddings/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/entity_memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/env.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/__main__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/badge.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/dataset.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/evaluators.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/generator.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/history.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/html.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/junit.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/llm_evaluators.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/pairwise.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/regression.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/report.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/serve.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/snapshot.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/suite.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/templates.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/evals/types.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/exceptions.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/base.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/format.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/injection.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/length.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/pii.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/topic.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/guardrails/toxicity.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge_backends.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge_graph.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge_sanitizers.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge_store_redis.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/knowledge_store_supabase.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/loop_detection.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/_loop.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/bridge.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/client.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/config.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/multi.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/mcp/server.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/models.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/observe/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/observe/langfuse.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/observe/otel.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/observe/trace_store.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/checkpoint.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/graph.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/node.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/state.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/orchestration/supervisor.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/parser.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/patterns/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/patterns/debate.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/patterns/plan_and_execute.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/patterns/reflective.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/patterns/team_lead.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/pending.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/pipeline.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/policy.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/pricing.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/prompt.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/azure_openai_provider.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/base.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/fallback.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/litellm_provider.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/ollama_provider.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/router.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/providers/stubs.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/bm25.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/chunking.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/hybrid.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/loaders.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/reranker.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/chroma.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/faiss.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/pgvector.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/pinecone.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/qdrant.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/stores/sqlite.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/rag/vector_store.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/results.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/scheduler.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/security.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/_starlette_app.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/_static/builder.css +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/_static/builder.html +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/_static/builder.js +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/api.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/app.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/builder.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/cli.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/models.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/serve/playground.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/stability.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/code_reviewer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/customer_support.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/data_analyst.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/rag_chatbot.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/templates/research_assistant.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/token_estimation.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/browser_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/calculator_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/code_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/data_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/datetime_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/db_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/discord_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/email_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/file_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/github_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/image_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/linear_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/memory_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/notion_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/pdf_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/reasoning_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/s3_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/search_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/slack_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/text_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/toolbox/web_tools.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/tools/__init__.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/tools/base.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/tools/decorators.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/tools/loader.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/tools/registry.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/trace.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/types.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/unified_memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools/usage.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools.egg-info/SOURCES.txt +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools.egg-info/dependency_links.txt +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools.egg-info/entry_points.txt +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools.egg-info/requires.txt +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/src/selectools.egg-info/top_level.txt +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_a2a.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_agent_api.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_agent_hitl.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_approval_gate.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_architecture.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_async_observers.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_audit.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_bake_window_hunt.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_budget.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_cache.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_cache_redis.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_cancellation.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_conversation_branching.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_e2e_langfuse_observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_e2e_otel_observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_e2e_v0_21_0_apps.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_e2e_v0_21_0_simulations.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_env.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_guardrails_injection.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_sanitizers.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_store_redis.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_knowledge_store_supabase.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_langfuse_observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_loop_detection.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_memory_async.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_model_switching.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_e2e.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_orchestration_primitives.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_otel_observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_parser.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_pending.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_pending_redis_smoke.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_policy.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_prompt.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_reasoning_strategy.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_routing_mode.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_scheduler.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_sessions_mongo.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_simple_observer.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_simulation_evals.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_ssrf.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_stability.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_structured.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_templates_coverage.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_time.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_tool_caching.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_tool_result_compression.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_unified_memory.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_unified_memory_config.py +0 -0
- {selectools-1.0.1 → selectools-1.1.0}/tests/test_yaml_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: selectools
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Production-ready Python framework for AI agents with multi-agent graphs, hybrid RAG, guardrails, audit logging, 50 evaluators, and a visual builder. Supports OpenAI, Anthropic, Gemini, Ollama. By NichevLabs.
|
|
5
5
|
Author-email: John Nichev <johnnichev@gmail.com>
|
|
6
6
|
Maintainer-email: NichevLabs <support@nichevlabs.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "selectools"
|
|
7
|
-
version = "1.0
|
|
7
|
+
version = "1.1.0"
|
|
8
8
|
description = "Production-ready Python framework for AI agents with multi-agent graphs, hybrid RAG, guardrails, audit logging, 50 evaluators, and a visual builder. Supports OpenAI, Anthropic, Gemini, Ollama. By NichevLabs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Public exports for the selectools package."""
|
|
2
2
|
|
|
3
|
-
__version__ = "1.0
|
|
3
|
+
__version__ = "1.1.0"
|
|
4
4
|
|
|
5
5
|
# Import submodules (lazy loading for optional dependencies)
|
|
6
6
|
from . import embeddings, evals, guardrails, models, observe, patterns, rag, toolbox
|
|
@@ -13,6 +13,7 @@ from .agent.config_groups import (
|
|
|
13
13
|
MemoryConfig,
|
|
14
14
|
RetryConfig,
|
|
15
15
|
SessionConfig,
|
|
16
|
+
StructuredOutputConfig,
|
|
16
17
|
SummarizeConfig,
|
|
17
18
|
ToolConfig,
|
|
18
19
|
TraceConfig,
|
|
@@ -6,7 +6,7 @@ import asyncio
|
|
|
6
6
|
import threading
|
|
7
7
|
import time
|
|
8
8
|
from concurrent.futures import ThreadPoolExecutor
|
|
9
|
-
from typing import TYPE_CHECKING, Callable, List, Optional, Tuple
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
|
|
10
10
|
|
|
11
11
|
# Module-level singleton for running sync provider calls in an async context.
|
|
12
12
|
# Creating a new ThreadPoolExecutor per call (inside a retry loop) wastes
|
|
@@ -50,8 +50,18 @@ class _ProviderCallerMixin:
|
|
|
50
50
|
stream_handler: Optional[Callable[[str], None]] = None,
|
|
51
51
|
trace: Optional[AgentTrace] = None,
|
|
52
52
|
run_id: Optional[str] = None,
|
|
53
|
+
response_format: Optional[Dict[str, Any]] = None,
|
|
54
|
+
tools_override: Optional[List[Any]] = None,
|
|
55
|
+
system_prompt_override: Optional[str] = None,
|
|
53
56
|
) -> Message:
|
|
54
57
|
call_start = time.time()
|
|
58
|
+
effective_tools = self.tools if tools_override is None else tools_override
|
|
59
|
+
effective_system_prompt = (
|
|
60
|
+
system_prompt_override if system_prompt_override is not None else self._system_prompt
|
|
61
|
+
)
|
|
62
|
+
provider_extra: Dict[str, Any] = {}
|
|
63
|
+
if response_format is not None:
|
|
64
|
+
provider_extra["response_format"] = response_format
|
|
55
65
|
|
|
56
66
|
cache_key: Optional[str] = None
|
|
57
67
|
if self.config.cache and not (
|
|
@@ -59,10 +69,11 @@ class _ProviderCallerMixin:
|
|
|
59
69
|
):
|
|
60
70
|
cache_key = CacheKeyBuilder.build(
|
|
61
71
|
model=self._effective_model,
|
|
62
|
-
system_prompt=
|
|
72
|
+
system_prompt=effective_system_prompt,
|
|
63
73
|
messages=self._history,
|
|
64
|
-
tools=
|
|
74
|
+
tools=effective_tools,
|
|
65
75
|
temperature=self.config.temperature,
|
|
76
|
+
response_format=response_format,
|
|
66
77
|
)
|
|
67
78
|
cached = self.config.cache.get(cache_key)
|
|
68
79
|
# Only treat a well-formed (Message, usage) pair as a cache hit;
|
|
@@ -82,7 +93,7 @@ class _ProviderCallerMixin:
|
|
|
82
93
|
run_id,
|
|
83
94
|
self._history,
|
|
84
95
|
self._effective_model,
|
|
85
|
-
|
|
96
|
+
effective_system_prompt,
|
|
86
97
|
)
|
|
87
98
|
self._notify_observers(
|
|
88
99
|
"on_llm_end",
|
|
@@ -122,12 +133,15 @@ class _ProviderCallerMixin:
|
|
|
122
133
|
run_id,
|
|
123
134
|
self._history,
|
|
124
135
|
self._effective_model,
|
|
125
|
-
|
|
136
|
+
effective_system_prompt,
|
|
126
137
|
)
|
|
127
138
|
|
|
128
139
|
if self.config.stream and getattr(self.provider, "supports_streaming", False):
|
|
129
140
|
response_text, streamed_tool_calls = self._streaming_call(
|
|
130
|
-
stream_handler=stream_handler
|
|
141
|
+
stream_handler=stream_handler,
|
|
142
|
+
response_format=response_format,
|
|
143
|
+
tools=effective_tools,
|
|
144
|
+
system_prompt=effective_system_prompt,
|
|
131
145
|
)
|
|
132
146
|
if run_id:
|
|
133
147
|
self._notify_observers("on_llm_end", run_id, response_text, None)
|
|
@@ -139,12 +153,13 @@ class _ProviderCallerMixin:
|
|
|
139
153
|
|
|
140
154
|
response_msg, usage_stats = self.provider.complete(
|
|
141
155
|
model=self._effective_model,
|
|
142
|
-
system_prompt=
|
|
156
|
+
system_prompt=effective_system_prompt,
|
|
143
157
|
messages=self._history,
|
|
144
|
-
tools=
|
|
158
|
+
tools=effective_tools,
|
|
145
159
|
temperature=self.config.temperature,
|
|
146
160
|
max_tokens=self.config.max_tokens,
|
|
147
161
|
timeout=self.config.request_timeout,
|
|
162
|
+
**provider_extra,
|
|
148
163
|
)
|
|
149
164
|
response_text = response_msg.content or ""
|
|
150
165
|
|
|
@@ -229,21 +244,29 @@ class _ProviderCallerMixin:
|
|
|
229
244
|
)
|
|
230
245
|
|
|
231
246
|
def _streaming_call(
|
|
232
|
-
self,
|
|
247
|
+
self,
|
|
248
|
+
stream_handler: Optional[Callable[[str], None]] = None,
|
|
249
|
+
response_format: Optional[Dict[str, Any]] = None,
|
|
250
|
+
tools: Optional[List[Any]] = None,
|
|
251
|
+
system_prompt: Optional[str] = None,
|
|
233
252
|
) -> Tuple[str, List[ToolCall]]:
|
|
234
253
|
if not getattr(self.provider, "supports_streaming", False):
|
|
235
254
|
raise ProviderError(f"Provider {self.provider.name} does not support streaming.")
|
|
236
255
|
|
|
256
|
+
provider_extra: Dict[str, Any] = {}
|
|
257
|
+
if response_format is not None:
|
|
258
|
+
provider_extra["response_format"] = response_format
|
|
237
259
|
aggregated: List[str] = []
|
|
238
260
|
tool_calls: List[ToolCall] = []
|
|
239
261
|
for chunk in self.provider.stream(
|
|
240
262
|
model=self._effective_model,
|
|
241
|
-
system_prompt=self._system_prompt,
|
|
263
|
+
system_prompt=self._system_prompt if system_prompt is None else system_prompt,
|
|
242
264
|
messages=self._history,
|
|
243
|
-
tools=self.tools,
|
|
265
|
+
tools=self.tools if tools is None else tools,
|
|
244
266
|
temperature=self.config.temperature,
|
|
245
267
|
max_tokens=self.config.max_tokens,
|
|
246
268
|
timeout=self.config.request_timeout,
|
|
269
|
+
**provider_extra,
|
|
247
270
|
):
|
|
248
271
|
if isinstance(chunk, str):
|
|
249
272
|
if chunk:
|
|
@@ -264,9 +287,19 @@ class _ProviderCallerMixin:
|
|
|
264
287
|
stream_handler: Optional[Callable[[str], None]] = None,
|
|
265
288
|
trace: Optional[AgentTrace] = None,
|
|
266
289
|
run_id: Optional[str] = None,
|
|
290
|
+
response_format: Optional[Dict[str, Any]] = None,
|
|
291
|
+
tools_override: Optional[List[Any]] = None,
|
|
292
|
+
system_prompt_override: Optional[str] = None,
|
|
267
293
|
) -> Message:
|
|
268
294
|
"""Async version of _call_provider with retry logic."""
|
|
269
295
|
call_start = time.time()
|
|
296
|
+
effective_tools = self.tools if tools_override is None else tools_override
|
|
297
|
+
effective_system_prompt = (
|
|
298
|
+
system_prompt_override if system_prompt_override is not None else self._system_prompt
|
|
299
|
+
)
|
|
300
|
+
provider_extra: Dict[str, Any] = {}
|
|
301
|
+
if response_format is not None:
|
|
302
|
+
provider_extra["response_format"] = response_format
|
|
270
303
|
|
|
271
304
|
cache_key: Optional[str] = None
|
|
272
305
|
if self.config.cache and not (
|
|
@@ -274,10 +307,11 @@ class _ProviderCallerMixin:
|
|
|
274
307
|
):
|
|
275
308
|
cache_key = CacheKeyBuilder.build(
|
|
276
309
|
model=self._effective_model,
|
|
277
|
-
system_prompt=
|
|
310
|
+
system_prompt=effective_system_prompt,
|
|
278
311
|
messages=self._history,
|
|
279
|
-
tools=
|
|
312
|
+
tools=effective_tools,
|
|
280
313
|
temperature=self.config.temperature,
|
|
314
|
+
response_format=response_format,
|
|
281
315
|
)
|
|
282
316
|
cached = self.config.cache.get(cache_key)
|
|
283
317
|
# Only treat a well-formed (Message, usage) pair as a cache hit;
|
|
@@ -297,14 +331,14 @@ class _ProviderCallerMixin:
|
|
|
297
331
|
run_id,
|
|
298
332
|
self._history,
|
|
299
333
|
self._effective_model,
|
|
300
|
-
|
|
334
|
+
effective_system_prompt,
|
|
301
335
|
)
|
|
302
336
|
await self._anotify_observers(
|
|
303
337
|
"on_llm_start",
|
|
304
338
|
run_id,
|
|
305
339
|
self._history,
|
|
306
340
|
self._effective_model,
|
|
307
|
-
|
|
341
|
+
effective_system_prompt,
|
|
308
342
|
)
|
|
309
343
|
self._notify_observers(
|
|
310
344
|
"on_llm_end",
|
|
@@ -357,19 +391,22 @@ class _ProviderCallerMixin:
|
|
|
357
391
|
run_id,
|
|
358
392
|
self._history,
|
|
359
393
|
self._effective_model,
|
|
360
|
-
|
|
394
|
+
effective_system_prompt,
|
|
361
395
|
)
|
|
362
396
|
await self._anotify_observers(
|
|
363
397
|
"on_llm_start",
|
|
364
398
|
run_id,
|
|
365
399
|
self._history,
|
|
366
400
|
self._effective_model,
|
|
367
|
-
|
|
401
|
+
effective_system_prompt,
|
|
368
402
|
)
|
|
369
403
|
|
|
370
404
|
if self.config.stream and getattr(self.provider, "supports_streaming", False):
|
|
371
405
|
response_text, streamed_tool_calls = await self._astreaming_call(
|
|
372
|
-
stream_handler=stream_handler
|
|
406
|
+
stream_handler=stream_handler,
|
|
407
|
+
response_format=response_format,
|
|
408
|
+
tools=effective_tools,
|
|
409
|
+
system_prompt=effective_system_prompt,
|
|
373
410
|
)
|
|
374
411
|
if run_id:
|
|
375
412
|
self._notify_observers("on_llm_end", run_id, response_text, None)
|
|
@@ -386,12 +423,13 @@ class _ProviderCallerMixin:
|
|
|
386
423
|
):
|
|
387
424
|
response_msg, usage_stats = await self.provider.acomplete(
|
|
388
425
|
model=self._effective_model,
|
|
389
|
-
system_prompt=
|
|
426
|
+
system_prompt=effective_system_prompt,
|
|
390
427
|
messages=self._history,
|
|
391
|
-
tools=
|
|
428
|
+
tools=effective_tools,
|
|
392
429
|
temperature=self.config.temperature,
|
|
393
430
|
max_tokens=self.config.max_tokens,
|
|
394
431
|
timeout=self.config.request_timeout,
|
|
432
|
+
**provider_extra,
|
|
395
433
|
)
|
|
396
434
|
response_text = response_msg.content or ""
|
|
397
435
|
else:
|
|
@@ -405,12 +443,13 @@ class _ProviderCallerMixin:
|
|
|
405
443
|
_get_async_provider_executor(),
|
|
406
444
|
lambda: self.provider.complete(
|
|
407
445
|
model=self._effective_model,
|
|
408
|
-
system_prompt=
|
|
446
|
+
system_prompt=effective_system_prompt,
|
|
409
447
|
messages=self._history,
|
|
410
|
-
tools=
|
|
448
|
+
tools=effective_tools,
|
|
411
449
|
temperature=self.config.temperature,
|
|
412
450
|
max_tokens=self.config.max_tokens,
|
|
413
451
|
timeout=self.config.request_timeout,
|
|
452
|
+
**provider_extra,
|
|
414
453
|
),
|
|
415
454
|
)
|
|
416
455
|
response_text = response_msg.content or ""
|
|
@@ -506,12 +545,21 @@ class _ProviderCallerMixin:
|
|
|
506
545
|
)
|
|
507
546
|
|
|
508
547
|
async def _astreaming_call(
|
|
509
|
-
self,
|
|
548
|
+
self,
|
|
549
|
+
stream_handler: Optional[Callable[[str], None]] = None,
|
|
550
|
+
response_format: Optional[Dict[str, Any]] = None,
|
|
551
|
+
tools: Optional[List[Any]] = None,
|
|
552
|
+
system_prompt: Optional[str] = None,
|
|
510
553
|
) -> Tuple[str, List[ToolCall]]:
|
|
511
554
|
"""Async version of _streaming_call."""
|
|
512
555
|
if not getattr(self.provider, "supports_streaming", False):
|
|
513
556
|
raise ProviderError(f"Provider {self.provider.name} does not support streaming.")
|
|
514
557
|
|
|
558
|
+
provider_extra: Dict[str, Any] = {}
|
|
559
|
+
if response_format is not None:
|
|
560
|
+
provider_extra["response_format"] = response_format
|
|
561
|
+
effective_tools = self.tools if tools is None else tools
|
|
562
|
+
effective_system_prompt = self._system_prompt if system_prompt is None else system_prompt
|
|
515
563
|
aggregated: List[str] = []
|
|
516
564
|
tool_calls: List[ToolCall] = []
|
|
517
565
|
|
|
@@ -521,12 +569,13 @@ class _ProviderCallerMixin:
|
|
|
521
569
|
async with aclosing(
|
|
522
570
|
self.provider.astream( # type: ignore[attr-defined]
|
|
523
571
|
model=self._effective_model,
|
|
524
|
-
system_prompt=
|
|
572
|
+
system_prompt=effective_system_prompt,
|
|
525
573
|
messages=self._history,
|
|
526
|
-
tools=
|
|
574
|
+
tools=effective_tools,
|
|
527
575
|
temperature=self.config.temperature,
|
|
528
576
|
max_tokens=self.config.max_tokens,
|
|
529
577
|
timeout=self.config.request_timeout,
|
|
578
|
+
**provider_extra,
|
|
530
579
|
)
|
|
531
580
|
) as stream:
|
|
532
581
|
async for chunk in stream:
|
|
@@ -546,12 +595,13 @@ class _ProviderCallerMixin:
|
|
|
546
595
|
with closing(
|
|
547
596
|
self.provider.stream(
|
|
548
597
|
model=self._effective_model,
|
|
549
|
-
system_prompt=
|
|
598
|
+
system_prompt=effective_system_prompt,
|
|
550
599
|
messages=self._history,
|
|
551
|
-
tools=
|
|
600
|
+
tools=effective_tools,
|
|
552
601
|
temperature=self.config.temperature,
|
|
553
602
|
max_tokens=self.config.max_tokens,
|
|
554
603
|
timeout=self.config.request_timeout,
|
|
604
|
+
**provider_extra,
|
|
555
605
|
)
|
|
556
606
|
) as stream:
|
|
557
607
|
for chunk in stream:
|
|
@@ -30,6 +30,7 @@ if TYPE_CHECKING:
|
|
|
30
30
|
MemoryConfig,
|
|
31
31
|
RetryConfig,
|
|
32
32
|
SessionConfig,
|
|
33
|
+
StructuredOutputConfig,
|
|
33
34
|
SummarizeConfig,
|
|
34
35
|
ToolConfig,
|
|
35
36
|
TraceConfig,
|
|
@@ -202,6 +203,8 @@ class AgentConfig:
|
|
|
202
203
|
budget: Optional["BudgetConfig"] = None
|
|
203
204
|
trace: Optional["TraceConfig"] = None
|
|
204
205
|
compress: Optional["CompressConfig"] = None
|
|
206
|
+
# Structured-output behavior (beta, v1.1). Group-only — no flat mirrors.
|
|
207
|
+
structured_output: Optional["StructuredOutputConfig"] = None
|
|
205
208
|
|
|
206
209
|
# -- Planning-as-config (ROADMAP P2). See PlanningConfig below and
|
|
207
210
|
# agent/_planning.py for the adapter. Self-contained: default None means
|
|
@@ -217,6 +220,7 @@ class AgentConfig:
|
|
|
217
220
|
MemoryConfig,
|
|
218
221
|
RetryConfig,
|
|
219
222
|
SessionConfig,
|
|
223
|
+
StructuredOutputConfig,
|
|
220
224
|
SummarizeConfig,
|
|
221
225
|
ToolConfig,
|
|
222
226
|
TraceConfig,
|
|
@@ -382,6 +386,10 @@ class AgentConfig:
|
|
|
382
386
|
keep_recent=self.compress_keep_recent,
|
|
383
387
|
)
|
|
384
388
|
|
|
389
|
+
self.structured_output = _unpack(self.structured_output, StructuredOutputConfig)
|
|
390
|
+
if self.structured_output is None:
|
|
391
|
+
self.structured_output = StructuredOutputConfig()
|
|
392
|
+
|
|
385
393
|
# -- Planning-as-config: auto-unpack dicts (for YAML / dict configs) --
|
|
386
394
|
if isinstance(self.planning, dict):
|
|
387
395
|
self.planning = PlanningConfig(**self.planning)
|
|
@@ -26,7 +26,7 @@ from __future__ import annotations
|
|
|
26
26
|
from dataclasses import dataclass, field
|
|
27
27
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
28
28
|
|
|
29
|
-
from ..stability import stable
|
|
29
|
+
from ..stability import beta, stable
|
|
30
30
|
|
|
31
31
|
if TYPE_CHECKING:
|
|
32
32
|
from ..cancellation import CancellationToken
|
|
@@ -174,6 +174,32 @@ class GuardrailsConfig:
|
|
|
174
174
|
output_screening_patterns: Optional[List[str]] = None
|
|
175
175
|
|
|
176
176
|
|
|
177
|
+
@beta
|
|
178
|
+
@dataclass
|
|
179
|
+
class StructuredOutputConfig:
|
|
180
|
+
"""Structured-output (``response_format``) behavior settings (beta, v1.1).
|
|
181
|
+
|
|
182
|
+
Attributes:
|
|
183
|
+
native: Use the provider's native structured-output mode (OpenAI
|
|
184
|
+
``json_schema``, Gemini ``response_json_schema``) when the provider
|
|
185
|
+
advertises support, instead of injecting a schema instruction into
|
|
186
|
+
the system prompt. Providers without native support keep the
|
|
187
|
+
prompt-injection + parse behavior unchanged. Default: True.
|
|
188
|
+
final_turn_only: Keep the schema out of tool-loop turns entirely.
|
|
189
|
+
The loop runs to convergence with no schema pressure (so tool
|
|
190
|
+
calling and the text ``ToolCallParser`` work normally), then one
|
|
191
|
+
extra synthesis call — with the schema applied and no tools —
|
|
192
|
+
produces the validated structured final answer. In ``astream()``
|
|
193
|
+
the synthesis JSON is delivered only via the terminal
|
|
194
|
+
``AgentResult`` (``.content`` / ``.parsed``), never leaked as
|
|
195
|
+
content chunks. Costs one extra provider call per run.
|
|
196
|
+
Default: False.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
native: bool = True
|
|
200
|
+
final_turn_only: bool = False
|
|
201
|
+
|
|
202
|
+
|
|
177
203
|
@stable
|
|
178
204
|
@dataclass
|
|
179
205
|
class SessionConfig:
|
|
@@ -323,6 +349,7 @@ __stability__ = "stable"
|
|
|
323
349
|
|
|
324
350
|
__all__ = [
|
|
325
351
|
"RetryConfig",
|
|
352
|
+
"StructuredOutputConfig",
|
|
326
353
|
"ToolConfig",
|
|
327
354
|
"CoherenceConfig",
|
|
328
355
|
"GuardrailsConfig",
|