Devin catalog emits '$4 / 1M Input · $0.2 / 1M Cached input · $20 / 1M Output'
but the vendored parseCost only matched '/MTok In/Out', leaving output and
cached prices at 0 so session cost totals for devin models were wrong.
Accept 1M Input/Output/Cached input labels and use the real cached-input
price for cacheRead instead of the 10% input heuristic.
- Vendor the patched pi-devin@0.1.2 tree at apps/pi-devin/upstream/
(third-party archive -> upstream_fork); git history replaces the patch
layer as the change archive. Includes the devin-desktop identity fix
and normalized catalog variant mapping from the previous patch.
- build-pi-package.sh now verifies source.sha256 against
host-local-packages.json and npm-packs the vendored tree; drop the
npm fetch + patch stage.
- install-pi-package.sh strips the npm-pack package/ prefix to match
the playbook's unarchive behavior.
- Deployed to a100 via deploy_pi_devin_package (--limit a100, R2 then
R3); remote verified to carry the fork source.
Ports #6 with optional-field validation, conversion before cache writes, an upstream-specific cache directory, and startup regression tests.
Co-authored-by: dualface <dualface@gmail.com>
KNOWN_BINS only listed Unix/macOS paths, and whichDevin() always shelled
out to /usr/bin/which. On Windows neither resolves, so the provider could
not find `devin.exe` even when it was installed and on PATH. The model
catalog therefore never loaded and the provider silently fell back to the
four hard-coded FALLBACK_MODELS entries.
- Probe the documented Windows install locations (%LOCALAPPDATA%\devin\
cli\bin\devin.exe, the Devin Desktop bundled CLI for both per-user and
machine-wide installs, plus two fallbacks).
- Build the candidate list lazily so a DEVIN_CLI value set after module
load is still honoured.
- Use `where` instead of /usr/bin/which on Windows, and accept multiple
result lines, since `where` prints one path per line.
All existing Unix/macOS paths are preserved.
Tested on Windows 11, Node 24.5.0, pi 0.87.1, Devin CLI 3000.11.3:
`pi --list-models devin` goes from 4 models to 52 with DEVIN_CLI unset.
`tsc --noEmit` and the existing test suite both pass.
`void resp.body?.cancel()` in streamChatEvents' finally floated a
rejected promise: an aborted fetch errors the body with the abort
reason, and cancel() on an errored stream rejects with it, escaping
as unhandledRejection -> uncaughtException and killing pi on Escape.
Await the cancel inside the existing try/catch so the rejection is
actually swallowed. Adds a regression test that aborts a mocked
in-flight stream and asserts no unhandled rejection is raised.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
pi 0.86.0 hands custom providers a TranscriptContext: `systemPrompt` and
`tools` are gone, and tool declarations live in the transcript's system
messages. Reading `context.tools` therefore sent zero tools to Devin, so
every Devin model answered that it cannot run commands, and the system
prompt was dropped with it.
Collapse the system messages first, then take the prompt and the current
tool set from the replayed transcript.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With ide=windsurf, GetChatMessage rejects every GPT-5.6 variant with
'This model is only in Devin Local.' Switching the client identity to
devin-desktop makes the server serve them; response-header wire echo
confirms the exact model (gpt-5-6-sol-high -> 'GPT-5.6 Sol High Thinking').
Unknown UIDs still hard-error, so there is no silent fallback.