CNSeniorious000 / CNSeniorious000/dsh-py-codeact
`_make_binding` fails three ways without saying so — one of them never answers the turn
- Dominant language
- JavaScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 2h 47m
- Merged PRs (30d)
- 27
Description
All three reproduced against a live kernel at `3c0195f`. They share a cause: the failure paths in `_make_binding` are narrower than the inputs, and each degrades silently.
### 1. A malformed spec makes the turn hang forever
```js
k.exec('1 + 1', undefined, [{ name: 'read', doc: 'r', params: [{ type: 'str', required: true }] }])
```
A parameter dict with no `name`, so `p["name"]` raises `KeyError` — not in the `except (ValueError, TypeError)` tuple. Observed:
```
first exec -> {"timeout": 4002} the promise never settles
shell after -> {"repr": "4"} the very next cell on the same shell is fine
```
`_handle` calls `_session_for(shell, specs)` **before** wrapping the exec in `_exec`'s blanket handler, whose stated purpose is that an exec must be answered or the host hangs. So this lands outside it, `serve()`'s frame guard prints to the real stderr and sends nothing, and the host waits forever on a shell that is demonstrably healthy — the hardest shape to diagnose.
dsh's own `toolSpec()` always fills `name`, so reachability is low. The structural point stands regardless: **every pre-exec failure is an unanswerable turn.**
### 2. A tool with a parameter named `kwargs` loses its entire signature
```
spec: weird(kwargs: str = ..., file-path: str)
str(inspect.signature(weird)) -> '(**kwargs)'
```
`file-path` is unrenderable, so the fold appends a hardcoded `VAR_KEYWORD` named `kwargs` — which collides with the real parameter, `inspect.Signature` raises, and the blanket `contextlib.suppress` discards everything. Docstring, return annotation and every renderable parameter gone, with no error and no log, while the prompt block still prints the full list. That is precisely the regression the comment above it says it fixed.
### 3. An unrenderable parameter vanishes instead of degrading
```
spec: notion_patch(file-path: str [required], limit: int = ...)
notion_patch? -> (*, limit: 'int' = Ellipsis, **kwargs) -> 'Any'
```
The **required** `file-path` appears nowhere, with no marker that anything was dropped. The `except` keeps only a boolean; the name, type and required flag are thrown away. Meanwhile the block emits `# parameter names are not all valid Python; see notion_patch?` and `lib/index.js` promises "`name?` still shows the real one" — so a model follows that pointer, sees only `limit`, calls `notion_patch(limit=10)`, and the host rejects it for an argument the model was never shown.
### Shape
1 is a liveness bug; 2 and 3 are honesty bugs where the fallback is quieter than the thing it replaced. 2 and 3 both contradict comments in the same function that claim the opposite.
Contributor guide
No contributing guide indexed for this repository
Research direction
Trace `_make_binding` through `_handle`, `_session_for`, `_exec`, and the `serve()` frame guard, then inspect the related handling in `lib/index.js`. Reproduce the malformed spec, the `kwargs` collision, and the unrenderable parameter case against a live kernel; done means each failure is surfaced or answered, and the fallback signature preserves the information the prompt promises.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, python
- Domain
- backend, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100