Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
6b44b1b
feat(engine): POST /provider/probe one-token reachability probe with …
aarontrowbridge Oct 28, 2026
8bd9f3a
test(service): RED — model-reachability cache, rate limit, demote, ru…
aarontrowbridge Oct 28, 2026
89db4ab
feat(service): model-reachability cache + scheduler + GET/refresh/dem…
aarontrowbridge Oct 28, 2026
b6f4708
test(app): RED — picker reachability merge: visible set, toggle count…
aarontrowbridge Oct 28, 2026
f78c29a
feat(app): model picker hides dead models — 'Show unavailable (N)' wi…
aarontrowbridge Oct 28, 2026
9f07829
test(app): RED — dead-pick: demote-class vs transient turn errors, fr…
aarontrowbridge Oct 28, 2026
c092d07
feat(app): fail fast on a dead pick — demote on denied/unavailable/in…
aarontrowbridge Oct 28, 2026
d974e7e
test(app): RED — picker short list: favorites → recommended → recent …
aarontrowbridge Oct 28, 2026
491289a
feat(app): model picker short list — favorites (star, persisted) → re…
aarontrowbridge Oct 28, 2026
be98bd2
Merge remote-tracking branch 'origin/opencode/1989-dead-pick' into am…
aarontrowbridge Oct 28, 2026
fccbd34
test(app): RED — picker row meta formatter (price rounding / free / m…
aarontrowbridge Oct 28, 2026
9026bc1
feat(app): model picker row meta — $in/$out · cache per Mtok, context…
aarontrowbridge Oct 28, 2026
5e4ae2c
test(engine): RED — probe retries once at a max_output_tokens floor (…
aarontrowbridge Oct 28, 2026
ee09bcc
fix(engine): probe retries once at a max_output_tokens floor (parsed …
aarontrowbridge Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions packages/app-bundle/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@
"packages/app/src/components/dialog-release-notes.tsx": "0ea5b049786787643a7f6b54d4ccf84c4f8ffa4e8272426c0d32f60d445b6890",
"packages/app/src/components/dialog-select-directory-v2.css": "2e2f18abdca77f9fe85da157c40f288f3b1641ca92845208749e16455fd58637",
"packages/app/src/components/dialog-select-file.tsx": "e6278ee35dd27d203e00ad73f70c709c44a6c06f81ffbd931edfaa0c986b9e03",
"packages/app/src/components/dialog-select-model-reachability-source.ts": "ecd6c5e5f1df6d9e71cc87483d87870acb5c42140d580262c9dc76a8bd8453bf",
"packages/app/src/components/dialog-select-model-reachability.test.ts": "03e4a5e72a03f2c7c05deed3eb008a7f832af7e9beb10d2889c9fe92061e3346",
"packages/app/src/components/dialog-select-model-reachability.ts": "479403f9e2c799542e89fa0a28d4271684c48deccf02bd1e7c2caed9482e1602",
"packages/app/src/components/dialog-select-model-shortlist-source.ts": "3de6605f0e950a0af9e01297f492b14940fb1ef2456afb584215ab5e0a1455c1",
"packages/app/src/components/dialog-select-model-shortlist.test.ts": "57aa5604f7d9cba9f0f82103f382c988e9ea26a2cf104d14e89e56f0b1b0bc29",
"packages/app/src/components/dialog-select-model-shortlist.ts": "3412a56925a540c2d0843406f7018f689b990ff4a81402ee2ed35767590cfbcd",
"packages/app/src/components/dialog-select-model.tsx": "3773becba23527b2b31afd55d337eb61bc3fa4dcd5c9dd5a9b85500af841bea2",
"packages/app/src/components/engine-state-signal.ts": "2726628b85d4bc58bf6b3bd3045fc4239ad384deaba14fc8f46b818741549a5e",
"packages/app/src/components/engine-toggle-utils.test.ts": "bf53ca7a6fac3696f8d9aac032ceee5e35fb3b7e3dfaef3f9afb1fa0ff3135bb",
"packages/app/src/components/engine-toggle-utils.ts": "bab8a7ddef9f49d4fc243477b7206feb741afdf5ec154a2d70a9f31c814f8c5d",
Expand All @@ -129,6 +136,12 @@
"packages/app/src/components/harness-switch.test.ts": "db263ece42911e756fb8b6e88697a6bbbd0d1317decd1e63b027d9fe8c69b405",
"packages/app/src/components/harness-switch.ts": "b4cb2b2241d71c477be71285fe6041d4b0d604a26d74c30dc5239694211a1f90",
"packages/app/src/components/help-button.tsx": "780d533f776a784660cfed072a131198bc6fcc8e8fe332e8e1a220d516c9684e",
"packages/app/src/components/model-dead-pick-warning.tsx": "51a3b761437e7cf0d33d49cf06ffa7be20c59cbdfb073637a5d7945e67840c14",
"packages/app/src/components/model-dead-pick.test.ts": "b4bd51255fffc12ca92ebeb21893e2d1ee329cc5845c0dfe0a79cb1c82419013",
"packages/app/src/components/model-dead-pick.ts": "eaa584e8072b59a9a6f0b4056c202ffeff4d96c8a0270d962b3d004e2d79f143",
"packages/app/src/components/model-row-meta.test.ts": "51c5e8b9c4ef3f8e2616e63c8cbc16ae055dedc5fec7c24280ed28a3712938ad",
"packages/app/src/components/model-row-meta.ts": "7870b265f4ca9b08505ae6f1b0afb66ca002fe05f67c3b8194417a45f0b170cd",
"packages/app/src/components/model-tooltip.tsx": "c402abe9674806c9dd308589d7acb96dfd9c400299e650a94fcc44a165e920e2",
"packages/app/src/components/new-session-machine-picker.ts": "8c7689f79c7610e32fef478320870d1468fa17a3a02463e2cbe058a487fb4769",
"packages/app/src/components/pane-bridge.tsx": "756b3306b51c963fac6778716f6c6c4626f0f3bf75c93b7cb4cab58ea0bf3d4e",
"packages/app/src/components/profile-popover.tsx": "eff742e90544455f13234a9351bb1b82189663cba2cd3172bdcea1a8a37284e8",
Expand Down Expand Up @@ -194,7 +207,9 @@
"packages/app/src/context/local-agent.test.ts": "a5a9d60bb4401d409218cc247c1cc06ede8b7878ddf01dc6080328f54eb9cade",
"packages/app/src/context/local-agent.ts": "0aab67e695dc3bb45a733ac0df80a0a5e14cfe29b2375b6dc3cd07fbccea33e2",
"packages/app/src/context/local.tsx": "3ab8b9fc2db082df4ba485373679f00a95d0ffe3c691a0afee1dc53db7eabd9e",
"packages/app/src/context/models.tsx": "8904525767b36ed5ba93e85a0fddb9bf737a8d066dfff084380ce1a67182f535",
"packages/app/src/context/models-favorites.test.ts": "6336bc4dd46a0492e393110ee7aab6ee58f152982ec657e17ad9f750d22483f8",
"packages/app/src/context/models-favorites.ts": "60d4e6889ca9143432417f624ddee14047f14bcfd1325fca2f491fb19803b1a2",
"packages/app/src/context/models.tsx": "39821854ea95753c583c05f9b911a0898ed8ef7b6da49613a19aa3ee39404707",
"packages/app/src/context/platform.tsx": "edd9b1773feb5c084b922a57b6914f6a473eed558b44f9de0eeb1c4d4e2b49da",
"packages/app/src/context/question-inbox.test.ts": "d4e2c666194fe6463d1a1da1901f2aef3b6a17eec00394a2b020d7ce698d4c92",
"packages/app/src/context/question-inbox.ts": "f42a2490670e44578f88d626bc0db0a0205fa2b5ec7cd719ba0544915f3a6179",
Expand Down Expand Up @@ -238,7 +253,7 @@
"packages/app/src/i18n/compaction-failure.test.ts": "a4a3765beb238a2c157c07c9c8ede8418b9febb814d8d1e3a5b2d8868cbd80d9",
"packages/app/src/i18n/da.ts": "db685cb94f22ace194850efe9bdc02c530777a4583dc9eb9d00b97002b0a0968",
"packages/app/src/i18n/de.ts": "c440ad7543321cae1425e0c2fad92ff73963f21672fbf31176831933573bf103",
"packages/app/src/i18n/en.ts": "d073d90198297bcc33ad5da1975a3829250b20a1e18fec35eb65809c35fca973",
"packages/app/src/i18n/en.ts": "068394508cd4af085017cbd9344dd8e7ef6d6a85fa6f4be4251520834eee95fc",
"packages/app/src/i18n/es.ts": "8cdec3592cddf0b91d7fd59002c81c4e8973c5bf6573e065df64d48c42e1802f",
"packages/app/src/i18n/fr.ts": "b9f646352189054b6918bfbac670579e76418c3148eb7e5afca9d71d97e7f2b7",
"packages/app/src/i18n/ja.ts": "27ffc41a0fd8dc4b2e814a45c55fad4726ff1c7a85c884cf6af95f8397f17cbf",
Expand Down Expand Up @@ -357,7 +372,8 @@
"packages/opencode/src/project/instance-context.ts": "65a35792e50e96a50ea14cd9f928045c0e2fc15eb49506f5bbceee38c4af1457",
"packages/opencode/src/project/instance-store.ts": "c22d3e2499e63dd8d9395d58189df75444d306774df833e746f22e327edcf2ab",
"packages/opencode/src/provider/auth.ts": "b0ab1322c1039e27176bf9e3500603eae27506065ac141a69710220f3361f6b8",
"packages/opencode/src/provider/error.ts": "d72310be26cfae5c2943f9939a6461e848532a5646ff405d628e9a50fc1ebe91",
"packages/opencode/src/provider/error.ts": "eef84e43f4d0f2779e53a5570498d08d2f339fdc01c24c12046b9107dacef516",
"packages/opencode/src/provider/probe.ts": "6f5b7f3a201a67b66c387411f4c893c7e91ca74a70fdcf7b220f1a2ff511adc7",
"packages/opencode/src/provider/provider.ts": "b89bc0ca0a12ea0cfaf5c956a4b731a0397d4c407e787a16cdd66fb7f54ee476",
"packages/opencode/src/provider/transform.ts": "70c7492d4a23a30ebc340a5605702b1602960f4b412e18557534e02962c137b8",
"packages/opencode/src/question/index.ts": "8317348c2ca27dd9e4f7d18fdc126a4d355c20495c1b86668430ad477a68e9b3",
Expand Down Expand Up @@ -442,7 +458,7 @@
"packages/opencode/test/server/httpapi-file.test.ts": "d3386129bc81467ecbcc57a3861f53767ee56ac41b4ff6ad58d8b168fb3b3373",
"packages/opencode/test/server/httpapi-global-event.test.ts": "8a78dc59edf48eb3cf6d1c09448f7dfe5ceb138e1bd6125949ebc88976c903f0",
"packages/opencode/test/server/httpapi-instance-route-auth.test.ts": "4b73a89d2431c02bc3b665d93f9002914e51eb1add979dc1867efbcbc0c36e25",
"packages/opencode/test/server/httpapi-provider.test.ts": "9e8b3e085b478e3f99b689ffff600e10c0b4b50b3cabdbd749f88dae19bf5904",
"packages/opencode/test/server/httpapi-provider.test.ts": "a047ee63f5a1000738a33afc4fee6c19c994ffe6ba12e124e34b83762e11ac47",
"packages/opencode/test/server/httpapi-session.test.ts": "eda6fd763ac4c17891cedaa4ccd49597c03e7227fcfdcf0f94a1b4545ba623ed",
"packages/opencode/test/server/httpapi-ui.test.ts": "d029e959cfd9347fff4cf17c5686dd125b0bd3a41afb3408a23b31418f12e3b0",
"packages/opencode/test/server/pasqal-secret.test.ts": "54be8c666160dad22cd37bbf041f5bd40aec120271818f3c56c94107d987b9fb",
Expand Down Expand Up @@ -820,7 +836,7 @@
"packages/app/src/pages/new-session/new-session-machine-picker.test.ts": "2f2adf9d738aee98f2989c5453c97eeba0e48522b7863c99d9c0be9a6c11ff3b",
"packages/app/src/pages/new-session/new-session-machine-selection.ts": "618df365b74547d997920fa3d14e1f73f3b5d618e54f2b1297b8374535900f7a",
"packages/app/src/pages/new-session/new-session-view.test.ts": "eb337485bf03facbc59d9eadac37cfeb04f75bf97814df80d3be4d0ec9455047",
"packages/app/src/pages/new-session/new-session-view.tsx": "8fa065e3d792f99de6fdb6f0de8c6205fab519159342655fe59fc09ea67691b1",
"packages/app/src/pages/new-session/new-session-view.tsx": "9390bb0c6d24d6ad1cbc753b6a57d85488a7355264e37641991a931769a3f482",
"packages/app/src/pages/session/amicode-session-relay.integration.test.ts": "4991e775d3a6c63a514072ccfa5aad190c586383b77ef41689c853fb271d3bf4",
"packages/app/src/pages/session/fleet-manager-tab.test.tsx": "f3bb956e343ccd82acd8bf38c9ad2413d48b24ec9f484c5dfd3939d9e07139b7",
"packages/app/src/pages/session/fleet-manager-tab.tsx": "1e7db225a1f2fa3234e0eb47f314de49185db1f3ebddb5585fd0247184adebaa",
Expand Down Expand Up @@ -951,8 +967,8 @@
"packages/app/src/pages/session/composer/session-bug-dock.stories.tsx": "a5730bb3699751d63629134924ce8dea021b264722c40f5f6bb98236dc15eda7",
"packages/app/src/pages/session/composer/session-bug-dock.tsx": "e7fed3c5ab80527d69a106440833f795bbbafc5deeba3883902ede9fba612605",
"packages/app/src/pages/session/composer/session-composer-controls.ts": "7ba9d56c81b1547acbdd47c4f9371ddc37c9a92059f5785f7286fc68e0cb4483",
"packages/app/src/pages/session/composer/session-composer-region-controller.ts": "d0403567856eb07ee93957e6d8a23c0f5c78620d94fa09407c01fc6ad3d9eadc",
"packages/app/src/pages/session/composer/session-composer-region.tsx": "415cd5c3a77b625a3142b828b6458687e1a35b382d3a208d90ff1555cc7098b1",
"packages/app/src/pages/session/composer/session-composer-region-controller.ts": "39b05c06b9e9ed42678d6b35dd2e2acd323e0ede8587a5592923c74f38307aca",
"packages/app/src/pages/session/composer/session-composer-region.tsx": "fcede95d91c72254d46481140adb3ff33d5ec69a54760f5a201fe87d0a2b1e6e",
"packages/app/src/pages/session/composer/session-composer-state.ts": "fcffa11d801309cf58f42a174143bf6eb3ea2b14f860ad91a8ffa4e097df5c16",
"packages/app/src/pages/session/composer/session-question-dock.helpers.test.ts": "a1fe31fe4dfdf2914bc184030a0427bcbdfae0f3e7b146e1d6ee29ce31d85b64",
"packages/app/src/pages/session/composer/session-question-dock.helpers.ts": "b16282d0cf5d39152bd76f4ef8bac32f964f68143a3067765ae0827a5f90deed",
Expand Down Expand Up @@ -1005,14 +1021,14 @@
"packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts": "944a0aee215a917e867fd9482f3c2bd40f49082bd3174c8a7d967ca40e34ec15",
"packages/opencode/src/server/routes/instance/httpapi/groups/file.ts": "a96fdc55ddb95ca7c481c86f67e37ed88d4cf2a190a482765ab55ce4409f3a59",
"packages/opencode/src/server/routes/instance/httpapi/groups/mcp.ts": "048efa7b74d43c4ad4a75d0f8421c808760c8c0dcd593f0051a87044e40487d6",
"packages/opencode/src/server/routes/instance/httpapi/groups/provider.ts": "34c6f1ab1a085d1b047c220bbff32a36032dc5e924784e9272cda166cf0ec84b",
"packages/opencode/src/server/routes/instance/httpapi/groups/provider.ts": "2d090445392a2c52efb26335297f4d44c70aa511b0524e4cd3a69880ffdc6078",
"packages/opencode/src/server/routes/instance/httpapi/groups/session.ts": "1421f8c07948b121c7e2005bd9b0fcd6b2c456565ddd1da32d8e6c35d03fac9c",
"packages/opencode/src/server/routes/instance/httpapi/handlers/event.ts": "88c7bae32fa01ab213e95cb4e4891fd3ccb961782e80a416e321c5daf90fb487",
"packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts": "69ca3dd48d95157fc822e1f76eb42ac873df50f22616b85194619ca658613867",
"packages/opencode/src/server/routes/instance/httpapi/handlers/file.ts": "10bcb79b117beebee04184fb48c1ad789e782e2f7ae4b0c68603edc00f03aee9",
"packages/opencode/src/server/routes/instance/httpapi/handlers/global.ts": "040554475b6ba22ad666dfeaca2576658854c46cd18efe3b2d68959f9eaaed80",
"packages/opencode/src/server/routes/instance/httpapi/handlers/mcp.ts": "7da08d58765cdf2b6ce4648fc70de371402949f5bb7b75696f674d43f2d5365b",
"packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts": "8baf16cad0992c5351b61b0c0fb27903bb25b17e1b25fc7c5d77f807c24413a6",
"packages/opencode/src/server/routes/instance/httpapi/handlers/provider.ts": "e899320a028e639a845d6c6aef547d448341671a195f5465ee4e8fa847957c52",
"packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts": "b37ff4136c4aea85b23083bf441f03e09820e3e4cdd95e4118ca570d8435b94f",
"packages/opencode/src/server/routes/instance/httpapi/middleware/file-write-workspace.ts": "665c33633173ee89c6da1d4a0eaacaf4eebe3ccdd04eb36b063515cb4c093e4a",
"packages/opencode/src/server/routes/instance/httpapi/middleware/gateway-secret.ts": "ec6133ee5d331920ded81042fbeb05221bec0c4b26f5897b3f28bc267d26aefa",
Expand All @@ -1031,11 +1047,11 @@
"packages/ui/src/v2/components/text-shimmer-v2.tsx"
],
"exceptions": [],
"extracted_at": "2026-10-26T18:34:42.306Z",
"extracted_at": "2026-10-28T19:40:57.940Z",
"per_package": {
"packages/app": {
"A": 257,
"M": 164,
"A": 270,
"M": 166,
"D": 0
},
"packages/core": {
Expand All @@ -1049,7 +1065,7 @@
"D": 0
},
"packages/opencode": {
"A": 101,
"A": 102,
"M": 100,
"D": 0
},
Expand Down Expand Up @@ -1080,7 +1096,7 @@
}
},
"counts": {
"overlay_total": 1009,
"overlay_total": 1025,
"deletions": 7,
"server_coupled": 0
},
Expand Down Expand Up @@ -1198,6 +1214,13 @@
"packages/app/src/components/dialog-release-notes.tsx": "M",
"packages/app/src/components/dialog-select-directory-v2.css": "M",
"packages/app/src/components/dialog-select-file.tsx": "M",
"packages/app/src/components/dialog-select-model-reachability-source.ts": "A",
"packages/app/src/components/dialog-select-model-reachability.test.ts": "A",
"packages/app/src/components/dialog-select-model-reachability.ts": "A",
"packages/app/src/components/dialog-select-model-shortlist-source.ts": "A",
"packages/app/src/components/dialog-select-model-shortlist.test.ts": "A",
"packages/app/src/components/dialog-select-model-shortlist.ts": "A",
"packages/app/src/components/dialog-select-model.tsx": "M",
"packages/app/src/components/engine-state-signal.ts": "A",
"packages/app/src/components/engine-toggle-utils.test.ts": "A",
"packages/app/src/components/engine-toggle-utils.ts": "A",
Expand All @@ -1206,6 +1229,12 @@
"packages/app/src/components/harness-switch.test.ts": "A",
"packages/app/src/components/harness-switch.ts": "A",
"packages/app/src/components/help-button.tsx": "M",
"packages/app/src/components/model-dead-pick-warning.tsx": "A",
"packages/app/src/components/model-dead-pick.test.ts": "A",
"packages/app/src/components/model-dead-pick.ts": "A",
"packages/app/src/components/model-row-meta.test.ts": "A",
"packages/app/src/components/model-row-meta.ts": "A",
"packages/app/src/components/model-tooltip.tsx": "M",
"packages/app/src/components/new-session-machine-picker.ts": "A",
"packages/app/src/components/pane-bridge.tsx": "A",
"packages/app/src/components/profile-popover.tsx": "A",
Expand Down Expand Up @@ -1271,6 +1300,8 @@
"packages/app/src/context/local-agent.test.ts": "M",
"packages/app/src/context/local-agent.ts": "M",
"packages/app/src/context/local.tsx": "M",
"packages/app/src/context/models-favorites.test.ts": "A",
"packages/app/src/context/models-favorites.ts": "A",
"packages/app/src/context/models.tsx": "M",
"packages/app/src/context/platform.tsx": "M",
"packages/app/src/context/question-inbox.test.ts": "A",
Expand Down Expand Up @@ -1435,6 +1466,7 @@
"packages/opencode/src/project/instance-store.ts": "M",
"packages/opencode/src/provider/auth.ts": "M",
"packages/opencode/src/provider/error.ts": "M",
"packages/opencode/src/provider/probe.ts": "A",
"packages/opencode/src/provider/provider.ts": "M",
"packages/opencode/src/provider/transform.ts": "M",
"packages/opencode/src/question/index.ts": "M",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// amicode#1986 (#1979 S3): the picker's reachability data source — fetches the
// S2 snapshot through the overlay's amicode-fetch (per-active-server Basic
// auth) and exposes a Re-check. Every failure (non-amicode host, 404, network,
// ok:false) resolves to `undefined` ⇒ the pure merge passes the list through
// untouched, so the picker degrades to exactly upstream behaviour.
import { createResource, createSignal } from "solid-js"
import { ServerConnection, useServer } from "@/context/server"
import { amicodeGet, amicodePost } from "@/utils/amicode-fetch"
import {
parseReachabilityResponse,
REACHABILITY_REFRESH_ROUTE,
REACHABILITY_ROUTE,
type ReachabilitySnapshot,
} from "./dialog-select-model-reachability"

export function createModelReachability() {
const server = useServer()
const [snapshot, { refetch }] = createResource(
() => (server.current ? ServerConnection.key(server.current) : undefined),
async (): Promise<ReachabilitySnapshot | undefined> => {
try {
return parseReachabilityResponse(await amicodeGet(server.current, REACHABILITY_ROUTE))
} catch {
return undefined
}
},
)
const [showUnavailable, setShowUnavailable] = createSignal(false)
const [rechecking, setRechecking] = createSignal(false)

return {
/** undefined ⇒ passthrough (no data / route unavailable). */
snapshot: (): ReachabilitySnapshot | undefined => (snapshot.error ? undefined : snapshot.latest),
/** amicode#1989: true until the first fetch settles (a demote waits for it
* so it never overrides a fresher probe it has not seen yet). */
loading: () => snapshot.loading,
showUnavailable,
setShowUnavailable,
rechecking,
refetch: () => void refetch(),
recheck: async () => {
if (rechecking()) return
setRechecking(true)
try {
await amicodePost(server.current, REACHABILITY_REFRESH_ROUTE, {})
} catch {
// a rate-limited / failed refresh still re-reads whatever the cache holds
} finally {
setRechecking(false)
void refetch()
}
},
}
}

export type ModelReachabilityState = ReturnType<typeof createModelReachability>
Loading
Loading