Skip to content

feat: sidecar model settings, stream fixes, autostart fallback - #15

Merged
lidge-jun merged 8 commits into
mainfrom
dev
Jun 22, 2026
Merged

lidge-jun merged 8 commits into
mainfrom
dev

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

  • Search/Vision sidecar model settings: Dashboard UI에서 검색 모델과 비전 모델을 독립적으로 설정 가능 (모델 선택 + reasoning effort)
  • Stream timeout fixes: Chat tool choice 및 passthrough stream idle disconnect 문제 수정
  • Codex autostart fallback: 포트 충돌 시 자동 대체 포트 사용 + uninstall 커맨드 추가
  • Devlog: PR [codex] Add Codex autostart ensure fallback #8 autostart ensure 코드 리뷰 및 적용 계획 문서화

Changes

  • gui/src/pages/Dashboard.tsx — sidecar model config UI (search model, vision model, reasoning effort)
  • src/server.ts — /api/config GET/PUT endpoints for sidecar settings
  • src/config.ts, src/types.ts — sidecar model config types
  • src/adapters/openai-chat.ts — chat tool choice fix
  • src/service.ts — stream timeout handling improvements
  • src/cli.ts — autostart ensure fallback + uninstall command
  • src/ports.ts — port availability check + fallback logic
  • Tests added for ports, config, reasoning effort, uninstall, service

Test plan

  • npm test passes
  • Dashboard UI renders sidecar model settings
  • Stream timeout no longer disconnects prematurely
  • Port fallback works when primary port is occupied

🤖 Generated with Claude Code

lidge-jun and others added 8 commits June 21, 2026 17:31
Refined review of PR #8 (codex/auto-start-proxy-port-fallback) with
2 must-fix, 2 should-fix, and 1 note. No code changes — review only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Squash of PR #8 — centralizes startup logic into `ocx ensure`,
adds port fallback when busy, `codexAutoStart` dashboard toggle,
and `ocx uninstall` for clean removal.

Co-Authored-By: 이완우 <Ingwannu@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- server.ts: remove redundant dynamic import of saveConfig, use static import
- cli.ts: log sync failures in handleEnsure instead of silent catch
- Dashboard.tsx: set error state on autostart toggle save failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com>
Dashboard now has two new panels to configure the web-search and vision
sidecar models (+ reasoning effort for search) without editing config.json.
API: GET/PUT /api/sidecar-settings. Supports gpt-5.3-codex-spark.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge origin/main into dev — kept dev's sidecar model settings,
improved error logging, and main's shim internal-command guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lidge-jun
lidge-jun merged commit e1d0fda into main Jun 22, 2026
2 checks passed
lidge-jun added a commit that referenced this pull request Aug 4, 2026
…claimed it did

Six findings, all from executed probes or an independent review that ran the
code rather than reading it.

The one that matters: I wrote that `injectCodexConfig` was a production caller
WP11 could serve on the apply direction. It is not. Production reaches it
directly from sync.ts and cli/init.ts, never through convergence.ts — the only
module this phase was scoped to touch — so the entry point I planned would have
been an export nothing calls. It also awaits history mid-function and there is
no runtime producer of AdmissionSnapshot at all. My own falsification test for
the narrowing fired, so WP11 becomes mechanism-only and the caller moves to WP12,
recorded as such instead of implied away.

The rest:

- The coordinator refuses to open on any routed home (probed both directions:
  clean opens, routed refuses legacy-ambiguous), so moving the catalog commit
  under N would regress every applied install.
- The residue guard reads the ambient CODEX_HOME while the lock keys on a
  caller-supplied one — a routed home locked while a clean one was checked.
  The obvious fix is itself a TOCTOU, and it also refuses a symlinked default
  home against itself.
- ACL success is cached by pathname, not file identity: unlink, recreate at the
  same name, and the replacement is credited with the old file's hardening.
  Absence-as-guarantee #15, and it is live in shipped code.
- Deadline exhaustion is classified as permanent refusal, discarding ETIMEDOUT.
- One citation was wrong and two were short; the type fence redeclares a brand
  that convergence-types and transition-state already own.
wxj123654 added a commit to wxj123654/opencodex that referenced this pull request Sep 16, 2026
…reasoning replay

A bundle of live-calibrated fixes for the Cascade wire:

- session-identity.ts: stable per-conversation ids (lidge-jun#16 cascadeId,
  lidge-jun#15 model config id + monotonic turn counter, lidge-jun#22 exchange id rotated
  per user exchange and absent on the first turn) so a long agent loop
  no longer reads as N brand-new sessions to the velocity limiter
- loop-fuse.ts: conversation-scoped step budget modeled on the language
  server's own mechanism — steer on empty turns, fail closed at the cap
