feat: v0.1.7 - comprehensive examples, ROLL integration, and bug fixes - #2
Conversation
Examples: - Add schedule examples: timeout, circuit breaker, adaptive limit, metrics callback, priority queue, telemetry, config hot reload, combined features - Add client examples: load balancer, model router, streaming, batch streaming - Add ROLL framework integration example with LLM-as-Judge reward worker - Fix normal/single_call.py: use httpx_request_hook parameter correctly - Fix normal/batch_call.py: fix BATCH_MESSAGES construction and usage Documentation: - Update README.md and README_ZH.md with full example index tables - Add ROLL example README with architecture diagram and usage guide Misc: - Update .gitignore to exclude sprint contract files - Remove sprint contracts from git tracking
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR bumps QReward to v0.1.7, adding a much more feature-rich scheduling subsystem (circuit breaker, adaptive limiting, telemetry, config hot-reload, priority queue) plus expanded examples and some bug fixes to existing utilities and OpenAI patching.
Changes:
- Introduces a new
qreward.utils.schedulerpackage (runners, config, limiter, overload detection, telemetry, etc.) and updates exports to use it. - Adds client-side load balancing and model routing utilities, along with new streaming/batch-streaming examples.
- Adds/updates tests and documentation (README tables, changelogs), plus tooling updates (Makefile, dependency version pinning).
Reviewed changes
Copilot reviewed 75 out of 78 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_socket_keepalive.py | Test formatting tweaks for keepalive adapter behavior. |
| tests/test_retry.py | Adds retry edge-case tests and normalizes patch quoting/style. |
| tests/test_patch_openai.py | Adds unpatch-related tests and refactors some patch setup formatting. |
| tests/test_globals.py | New tests covering overload constants in qreward.globals. |
| tests/conftest.py | Adds shared fixtures for proxy tests. |
| requirements.txt | Pins minimum versions for runtime dependencies. |
| qreward/utils/socket_keepalive.py | Formatting and minor style adjustments for socket options and pool kwargs. |
| qreward/utils/scheduler/telemetry.py | New optional OpenTelemetry exporter for schedule metrics/spans. |
| qreward/utils/scheduler/sync_runner.py | New sync runner implementation for schedule execution. |
| qreward/utils/scheduler/priority_queue.py | New thread-safe priority queue with starvation protection. |
| qreward/utils/scheduler/pools.py | New running-task pool for concurrency / overload heuristics. |
| qreward/utils/scheduler/overload.py | New overload detection helper based on status, exception types, keywords. |
| qreward/utils/scheduler/metrics.py | New ScheduleMetrics dataclass + OTel export hook. |
| qreward/utils/scheduler/limiter.py | New sliding-window rate limiter with sync+async APIs. |
| qreward/utils/scheduler/decorator.py | New schedule decorator integrating runners, limiter, breaker, metrics, telemetry. |
| qreward/utils/scheduler/context.py | New execution context for schedule state/timeouts/hedging/metrics. |
| qreward/utils/scheduler/config_watcher.py | New hot-reload watcher for schedule config (file/env/callback). |
| qreward/utils/scheduler/config.py | New schedule config object with validation + hot-update callbacks. |
| qreward/utils/scheduler/circuit_breaker.py | New circuit breaker implementation. |
| qreward/utils/scheduler/base.py | New shared runner base + exception handling helpers. |
| qreward/utils/scheduler/async_runner.py | New async runner implementation for schedule execution. |
| qreward/utils/scheduler/adaptive_limiter.py | New adaptive limiter tracking latency/errors to adjust limits. |
| qreward/utils/scheduler/init.py | Scheduler package exports for public API. |
| qreward/utils/retry.py | Refactors isinstance check formatting in should_retry. |
| qreward/utils/patch.py | Minor whitespace changes in optional JSON lib imports. |
| qreward/utils/init.py | Switches schedule export to qreward.utils.scheduler. |
| qreward/globals.py | Reformats overload constants and exception/keyword sets. |
| qreward/client/patch_openai.py | Adds reversible unpatch support for embeddings monkey-patch. |
| qreward/client/model_router.py | New model-router for selecting proxy groups by model pattern. |
| qreward/client/load_balancer.py | New load-balancing strategies + selectors. |
| qreward/client/init.py | Exposes load balancing and model router APIs. |
| qreward/_version.py | Bumps version to 0.1.7. |
| pyproject.toml | Pins dependency versions and adds optional otel extra; coverage exclude tweak. |
| examples/schedule/schedule_timeout.py | New timeout usage examples for schedule. |
| examples/schedule/schedule_telemetry.py | New OpenTelemetry integration example for schedule. |
| examples/schedule/schedule_priority.py | New priority usage example (decorator + direct queue). |
| examples/schedule/schedule_metrics_callback.py | New metrics callback example for schedule. |
| examples/schedule/schedule_config_hot_reload.py | New config hot-reload usage example. |
| examples/schedule/schedule_combined.py | New “combined features” schedule example. |
| examples/schedule/schedule_circuit_breaker.py | New circuit breaker schedule example. |
| examples/schedule/schedule_adaptive_limit.py | New adaptive limiting schedule example. |
| examples/roll_example/rlvr_qreward_llm_judge.yaml | New ROLL integration config for QReward-based reward worker. |
| examples/roll_example/README_ZH.md | New Chinese documentation for ROLL integration example. |
| examples/roll_example/README.md | New English documentation for ROLL integration example. |
| examples/normal/single_call.py | Fixes incorrect request hook argument usage in example. |
| examples/normal/batch_call.py | Fixes batch message construction and usage in example. |
| examples/client/client_streaming.py | New streaming client example. |
| examples/client/client_model_router.py | New model router example. |
| examples/client/client_load_balancer.py | New load balancer and failover example. |
| examples/client/client_batch_streaming.py | New batch streaming client example. |
| README_ZH.md | Expands example index tables and adds new sections. |
| README.md | Expands example index tables and adds new sections. |
| Makefile | Adds test-cov/fmt/dev/check targets and updates help text. |
| CLAUDE.md | Adds repository guidance docs and harness workflow description. |
| CHANGELOG_ZH.md | Updates changelog to 0.1.7 with detailed feature list. |
| CHANGELOG.md | Updates changelog to 0.1.7 with detailed feature list. |
| .harness/vision-state.json | Adds/updates harness state for multi-sprint tracking. |
| .harness/sprints/sprint-template.md | Adds sprint contract template. |
| .harness/sprints/SPRINT_INDEX.md | Adds sprint index summary. |
| .harness/scripts/vision-master.sh | Adds multi-sprint orchestrator script. |
| .harness/scripts/regression.sh | Adds full regression script for harness. |
| .harness/scripts/preflight.sh | Adds preflight validation script. |
| .harness/scripts/harness-iterate.sh | Adds evaluation loop script. |
| .harness/prompts/regression.md | Adds regression prompt template. |
| .harness/prompts/planner.md | Adds planner prompt template. |
| .harness/prompts/generator.md | Adds generator prompt template. |
| .harness/prompts/evaluator.md | Adds evaluator prompt template. |
| .harness/config.env | Adds harness configuration. |
| .harness/artifacts/build-context.md | Adds build context artifact documentation. |
| .gitignore | Ignores harness sprint artifacts and logs. |
Comments suppressed due to low confidence (12)
qreward/utils/scheduler/limiter.py:1
- LimiterPool is not thread-safe across sync+async usage:
allow()protects_timeswithself._condition, butasync_allow()uses a separateasyncio.Lock, so_check_and_add()and_sleep_time()can concurrently mutate/read_timesfrom sync and async callers, causing data races and corrupted state. Use a single shared lock to guard_times(e.g., athreading.Lockused by both methods), or implementasync_allow()by delegating to the sync path viaasyncio.to_thread(self.allow, timeout)(tradeoff: uses a thread) so there is exactly one synchronization mechanism around_times.
qreward/utils/scheduler/pools.py:1 can_submit()contradicts its own docstring: comment says 'If historical max exceeds current value * multiply, system is overloaded' (which should typically reject new submissions), but the implementation returnsTruein that case. If the intent is to throttle when overloaded, the return values in the last two branches likely need to be inverted (or the docstring updated to match the intended semantics).
qreward/utils/scheduler/priority_queue.py:1peek()is incorrect for a heap: iterating overself._heapdoes not guarantee the first non-cancelled entry is the priority-minimum (onlyself._heap[0]is guaranteed minimal). This can return the wrong item. A correct approach is to examine the heap root and, if it's cancelled, temporarily pop cancelled roots until you find a non-cancelled one (then push popped items back), or computemin()across non-cancelled entries (O(n)) if you prefer simplicity.
qreward/utils/scheduler/config.py:1update()useshasattr(self, key)which is too broad and can match non-field attributes like properties/methods (e.g.hedged_request_multiply). Attempting tosetattr()a read-only property will raiseAttributeError, breaking hot-reload. Restrict updates to actual dataclass field names (e.g.,self.__dataclass_fields__) and ignore everything else.
qreward/utils/scheduler/sync_runner.py:1execute_impl()submits work viaself._executordirectly without a guard, butSyncRunnerallows construction without callingset_executor(). This can raise anAttributeErrorat runtime. Prefer usingself.create_task(...)here (which already checks and raises a clearRuntimeError), or add an explicit executor check at the start ofexecute_impl().
qreward/client/patch_openai.py:1- The patch stores
Nonewhen the target class (e.g., a dummy/mocked AsyncEmbeddings) has nocreate. In that case,unpatch_openai_embeddings()will later setAsyncEmbeddings.create = None, leaving a broken attribute behind. Consider explicitly tracking whether the attribute existed (e.g., store a sentinel) and inunpatcheitherdelattr(AsyncEmbeddings, 'create')if it originally didn't exist, or restore the original callable if it did.
tests/test_patch_openai.py:1 - This import is added mid-file after test definitions, which commonly triggers
flake8E402 (module level import not at top of file) and makes test dependencies harder to scan. Movefrom qreward.client.patch_openai import unpatch_openai_embeddingsto the existing import section at the top of the file.
qreward/utils/scheduler/telemetry.py:1 - The docstring example references
exporter.span(...), but the class definesstart_span()/end_span()and nospan()method. Also, real OpenTelemetry spans are not typically used as context managers unless created viastart_as_current_span(). Update the example to match the actual API (e.g.,span = exporter.start_span(...)+exporter.end_span(...), or implement aspan()contextmanager wrapper if that's the desired public API).
qreward/utils/scheduler/context.py:1 priorityis stored on the context/config but (based on the new scheduler modules in this PR) it isn't used to influence submission ordering or concurrency decisions. This makes thepriority=parameter on@scheduleeffectively a no-op, while examples/docs imply priority affects execution. Either wirepriorityinto actual scheduling (e.g., a sharedPriorityTaskQueueor priority-aware submission gate), or remove/clearly document it as informational-only to avoid misleading API behavior.
qreward/utils/scheduler/priority_queue.py:1- The new
PriorityTaskQueuehas correctness-sensitive behavior (heap ordering, starvation promotion, cancelled entry skipping), but no dedicated unit tests are added in this PR forget(),peek(), and_apply_starvation_protection(). Add tests that assert: (1)peek()returns the same item as the nextget()without removal, (2) FIFO ordering within same priority, (3) starvation promotion changes dequeue order after threshold, and (4) cancelled entries are skipped.
qreward/utils/scheduler/priority_queue.py:1 - The new
PriorityTaskQueuehas correctness-sensitive behavior (heap ordering, starvation promotion, cancelled entry skipping), but no dedicated unit tests are added in this PR forget(),peek(), and_apply_starvation_protection(). Add tests that assert: (1)peek()returns the same item as the nextget()without removal, (2) FIFO ordering within same priority, (3) starvation promotion changes dequeue order after threshold, and (4) cancelled entries are skipped.
qreward/utils/scheduler/priority_queue.py:1 - The new
PriorityTaskQueuehas correctness-sensitive behavior (heap ordering, starvation promotion, cancelled entry skipping), but no dedicated unit tests are added in this PR forget(),peek(), and_apply_starvation_protection(). Add tests that assert: (1)peek()returns the same item as the nextget()without removal, (2) FIFO ordering within same priority, (3) starvation promotion changes dequeue order after threshold, and (4) cancelled entries are skipped.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
本次提交统一了项目中的代码格式化规则,包括: - 函数参数分行显示 - 条件判断语句分行处理 - 字符串拼接优化 - 注释格式规范化 - 导入语句整理 主要改进了代码的可读性和一致性。 Co-developed-by: Aone Copilot <[email protected]>
将_config_watcher中的_last_update_time初始化值从0改为负无穷,避免首次检查时间戳时出现意外行为。 Co-developed-by: Aone Copilot <[email protected]>
添加了 `test_scheduler_advanced.py`、`test_load_balancer.py`、`test_manager.py`、`test_model_router.py` 和 `test_scheduler_core.py` 测试文件。同时对 `test_globals.py` 中的断言语句进行了格式调整,并更新了 `Makefile` 中的 flake8 排除规则。 Co-developed-by: Aone Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR ships the v0.1.7 release, expanding QReward’s scheduling utilities and client-side routing/load-balancing capabilities, plus adding comprehensive examples, documentation updates, and additional tests.
Changes:
- Added/extended scheduler components (telemetry export, circuit breaker, adaptive limiting, config hot reload, priority queue, new runners).
- Added client routing/load-balancing utilities (LoadBalanceStrategy, selectors, ModelRouter) and improved OpenAI SDK patching/unpatching.
- Updated docs/changelogs/examples/tooling and pinned minimum dependency versions.
Reviewed changes
Copilot reviewed 81 out of 84 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_socket_keepalive.py | Formatting/patch lambda adjustments for keepalive adapter tests. |
| tests/test_retry.py | Minor formatting + added tests for callable retry_on branch coverage. |
| tests/test_patch_openai.py | Adds unpatch_openai_embeddings test coverage + formatting tweaks. |
| tests/test_model_router.py | New tests for ModelRouter selection, health marking, and route listing. |
| tests/test_manager.py | New tests for manager selection behaviors and batch streaming. |
| tests/test_load_balancer.py | New tests for RR/WRR selectors. |
| tests/test_globals.py | New tests covering overload-related global constants. |
| tests/conftest.py | New shared fixtures for OpenAIChatProxy tests. |
| requirements.txt | Pins minimum dependency versions. |
| qreward/utils/socket_keepalive.py | Formatting tweaks + consistent quoting. |
| qreward/utils/scheduler/telemetry.py | New optional OpenTelemetry exporter module. |
| qreward/utils/scheduler/sync_runner.py | New sync runner implementation for schedule execution. |
| qreward/utils/scheduler/priority_queue.py | New thread-safe priority queue with starvation protection. |
| qreward/utils/scheduler/pools.py | New RunningTaskPool implementation + deprecation alias. |
| qreward/utils/scheduler/overload.py | New overload detection helper (iterative exception-chain walk). |
| qreward/utils/scheduler/metrics.py | New ScheduleMetrics dataclass. |
| qreward/utils/scheduler/limiter.py | New sliding-window limiter pool with sync/async APIs. |
| qreward/utils/scheduler/config_watcher.py | New config watcher for hot-reloading schedule config. |
| qreward/utils/scheduler/config.py | New ScheduleConfig with validation, update hooks, and snapshot. |
| qreward/utils/scheduler/circuit_breaker.py | New CircuitBreaker implementation. |
| qreward/utils/scheduler/base.py | New BaseRunner with shared scheduling logic (template method). |
| qreward/utils/scheduler/async_runner.py | New async runner implementation for schedule execution. |
| qreward/utils/scheduler/adaptive_limiter.py | New adaptive rate limiter based on error rate/latency. |
| qreward/utils/scheduler/init.py | Exports scheduler public API surface. |
| qreward/utils/retry.py | Formatting cleanup for retry type checks. |
| qreward/utils/patch.py | Minor formatting changes for optional JSON libs. |
| qreward/utils/init.py | Switches schedule import to new scheduler package. |
| qreward/globals.py | Reformats overload constants; keeps same semantics. |
| qreward/client/patch_openai.py | Adds unpatch_openai_embeddings + original-method tracking. |
| qreward/client/model_router.py | New ModelRouter for model-based proxy routing. |
| qreward/client/load_balancer.py | New RR/WRR selector implementations and strategy enum. |
| qreward/client/init.py | Exposes new client APIs (strategy/router). |
| qreward/_version.py | Version bump to 0.1.7. |
| pyproject.toml | Pins deps + adds optional otel extra + coverage exclude tweak. |
| examples/schedule/schedule_timeout.py | New timeout example for schedule. |
| examples/schedule/schedule_telemetry.py | New telemetry integration example. |
| examples/schedule/schedule_priority.py | New priority example. |
| examples/schedule/schedule_metrics_callback.py | New metrics callback example. |
| examples/schedule/schedule_config_hot_reload.py | New config hot reload example. |
| examples/schedule/schedule_combined.py | New combined “all features” schedule example. |
| examples/schedule/schedule_circuit_breaker.py | New circuit breaker example. |
| examples/schedule/schedule_adaptive_limit.py | New adaptive limit example. |
| examples/roll_example/rlvr_qreward_llm_judge.yaml | New ROLL RLVR config for QReward-based judge worker. |
| examples/roll_example/README_ZH.md | New ROLL integration guide (ZH). |
| examples/roll_example/README.md | New ROLL integration guide (EN). |
| examples/normal/single_call.py | Fixes hook parameter usage example. |
| examples/normal/batch_call.py | Fixes batch_messages construction/usage in example. |
| examples/client/client_streaming.py | New streaming example. |
| examples/client/client_model_router.py | New model-router usage example. |
| examples/client/client_load_balancer.py | New load-balancer/failover example. |
| examples/client/client_batch_streaming.py | New batch streaming example. |
| README_ZH.md | Replaces example links with detailed example index table. |
| README.md | Replaces example links with detailed example index table. |
| Makefile | Adds test-cov/fmt/dev/check targets and adjusts lint exclude set. |
| CLAUDE.md | Adds/updates repo guidance and harness process documentation. |
| CHANGELOG_ZH.md | Adds v0.1.7 changelog entries (ZH). |
| CHANGELOG.md | Adds v0.1.7 changelog entries (EN). |
| .harness/vision-state.json | Updates harness state tracking for completed sprints/features. |
| .harness/sprints/sprint-template.md | Adds sprint contract template. |
| .harness/sprints/SPRINT_INDEX.md | Adds sprint index/summary file. |
| .harness/scripts/vision-master.sh | Adds harness multi-sprint orchestrator script. |
| .harness/scripts/regression.sh | Adds harness regression script. |
| .harness/scripts/preflight.sh | Adds harness preflight script. |
| .harness/scripts/harness-iterate.sh | Adds harness auto-iteration script. |
| .harness/prompts/regression.md | Adds regression prompt/template. |
| .harness/prompts/planner.md | Adds planner prompt/template. |
| .harness/prompts/generator.md | Adds generator prompt/template. |
| .harness/prompts/evaluator.md | Adds evaluator prompt/template. |
| .harness/config.env | Adds harness configuration. |
| .harness/artifacts/build-context.md | Adds harness build context reference. |
| .gitignore | Ignores harness-generated artifacts/logs. |
| .github/workflows/python-app.yml | Increases test step timeout for CI reliability. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
调整了测试中的时间等待阈值,使其更加宽松,以便在Windows系统上避免由于`time.sleep()`精度限制导致的不稳定测试结果。 Co-developed-by: Aone Copilot <[email protected]>
Examples:
Documentation:
Misc: