Reduce local verified first-draft reasoning
ober
e12ddd8429f595a0b112ab88744d0567f178c4b9
--- a/src/jcode/core/verified-run.ss +++ b/src/jcode/core/verified-run.ss @@ -7114,7 +7114,7 @@ (number->string local-pre-edit-inspection-limit) " substantive read/shell/MCP inspections. Do not inspect external Jerboa sources unless one exact API fact blocks the implementation. Write the first complete draft within these budgets. After a failed verify, use at most " (number->string local-inspection-after-failed-verify-limit) - " focused inspections before editing the diagnosed span. Code written in reasoning, analysis, markdown fences, or prose does not change files and will be discarded; put the implementation directly in an edit/write/line_edit/replace_def/replace_range tool call. For the first implementation draft, use one edit/write tool call with the complete file content instead of drafting the file in reasoning. For larger app/game/TUI tasks, write the smallest acceptance-complete vertical slice first: satisfy the verifier's required modes and source hooks, verify it, then add only behavior the verifier proves is missing. Local replace_range edits are transactional: a syntactically broken result is rejected and leaves the on-disk file unchanged.\n") + " focused inspections before editing the diagnosed span. Code written in reasoning, analysis, markdown fences, or prose does not change files and will be discarded; put the implementation directly in an edit/write/line_edit/replace_def/replace_range tool call. For the first implementation draft, use one edit/write tool call with the complete file content instead of drafting the file in reasoning. If you need to plan, keep it brief and emit the edit/write tool call in the same response; a reasoning-only implementation turn makes no progress. For larger app/game/TUI tasks, write the smallest acceptance-complete vertical slice first: satisfy the verifier's required modes and source hooks, verify it, then add only behavior the verifier proves is missing. Local replace_range edits are transactional: a syntactically broken result is rejected and leaves the on-disk file unchanged.\n") "") (if run-aliases? (string-append --- a/src/jcode/provider/provider.ss +++ b/src/jcode/provider/provider.ss @@ -1104,13 +1104,16 @@ (when v (hash-put! body field v)))) *openai-provider-request-fields*)) -(def (apply-local-forced-tool-overrides! body provider) - ;; Local reasoning models can spend a forced tool turn drafting code in - ;; reasoning_content before they emit the required function call. When jcode - ;; has already narrowed the schema and set tool_choice, ask for low reasoning - ;; effort unless the provider config made an explicit choice. +(def (apply-local-verified-overrides! body provider) + ;; Local reasoning models can spend a forced tool turn or verified first + ;; draft drafting code in reasoning_content before they emit the required + ;; function call. Verified local runs bind current-max-tokens-floor/cap; use + ;; that as the provider-layer signal to keep reasoning short unless the + ;; provider config made an explicit choice. (when (and (local-provider? (provider-name provider)) - (current-tool-choice-override) + (or (current-tool-choice-override) + (current-max-tokens-floor) + (current-max-tokens-cap)) (not (hash-get body "reasoning_effort"))) (hash-put! body "reasoning_effort" "low"))) @@ -1595,7 +1598,7 @@ (hash-put! body "max_tokens" (openai-max-tokens provider)) (apply-sampling-to-body! body (provider-model provider) (provider-name provider)) (apply-openai-provider-overrides! body provider) - (apply-local-forced-tool-overrides! body provider) + (apply-local-verified-overrides! body provider) (maybe-apply-logprobs! body provider tools) (apply-prompt-cache-controls! body provider) (hash-put! body "messages" (map (lambda (m) (openai-message->json provider m)) messages)) @@ -2333,7 +2336,7 @@ (hash-put! body "max_tokens" (openai-max-tokens provider)) (apply-sampling-to-body! body (provider-model provider) (provider-name provider)) (apply-openai-provider-overrides! body provider) - (apply-local-forced-tool-overrides! body provider) + (apply-local-verified-overrides! body provider) (maybe-apply-logprobs! body provider tools) (apply-prompt-cache-controls! body provider) ;; Request usage data in stream --- a/test/run.ss +++ b/test/run.ss @@ -5024,6 +5024,12 @@ (and (not (str-contains? s "External MCP tools are available")) (str-contains? s "MCP tools are unavailable in local-model verified sessions")))) + (check-pred! "verified-run: local prompt forbids reasoning-only first draft" + first-history + (lambda (s) + (and (str-contains? s "emit the edit/write tool call in the same response") + (str-contains? s + "a reasoning-only implementation turn makes no progress")))) (check-pred! "verified-run: stale local full rewrite is rejected" (reverse tool-results) (lambda (xs) @@ -12696,7 +12702,9 @@ (provider-chat p (list (make-user-message "hi")) '()))] [req (vector-ref captured 0)]) (check! "mlx local verified floor raises configured max_tokens" - (and req (str-contains? req "\"max_tokens\":8192")) #t))) + (and req (str-contains? req "\"max_tokens\":8192")) #t) + (check! "mlx local verified first draft defaults reasoning_effort low" + (and req (str-contains? req "\"reasoning_effort\":\"low\"")) #t))) (lambda () (putenv "JCODE_MAX_TOKENS" (or old-max-tokens "")) (tcp-close srv))))