Skip to content

Commit dccea2d

Browse files
Merge fix/mlflow-settings-race-153: settings race, npm retry, skill conflicts
2 parents fa1312f + 46f05c6 commit dccea2d

14 files changed

Lines changed: 349 additions & 93 deletions

.codex/databricks-models.json

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{
2+
"models": [
3+
{
4+
"slug": "databricks-gpt-5-5",
5+
"display_name": "Databricks GPT-5.5",
6+
"description": "GPT-5.5 hosted through Databricks AI Gateway",
7+
"default_reasoning_level": "medium",
8+
"supported_reasoning_levels": [
9+
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
10+
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
11+
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
12+
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
13+
],
14+
"shell_type": "default",
15+
"visibility": "list",
16+
"supported_in_api": true,
17+
"priority": 100,
18+
"additional_speed_tiers": [],
19+
"availability_nux": null,
20+
"upgrade": null,
21+
"base_instructions": "",
22+
"supports_reasoning_summaries": true,
23+
"support_verbosity": true,
24+
"default_verbosity": null,
25+
"apply_patch_tool_type": null,
26+
"truncation_policy": { "mode": "tokens", "limit": 200000 },
27+
"supports_parallel_tool_calls": true,
28+
"experimental_supported_tools": []
29+
},
30+
{
31+
"slug": "databricks-gpt-5-4",
32+
"display_name": "Databricks GPT-5.4",
33+
"description": "GPT-5.4 hosted through Databricks AI Gateway",
34+
"default_reasoning_level": "medium",
35+
"supported_reasoning_levels": [
36+
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
37+
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
38+
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
39+
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
40+
],
41+
"shell_type": "default",
42+
"visibility": "list",
43+
"supported_in_api": true,
44+
"priority": 90,
45+
"additional_speed_tiers": [],
46+
"availability_nux": null,
47+
"upgrade": null,
48+
"base_instructions": "",
49+
"supports_reasoning_summaries": true,
50+
"support_verbosity": true,
51+
"default_verbosity": null,
52+
"apply_patch_tool_type": null,
53+
"truncation_policy": { "mode": "tokens", "limit": 200000 },
54+
"supports_parallel_tool_calls": true,
55+
"experimental_supported_tools": []
56+
},
57+
{
58+
"slug": "databricks-gpt-5-4-mini",
59+
"display_name": "Databricks GPT-5.4 Mini",
60+
"description": "GPT-5.4 Mini hosted through Databricks AI Gateway",
61+
"default_reasoning_level": "medium",
62+
"supported_reasoning_levels": [
63+
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
64+
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
65+
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
66+
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
67+
],
68+
"shell_type": "default",
69+
"visibility": "list",
70+
"supported_in_api": true,
71+
"priority": 80,
72+
"additional_speed_tiers": [],
73+
"availability_nux": null,
74+
"upgrade": null,
75+
"base_instructions": "",
76+
"supports_reasoning_summaries": true,
77+
"support_verbosity": true,
78+
"default_verbosity": null,
79+
"apply_patch_tool_type": null,
80+
"truncation_policy": { "mode": "tokens", "limit": 200000 },
81+
"supports_parallel_tool_calls": true,
82+
"experimental_supported_tools": []
83+
},
84+
{
85+
"slug": "databricks-gpt-5-3-codex",
86+
"display_name": "Databricks GPT-5.3 Codex",
87+
"description": "GPT-5.3 Codex hosted through Databricks AI Gateway",
88+
"default_reasoning_level": "medium",
89+
"supported_reasoning_levels": [
90+
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
91+
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
92+
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
93+
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
94+
],
95+
"shell_type": "default",
96+
"visibility": "list",
97+
"supported_in_api": true,
98+
"priority": 70,
99+
"additional_speed_tiers": [],
100+
"availability_nux": null,
101+
"upgrade": null,
102+
"base_instructions": "",
103+
"supports_reasoning_summaries": true,
104+
"support_verbosity": true,
105+
"default_verbosity": null,
106+
"apply_patch_tool_type": null,
107+
"truncation_policy": { "mode": "tokens", "limit": 200000 },
108+
"supports_parallel_tool_calls": true,
109+
"experimental_supported_tools": []
110+
},
111+
{
112+
"slug": "databricks-gpt-5-2",
113+
"display_name": "Databricks GPT-5.2",
114+
"description": "GPT-5.2 hosted through Databricks AI Gateway",
115+
"default_reasoning_level": "medium",
116+
"supported_reasoning_levels": [
117+
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
118+
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
119+
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
120+
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
121+
],
122+
"shell_type": "default",
123+
"visibility": "list",
124+
"supported_in_api": true,
125+
"priority": 60,
126+
"additional_speed_tiers": [],
127+
"availability_nux": null,
128+
"upgrade": null,
129+
"base_instructions": "",
130+
"supports_reasoning_summaries": true,
131+
"support_verbosity": true,
132+
"default_verbosity": null,
133+
"apply_patch_tool_type": null,
134+
"truncation_policy": { "mode": "tokens", "limit": 200000 },
135+
"supports_parallel_tool_calls": true,
136+
"experimental_supported_tools": []
137+
}
138+
]
139+
}

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@ uploads/
2020

