Answer the turn when binding the tools fails - #23
Conversation
|
Warning Review limit reachedNext included review available in 54 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 Walkthrough变更摘要
Walkthrough本次变更处理工具目录绑定失败,并扩展参数自省结果。内核会返回可识别的失败应答,初始化仍完成握手,外壳不会缓存未成功发送的绑定。 Changes工具目录绑定与自省
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: 🔵 Low · up to The change prevents failed tool binding from hanging startup or execution and avoids losing tool signature details. A bounded lifecycle risk remains if session disposal overlaps an already accepted execution, because the disposed shell could briefly be recreated with its tool access; the PR is mergeable with explicit owner awareness or follow-up. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
你好——我已经审阅了你的更改,整体看起来很棒!
Sourcery 评估
已批准。
请帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用反馈来改进评审。
Original comment in English
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Approved.
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Sourcery withdrew this approval because the latest commits introduced blocking findings.
158e485 to
423298b
Compare
|
Follow-up worth doing once this and #33 are both in: a cross-half assertion on the fold note. Both halves name the folded parameters from the same spec, in their own words — this PR gives The test drives ONE schema through the real pipeline ( const folds = (text) => [...text.matchAll(/["']([^"']+)["']: (\w+)( = \.\.\.)?/g)].map((m) => `${m[1]}: ${m[2]}${m[3] ? ' optional' : ' REQUIRED'}`).sort()
assert.deepEqual(folds(kernelNote), folds(blockNote))It cannot live in either PR alone: against |
Closes #14. All three reproduce at
5518478, and one of them is worse than the issue recorded.1 — a failure before the cell hangs the turn
Building the bindings ran in
_handle, outside_exec's handler — the one whose stated purpose is that an exec is answered however it went wrong. So a spec that raised was logged byserve()'s frame guard and answered by nobody:A host waiting forever on a shell that is demonstrably healthy is the hardest shape to diagnose.
initis the same bug and strictly more reachable, which #14 did not record:start()awaitsready, nothing else resolves it, and the firststart()carries the same specs.The fix is structural rather than per-input, because the issue's own point is that every pre-exec failure is an unanswerable turn — not just this
KeyError. Binding moves inside the try that already guarantees an answer, and the handshake is completed even when nothing binds:dsh-py-codeact/py/kernel.py
Lines 724 to 727 in a9e64ed
dsh-py-codeact/py/kernel.py
Lines 766 to 770 in a9e64ed
Two edge cases improve as a side effect: a
disposeracing anexecused to rebuild the shell with no bindings, and aninitarriving mid-flight used to win over the exec's own catalogue. Both now resolve to the exec's specs. Nothing else calls_exec.2 — a tool with its own
kwargsloses its entire signatureThe overflow parameter is hardcoded
kwargs, so a tool declaring one collided,inspect.Signatureraised, and the blanketcontextlib.suppressdiscarded everything — return annotation and every renderable parameter — which is precisely the regression the comment above it says it fixed.3 — an unrenderable parameter vanishes instead of degrading
The
exceptkept only a boolean, so name, type and required flag were thrown away. Meanwhile the block renders# ... see notion_patch?andlib/index.jspromises "name?still shows the real one" — so a model follows the pointer, sees onlylimit, and the host rejects its call for an argument it was never shown.dsh-py-codeact/py/kernel.py
Lines 234 to 242 in a9e64ed
Required is signalled the way the signature signals it: no
= ....Verification
Five assertions added (115 total, all pass), each mutation-checked by reverting the exact line it guards — every mutation fails its own assertion and no other:
_handlea spec that raises answers the exec rather than hanging itinitguardthe same spec at init still completes the handshakea tool with its own \kwargs` keeps its whole signature`a parameter it cannot spell is still named where the block pointsNote
One existing assertion moved:
a same-named tool with a changed schema is reboundcompared the whole docstring to'REVISED', and that spec carries afile-path, so it now also names what the signature could not spell. It reads the first line instead, keeping its subject — the rebind — intact.The hang tests race an 8 s timeout, so a regression fails the suite rather than wedging it.
Gates:
node test/smoke.js,uvx ruff check py/,TY_UV=scripts uvx ty check py/kernel.py— all clean. Merges cleanly onto8a2d963; the full stack with #22 and #24 runs 130 assertions green.