- images.ts: normalize replayed images under the upstream ~14MB nginx
  body cap so one oversized screenshot cannot 413 every later turn
- proto.ts: ASSISTANT source value, ModelConfig (lidge-jun#15), prompt_cache_key
  (lidge-jun#27), and a 413 error that names the real cause
- client.ts: 300s upstream idle budget matching the turn budget, and an
  abort-raced read so a silent stream still trips the idle path
- chat/inbound.ts: replay assistant reasoning_content as a reasoning
  item before the message so downstream providers see the thinking the
  model actually produced
- tests: session identity, loop fuse, images, proto, and inbound
  reasoning-replay coverage; layout maps registered
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
feat: sidecar model settings, stream fixes, autostart fallback
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
…claimed it did

Six findings, all from executed probes or an independent review that ran the
code rather than reading it.

The one that matters: I wrote that `injectCodexConfig` was a production caller
WP11 could serve on the apply direction. It is not. Production reaches it
directly from sync.ts and cli/init.ts, never through convergence.ts — the only
module this phase was scoped to touch — so the entry point I planned would have
been an export nothing calls. It also awaits history mid-function and there is
no runtime producer of AdmissionSnapshot at all. My own falsification test for
the narrowing fired, so WP11 becomes mechanism-only and the caller moves to WP12,
recorded as such instead of implied away.

The rest:

- The coordinator refuses to open on any routed home (probed both directions:
  clean opens, routed refuses legacy-ambiguous), so moving the catalog commit
  under N would regress every applied install.
- The residue guard reads the ambient CODEX_HOME while the lock keys on a
  caller-supplied one — a routed home locked while a clean one was checked.
  The obvious fix is itself a TOCTOU, and it also refuses a symlinked default
  home against itself.
- ACL success is cached by pathname, not file identity: unlink, recreate at the
  same name, and the replacement is credited with the old file's hardening.
  Absence-as-guarantee lidge-jun#15, and it is live in shipped code.
- Deadline exhaustion is classified as permanent refusal, discarding ETIMEDOUT.
- One citation was wrong and two were short; the type fence redeclares a brand
  that convergence-types and transition-state already own.
lidge-jun pushed a commit that referenced this pull request Sep 28, 2026
…tory overflow

- Send the leading system text as GetChatMessage #2 instead of folding it into
  the first user prompt. Live on swe-1-6 with a ~6.7k-token system prompt the
  turn-2 cache ratio is unchanged (6688/6715 vs 7072/7097) and the prompt is
  smaller; swe-1-6, swe-2-medium, gemini and claude all obey #2.
- Mark failed tool results with ChatMessagePrompt #9 tool_result_is_error
  instead of an in-band "ERROR:" prefix.
- Rewrite JSON-Schema type arrays to anyOf in tool parameters for Gemini uids,
  which Cognition refuses with invalid_argument on every turn.
- Surface a pre-output invalid_argument on a history near or past the model's
  input window as context_length_exceeded so Codex compacts; small requests
  with the same code stay a plain 400.
- Correct the #15 (CortexTrajectoryReference), #17 prompt_id and #22
  execution_id comments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 29688bf)
lidge-jun pushed a commit that referenced this pull request Sep 28, 2026
…tory overflow

- Send the leading system text as GetChatMessage #2 instead of folding it into
  the first user prompt. Live on swe-1-6 with a ~6.7k-token system prompt the
  turn-2 cache ratio is unchanged (6688/6715 vs 7072/7097) and the prompt is
  smaller; swe-1-6, swe-2-medium, gemini and claude all obey #2.
- Mark failed tool results with ChatMessagePrompt #9 tool_result_is_error
  instead of an in-band "ERROR:" prefix.
- Rewrite JSON-Schema type arrays to anyOf in tool parameters for Gemini uids,
  which Cognition refuses with invalid_argument on every turn.
- Surface a pre-output invalid_argument on a history near or past the model's
  input window as context_length_exceeded so Codex compacts; small requests
  with the same code stay a plain 400.
- Correct the #15 (CortexTrajectoryReference), #17 prompt_id and #22
  execution_id comments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 29688bf)
lidge-jun added a commit that referenced this pull request Sep 28, 2026
…flag tool errors, system prompt in #2 (carry #6092) (#6178)

* fix(devin): system prompt in #2, tool-error flag, Gemini schemas, history overflow

- Send the leading system text as GetChatMessage #2 instead of folding it into
  the first user prompt. Live on swe-1-6 with a ~6.7k-token system prompt the
  turn-2 cache ratio is unchanged (6688/6715 vs 7072/7097) and the prompt is
  smaller; swe-1-6, swe-2-medium, gemini and claude all obey #2.
- Mark failed tool results with ChatMessagePrompt #9 tool_result_is_error
  instead of an in-band "ERROR:" prefix.
