Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
139 changes: 139 additions & 0 deletions .codex/databricks-models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"models": [
{
"slug": "databricks-gpt-5-5",
"display_name": "Databricks GPT-5.5",
"description": "GPT-5.5 hosted through Databricks AI Gateway",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
],
"shell_type": "default",
"visibility": "list",
"supported_in_api": true,
"priority": 100,
"additional_speed_tiers": [],
"availability_nux": null,
"upgrade": null,
"base_instructions": "",
"supports_reasoning_summaries": true,
"support_verbosity": true,
"default_verbosity": null,
"apply_patch_tool_type": null,
"truncation_policy": { "mode": "tokens", "limit": 200000 },
"supports_parallel_tool_calls": true,
"experimental_supported_tools": []
},
{
"slug": "databricks-gpt-5-4",
"display_name": "Databricks GPT-5.4",
"description": "GPT-5.4 hosted through Databricks AI Gateway",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
],
"shell_type": "default",
"visibility": "list",
"supported_in_api": true,
"priority": 90,
"additional_speed_tiers": [],
"availability_nux": null,
"upgrade": null,
"base_instructions": "",
"supports_reasoning_summaries": true,
"support_verbosity": true,
"default_verbosity": null,
"apply_patch_tool_type": null,
"truncation_policy": { "mode": "tokens", "limit": 200000 },
"supports_parallel_tool_calls": true,
"experimental_supported_tools": []
},
{
"slug": "databricks-gpt-5-4-mini",
"display_name": "Databricks GPT-5.4 Mini",
"description": "GPT-5.4 Mini hosted through Databricks AI Gateway",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
],
"shell_type": "default",
"visibility": "list",
"supported_in_api": true,
"priority": 80,
"additional_speed_tiers": [],
"availability_nux": null,
"upgrade": null,
"base_instructions": "",
"supports_reasoning_summaries": true,
"support_verbosity": true,
"default_verbosity": null,
"apply_patch_tool_type": null,
"truncation_policy": { "mode": "tokens", "limit": 200000 },
"supports_parallel_tool_calls": true,
"experimental_supported_tools": []
},
{
"slug": "databricks-gpt-5-3-codex",
"display_name": "Databricks GPT-5.3 Codex",
"description": "GPT-5.3 Codex hosted through Databricks AI Gateway",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
],
"shell_type": "default",
"visibility": "list",
"supported_in_api": true,
"priority": 70,
"additional_speed_tiers": [],
"availability_nux": null,
"upgrade": null,
"base_instructions": "",
"supports_reasoning_summaries": true,
"support_verbosity": true,
"default_verbosity": null,
"apply_patch_tool_type": null,
"truncation_policy": { "mode": "tokens", "limit": 200000 },
"supports_parallel_tool_calls": true,
"experimental_supported_tools": []
},
{
"slug": "databricks-gpt-5-2",
"display_name": "Databricks GPT-5.2",
"description": "GPT-5.2 hosted through Databricks AI Gateway",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balanced speed and reasoning depth" },
{ "effort": "high", "description": "Greater reasoning depth for complex tasks" },
{ "effort": "xhigh", "description": "Maximum reasoning depth for complex tasks" }
],
"shell_type": "default",
"visibility": "list",
"supported_in_api": true,
"priority": 60,
"additional_speed_tiers": [],
"availability_nux": null,
"upgrade": null,
"base_instructions": "",
"supports_reasoning_summaries": true,
"support_verbosity": true,
"default_verbosity": null,
"apply_patch_tool_type": null,
"truncation_policy": { "mode": "tokens", "limit": 200000 },
"supports_parallel_tool_calls": true,
"experimental_supported_tools": []
}
]
}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ uploads/

# uv lockfile — not portable across PyPI proxies, generate locally with `uv lock`
uv.lock

