Update to Codex Advisor
Snapshot Oct 28, 2026 · 13:16 UTC · version 1.4.10
Package or technical metadata updated
Package or technical metadata updated
Observed in package metadata. These changes alone do not establish a new customer-facing feature.
Up to 3 plugins free · no card required.
All fields and original values.
These are saved file metadata. Open a changed file to read its text edits.
Package file
Sep 30, 2026 · 23:15 UTC
{"sha256":"ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a","size":234585}
Oct 28, 2026 · 13:16 UTC
Not present
Package file
Sep 30, 2026 · 23:15 UTC
{"sha256":"ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a","size":234585}
Oct 28, 2026 · 13:16 UTC
Not present
Package file
Sep 30, 2026 · 23:15 UTC
bd2b05047cb9c0e431191d6dbb7c5f8a6baae2afb5fe52f37ac8fed46588edac
Oct 28, 2026 · 13:16 UTC
4ab3069acea26fc5863aaacaf2dadfe0052c9d68fa22eb0211da0440c7ad3d31
Package file
Sep 30, 2026 · 23:15 UTC
2298
Oct 28, 2026 · 13:16 UTC
2503
Compare saved observations
Download comparison JSONChanged files
Choose a file to see its text changes. Binary or large files show metadata only.
.codex-plugin/assets/composer-icon.png →
.codex-plugin/assets/logo.png →
LICENSE →
scripts/advisor_discovery.py →
scripts/evaluate-triggers.sh →
skills/consultation/SKILL.md →
skills/consultation/references/operations.md →
tests/advisor_transport_support.py →
tests/test_advisor_config.py →
scripts/advisor_discovery.py
− removed · + added
--- before +++ after @@ -0,0 +1,243 @@ +"""Bounded Advisor app-server model discovery.""" + +from __future__ import annotations + +import os +import shutil +import tempfile +import time +from collections.abc import Callable, Mapping, Sequence +from typing import Any + +from advisor_catalog import _validate_candidate, load_catalog, validate_catalog +from advisor_process import JsonRpcProcess, ProcessUnavailable +from advisor_state import ( + DEFAULT_DEADLINE_SECONDS, + EFFORTS, + MAX_DEADLINE_SECONDS, + MAX_MODELS, + MAX_PAGES, + MIN_DEADLINE_SECONDS, + TRANSPORT_CONTRACT_VERSION, + ConfigError, + DiscoveryError, + DiscoveryUnavailable, + StatePaths, + _atomic_write, + _run_bounded_output, + _validate_effort, + _validate_selector, + state_lock, + state_paths, +) + +def normalize_discovery_pages( + pages: Sequence[Mapping[str, Any]], *, now: Callable[[], float] = time.time +) -> list[dict[str, Any]]: + if not isinstance(pages, Sequence) or len(pages) > MAX_PAGES: + raise DiscoveryError("discovery page limit exceeded") + candidates = [] + cursors = set() + for page in pages: + if ( + not isinstance(page, Mapping) + or "data" not in page + or "nextCursor" not in page + ): + raise DiscoveryError("malformed discovery response") + data, cursor = page["data"], page["nextCursor"] + if not isinstance(data, list) or len(data) > MAX_MODELS: + raise DiscoveryError("malformed discovery models") + if cursor is not None: + if not isinstance(cursor, str) or not cursor or cursor in cursors: + raise DiscoveryError("discovery cursor loop") + cursors.add(cursor) + for raw in data: + required = { + "id", + "model", + "displayName", + "description", + "hidden", + "isDefault", + "defaultReasoningEffort", + "supportedReasoningEfforts", + } + if ( + not isinstance(raw, Mapping) + or not required.issubset(raw) + or not isinstance(raw["hidden"], bool) + or not isinstance(raw["isDefault"], bool) + or not isinstance(raw["description"], str) + ): + raise DiscoveryError("malformed discovered model") + supported = raw["supportedReasoningEfforts"] + if ( + not isinstance(supported, list) + or not supported + or len(supported) > len(EFFORTS) + ): + raise DiscoveryError("malformed supported efforts") + efforts = [] + for item in supported: + if ( + not isinstance(item, Mapping) + or not {"reasoningEffort", "description"}.issubset(item) + or not isinstance(item["description"], str) + ): + raise DiscoveryError("malformed supported effort") + efforts.append(_validate_effort(item["reasoningEffort"])) + if len(set(efforts)) != len(efforts): + raise DiscoveryError("duplicate supported effort") + try: + candidate = _validate_candidate( + { + "id": _validate_selector(raw["id"], label="candidate id"), + "model": _validate_selector(raw["model"]), + "display_name": raw["displayName"], + "provenance": "discovery", + "visible": not raw["hidden"], + "last_seen_at": str(int(now())), + "advertised_efforts": efforts, + "default_effort": _validate_effort( + raw["defaultReasoningEffort"] + ), + } + ) + except (ConfigError, KeyError) as exc: + raise DiscoveryError("malformed discovered model") from exc + candidates.append(candidate) + if len(candidates) > MAX_MODELS: + raise DiscoveryError("discovery model limit exceeded") + return candidates + + +class AppServerDiscovery: + """Dedicated, inherited-context app-server model-list client.""" + + def __init__( + self, + connection_factory: Callable[[], Any] | None = None, + *, + deadline_seconds: int = DEFAULT_DEADLINE_SECONDS, + on_status: Callable[[str], None] | None = None, + ) -> None: + self.connection_factory = connection_factory or self._connection + self.deadline_seconds = deadline_seconds + self.on_status = on_status + + def _connection(self) -> JsonRpcProcess: + remaining = max(0.1, min(5.0, float(self.deadline_seconds))) + try: + returncode, output = _run_bounded_output( + ["codex", "app-server", "--help"], + timeout_seconds=remaining, + max_bytes=200_000, + ) + except ConfigError as exc: + raise ProcessUnavailable("app-server capability check failed") from exc + if ( + returncode != 0 + or b"--ignore-user-config" not in output + or b"--ignore-rules" not in output + ): + raise ProcessUnavailable( + "app-server cannot safely ignore user configuration" + ) + scratch = tempfile.mkdtemp(prefix="advisor-discovery-") + os.chmod(scratch, 0o700) + return JsonRpcProcess( + ["codex", "app-server", "--ignore-user-config", "--ignore-rules"], + deadline_seconds=self.deadline_seconds, + cwd=scratch, + on_status=self.on_status, + on_close=lambda: shutil.rmtree(scratch, ignore_errors=True), + ) + + def pages(self) -> list[dict[str, Any]]: + if not MIN_DEADLINE_SECONDS <= self.deadline_seconds <= MAX_DEADLINE_SECONDS: + raise DiscoveryUnavailable("discovery unavailable: invalid deadline") + try: + connection = self.connection_factory() + except (OSError, ProcessUnavailable) as exc: + raise DiscoveryUnavailable( + "discovery unavailable: app-server cannot start" + ) from exc + pages = [] + cursor = None + seen = set() + try: + connection.request( + "initialize", + { + "clientInfo": { + "name": "codex-advisor", + "version": TRANSPORT_CONTRACT_VERSION, + } + }, + ) + connection.notify("initialized", {}) + for _ in range(MAX_PAGES): + params = {"includeHidden": True} + if cursor is not None: + params["cursor"] = cursor + response = connection.request("model/list", params) + if not isinstance(response, Mapping) or set(response) - { + "data", + "nextCursor", + }: + raise DiscoveryError("malformed discovery response") + page = { + "data": response.get("data"), + "nextCursor": response.get("nextCursor"), + } + pages.append(page) + cursor = page["nextCursor"] + if cursor is None: + return pages + if not isinstance(cursor, str) or not cursor or cursor in seen: + raise DiscoveryError("discovery cursor loop") + seen.add(cursor) + raise DiscoveryError("discovery page limit exceeded") + except (ProcessUnavailable, TimeoutError) as exc: + raise DiscoveryUnavailable( + "discovery unavailable: app-server request failed" + ) from exc + finally: + close = getattr(connection, "close", None) + if callable(close): + close() + + +def refresh_catalog( + discovery: Callable[[], Sequence[Mapping[str, Any]]], + *, + paths: StatePaths | None = None, + now: Callable[[], float] = time.time, +) -> dict[str, Any]: + discovered = normalize_discovery_pages(discovery(), now=now) + paths = paths or state_paths() + with state_lock(paths): + catalog = load_catalog(paths) + manual = [ + item for item in catalog["candidates"] if item["provenance"] == "manual" + ] + prior = { + (item["id"], item["model"]): item + for item in catalog["candidates"] + if item["provenance"] == "discovery" + } + keys = {(item["id"], item["model"]) for item in discovered} + catalog["candidates"] = ( + manual + + discovered + + [ + {**item, "visible": False} + for key, item in prior.items() + if key not in keys + ] + ) + catalog["last_successful_refresh"] = str(int(now())) + catalog["revision"] += 1 + _atomic_write(paths.catalog, validate_catalog(catalog)) + return catalog
Full technical diff · 47 changed fields
removed /files/.codex-plugin~1assets~1composer-icon.png
{
"sha256": "ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a",
"size": 234585
}Field is absent
removed /files/.codex-plugin~1assets~1logo.png
{
"sha256": "ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a",
"size": 234585
}Field is absent
changed /files/.codex-plugin~1plugin.json/sha256
"bd2b05047cb9c0e431191d6dbb7c5f8a6baae2afb5fe52f37ac8fed46588edac"
"4ab3069acea26fc5863aaacaf2dadfe0052c9d68fa22eb0211da0440c7ad3d31"
changed /files/.codex-plugin~1plugin.json/size
2298
2503
added /files/LICENSE
Field was absent
{
"sha256": "9bd605a064788e28a3961c76ba61142bed298270bfa96b06028ac450821a5258",
"size": 1071
}added /files/NOTICE.md
Field was absent
{
"sha256": "6fbd501f4d2dc5deb6656dbe7571ce7c78c59db8bac92416c41f2f7fd1891316",
"size": 332
}changed /files/advisor.toml/sha256
"55b952049fb9ac8b472f700321a5d92eb579605c7147797f41735b221ecab191"
"73bbb4b5bad3eb5146af1e17c270517187028266da3c4a3db722e6adf81a71da"
changed /files/advisor.toml/size
595
597
changed /files/agents~1advisor-sol.toml/sha256
"517f670937b2174dcd6467e39381b55d3ba133bd97c697c988bf77082dd1531d"
"b3d58c2bd9164f0117338e9d620c3c668abf7eba12949bb840704b65d86c9a1f"
changed /files/agents~1advisor-sol.toml/size
1584
1586
changed /files/agents~1advisor-terra.toml/sha256
"4b46bd1f354e17d0ed2eaa746fb3f838e2d5bee04ed44524b9557de1820b064e"
"97e9beed9a0a571423a580b6d5190d9b6b2d65a31f5dcef694f02c0246dea1ee"
changed /files/models.json/sha256
"06f8c49d7943d56682a40633a6bb072831d087d6f589f25096c2042e8017a252"
"7e6fa2bf8998c8c6f55534b15da19bccf6d239db74da517b9bf78d2063e4caa3"
changed /files/models.json/size
899
903
changed /files/scripts~1advisor-config.sh/sha256
"41fe054137a6530e6d14c7a4811c857c131a95d81eae6a95080f0cf45d151e28"
"3889220b9198ca419a3deece0a0d8f212965b5d9b95e62effa2b27df49abdd70"
changed /files/scripts~1advisor-config.sh/size
325
692
added /files/scripts~1advisor_canary.py
Field was absent
{
"sha256": "39c912ee039e087bb1abc614a6fa7eee56057084991cf66230528f4e1c1f7a5e",
"size": 10505
}added /files/scripts~1advisor_catalog.py
Field was absent
{
"sha256": "c78f3898475acb922432cc0c78c70cd67b3c61e5072ec7b77a76789f7a51a01f",
"size": 14818
}changed /files/scripts~1advisor_config.py/sha256
"f5feee3e230f98a988b305f916eb4684282ca4597eebfa11286ab4acb1aa4c8d"
"e7539d73a9317b4c39e3c222052fdabfa165ea274f43706b2f922523877e73bf"
changed /files/scripts~1advisor_config.py/size
90558
16411
added /files/scripts~1advisor_discovery.py
Field was absent
{
"sha256": "03b4df7bf8fc58b7ac3ed3576831ba128a616fd8817be4abe9faf3b97cb464d9",
"size": 9135
}added /files/scripts~1advisor_doctor.py
Field was absent
{
"sha256": "0cd8973ace6fee18fab8400725090d919e73e3cde20a3bd8033029a1d529d603",
"size": 9041
}added /files/scripts~1advisor_journal.py
Field was absent
{
"sha256": "6a2a994097b01fa8c956dcd73763565169e7ee5fca2cb05ee1fbca8bad852c88",
"size": 9681
}added /files/scripts~1advisor_settings.py
Field was absent
{
"sha256": "8a3f89f0983534ed726cc1bb1dc8f7dcf14d0443e08dba655fa1d4692756be9d",
"size": 13440
}added /files/scripts~1advisor_state.py
Field was absent
{
"sha256": "e788e9b64d2cdb21c52ca76e6a7b68b5d7695e449f66d80f440da0319118b56e",
"size": 12326
}changed /files/scripts~1evaluate-triggers.sh/sha256
"ead7570ec2086ed726820b56251596120107f8e7bc07caa028d6ee89342dd8fe"
"e2a5d537e51a2c9c1cd31c0a8060e9fbdc7d9eecad3ccdbcc9c3baddf4f238c9"
changed /files/scripts~1evaluate-triggers.sh/size
25580
25586
changed /files/scripts~1install-agents.sh/sha256
"59ac0e3cadae49cd6228d592a0e665aef80a0f03cd46e00f639c3c792753285f"
"c8bcb94735ae0bdb276a05e68e69bba293155fe3644545bff0cd920208ebd83b"
changed /files/scripts~1install-agents.sh/size
16432
18620
changed /files/scripts~1run-advisor.sh/sha256
"e93d33441b827c3b6cb87ea75cee87dd4e7d7c8381fdb1c676b8421f30e83131"
"c31b5f6af99f5d577748260e63ea0cebc17ef55a7c20e93917358e2bf1afb4ab"
changed /files/scripts~1run-advisor.sh/size
27596
27506
changed /files/scripts~1verify.sh/sha256
"06a5b9bceda7dfb693353744e75fb371e335f815be25e5dd0fe4b5c941f52566"
"dde2181752a614b3b914b48dd62f29798185b6dbe3e5d57ddcbe068ef8ef0d62"
changed /files/scripts~1verify.sh/size
129023
4700
removed /files/settings.schema.json
{
"sha256": "2b38841cbc898b9da626845e23b6db002d71755a1ff16114e67fb2ad9b1a9cb5",
"size": 1200
}Field is absent
changed /files/skills~1consultation~1SKILL.md/sha256
"8314e737292358a8731034058946cf53a534082e5d098f1d03ec5b4a24517dd5"
"fc07af46962e0ddcdc0d4fadd53c959d7938580e624fcb959820105d92f5cc9f"
changed /files/skills~1consultation~1SKILL.md/size
17484
17488
changed /files/skills~1consultation~1references~1operations.md/sha256
"3d82d8689478200f19ac76aa02375512a8c8bd096959b8c78f73d81b5c548004"
"41f6790b742bf146e9f58ae2b7d5fc710e07f19b4ed2fe282cdd63475f621047"
changed /files/skills~1consultation~1references~1operations.md/size
22558
22564
added /files/tests~1advisor_transport_support.py
Field was absent
{
"sha256": "ab4d43ce97049e90f3902947c9251c087b681e5a2f6b963085b85b5c0b54ffd2",
"size": 11089
}changed /files/tests~1test_advisor_cli.py/sha256
"b1b2ad9415e560da63ff6f8f8cfb76233b828de6fb459f306e3a6b58b3100f64"
"0edfa5b16f1d35ebb714b177ab4b6c12ad3f4647ab965e290e1c19415058540b"
changed /files/tests~1test_advisor_cli.py/size
17635
27646
changed /files/tests~1test_advisor_config.py/sha256
"169b5aa46700a4f09c6ee0dbadf3d02b1b6c91465a356de38804d5ebdc8ed9dc"
"aa52b9fadef51b8121f4da4038914058952c1268aac23b68e1d8c7dcddd9a677"
changed /files/tests~1test_advisor_config.py/size
25728
28147
added /files/tests~1test_advisor_setup.py
Field was absent
{
"sha256": "88f7545477e62f2a3d4317e32410eecdd92ea907679fc64206eddbd824d12ed9",
"size": 10603
}changed /files/tests~1test_advisor_transport.py/sha256
"aa566e1057819c5c1385b8659ddb51eb1f7e55ec8551e2acdb52a1feadb9067f"
"d5318adabba6b6c1d2d5b7c9d41d48f91ac6b61352f897e5368afbf1bcacc4b9"
changed /files/tests~1test_advisor_transport.py/size
26202
21224
changed /files/tests~1test_advisor_usage.py/sha256
"d5a5d1ecf82c9a2254e3565d24d7854ef05442cbacc1725432503138f153f70b"
"3cfe33013652669e3756f5945248ac33776ce7f03ab53435aca794ca50f53d68"
changed /files/tests~1test_advisor_usage.py/size
24681
24870
Full snapshot data
{
"files": {
".codex-plugin/plugin.json": {
"sha256": "4ab3069acea26fc5863aaacaf2dadfe0052c9d68fa22eb0211da0440c7ad3d31",
"size": 2503
},
"LICENSE": {
"sha256": "9bd605a064788e28a3961c76ba61142bed298270bfa96b06028ac450821a5258",
"size": 1071
},
"NOTICE.md": {
"sha256": "6fbd501f4d2dc5deb6656dbe7571ce7c78c59db8bac92416c41f2f7fd1891316",
"size": 332
},
"advisor-response.schema.json": {
"sha256": "01019be4a32a8257d852d50ec791184e6edbfbaa39cafd61a575e990c9933c40",
"size": 666
},
"advisor.toml": {
"sha256": "73bbb4b5bad3eb5146af1e17c270517187028266da3c4a3db722e6adf81a71da",
"size": 597
},
"agents/advisor-astra.toml": {
"sha256": "355b6e0286a15900f64e8bf6a5e743b26eb4a9fdf7e282ef70c7adb61352f754",
"size": 1582
},
"agents/advisor-sol.toml": {
"sha256": "b3d58c2bd9164f0117338e9d620c3c668abf7eba12949bb840704b65d86c9a1f",
"size": 1586
},
"agents/advisor-terra.toml": {
"sha256": "97e9beed9a0a571423a580b6d5190d9b6b2d65a31f5dcef694f02c0246dea1ee",
"size": 1597
},
"assets/advisor-composer-icon.png": {
"sha256": "ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a",
"size": 234585
},
"assets/advisor-logo.png": {
"sha256": "ea58c4a9d45cdc20ed9ded61d690d96487004a5f12643f9bb09e53260eabbf6a",
"size": 234585
},
"evals/trigger-cases.json": {
"sha256": "68aa2b683073c632d16f146c55598ff906044248ad85998aaac3f9074278cfc1",
"size": 2943
},
"models.json": {
"sha256": "7e6fa2bf8998c8c6f55534b15da19bccf6d239db74da517b9bf78d2063e4caa3",
"size": 903
},
"scripts/advisor-audit.sh": {
"sha256": "c8e905fbf62f620b273ff839f574a0f1a0367b46e6b839426f0c05721a886bc8",
"size": 37485
},
"scripts/advisor-config.sh": {
"sha256": "3889220b9198ca419a3deece0a0d8f212965b5d9b95e62effa2b27df49abdd70",
"size": 692
},
"scripts/advisor_canary.py": {
"sha256": "39c912ee039e087bb1abc614a6fa7eee56057084991cf66230528f4e1c1f7a5e",
"size": 10505
},
"scripts/advisor_catalog.py": {
"sha256": "c78f3898475acb922432cc0c78c70cd67b3c61e5072ec7b77a76789f7a51a01f",
"size": 14818
},
"scripts/advisor_config.py": {
"sha256": "e7539d73a9317b4c39e3c222052fdabfa165ea274f43706b2f922523877e73bf",
"size": 16411
},
"scripts/advisor_discovery.py": {
"sha256": "03b4df7bf8fc58b7ac3ed3576831ba128a616fd8817be4abe9faf3b97cb464d9",
"size": 9135
},
"scripts/advisor_doctor.py": {
"sha256": "0cd8973ace6fee18fab8400725090d919e73e3cde20a3bd8033029a1d529d603",
"size": 9041
},
"scripts/advisor_journal.py": {
"sha256": "6a2a994097b01fa8c956dcd73763565169e7ee5fca2cb05ee1fbca8bad852c88",
"size": 9681
},
"scripts/advisor_process.py": {
"sha256": "841274eebb90ef5d0a99fe26ab5f2ff30e86883dcb3d20bce112206625953c04",
"size": 17793
},
"scripts/advisor_settings.py": {
"sha256": "8a3f89f0983534ed726cc1bb1dc8f7dcf14d0443e08dba655fa1d4692756be9d",
"size": 13440
},
"scripts/advisor_state.py": {
"sha256": "e788e9b64d2cdb21c52ca76e6a7b68b5d7695e449f66d80f440da0319118b56e",
"size": 12326
},
"scripts/evaluate-triggers.sh": {
"sha256": "e2a5d537e51a2c9c1cd31c0a8060e9fbdc7d9eecad3ccdbcc9c3baddf4f238c9",
"size": 25586
},
"scripts/inspect-agent-runtime.sh": {
"sha256": "bb5d7d3011529e73899c76474527d8106486f67017ea09bccb107b36bc4e8831",
"size": 4560
},
"scripts/inspect-parent-runtime.sh": {
"sha256": "b647eb7ea5d00c2fe297840e7a4ad8a2e13e9ddedcd679cf89da3865f41080bd",
"size": 2224
},
"scripts/install-agents.sh": {
"sha256": "c8bcb94735ae0bdb276a05e68e69bba293155fe3644545bff0cd920208ebd83b",
"size": 18620
},
"scripts/run-advisor.sh": {
"sha256": "c31b5f6af99f5d577748260e63ea0cebc17ef55a7c20e93917358e2bf1afb4ab",
"size": 27506
},
"scripts/verify.sh": {
"sha256": "dde2181752a614b3b914b48dd62f29798185b6dbe3e5d57ddcbe068ef8ef0d62",
"size": 4700
},
"skills/consultation/SKILL.md": {
"sha256": "fc07af46962e0ddcdc0d4fadd53c959d7938580e624fcb959820105d92f5cc9f",
"size": 17488
},
"skills/consultation/agents/openai.yaml": {
"sha256": "3a9c1d3552e1d5aa94812fea0bc6af189a5bde271596ca8de7b3ea979e01a73f",
"size": 312
},
"skills/consultation/references/operations.md": {
"sha256": "41f6790b742bf146e9f58ae2b7d5fc710e07f19b4ed2fe282cdd63475f621047",
"size": 22564
},
"tests/advisor_transport_support.py": {
"sha256": "ab4d43ce97049e90f3902947c9251c087b681e5a2f6b963085b85b5c0b54ffd2",
"size": 11089
},
"tests/test_advisor_cli.py": {
"sha256": "0edfa5b16f1d35ebb714b177ab4b6c12ad3f4647ab965e290e1c19415058540b",
"size": 27646
},
"tests/test_advisor_config.py": {
"sha256": "aa52b9fadef51b8121f4da4038914058952c1268aac23b68e1d8c7dcddd9a677",
"size": 28147
},
"tests/test_advisor_setup.py": {
"sha256": "88f7545477e62f2a3d4317e32410eecdd92ea907679fc64206eddbd824d12ed9",
"size": 10603
},
"tests/test_advisor_transport.py": {
"sha256": "d5318adabba6b6c1d2d5b7c9d41d48f91ac6b61352f897e5368afbf1bcacc4b9",
"size": 21224
},
"tests/test_advisor_usage.py": {
"sha256": "3cfe33013652669e3756f5945248ac33776ce7f03ab53435aca794ca50f53d68",
"size": 24870
}
}
}SHA-256 of public snapshot: a367e114a58cede454294847a55b600b337e44eb1140d8192311a44c4c2da40e