- Rewrite JSON-Schema type arrays to anyOf in tool parameters for Gemini uids,
  which Cognition refuses with invalid_argument on every turn.
- Surface a pre-output invalid_argument on a history near or past the model's
  input window as context_length_exceeded so Codex compacts; small requests
  with the same code stay a plain 400.
- Correct the #15 (CortexTrajectoryReference), #17 prompt_id and #22
  execution_id comments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 29688bf)

* fix(devin): measured overflow boundary, per-type Gemini branches, tool-error marker

- Overflow: binary-searched live on swe-1-6 (200k window) the refusal sits at
  ~200-203k real tokens for prose and JSON alike, and a 32000 output cap does
  not move it. Characters per token ran 1.33-5.53 across samples, so the
  chars/4 estimate is replaced by a word-piece count (1.00-1.54x real) at 95%
  of the window: every sample at the window is caught, none at 60% is.
- Gemini schemas: `{type:[T,"null"], ...}` becomes anyOf branches that carry
  the type-specific keywords (items, properties, ...); an existing anyOf is
  folded in rather than nested under allOf. Draft-7 `dependencies` is walked as
  a schema map with name lists left as data.
- Tool errors keep the in-band ERROR: marker beside #9: with a neutral result
  flagged as an error only gemini reported a failure; swe-1-6, gpt-6-sol-low
  and gpt-5-6-luna-low read it as success.
- A request with only system text keeps it as a user prompt instead of
  sending no prompts.
- Docs: describe the context_length_exceeded reclassification beside the
  allowDevinInvalidArgument recovery option.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit d84edae)

* fix(devin): keep outer constraints when folding a Gemini anyOf

Folding each existing anyOf branch into the outer keywords let a branch
override a contradicting outer keyword, so `{maxLength: 5, anyOf:
[{maxLength: 50}]}` loosened to 50. On any such disagreement, keep both
constraints under allOf instead; live, gemini-3-8-flash-medium accepts
allOf.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit db28e2d)

* docs(devin): match the collapseSystemIntoUser example to the #2 system prompt

The example still showed the leading system messages folded into the
first user turn, which now travel in request #2. Show a mid-conversation
system run instead, with the real blank-line join, and note that a
system-only request passes through whole.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b2d9ded)

* docs(devin): show the blank-line join in the collapse example

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 3232330)

* fix(devin): keep both constraints when a Gemini type union and anyOf are disjoint

When no existing anyOf branch shared a type with the type array, the
fallback kept the anyOf and dropped the type union, so the branches
admitted types the node never allowed. Keep both under allOf, the same
form the conflict path uses; live, gemini-3-8-flash-medium accepts it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit b87b332)

* fix(devin): classify overflow from the selected catalog window

Co-authored-by: Sayo <hi@sayo.wtf>

* fix(devin): preserve null constraints in Gemini schema rewrite

Co-authored-by: Sayo <hi@sayo.wtf>

* docs(devin): record malformed-schema overflow ambiguity

Co-authored-by: Sayo <hi@sayo.wtf>

* fix(devin): preserve outer schema constraints on nullable types

Co-authored-by: Sayo <hi@sayo.wtf>

* fix(devin): estimate overflow from transmitted tool descriptions

Co-authored-by: Sayo <hi@sayo.wtf>

* docs(structure): keep the effective Devin family default in the adapter row

Co-authored-by: Sayo <hi@sayo.wtf>

---------

Co-authored-by: Sayo <hi@sayo.wtf>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lidge-jun added a commit that referenced this pull request Oct 4, 2026
Named Devin conversations retain an upstream trajectory across sequential turns and request-scoped adapters. Scope retained IDs by resolved credential, tenant host, and conversation; use fresh IDs for overlaps and when every retained slot is active. A 256-entry store evicts only inactive entries, and idempotent release in `finally` covers success, failure, and cancellation. The optional wire field preserves per-request allocation for unnamed calls.

Refines #6488 at `a0b199fc6b96367fb174f6488a7a45eb58eccd54`. Carries the optional #15.1 field, named continuity across adapters, unnamed fallback, overlap isolation, and failure release regressions. Replaces the source's map-plus-live-set with one bounded store, hashes a structured identity tuple, and prefers own-thread identity over a shared parent. Adds credential/host/alias/parent/cancellation/eviction/overflow/idempotence/retry coverage and documents the contract. The original author's live cache measurements are original source evidence; this replacement does not claim new measured savings. Independent of #6554; neither PR's runtime commits are required by the other. Coordinator owns source disposition.

Co-authored-by: Hanqing Zhao <hanqing@gatech.edu>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

Verified current head f09d987 with CI 37174376575 and scoped independent technical/security review.

Co-authored-by: Hanqing Zhao <hanqing@gatech.edu>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants