Skip to content
Merged
Show file tree
Hide file tree
Changes from 104 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
d4de363
feat(backend/db): add LLM catalog runtime tables
ntindle Jul 20, 2026
17a0b4e
feat(backend): add the canonical LLM catalog file and read cache
ntindle Jul 20, 2026
31b675a
feat(backend/copilot): resolve copilot models through the LLM catalog
ntindle Jul 20, 2026
be71b6c
feat(backend/api): public LLM catalog endpoint
ntindle Jul 20, 2026
28211d2
test(backend/copilot): isolate router tests from the loaded catalog
ntindle Jul 20, 2026
aeacb12
Merge branch 'feat/llm-catalog-copilot-routing' into feat/llm-catalog…
ntindle Jul 20, 2026
5102bd3
feat(backend): LLM model retirement CLI
ntindle Jul 20, 2026
90d8b0c
docs(platform): catalog-as-code LLM model management
ntindle Jul 20, 2026
f690290
fix(backend/copilot): local transports ignore catalog routing cells
ntindle Jul 20, 2026
229dc52
Merge branch 'feat/llm-catalog-copilot-routing' into feat/llm-catalog…
ntindle Jul 20, 2026
5da0d6a
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 20, 2026
0ed4308
Merge branch 'feat/llm-catalog-retirement' into docs/llm-catalog
ntindle Jul 20, 2026
61b10ec
fix(backend): transport-ready routing cells + fail-soft catalog const…
ntindle Jul 20, 2026
cfa926b
Merge branch 'feat/llm-catalog-file' into feat/llm-catalog-copilot-ro…
ntindle Jul 20, 2026
aac3394
Merge branch 'feat/llm-catalog-copilot-routing' into feat/llm-catalog…
ntindle Jul 20, 2026
f90220f
fix(backend/copilot): load catalog in the executor process; cells ver…
ntindle Jul 20, 2026
27eb2a2
fix(backend/api): tier in public payload; no dangling fallback refs
ntindle Jul 20, 2026
1c6624d
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 20, 2026
f777965
fix(frontend): prettify OpenAPI spec (regen during network outage ski…
ntindle Jul 20, 2026
5f88593
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 20, 2026
a0ac2f1
fix(backend): retire CLI matches full enum node values; exclusive CLI…
ntindle Jul 20, 2026
b4060fd
Merge branch 'feat/llm-catalog-retirement' into docs/llm-catalog
ntindle Jul 20, 2026
103bba9
fix(backend): type-align min_subscription_tier across catalog and reg…
ntindle Jul 20, 2026
87162cc
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 20, 2026
aaaeec6
Merge branch 'feat/llm-catalog-retirement' into docs/llm-catalog
ntindle Jul 20, 2026
0d5fc18
docs(platform): correct local-transport and stamping claims
ntindle Jul 20, 2026
a877e04
fix(backend): ship routing cells empty — claiming a cell is explicit
ntindle Jul 20, 2026
e53ff78
Merge branch 'feat/llm-catalog-file' into feat/llm-catalog-copilot-ro…
ntindle Jul 20, 2026
9aa7635
fix(backend/copilot): routing cells apply on cloud deployments only
ntindle Jul 20, 2026
dccfa3f
Merge branch 'feat/llm-catalog-copilot-routing' into feat/llm-catalog…
ntindle Jul 20, 2026
f14f159
Merge branch 'feat/llm-catalog-retirement' into docs/llm-catalog
ntindle Jul 20, 2026
71ce9c7
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 20, 2026
7fcfbc4
docs(platform): cells ship empty, apply on cloud only; hotfix back-me…
ntindle Jul 20, 2026
995cae5
fix(backend): preserve None max_output_tokens instead of overstating …
ntindle Jul 21, 2026
e0303c5
Merge branch 'feat/llm-catalog-file' into feat/llm-catalog-copilot-ro…
ntindle Jul 21, 2026
a232ecb
Merge branch 'feat/llm-catalog-copilot-routing' into feat/llm-catalog…
ntindle Jul 21, 2026
5398d61
fix(backend/api): trust X-Forwarded-For only behind the cloud LB
ntindle Jul 21, 2026
bc8e942
Merge branch 'feat/llm-catalog-endpoint' into feat/llm-catalog-retire…
ntindle Jul 21, 2026
fc13647
Merge branch 'feat/llm-catalog-retirement' into docs/llm-catalog
ntindle Jul 21, 2026
af25b37
feat(backend): add closed-world fixture test for stored graph model v…
ntindle Jul 21, 2026
ba0007a
feat(backend): cut LLM model config over to the catalog and add Kimi K3
ntindle Jul 21, 2026
1979672
refactor(backend): drop the public catalog endpoint — the catalog shi…
ntindle Jul 21, 2026
e4f1c84
fix(backend): fail hard when the LLM catalog cannot load
ntindle Jul 21, 2026
c0b0134
fix(backend): update executor catalog-load tests for fail-hard semantics
ntindle Jul 21, 2026
a4b964a
docs(blocks): regenerate block docs for Kimi K3 and provider display …
ntindle Jul 21, 2026
6885eaa
refactor(backend): cut consumer-less catalog perimeter; fix router ga…
ntindle Jul 21, 2026
571e0ec
refactor(backend): model identity joins the catalog package; review f…
ntindle Jul 21, 2026
69c96af
fix(backend/copilot): baseline resolution tests assert the ResolvedMo…
ntindle Jul 21, 2026
369b7e2
fix(backend/copilot): stamp SDK-path messages; close review-bot findings
ntindle Jul 21, 2026
6d384c7
fix(backend/copilot): update remaining SDK resolver mocks to Resolved…
ntindle Jul 21, 2026
eaddc78
fix(backend): third-review fixes — boot-safe default, catalog label, …
ntindle Jul 21, 2026
3a84940
test(backend/copilot): cover the Prisma persistence boundary for stam…
ntindle Jul 21, 2026
85f79e5
fix(backend): K3 max_output_tokens is unpublished — record None, not …
ntindle Jul 21, 2026
f7c151d
refactor(backend): self-review round — drop dead Phase B reference, e…
ntindle Jul 21, 2026
a001c42
fix(backend): thread-triage round — stamp observed model, tidy flagge…
ntindle Jul 21, 2026
8da37d5
fix(backend): drop dead json branch in revert-guard test
ntindle Jul 21, 2026
76f3d7a
fix(backend): align v0 creator brand (disclosed); test the fallback p…
ntindle Jul 21, 2026
1c00fdb
fix(backend/copilot): fallback-served turns stamp routing_source="fal…
ntindle Jul 21, 2026
203314c
fix(backend/copilot): back-fill stamps onto mid-turn-flushed rows
ntindle Jul 21, 2026
0b8caf6
fix(backend): register update_chat_message_stamps on the DatabaseManager
ntindle Jul 21, 2026
7cadaa9
fix(backend): canonical fallback compare; visibility honored in picker
ntindle Jul 21, 2026
8735cf1
test(backend/copilot): retry harness mocks carry real model strings
ntindle Jul 21, 2026
66c6bfe
fix(backend): round-five review — back-fill tests, gather, shared regex
ntindle Jul 21, 2026
f47baa5
fix(backend): round-six review — cohort privacy, O(1) fallback, AST w…
ntindle Jul 21, 2026
e11f41f
test(backend): revert refusal paths covered; runbook kill-switch caveats
ntindle Jul 21, 2026
43d7b5c
refactor(backend): a catalog field exists only with its consumer
ntindle Jul 22, 2026
508c036
Merge branch 'dev' into feat/llm-catalog
ntindle Jul 22, 2026
0ac5963
Merge branch 'dev' into feat/llm-catalog — translate #12619's models …
ntindle Jul 22, 2026
504319d
fix(platform): builder shows the truth for unavailable stored models;…
ntindle Jul 22, 2026
70b5cc2
fix(backend/copilot): LD slugs with any vendor prefix resolve through…
ntindle Jul 22, 2026
a73436d
fix(backend): apply the vendor-prefix generalization the prior commit…
ntindle Jul 22, 2026
5449411
docs(backend): moonshot prefix docstring stops hand-rostering SKUs
ntindle Jul 22, 2026
7449460
fix(backend/copilot): subscription-default turns never stamp "fallback"
ntindle Jul 22, 2026
0e733ef
refactor(backend): rename LlmModel → LLMModel per review
ntindle Jul 22, 2026
cdd0ea5
fix(backend/copilot): LD/env OpenAI slugs resolve through the enum al…
ntindle Jul 22, 2026
5fd14df
fix(backend/copilot): capture turn-stamp boundary after message cleanup
ntindle Jul 22, 2026
98b972d
feat(platform): add ChatGPT Codex subscription preview
ntindle Jul 31, 2026
30b683e
feat(platform): route Codex auth through Claude SDK
ntindle Aug 1, 2026
3b58a01
Merge remote-tracking branch 'origin/dev' into codex/chatgpt-sdk-preview
ntindle Aug 1, 2026
4957c2a
fix(platform): translate reserved Codex tool names
ntindle Aug 1, 2026
10fc5eb
Merge branch 'dev' into feat/llm-catalog
ntindle Aug 1, 2026
55c6c75
fix(backend): address post-merge review — default GA-gating, type reu…
ntindle Aug 1, 2026
c69a74b
fix(backend): round 2 review — admin default label, metadata-guard te…
ntindle Aug 1, 2026
cd0adee
Merge remote-tracking branch 'origin/feat/llm-catalog' into codex/cha…
ntindle Aug 2, 2026
dae4e1d
feat(platform): make subscription routing automatic
ntindle Aug 3, 2026
f5f3f02
fix(frontend): sync generated session schema
ntindle Aug 3, 2026
40d03fe
fix(platform): resolve dev conflicts for Codex transport
ntindle Aug 5, 2026
620cd2d
Merge remote-tracking branch 'origin/dev' into codex/subscription-tra…
ntindle Aug 5, 2026
f849c5c
fix(blocks): sync Codex block documentation
ntindle Aug 5, 2026
8ac4937
fix(platform): expose available AutoPilot transports
ntindle Aug 5, 2026
834c678
fix(frontend): sync AutoPilot transport schema
ntindle Aug 5, 2026
802d34c
fix(platform): stabilize Codex transport checks
ntindle Aug 5, 2026
038c75a
fix(backend): support concurrent Codex chats
ntindle Aug 6, 2026
2d1f106
Merge remote-tracking branch 'origin/dev' into codex/subscription-tra…
ntindle Aug 6, 2026
c39b67d
fix(backend): address Codex transport review findings
ntindle Aug 6, 2026
ff3eaed
fix(platform): sync Codex transport with dev
ntindle Aug 7, 2026
2ea4e20
feat(platform): present ChatGPT sign-in under OpenAI
ntindle Aug 7, 2026
c6e0f05
Merge remote-tracking branch 'origin/dev' into codex/openai-chatgpt-b…
ntindle Aug 11, 2026
8268e56
feat(platform): gate and harden Codex sign-in
ntindle Aug 11, 2026
4029a77
Merge remote-tracking branch 'origin/dev' into codex/openai-chatgpt-b…
ntindle Aug 11, 2026
3af1a76
fix(platform): satisfy backend architecture checks
ntindle Aug 11, 2026
64aa54e
Merge remote-tracking branch 'origin/dev' into codex/openai-chatgpt-b…
ntindle Aug 11, 2026
55a6758
fix(platform): harden Codex single-container runtime
ntindle Aug 11, 2026
51217f8
fix(platform): pass Codex temp root to smoke probe
ntindle Aug 11, 2026
b7f6422
fix(platform): preserve first chat send across navigation
ntindle Aug 11, 2026
9eb8283
fix(frontend): support chat sends on LAN HTTP
ntindle Aug 11, 2026
9cbe549
fix(platform): address Codex transport review feedback
ntindle Aug 12, 2026
da480f5
fix(platform): restore Codex CI and macOS temp roots
ntindle Aug 12, 2026
c7b4ecc
docs(platform): sync Codex block reference
ntindle Aug 12, 2026
aa4bcb4
test(platform): patch Codex shutdown transport binding
ntindle Aug 12, 2026
1441864
fix(backend): guard first DB call in store-agent search integration t…
ntindle Jul 22, 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
5 changes: 4 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ docs/_javascript/** linguist-vendored
# Exclude VCR cassettes from stats
classic/forge/tests/vcr_cassettes/**/**.y*ml linguist-generated

* text=auto
* text=auto

.github/scripts/platform-single-container-*.sh text eol=lf
autogpt_platform/single-container/*.sh text eol=lf
107 changes: 107 additions & 0 deletions .github/scripts/platform-single-container-smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set -Eeuo pipefail
: "${SMOKE_PLATFORM:?SMOKE_PLATFORM is required}"

readonly PUBLIC_URL=http://localhost:3300
readonly EXPECTED_CODEX_TEMP_ROOT=/dev/shm/autogpt-codex
readonly TIMEOUT_SECONDS="${SMOKE_TIMEOUT_SECONDS:-2700}"
readonly SAFE_PLATFORM="${SMOKE_PLATFORM//\//-}"
readonly RUN_TOKEN="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-0}-${SAFE_PLATFORM}-${RANDOM}"
Expand Down Expand Up @@ -477,6 +478,110 @@ assert_email_auth_flow() {
"${email}"
}

assert_codex_provider_discovery() {
curl --fail-with-body --silent --show-error --max-time 30 \
--cookie "${AUTH_COOKIE_FILE}" \
"${PUBLIC_URL}/api/proxy/api/integrations/providers" |
python3 -c '
import json
import sys

providers = json.load(sys.stdin)
codex = [provider for provider in providers if provider.get("name") == "codex"]
assert len(codex) == 1, codex
assert "oauth2" in codex[0].get("supported_auth_types", []), codex[0]
'
}

assert_codex_runtime_contract() {
local filesystem_type
local ownership_and_mode
local process_name
local process_id
local process_environment

filesystem_type="$(
docker exec "${CONTAINER_NAME}" \
stat -f -c '%T' "${EXPECTED_CODEX_TEMP_ROOT}"
)"
[[ "${filesystem_type}" == tmpfs ]] || {
echo "Codex temporary root is not memory-backed: ${filesystem_type}" >&2
return 1
}

ownership_and_mode="$(
docker exec "${CONTAINER_NAME}" \
stat -c '%u:%g:%a' "${EXPECTED_CODEX_TEMP_ROOT}"
)"
[[ "${ownership_and_mode}" == 10001:10001:700 ]] || {
echo "Codex temporary root is not owned by autogpt with mode 0700" >&2
return 1
}

for process_name in rest executor copilot-executor; do
process_id="$(
docker exec "${CONTAINER_NAME}" \
supervisorctl \
-c /opt/autogpt/single-container/supervisor/supervisord.conf \
pid "${process_name}"
)"
[[ "${process_id}" =~ ^[0-9]+$ ]]
process_environment="$(
docker exec --user autogpt "${CONTAINER_NAME}" \
/bin/bash -Eeuo pipefail -c 'tr "\0" "\n" <"/proc/${1}/environ"' \
bash "${process_id}"
)"
grep -Fxq \
"CODEX_TEMP_ROOT=${EXPECTED_CODEX_TEMP_ROOT}" \
<<<"${process_environment}" || {
echo "${process_name} did not inherit CODEX_TEMP_ROOT" >&2
return 1
}
done

docker exec --interactive --user autogpt \
--env "CODEX_TEMP_ROOT=${EXPECTED_CODEX_TEMP_ROOT}" \
--workdir /app/autogpt_platform/backend \
"${CONTAINER_NAME}" \
/app/autogpt_platform/backend/.venv/bin/python - <<'PY'
import os
import subprocess
from pathlib import Path

from backend.integrations.codex.runtime import (
CODEX_RUNTIME_VERSION,
assert_pinned_versions,
build_runtime_config,
)
from backend.integrations.codex.temporary_home import TemporaryCodexHome

root = Path(os.environ["CODEX_TEMP_ROOT"])
assert root == Path("/dev/shm/autogpt-codex")
assert_pinned_versions()
before = set(root.iterdir())
with TemporaryCodexHome.create(root) as home:
config = build_runtime_config(home)
launch_args = config.launch_args_override
assert launch_args is not None
completed = subprocess.run(
[*launch_args[:3], "--version"],
env=config.env,
check=False,
capture_output=True,
text=True,
timeout=30,
)
output = completed.stdout + completed.stderr
assert completed.returncode == 0, output
assert CODEX_RUNTIME_VERSION in output, output
home_path = home.path

assert not home_path.exists()
assert set(root.iterdir()) == before
print("codex-sdk-runtime-ok")
PY
}

assert_request_tokens_absent_from_logs() {
local sentinel=AUTOGPT_LOG_SENTINEL_6f2b3cb87e9a
local websocket_key=dGhlIHNhbXBsZSBub25jZQ== # pragma: allowlist secret # gitleaks:allow
Expand Down Expand Up @@ -750,6 +855,7 @@ docker run --detach \
"${SMOKE_IMAGE}" >/dev/null
discover_data_volume
wait_for_healthy
assert_codex_runtime_contract
assert_prisma_cli_is_prebundled
assert_falkordb_binary_contract
assert_memory_contract seed
Expand Down Expand Up @@ -793,6 +899,7 @@ assert_runtime_config_mode
assert_frontend_database_isolation
assert_pinned_topology_environment
assert_email_auth_flow
assert_codex_provider_discovery
assert_falkordb_binary_contract
assert_memory_contract verify
curl --fail --silent --show-error "${PUBLIC_URL}/healthz" >/dev/null
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/platform-fullstack-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ jobs:
run: |
cp ../backend/.env.default ../backend/.env
echo "OPENAI_INTERNAL_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> ../backend/.env
echo "CHAT_TEST_MODE=true" >> ../backend/.env
echo "SCHEDULER_STARTUP_EMBEDDING_BACKFILL=false" >> ../backend/.env
env:
# Used by E2E test data script to generate embeddings for approved store agents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
UserPasswordCredentials,
is_sdk_default,
)
from backend.integrations.codex.access import has_codex_access_for_discovery
from backend.integrations.credentials_store import (
is_system_credential,
provider_matches,
Expand Down Expand Up @@ -272,7 +273,10 @@ async def list_providers(
from backend.sdk.registry import AutoRegistry

providers = []
codex_allowed = await has_codex_access_for_discovery(auth.user_id)
for name in get_all_provider_names():
if name == ProviderName.CODEX and not codex_allowed:
continue
supports_oauth = name in HANDLERS_BY_NAME
handler_class = HANDLERS_BY_NAME.get(name)
default_scopes = (
Expand Down Expand Up @@ -540,6 +544,11 @@ async def create_credential(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Provider '{provider}' not found",
)
if provider == "codex":
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Codex credentials must be created through ChatGPT sign-in",
)

# Create the appropriate credential type
credentials: Credentials
Expand Down
Loading
Loading