2121
# uv lockfile — not portable across PyPI proxies, generate locally with `uv lock`
2222
uv.lock
23+
24+
# Codex CLI generated/cached files (only the bundled model catalog is tracked)
25+
.codex/*
26+
!.codex/databricks-models.json
27+
28+
# Codex skills are generated at runtime by setup_codex.py from .claude/skills/
29+
.agents/
30+
31+
# Agent-plane reference clone
32+
agent-plane-ref/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ This template repo opens that vision up for every Databricks user — no IDE set
284284
|----------|----------|-------------|
285285
| `DATABRICKS_TOKEN` | No | Optional. If not set, the app prompts for a token on first session. Auto-rotated every 10 minutes |
286286
| `HOME` | Yes | Set to `/app/python/source_code` in app.yaml |
287-
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-6`) |
288-
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-3-codex`) |
287+
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-7`) |
288+
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-5`) |
289289
| `GEMINI_MODEL` | No | Gemini model name (default: `databricks-gemini-2-5-pro`) |
290290
| `DATABRICKS_GATEWAY_HOST` | No | AI Gateway URL override. Auto-discovered from `DATABRICKS_WORKSPACE_ID` if unset |
291291

app.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -293,20 +293,24 @@ def _configure_all_cli_auth(token):
293293
else:
294294
anthropic_base_url = f"{databricks_host}/serving-endpoints/anthropic"
295295

296-
settings = {
297-
"env": {
298-
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-6"),
299-
"ANTHROPIC_BASE_URL": anthropic_base_url,
300-
"ANTHROPIC_AUTH_TOKEN": token,
301-
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-6",
302-
"ANTHROPIC_DEFAULT_SONNET_MODEL": "databricks-claude-sonnet-4-6",
303-
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "databricks-claude-haiku-4-5",
304-
"ANTHROPIC_CUSTOM_HEADERS": "x-databricks-use-coding-agent-mode: true",
305-
"CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
306-
}
307-
}
308-
296+
# Read-merge-write to preserve env vars from other setup scripts (e.g. setup_mlflow.py)
309297
settings_path = os.path.join(claude_dir, "settings.json")
298+
try:
299+
with open(settings_path) as f:
300+
settings = json.load(f)
301+
except (FileNotFoundError, json.JSONDecodeError):
302+
settings = {}
303+
304+
settings.setdefault("env", {})
305+
settings["env"]["ANTHROPIC_MODEL"] = os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-7")
306+
settings["env"]["ANTHROPIC_BASE_URL"] = anthropic_base_url
307+
settings["env"]["ANTHROPIC_AUTH_TOKEN"] = token
308+
settings["env"]["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "databricks-claude-opus-4-7"
309+
settings["env"]["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "databricks-claude-sonnet-4-6"
310+
settings["env"]["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "databricks-claude-haiku-4-5"
311+
settings["env"]["ANTHROPIC_CUSTOM_HEADERS"] = "x-databricks-use-coding-agent-mode: true"
312+
settings["env"]["CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"] = "1"
313+
310314
with open(settings_path, "w") as f:
311315
json.dump(settings, f, indent=2)
312316

@@ -373,7 +377,6 @@ def run_setup():
373377
("gemini", ["uv", "run", "python", "setup_gemini.py"]),
374378
("hermes", ["uv", "run", "python", "setup_hermes.py"]),
375379
("databricks", ["uv", "run", "python", "setup_databricks.py"]),
376-
("mlflow", ["uv", "run", "python", "setup_mlflow.py"]),
377380
]
378381

379382
with ThreadPoolExecutor(max_workers=len(parallel_steps)) as executor:
@@ -383,6 +386,11 @@ def run_setup():
383386
]
384387
wait(futures)
385388

389+
# --- MLflow setup runs AFTER claude setup to avoid settings.json race ---
390+
# setup_mlflow.py merges env vars into ~/.claude/settings.json which
391+
# setup_claude.py also writes; running sequentially prevents clobbering.
392+
_run_step("mlflow", ["uv", "run", "python", "setup_mlflow.py"])
393+
386394
# Sync latest token into all CLI configs — covers the race where PAT
387395
# rotation happened while a setup script was still installing (the
388396
# rotation's update_cli_tokens() call silently skips missing config files).

app.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ env:
99
- name: GEMINI_MODEL
1010
value: databricks-gemini-2-5-pro
1111
- name: CODEX_MODEL
12-
value: databricks-gpt-5-3-codex
12+
value: databricks-gpt-5-5
1313
- name: CLAUDE_CODE_DISABLE_AUTO_MEMORY
1414
value: 0
1515
- name: MAX_CONCURRENT_SESSIONS

docs/deployment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ databricks apps deploy <your-app-name> \
6767
|----------|----------|-------------|
6868
| `DATABRICKS_TOKEN` | No | Optional. If not set, the app prompts for a token on first session. Auto-rotated every 10 minutes |
6969
| `HOME` | Yes | Set to `/app/python/source_code` in app.yaml |
70-
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-6`) |
71-
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-3-codex`) |
70+
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-7`) |
71+
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-5`) |
7272
| `GEMINI_MODEL` | No | Gemini model name (default: `databricks-gemini-2-5-pro`) |
7373
| `HERMES_MODEL` | No | Hermes model name (default: `databricks-claude-opus-4-7`) |
7474
| `DATABRICKS_GATEWAY_HOST` | No | AI Gateway URL override. Auto-discovered from `DATABRICKS_WORKSPACE_ID` if unset. Falls back to direct model serving if neither is available |

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "coda"
3-
version = "0.17.4"
3+
version = "0.18.1"
44
description = "CoDA - Coding Agents on Databricks Apps"
55
requires-python = ">=3.10"
66
dependencies = [

setup_claude.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,27 @@
2929
anthropic_base_url = f"{databricks_host}/serving-endpoints/anthropic"
3030
print(f"Using Databricks Host: {databricks_host}")
3131

32-
settings = {
33-
"env": {
34-
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-6"),
35-
"ANTHROPIC_BASE_URL": anthropic_base_url,
36-
"ANTHROPIC_AUTH_TOKEN": token,
37-
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-6",
38-
"ANTHROPIC_DEFAULT_SONNET_MODEL": "databricks-claude-sonnet-4-6",
39-
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "databricks-claude-haiku-4-5",
40-
"ANTHROPIC_CUSTOM_HEADERS": "x-databricks-use-coding-agent-mode: true",
41-
"CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
42-
}
43-
}
44-
4532
settings_path = claude_dir / "settings.json"
33+
34+
# Read-merge-write to preserve env vars from other setup scripts (e.g. setup_mlflow.py)
35+
if settings_path.exists():
36+
try:
37+
settings = json.loads(settings_path.read_text())
38+
except (json.JSONDecodeError, OSError):
39+
settings = {}
40+
else:
41+
settings = {}
42+
43+
settings.setdefault("env", {})
44+
settings["env"]["ANTHROPIC_MODEL"] = os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-7")
45+
settings["env"]["ANTHROPIC_BASE_URL"] = anthropic_base_url
46+
settings["env"]["ANTHROPIC_AUTH_TOKEN"] = token
47+
settings["env"]["ANTHROPIC_DEFAULT_OPUS_MODEL"] = "databricks-claude-opus-4-7"
48+
settings["env"]["ANTHROPIC_DEFAULT_SONNET_MODEL"] = "databricks-claude-sonnet-4-6"
49+
settings["env"]["ANTHROPIC_DEFAULT_HAIKU_MODEL"] = "databricks-claude-haiku-4-5"
50+
settings["env"]["ANTHROPIC_CUSTOM_HEADERS"] = "x-databricks-use-coding-agent-mode: true"
51+
settings["env"]["CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS"] = "1"
52+
4653
settings_path.write_text(json.dumps(settings, indent=2))
4754
print(f"Claude configured: {settings_path}")
4855
else:

0 commit comments

Comments
 (0)