# Codex CLI generated/cached files (only the bundled model catalog is tracked)
.codex/*
!.codex/databricks-models.json

# Codex skills are generated at runtime by setup_codex.py from .claude/skills/
.agents/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ This template repo opens that vision up for every Databricks user — no IDE set
|----------|----------|-------------|
| `DATABRICKS_TOKEN` | No | Optional. If not set, the app prompts for a token on first session. Auto-rotated every 10 minutes |
| `HOME` | Yes | Set to `/app/python/source_code` in app.yaml |
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-6`) |
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-3-codex`) |
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-7`) |
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-5`) |
| `GEMINI_MODEL` | No | Gemini model name (default: `databricks-gemini-2-5-pro`) |
| `DATABRICKS_GATEWAY_HOST` | No | AI Gateway URL override. Auto-discovered from `DATABRICKS_WORKSPACE_ID` if unset |

Expand Down
4 changes: 2 additions & 2 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,10 @@ def _configure_all_cli_auth(token):

settings = {
"env": {
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-6"),
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-7"),
"ANTHROPIC_BASE_URL": anthropic_base_url,
"ANTHROPIC_AUTH_TOKEN": token,
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-6",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-7",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "databricks-claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "databricks-claude-haiku-4-5",
"ANTHROPIC_CUSTOM_HEADERS": "x-databricks-use-coding-agent-mode: true",
Expand Down
2 changes: 1 addition & 1 deletion app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:
- name: GEMINI_MODEL
value: databricks-gemini-2-5-pro
- name: CODEX_MODEL
value: databricks-gpt-5-3-codex
value: databricks-gpt-5-5
- name: CLAUDE_CODE_DISABLE_AUTO_MEMORY
value: 0
- name: MAX_CONCURRENT_SESSIONS
Expand Down
4 changes: 2 additions & 2 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ databricks apps deploy <your-app-name> \
|----------|----------|-------------|
| `DATABRICKS_TOKEN` | No | Optional. If not set, the app prompts for a token on first session. Auto-rotated every 10 minutes |
| `HOME` | Yes | Set to `/app/python/source_code` in app.yaml |
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-6`) |
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-3-codex`) |
| `ANTHROPIC_MODEL` | No | Claude model name (default: `databricks-claude-opus-4-7`) |
| `CODEX_MODEL` | No | Codex model name (default: `databricks-gpt-5-5`) |
| `GEMINI_MODEL` | No | Gemini model name (default: `databricks-gemini-2-5-pro`) |
| `HERMES_MODEL` | No | Hermes model name (default: `databricks-claude-opus-4-7`) |
| `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 |
Expand Down
4 changes: 2 additions & 2 deletions setup_claude.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@

settings = {
"env": {
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-6"),
"ANTHROPIC_MODEL": os.environ.get("ANTHROPIC_MODEL", "databricks-claude-opus-4-7"),
"ANTHROPIC_BASE_URL": anthropic_base_url,
"ANTHROPIC_AUTH_TOKEN": token,
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-6",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "databricks-claude-opus-4-7",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "databricks-claude-sonnet-4-6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "databricks-claude-haiku-4-5",
"ANTHROPIC_CUSTOM_HEADERS": "x-databricks-use-coding-agent-mode: true",
Expand Down
29 changes: 27 additions & 2 deletions setup_codex.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Auth: Bearer token via DATABRICKS_TOKEN environment variable.
"""
import os
import shutil
import subprocess
from pathlib import Path

Expand All @@ -22,7 +23,7 @@

host = os.environ.get("DATABRICKS_HOST", "")
token = os.environ.get("DATABRICKS_TOKEN", "")
codex_model = os.environ.get("CODEX_MODEL", "databricks-gpt-5-3-codex")
codex_model = os.environ.get("CODEX_MODEL", "databricks-gpt-5-5")

# 1. Install Codex CLI into ~/.local/bin (always, even without token)
local_bin = home / ".local" / "bin"
Expand Down Expand Up @@ -75,13 +76,22 @@
codex_dir = home / ".codex"
codex_dir.mkdir(exist_ok=True)

# Copy bundled Databricks model catalog into ~/.codex so it can be referenced
# by relative path in config.toml (codex resolves relatives against CODEX_HOME).
catalog_src = Path(__file__).parent / ".codex" / "databricks-models.json"
catalog_dst = codex_dir / "databricks-models.json"
if catalog_src.exists() and catalog_src.resolve() != catalog_dst.resolve():
shutil.copyfile(catalog_src, catalog_dst)
print(f"Codex model catalog copied: {catalog_dst}")

# Codex CLI uses TOML config with custom model_providers
config_content = f"""# Databricks Model Serving Configuration for Codex CLI
# Generated by setup_codex.py

# Active model and provider
model = "{codex_model}"
model_provider = "databricks"
model_catalog_json = "databricks-models.json"

# Disable web_search - not supported by Databricks Responses API
web_search = "disabled"
Expand Down Expand Up @@ -110,7 +120,22 @@
env_path.chmod(0o600)
print(f"Codex CLI env configured: {env_path}")

# 5. Adapt CLAUDE.md to AGENTS.md for Codex
# 5. Copy Claude skills into ~/.agents/skills/ where Codex discovers them.
# Codex searches `$HOME/.agents/skills/` plus `.agents/skills/` walking up
# from cwd; both resolve to the same path on the deployed app since
# HOME == repo root, and the user-level lookup also covers local dev.
claude_skills_dir = home / ".claude" / "skills"
codex_skills_dir = home / ".agents" / "skills"
if claude_skills_dir.exists():
codex_skills_dir.parent.mkdir(exist_ok=True)
if codex_skills_dir.exists():
shutil.rmtree(codex_skills_dir)
shutil.copytree(claude_skills_dir, codex_skills_dir)
print(f"Skills copied: {claude_skills_dir} -> {codex_skills_dir}")
else:
print(f"No Claude skills found at {claude_skills_dir}, skipping copy")

# 6. Adapt CLAUDE.md to AGENTS.md for Codex
# Look for CLAUDE.md in common locations
claude_md_locations = [
Path(__file__).parent / "CLAUDE.md", # Same directory as setup script
Expand Down