agentbyte 0.34.0__tar.gz → 0.38.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.
- {agentbyte-0.34.0 → agentbyte-0.38.0}/CHANGELOG.md +89 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/PKG-INFO +3 -3
- {agentbyte-0.34.0 → agentbyte-0.38.0}/README.md +2 -2
- agentbyte-0.38.0/src/agentbyte/__about__.py +2 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/__init__.py +2 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/base.py +51 -17
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/decorator.py +6 -3
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/keyword.py +8 -3
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/models.py +16 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/recorder.py +9 -5
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/composite.py +2 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/llm.py +4 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/pairwise.py +10 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/reference.py +25 -7
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/trajectory.py +7 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/types.py +27 -6
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/coordinator.py +8 -5
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/verdict.py +2 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/__init__.py +16 -1
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/base.py +31 -14
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/config.py +82 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/reflective.py +3 -3
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/spec.py +59 -1
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/eval_routes.py +3 -3
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_history.py +42 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_types_and_judges.py +148 -0
- agentbyte-0.38.0/tests/optim/test_orchestrator_optim.py +288 -0
- agentbyte-0.34.0/src/agentbyte/__about__.py +0 -2
- {agentbyte-0.34.0 → agentbyte-0.38.0}/.gitignore +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/LICENSE +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/pyproject.toml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/_optional.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/agent_as_tool.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/embedding_agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/agents/types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cancellation_token.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/catalog.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/__main__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/eval_commands.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/loading.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/cli/main.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/counters.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/errors.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/grouping.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/compaction/strategies.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/component.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/skill_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/context_providers/skills.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/_aiosqlite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/config.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/importer.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/json.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/loader.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publish.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publish_config.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/publishers.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/s3.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sources.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sqlite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/sqlite_db.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/write_config.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/dataset/writers.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/entity.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/local.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/process.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/tool.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/checks/types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/comparison.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/eval_dataset.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/conformance.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/errors.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/sql.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/sqlite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/store.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/history/transitions.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/judges/validation.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/pairwise.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/report.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/runner.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/splitting.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/model.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/multi_turn.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/orchestrator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/runtime.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/targets/workflow.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/jobs.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/smoke.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/smoke_tasks.json +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/eval/workbench/suite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/collector.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/execution_trace/models.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/_retry_observability.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/auth.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/auth.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/chat.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/embedding.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure/settings.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure_openai.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/azure_openai_embedding.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/embeddings_base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/chat.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/embedding.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai/settings.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/openai_embedding.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/pricing.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/retry_policy.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/settings.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/llm/types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/logger.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/memory/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/memory/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/messages.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/otel.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/retry.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/sql_usage.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/middleware/usage_logger.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/notebook.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/gepa.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/mipro.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/pareto.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/optim/trace.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/ai.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/handoff.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/plan.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/policies.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/orchestration/round_robin.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/agents.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/clients.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instruction_registry.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/orchestrator.yaml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/query_rewriter.yaml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/researcher.yaml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/reviewer.yaml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/instructions/writer.yaml +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/orchestration.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/contracts-analyst/SKILL.md +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/SKILL.md +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/departments.md +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/employees.md +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/skills/hr-analyst/resources/payroll.md +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/streaming.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/presets/workflow.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/session_store.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/resources.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/scripts.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/sources.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/skills/validation.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/cancellation.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/composite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/consecutive_agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/external.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/function_call.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/handoff.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/max_message.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/predicate.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/source.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/text_mention.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/timeout.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/termination/token_usage.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/coding_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/core_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/decorator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/memory_tool.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/tools/research_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/discovery.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/execution.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/models.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/registry.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/server.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/session_store.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/sessions.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/assets/index-C-wj-OzO.js +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/assets/index-DW8IDODJ.css +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/index.html +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/webui/ui/vite.svg +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/_structure_hash.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/checkpoint.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/models.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/runner.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/core/workflow.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/defaults.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/errors.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/loader.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/schema.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/schema_utils.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/sqlite_checkpoint.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/echo.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/function.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/http.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/step.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/subworkflow.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/steps/transform.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/src/agentbyte/workflow/visualizer.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_as_tool.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_basic.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_context_providers.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_error_response.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_event_types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_memory_integration.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_middleware_integration.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_response_accessors.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_retry_middleware.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_agent_stream_events.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_embedding_agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_approval.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_batch_resolution.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/agents/test_tool_metadata.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/cli/test_loading.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/cli/test_registry_check.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/compaction/test_compaction.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/test_skill_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/context_providers/test_skills_provider.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/fake_s3.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_dataset_exit.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_loader.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_multi_table.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_publish.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/dataset/test_sqlite_db.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_dataset.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_history_backends.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_jobs.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_eval_workbench.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_execution_trajectories.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_multi_turn.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_pairwise.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_phase1_runner_and_targets.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_phase2_checks_and_reports.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_score_integrity.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/eval/test_splitting.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/examples/test_compaction_webapp.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_azure_client.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_azure_embedding_client.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_llm_types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_openai_client.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_openai_embedding_client.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_pricing.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retry_observability.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retry_policy_api.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/llm/test_retryable_error_substrings.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/memory/test_memory.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_context_compaction.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_deduplicate_tool_result.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_middleware_chain.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_otel.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_retry_middleware.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_sql_usage.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/middleware/test_usage_logger.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_base_integration.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_config.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_gepa.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_mipro.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_pareto.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_reflective.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_score_integrity.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_spec.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/optim/test_trace.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_ai_orchestrator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_base_orchestrator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_handoff_orchestrator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_orchestrator_finalization.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_plan_orchestrator.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/orchestration/test_round_robin.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_agents.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_clients.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_instruction_registry.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_orchestration.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_streaming.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/presets/test_workflow.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_resources.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_scripts.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/skills/test_sources.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_base.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_cancellation.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_composite.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_consecutive_agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_external.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_function_call.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_handoff.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_max_message.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_predicate.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_source.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_text_mention.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_timeout.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/termination/test_token_usage.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_cancellation_token.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_context.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_logger.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_messages.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_optional_extras.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_package_api.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_session_store.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_types.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/test_vanilla_chunker.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_coding_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_memory_tool.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_research_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/tools/test_tools.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/__init__.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/helpers.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_eval_routes.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_execution.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_package_api.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_registry.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_server.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_sessions.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/webui/test_workflow_streaming.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/recovery_worker.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_agent_step_imports.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_checkpoint.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_subworkflow_step.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_agent.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_class.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_models.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_reliability.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_runner.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_schema.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_steps.py +0 -0
- {agentbyte-0.34.0 → agentbyte-0.38.0}/tests/workflow/test_workflow_visualizer.py +0 -0
|
@@ -6,6 +6,95 @@ The format follows Keep a Changelog principles and semantic versioning.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.38.0] - 2026-10-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Orchestrator optimization (spec 0062). `agentbyte.optim` can now optimize a
|
|
14
|
+
multi-agent orchestrator as a whole, not only a single agent:
|
|
15
|
+
- A pluggable `build_target` seam on `BaseOptimizer` maps a candidate config to a
|
|
16
|
+
`BaseEvalTarget`. Omitting it preserves the single-agent path byte-for-byte
|
|
17
|
+
(`config.to_agent` + `AgentEvalTarget`).
|
|
18
|
+
- `agentbyte.optim.OrchestratorConfig` — a frozen, serializable composite candidate
|
|
19
|
+
(`{member_name: AgentConfig}`). The controller/termination is *not* snapshotted; it
|
|
20
|
+
is reattached by a user-supplied `OrchestratorAssembler`.
|
|
21
|
+
- `orchestrator_build_target(model_client, tool_catalog, assemble)` builds an
|
|
22
|
+
`OrchestratorEvalTarget` in factory form (a fresh orchestrator per eval case).
|
|
23
|
+
- `OptimizationSpec.for_members({...})` (→ `MemberOptimizationSpec`) exposes each
|
|
24
|
+
member's components under a namespaced name (`support.instructions`); edits route
|
|
25
|
+
back to the owning member, and names outside the composite spec become no-ops.
|
|
26
|
+
- Per-member credit assignment reuses `source_filter` (spec 0060/0061): the judge
|
|
27
|
+
scores only one member's messages in the multi-source orchestrated trajectory.
|
|
28
|
+
- New exports: `OrchestratorConfig`, `OptimizableConfig`, `OrchestratorAssembler`,
|
|
29
|
+
`TargetBuilder`, `orchestrator_build_target`, `MemberOptimizationSpec`.
|
|
30
|
+
|
|
31
|
+
### Notes
|
|
32
|
+
|
|
33
|
+
- Single-agent optimization is unchanged (default `build_target`, `AgentConfig` seed).
|
|
34
|
+
- Workflow-level optimization remains a non-goal: optimize each `AgentStep`'s agent
|
|
35
|
+
standalone and compose. GEPA stays single-agent (it runs the external `gepa` loop).
|
|
36
|
+
|
|
37
|
+
## [0.37.0] - 2026-10-02
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `agentbyte.eval.history.CaptureMode` is now an `enum.StrEnum` (`SUMMARY`, `FULL`) instead of a
|
|
42
|
+
`Literal["summary", "full"]` alias (spec 0063). The valid values are importable and
|
|
43
|
+
autocomplete, and the enum is the single source of truth: the duplicated `("summary", "full")`
|
|
44
|
+
checks in `EvalRunRecorder` and `EvalSuiteCoordinator._check_capture`, and the re-declared
|
|
45
|
+
`Literal` on the WebUI request model, are gone. Because `StrEnum` members are `str` subclasses
|
|
46
|
+
with value-equality (`CaptureMode.FULL == "full"`), callers passing the raw strings keep
|
|
47
|
+
working, the WebUI JSON contract (`"capture": "full"`) is unchanged, and stored runs reload
|
|
48
|
+
identically.
|
|
49
|
+
|
|
50
|
+
### Notes
|
|
51
|
+
|
|
52
|
+
- Breaking only for code that compared `CaptureMode` with `is` against a string literal
|
|
53
|
+
(identity); equality (`==`) is the supported contract and is unchanged.
|
|
54
|
+
|
|
55
|
+
## [0.36.0] - 2026-10-02
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- `agentbyte.eval.ConversationScope` — a `StrEnum` (`FULL`, `LAST_TURN`) that selects which
|
|
60
|
+
part of a multi-turn conversation a judge evaluates (spec 0061). It is applied before
|
|
61
|
+
`source_filter` and `AnswerStrategy`, so the three selection axes compose: scope narrows the
|
|
62
|
+
trajectory to a turn window, `source_filter` keeps matching sources, then `AnswerStrategy`
|
|
63
|
+
picks the message(s). A turn boundary is the last `UserMessage`; `LAST_TURN` scopes from
|
|
64
|
+
there to the end of the trajectory.
|
|
65
|
+
- `conversation_scope` keyword (default `ConversationScope.FULL`) on `BaseEvalJudge` and the
|
|
66
|
+
judges/checks that already accept `answer_strategy` (`LLMEvalJudge`, reference judges,
|
|
67
|
+
`PairwiseJudge`, `LLMTrajectoryJudge`, `keyword_check`, the `evaluator` decorator).
|
|
68
|
+
- `agentbyte.eval.base.scope_messages(messages, scope)` — the pure helper implementing the
|
|
69
|
+
turn-window selection.
|
|
70
|
+
|
|
71
|
+
### Notes
|
|
72
|
+
|
|
73
|
+
- Additive and non-breaking: the default `FULL` reproduces today's whole-trajectory behaviour
|
|
74
|
+
for every existing single- and multi-turn caller. `LAST_TURN` is strictly opt-in.
|
|
75
|
+
|
|
76
|
+
## [0.35.0] - 2026-10-02
|
|
77
|
+
|
|
78
|
+
Upgrade notes (breaking):
|
|
79
|
+
|
|
80
|
+
- `agentbyte.eval.AnswerStrategy` is now an `enum.StrEnum` instead of a `Literal[...]` type
|
|
81
|
+
alias (spec 0060). Prefer the members `AnswerStrategy.LAST_NON_EMPTY`,
|
|
82
|
+
`AnswerStrategy.LAST_ASSISTANT`, `AnswerStrategy.LAST_CONTENT` and
|
|
83
|
+
`AnswerStrategy.ALL_ASSISTANT`. Because `StrEnum` members are `str` subclasses with
|
|
84
|
+
value-equality, passing the raw strings (`"last_assistant"`, etc.) keeps working and
|
|
85
|
+
serialization is unchanged; only code that compared the value with `is` against a string
|
|
86
|
+
literal (identity) is affected.
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
|
|
90
|
+
- `AnswerStrategy` is a single source of truth: the duplicated `_VALID_ANSWER_STRATEGIES`
|
|
91
|
+
tuple in `agentbyte.eval.base` is removed and unknown values are rejected via
|
|
92
|
+
`AnswerStrategy(value)` with a `ValueError` naming the valid members. All judges and checks
|
|
93
|
+
(`LLMEvalJudge`, reference judges, `PairwiseJudge`, `keyword_check`, the `evaluator`
|
|
94
|
+
decorator, composite/trajectory judges) default to the enum members.
|
|
95
|
+
- Eval end-to-end notebook (`notebooks/usecases/eval/06-eval-end-to-end.ipynb`) and the
|
|
96
|
+
example catalog (`examples/eval/acme_support.py`) use the typed `AnswerStrategy` enum.
|
|
97
|
+
|
|
9
98
|
## [0.34.0] - 2026-10-01
|
|
10
99
|
|
|
11
100
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentbyte
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.38.0
|
|
4
4
|
Summary: A toolkit for designing multiagent systems
|
|
5
5
|
Author-email: MrDataPsycho <mr.data.psycho@gmail.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -72,7 +72,7 @@ Description-Content-Type: text/markdown
|
|
|
72
72
|
|
|
73
73
|
Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
|
|
74
74
|
|
|
75
|
-
Current release: **0.
|
|
75
|
+
Current release: **0.38.0**
|
|
76
76
|
|
|
77
77
|
## Building an Agent
|
|
78
78
|
|
|
@@ -368,7 +368,7 @@ uv run agentbyte eval ui --catalog examples/eval/workbench_catalog.py # htt
|
|
|
368
368
|
- To serve agents and Evaluations together: `agentbyte webui --dir my_entities --eval-catalog myapp/evaluations.py`.
|
|
369
369
|
|
|
370
370
|
Start with the end-to-end guide, `docs/guides/evaluation-end-to-end.md` (dataset → suite → history → UI), and the
|
|
371
|
-
notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/
|
|
371
|
+
notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/design-guide/05-eval_topics/`.
|
|
372
372
|
|
|
373
373
|
### Option 3: Scan a project directory
|
|
374
374
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Agentbyte is an observability-first agentic AI framework for building and studying multiagent systems with a learning-first, implementation-oriented workflow.
|
|
4
4
|
|
|
5
|
-
Current release: **0.
|
|
5
|
+
Current release: **0.38.0**
|
|
6
6
|
|
|
7
7
|
## Building an Agent
|
|
8
8
|
|
|
@@ -298,7 +298,7 @@ uv run agentbyte eval ui --catalog examples/eval/workbench_catalog.py # htt
|
|
|
298
298
|
- To serve agents and Evaluations together: `agentbyte webui --dir my_entities --eval-catalog myapp/evaluations.py`.
|
|
299
299
|
|
|
300
300
|
Start with the end-to-end guide, `docs/guides/evaluation-end-to-end.md` (dataset → suite → history → UI), and the
|
|
301
|
-
notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/
|
|
301
|
+
notebook `notebooks/usecases/eval/06-eval-end-to-end.ipynb` (real OpenAI/Azure model). Details: `docs/design-guide/05-eval_topics/`.
|
|
302
302
|
|
|
303
303
|
### Option 3: Scan a project directory
|
|
304
304
|
|
|
@@ -48,6 +48,7 @@ from .splitting import (
|
|
|
48
48
|
from .targets import AgentEvalTarget, ModelEvalTarget, MultiTurnAgentEvalTarget, OrchestratorEvalTarget
|
|
49
49
|
from .types import (
|
|
50
50
|
AnswerStrategy,
|
|
51
|
+
ConversationScope,
|
|
51
52
|
EvalResult,
|
|
52
53
|
EvalScore,
|
|
53
54
|
EvalTask,
|
|
@@ -63,6 +64,7 @@ __all__ = [
|
|
|
63
64
|
"WorkflowEvalTask", "WorkflowEvalTarget", "LLMTrajectoryJudge",
|
|
64
65
|
"select_span", "terminal_status", "steps_completed", "edge_activated", "usage_limits",
|
|
65
66
|
"AnswerStrategy",
|
|
67
|
+
"ConversationScope",
|
|
66
68
|
"ExpectedToolCall",
|
|
67
69
|
"EvalTask",
|
|
68
70
|
"MultiTurnEvalTask",
|
|
@@ -5,16 +5,29 @@ from __future__ import annotations
|
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
6
|
|
|
7
7
|
from agentbyte.cancellation_token import CancellationToken
|
|
8
|
-
from agentbyte.messages import AssistantMessage
|
|
8
|
+
from agentbyte.messages import AssistantMessage, Message, UserMessage
|
|
9
9
|
|
|
10
|
-
from .types import AnswerStrategy, EvalScore, EvalTask, EvalTrajectory
|
|
10
|
+
from .types import AnswerStrategy, ConversationScope, EvalScore, EvalTask, EvalTrajectory
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
|
|
13
|
+
def scope_messages(
|
|
14
|
+
messages: list[Message],
|
|
15
|
+
scope: ConversationScope,
|
|
16
|
+
) -> list[Message]:
|
|
17
|
+
"""Narrow a message list to the chosen conversation scope.
|
|
18
|
+
|
|
19
|
+
``FULL`` returns the list unchanged. ``LAST_TURN`` returns the messages from
|
|
20
|
+
the last ``UserMessage`` (a turn boundary) to the end, inclusive of that
|
|
21
|
+
user message; if there is no ``UserMessage`` the whole list is returned.
|
|
22
|
+
This runs before ``source_filter`` and ``AnswerStrategy`` so the three
|
|
23
|
+
selection axes compose.
|
|
24
|
+
"""
|
|
25
|
+
if scope == ConversationScope.LAST_TURN:
|
|
26
|
+
for index in range(len(messages) - 1, -1, -1):
|
|
27
|
+
if isinstance(messages[index], UserMessage):
|
|
28
|
+
return list(messages[index:])
|
|
29
|
+
return list(messages)
|
|
30
|
+
return list(messages)
|
|
18
31
|
|
|
19
32
|
|
|
20
33
|
class JudgeScoringError(Exception):
|
|
@@ -51,17 +64,28 @@ class BaseEvalJudge(ABC):
|
|
|
51
64
|
def __init__(
|
|
52
65
|
self,
|
|
53
66
|
name: str,
|
|
54
|
-
answer_strategy: AnswerStrategy =
|
|
67
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
55
68
|
source_filter: str | None = None,
|
|
69
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
56
70
|
) -> None:
|
|
57
|
-
|
|
71
|
+
try:
|
|
72
|
+
answer_strategy = AnswerStrategy(answer_strategy)
|
|
73
|
+
except ValueError as exc:
|
|
58
74
|
raise ValueError(
|
|
59
75
|
f"Unsupported answer_strategy: {answer_strategy!r}. "
|
|
60
|
-
f"Expected one of {
|
|
61
|
-
)
|
|
76
|
+
f"Expected one of {[s.value for s in AnswerStrategy]}."
|
|
77
|
+
) from exc
|
|
78
|
+
try:
|
|
79
|
+
conversation_scope = ConversationScope(conversation_scope)
|
|
80
|
+
except ValueError as exc:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Unsupported conversation_scope: {conversation_scope!r}. "
|
|
83
|
+
f"Expected one of {[s.value for s in ConversationScope]}."
|
|
84
|
+
) from exc
|
|
62
85
|
self.name = name
|
|
63
86
|
self.answer_strategy = answer_strategy
|
|
64
87
|
self.source_filter = source_filter
|
|
88
|
+
self.conversation_scope = conversation_scope
|
|
65
89
|
|
|
66
90
|
def extract_answer(self, trajectory: EvalTrajectory) -> str:
|
|
67
91
|
"""Extract the answer text from a trajectory using the configured strategy.
|
|
@@ -71,23 +95,27 @@ class BaseEvalJudge(ABC):
|
|
|
71
95
|
lets callers target a specific agent's output in multi-agent trajectories
|
|
72
96
|
(e.g. extract the Writer's last message from a Researcher→Writer→Reviewer
|
|
73
97
|
orchestrator run).
|
|
98
|
+
|
|
99
|
+
Selection runs in a fixed order: ``conversation_scope`` narrows the
|
|
100
|
+
trajectory to a turn window, then ``source_filter`` keeps only matching
|
|
101
|
+
sources, then ``answer_strategy`` picks the message(s) that remain.
|
|
74
102
|
"""
|
|
75
|
-
messages =
|
|
103
|
+
messages = scope_messages(trajectory.messages, self.conversation_scope)
|
|
76
104
|
if self.source_filter:
|
|
77
105
|
messages = [m for m in messages if m.source == self.source_filter]
|
|
78
106
|
if not messages:
|
|
79
107
|
return ""
|
|
80
108
|
|
|
81
|
-
if self.answer_strategy ==
|
|
109
|
+
if self.answer_strategy == AnswerStrategy.LAST_CONTENT:
|
|
82
110
|
return messages[-1].content
|
|
83
111
|
|
|
84
|
-
if self.answer_strategy ==
|
|
112
|
+
if self.answer_strategy == AnswerStrategy.LAST_NON_EMPTY:
|
|
85
113
|
for message in reversed(messages):
|
|
86
114
|
if message.content and message.content.strip():
|
|
87
115
|
return message.content
|
|
88
116
|
return ""
|
|
89
117
|
|
|
90
|
-
if self.answer_strategy ==
|
|
118
|
+
if self.answer_strategy == AnswerStrategy.LAST_ASSISTANT:
|
|
91
119
|
for message in reversed(messages):
|
|
92
120
|
if isinstance(message, AssistantMessage):
|
|
93
121
|
return message.content
|
|
@@ -134,4 +162,10 @@ class BaseEvalRunner(ABC):
|
|
|
134
162
|
"""Evaluate a target on multiple tasks."""
|
|
135
163
|
|
|
136
164
|
|
|
137
|
-
__all__ = [
|
|
165
|
+
__all__ = [
|
|
166
|
+
"BaseEvalTarget",
|
|
167
|
+
"BaseEvalJudge",
|
|
168
|
+
"BaseEvalRunner",
|
|
169
|
+
"JudgeScoringError",
|
|
170
|
+
"scope_messages",
|
|
171
|
+
]
|
|
@@ -7,7 +7,7 @@ from collections.abc import Callable
|
|
|
7
7
|
from typing import Any, overload
|
|
8
8
|
|
|
9
9
|
from agentbyte.eval.base import BaseEvalJudge
|
|
10
|
-
from agentbyte.eval.types import AnswerStrategy, EvalTrajectory
|
|
10
|
+
from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalTrajectory
|
|
11
11
|
|
|
12
12
|
from .types import CheckResult, EvalCheck
|
|
13
13
|
|
|
@@ -95,18 +95,20 @@ def evaluator(fn: Callable[..., Any], /) -> EvalCheck: ...
|
|
|
95
95
|
@overload
|
|
96
96
|
def evaluator(
|
|
97
97
|
*,
|
|
98
|
-
answer_strategy: AnswerStrategy =
|
|
98
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
99
99
|
name: str | None = None,
|
|
100
100
|
source_filter: str | None = None,
|
|
101
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
101
102
|
) -> Callable[[Callable[..., Any]], EvalCheck]: ...
|
|
102
103
|
|
|
103
104
|
|
|
104
105
|
def evaluator(
|
|
105
106
|
fn: Callable[..., Any] | None = None,
|
|
106
107
|
*,
|
|
107
|
-
answer_strategy: AnswerStrategy =
|
|
108
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
108
109
|
name: str | None = None,
|
|
109
110
|
source_filter: str | None = None,
|
|
111
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
110
112
|
) -> EvalCheck | Callable[[Callable[..., Any]], EvalCheck]:
|
|
111
113
|
"""Wrap a plain function as an EvalCheck with parameter injection.
|
|
112
114
|
|
|
@@ -139,6 +141,7 @@ def evaluator(
|
|
|
139
141
|
name="extractor",
|
|
140
142
|
answer_strategy=answer_strategy,
|
|
141
143
|
source_filter=source_filter,
|
|
144
|
+
conversation_scope=conversation_scope,
|
|
142
145
|
)
|
|
143
146
|
kwargs = _resolve_args(
|
|
144
147
|
func,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from agentbyte.eval.judges.reference import ExactMatchJudge
|
|
6
|
-
from agentbyte.eval.types import AnswerStrategy, EvalTrajectory
|
|
6
|
+
from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalTrajectory
|
|
7
7
|
|
|
8
8
|
from .types import CheckResult, EvalCheck
|
|
9
9
|
|
|
@@ -12,7 +12,8 @@ def keyword_check(
|
|
|
12
12
|
*keywords: str,
|
|
13
13
|
case_sensitive: bool = False,
|
|
14
14
|
source_filter: str | None = None,
|
|
15
|
-
answer_strategy: AnswerStrategy =
|
|
15
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_ASSISTANT,
|
|
16
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
16
17
|
) -> EvalCheck:
|
|
17
18
|
"""Return a check that verifies all keywords appear in the extracted response.
|
|
18
19
|
|
|
@@ -22,7 +23,11 @@ def keyword_check(
|
|
|
22
23
|
Pass ``source_filter`` to target a specific agent in multi-agent trajectories
|
|
23
24
|
(e.g. ``source_filter="writer"`` in a Researcher→Writer→Reviewer pipeline).
|
|
24
25
|
"""
|
|
25
|
-
extractor = ExactMatchJudge(
|
|
26
|
+
extractor = ExactMatchJudge(
|
|
27
|
+
answer_strategy=answer_strategy,
|
|
28
|
+
source_filter=source_filter,
|
|
29
|
+
conversation_scope=conversation_scope,
|
|
30
|
+
)
|
|
26
31
|
|
|
27
32
|
async def _check(trajectory: EvalTrajectory) -> CheckResult:
|
|
28
33
|
response = extractor.extract_answer(trajectory)
|
|
@@ -12,6 +12,7 @@ import math
|
|
|
12
12
|
import re
|
|
13
13
|
from collections.abc import Callable
|
|
14
14
|
from datetime import date, datetime, timezone
|
|
15
|
+
from enum import StrEnum
|
|
15
16
|
from typing import Any, Literal
|
|
16
17
|
from uuid import uuid4
|
|
17
18
|
|
|
@@ -30,7 +31,20 @@ EVIDENCE_VERSION = 1
|
|
|
30
31
|
|
|
31
32
|
RunStatus = Literal["queued", "running", "completed", "failed", "cancelled", "interrupted"]
|
|
32
33
|
ItemState = Literal["pending", "running", "finished", "cancelled", "not_started"]
|
|
33
|
-
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class CaptureMode(StrEnum):
|
|
37
|
+
"""How much evidence an evaluation run captures.
|
|
38
|
+
|
|
39
|
+
A ``StrEnum``: members compare and serialize as their plain string value
|
|
40
|
+
(``CaptureMode.FULL == "full"``), so callers may pass either the member or
|
|
41
|
+
the raw string.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
SUMMARY = "summary"
|
|
45
|
+
FULL = "full"
|
|
46
|
+
|
|
47
|
+
|
|
34
48
|
EvidenceStatus = Literal["not_captured", "captured", "redacted", "unavailable"]
|
|
35
49
|
TaskType = Literal["task", "workflow", "multi_turn"]
|
|
36
50
|
|
|
@@ -71,7 +85,7 @@ class EvalRunRecord(BaseModel):
|
|
|
71
85
|
schema_version: int = SCHEMA_VERSION
|
|
72
86
|
status: RunStatus = "queued"
|
|
73
87
|
revision: int = 0
|
|
74
|
-
capture: CaptureMode =
|
|
88
|
+
capture: CaptureMode = CaptureMode.SUMMARY
|
|
75
89
|
dataset_id: str
|
|
76
90
|
dataset_revision: str | None = None
|
|
77
91
|
target_id: str
|
|
@@ -59,17 +59,21 @@ class EvalRunRecorder:
|
|
|
59
59
|
def __init__(
|
|
60
60
|
self,
|
|
61
61
|
store: EvalRunStore,
|
|
62
|
-
capture: CaptureMode =
|
|
62
|
+
capture: CaptureMode = CaptureMode.SUMMARY,
|
|
63
63
|
*,
|
|
64
64
|
concurrency: int = 4,
|
|
65
65
|
redact: Redactor | None = None,
|
|
66
66
|
worker_id: str | None = None,
|
|
67
67
|
) -> None:
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
try:
|
|
69
|
+
capture = CaptureMode(capture)
|
|
70
|
+
except ValueError as exc:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
f"capture must be one of {[m.value for m in CaptureMode]}, got {capture!r}"
|
|
73
|
+
) from exc
|
|
70
74
|
if concurrency < 1:
|
|
71
75
|
raise ValueError("concurrency must be at least 1")
|
|
72
|
-
if redact is not None and capture !=
|
|
76
|
+
if redact is not None and capture != CaptureMode.FULL:
|
|
73
77
|
raise ValueError("redact applies only to capture='full'")
|
|
74
78
|
self.store = store
|
|
75
79
|
self.capture = capture
|
|
@@ -315,7 +319,7 @@ class EvalRunRecorder:
|
|
|
315
319
|
def _outcome(self, run_id: str, index: int, task: EvalTask, score: EvalScore) -> EvalItemRecord:
|
|
316
320
|
evidence: EvalScore | None = None
|
|
317
321
|
evidence_status: EvidenceStatus = "not_captured"
|
|
318
|
-
if self.capture ==
|
|
322
|
+
if self.capture == CaptureMode.FULL:
|
|
319
323
|
evidence, evidence_status = score, "captured"
|
|
320
324
|
if self.redact is not None:
|
|
321
325
|
try:
|
|
@@ -8,7 +8,7 @@ from collections.abc import Sequence
|
|
|
8
8
|
from agentbyte.cancellation_token import CancellationToken
|
|
9
9
|
|
|
10
10
|
from agentbyte.eval.base import BaseEvalJudge, JudgeScoringError
|
|
11
|
-
from agentbyte.eval.types import EvalScore, EvalTrajectory
|
|
11
|
+
from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class CompositeJudge(BaseEvalJudge):
|
|
@@ -36,7 +36,7 @@ class CompositeJudge(BaseEvalJudge):
|
|
|
36
36
|
)
|
|
37
37
|
normalized = list(judges)
|
|
38
38
|
|
|
39
|
-
super().__init__(name=name, answer_strategy=
|
|
39
|
+
super().__init__(name=name, answer_strategy=AnswerStrategy.LAST_NON_EMPTY)
|
|
40
40
|
self.judges = normalized
|
|
41
41
|
|
|
42
42
|
async def score(
|
|
@@ -21,7 +21,7 @@ from agentbyte.eval.judges.validation import (
|
|
|
21
21
|
resolve_criteria,
|
|
22
22
|
validate_criterion_scores,
|
|
23
23
|
)
|
|
24
|
-
from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
|
|
24
|
+
from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class _JudgeCriterionScore(BaseModel):
|
|
@@ -51,8 +51,9 @@ class LLMEvalJudge(BaseEvalJudge):
|
|
|
51
51
|
client: BaseChatCompletionClient,
|
|
52
52
|
*,
|
|
53
53
|
name: str | None = None,
|
|
54
|
-
answer_strategy: AnswerStrategy =
|
|
54
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
55
55
|
source_filter: str | None = None,
|
|
56
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
56
57
|
default_criteria: list[str] | None = None,
|
|
57
58
|
custom_instructions: str | None = None,
|
|
58
59
|
use_structured_output: bool = True,
|
|
@@ -61,6 +62,7 @@ class LLMEvalJudge(BaseEvalJudge):
|
|
|
61
62
|
name=name or f"LLM-{client.model}",
|
|
62
63
|
answer_strategy=answer_strategy,
|
|
63
64
|
source_filter=source_filter,
|
|
65
|
+
conversation_scope=conversation_scope,
|
|
64
66
|
)
|
|
65
67
|
require_non_empty_defaults(default_criteria, "default_criteria")
|
|
66
68
|
self.client = client
|
|
@@ -15,7 +15,13 @@ from agentbyte.messages import SystemMessage, UserMessage
|
|
|
15
15
|
|
|
16
16
|
from agentbyte.eval.base import BaseEvalJudge, JudgeScoringError
|
|
17
17
|
from agentbyte.eval.judges.validation import loads_judge_json, require_non_empty_defaults
|
|
18
|
-
from agentbyte.eval.types import
|
|
18
|
+
from agentbyte.eval.types import (
|
|
19
|
+
AnswerStrategy,
|
|
20
|
+
ConversationScope,
|
|
21
|
+
EvalScore,
|
|
22
|
+
EvalTrajectory,
|
|
23
|
+
PairwiseResult,
|
|
24
|
+
)
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
class _PairwiseResponse(BaseModel):
|
|
@@ -47,14 +53,16 @@ class PairwiseJudge(BaseEvalJudge):
|
|
|
47
53
|
*,
|
|
48
54
|
name: str | None = None,
|
|
49
55
|
criteria: list[str] | None = None,
|
|
50
|
-
answer_strategy: AnswerStrategy =
|
|
56
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_ASSISTANT,
|
|
51
57
|
source_filter: str | None = None,
|
|
58
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
52
59
|
custom_instructions: str | None = None,
|
|
53
60
|
) -> None:
|
|
54
61
|
super().__init__(
|
|
55
62
|
name=name or f"Pairwise-{client.model}",
|
|
56
63
|
answer_strategy=answer_strategy,
|
|
57
64
|
source_filter=source_filter,
|
|
65
|
+
conversation_scope=conversation_scope,
|
|
58
66
|
)
|
|
59
67
|
require_non_empty_defaults(criteria, "criteria")
|
|
60
68
|
self.client = client
|
|
@@ -7,7 +7,7 @@ from difflib import SequenceMatcher
|
|
|
7
7
|
from agentbyte.cancellation_token import CancellationToken
|
|
8
8
|
|
|
9
9
|
from agentbyte.eval.base import BaseEvalJudge
|
|
10
|
-
from agentbyte.eval.types import AnswerStrategy, EvalScore, EvalTrajectory
|
|
10
|
+
from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _failed_score(judge_name: str, trajectory: EvalTrajectory) -> EvalScore:
|
|
@@ -28,12 +28,18 @@ class ExactMatchJudge(BaseEvalJudge):
|
|
|
28
28
|
self,
|
|
29
29
|
*,
|
|
30
30
|
name: str = "ExactMatch",
|
|
31
|
-
answer_strategy: AnswerStrategy =
|
|
31
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
32
32
|
source_filter: str | None = None,
|
|
33
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
33
34
|
case_sensitive: bool = False,
|
|
34
35
|
strip_whitespace: bool = True,
|
|
35
36
|
) -> None:
|
|
36
|
-
super().__init__(
|
|
37
|
+
super().__init__(
|
|
38
|
+
name=name,
|
|
39
|
+
answer_strategy=answer_strategy,
|
|
40
|
+
source_filter=source_filter,
|
|
41
|
+
conversation_scope=conversation_scope,
|
|
42
|
+
)
|
|
37
43
|
self.case_sensitive = case_sensitive
|
|
38
44
|
self.strip_whitespace = strip_whitespace
|
|
39
45
|
|
|
@@ -76,11 +82,17 @@ class ContainsJudge(BaseEvalJudge):
|
|
|
76
82
|
self,
|
|
77
83
|
*,
|
|
78
84
|
name: str = "Contains",
|
|
79
|
-
answer_strategy: AnswerStrategy =
|
|
85
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
80
86
|
source_filter: str | None = None,
|
|
87
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
81
88
|
case_sensitive: bool = False,
|
|
82
89
|
) -> None:
|
|
83
|
-
super().__init__(
|
|
90
|
+
super().__init__(
|
|
91
|
+
name=name,
|
|
92
|
+
answer_strategy=answer_strategy,
|
|
93
|
+
source_filter=source_filter,
|
|
94
|
+
conversation_scope=conversation_scope,
|
|
95
|
+
)
|
|
84
96
|
self.case_sensitive = case_sensitive
|
|
85
97
|
|
|
86
98
|
async def score(
|
|
@@ -123,14 +135,20 @@ class FuzzyMatchJudge(BaseEvalJudge):
|
|
|
123
135
|
self,
|
|
124
136
|
*,
|
|
125
137
|
name: str = "FuzzyMatch",
|
|
126
|
-
answer_strategy: AnswerStrategy =
|
|
138
|
+
answer_strategy: AnswerStrategy = AnswerStrategy.LAST_NON_EMPTY,
|
|
127
139
|
source_filter: str | None = None,
|
|
140
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
128
141
|
case_sensitive: bool = False,
|
|
129
142
|
threshold: float = 0.8,
|
|
130
143
|
) -> None:
|
|
131
144
|
if not 0 <= threshold <= 1:
|
|
132
145
|
raise ValueError("threshold must be within [0, 1]")
|
|
133
|
-
super().__init__(
|
|
146
|
+
super().__init__(
|
|
147
|
+
name=name,
|
|
148
|
+
answer_strategy=answer_strategy,
|
|
149
|
+
source_filter=source_filter,
|
|
150
|
+
conversation_scope=conversation_scope,
|
|
151
|
+
)
|
|
134
152
|
self.case_sensitive = case_sensitive
|
|
135
153
|
self.threshold = threshold
|
|
136
154
|
|
|
@@ -18,7 +18,7 @@ from agentbyte.eval.judges.validation import (
|
|
|
18
18
|
resolve_criteria,
|
|
19
19
|
validate_criterion_scores,
|
|
20
20
|
)
|
|
21
|
-
from agentbyte.eval.types import EvalScore, EvalTrajectory
|
|
21
|
+
from agentbyte.eval.types import AnswerStrategy, ConversationScope, EvalScore, EvalTrajectory
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class ProcessCriterionScore(BaseModel):
|
|
@@ -49,8 +49,13 @@ class LLMTrajectoryJudge(BaseEvalJudge):
|
|
|
49
49
|
default_criteria: list[str] | None = None,
|
|
50
50
|
custom_instructions: str | None = None,
|
|
51
51
|
max_payload_chars: int = 100_000,
|
|
52
|
+
conversation_scope: ConversationScope = ConversationScope.FULL,
|
|
52
53
|
) -> None:
|
|
53
|
-
super().__init__(
|
|
54
|
+
super().__init__(
|
|
55
|
+
name,
|
|
56
|
+
answer_strategy=AnswerStrategy.LAST_ASSISTANT,
|
|
57
|
+
conversation_scope=conversation_scope,
|
|
58
|
+
)
|
|
54
59
|
if max_payload_chars <= 0:
|
|
55
60
|
raise ValueError("max_payload_chars must be positive")
|
|
56
61
|
require_non_empty_defaults(default_criteria, "default_criteria")
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import math
|
|
6
|
+
from enum import StrEnum
|
|
6
7
|
from typing import Any, Literal
|
|
7
8
|
|
|
8
9
|
from pydantic import (
|
|
@@ -17,12 +18,31 @@ from agentbyte.execution_trace import ExecutionTrace
|
|
|
17
18
|
|
|
18
19
|
from agentbyte.messages import Message, Usage
|
|
19
20
|
|
|
20
|
-
AnswerStrategy
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
21
|
+
class AnswerStrategy(StrEnum):
|
|
22
|
+
"""Which message in a trajectory counts as the answer to be judged.
|
|
23
|
+
|
|
24
|
+
A ``StrEnum``: members compare and serialize as their plain string value
|
|
25
|
+
(``AnswerStrategy.LAST_ASSISTANT == "last_assistant"``), so callers may pass
|
|
26
|
+
either the member or the raw string.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
LAST_NON_EMPTY = "last_non_empty"
|
|
30
|
+
LAST_ASSISTANT = "last_assistant"
|
|
31
|
+
LAST_CONTENT = "last_content"
|
|
32
|
+
ALL_ASSISTANT = "all_assistant"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ConversationScope(StrEnum):
|
|
36
|
+
"""Which part of a multi-turn conversation a judge evaluates.
|
|
37
|
+
|
|
38
|
+
Applied before ``source_filter`` and ``AnswerStrategy``, this narrows the
|
|
39
|
+
trajectory to a turn window first. A ``StrEnum``: members compare and
|
|
40
|
+
serialize as their plain string value (``ConversationScope.LAST_TURN ==
|
|
41
|
+
"last_turn"``), so callers may pass either the member or the raw string.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
FULL = "full"
|
|
45
|
+
LAST_TURN = "last_turn"
|
|
26
46
|
|
|
27
47
|
|
|
28
48
|
class ExpectedToolCall(BaseModel):
|
|
@@ -287,6 +307,7 @@ class PairwiseResult(BaseModel):
|
|
|
287
307
|
__all__ = [
|
|
288
308
|
"WorkflowEvalTask",
|
|
289
309
|
"AnswerStrategy",
|
|
310
|
+
"ConversationScope",
|
|
290
311
|
"ScoringStatus",
|
|
291
312
|
"ExpectedToolCall",
|
|
292
313
|
"EvalTask",
|