-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathapp.yaml.workshop
More file actions
147 lines (147 loc) Β· 8.4 KB
/
Copy pathapp.yaml.workshop
File metadata and controls
147 lines (147 loc) Β· 8.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Workshop variant of app.yaml (spec-A-coda-workshop-layer.md, milestone M1).
# Deployed by `make deploy-workshop` which swaps this in as app.yaml in the
# workspace copy. Differences from the standard app.yaml:
# - Full agent fleet: Claude + Codex + OpenCode + Gemini + Hermes + Pi all
# "true" (workshop drives all agents; MLflow tracing spans every channel).
# Heavier boot (more npm/pip installs) β smoke-test cold start on LARGE.
# - MAX_CONCURRENT_SESSIONS raised to 10 (A-C1; fleet sizing decision)
# - OMNIGENTS_SERVER_URL/OMNIGENTS_WHEEL_SPEC omitted -> boot host-register
# no-ops (A-R3: attendees use CoDA's own terminal, not the Omnigent tunnel)
# - CHALLENGE_REPO_URL + CHALLENGE_REPO_READ_TOKEN added: the ONE config
# spot for the preloaded private challenge repo (A-R7). Compute size is
# NOT set here β it's a create-time property
# (`databricks apps create --compute-size LARGE`, see Makefile).
command:
- gunicorn
- app:app
env:
- name: HOME
value: /app/python/source_code
- name: ANTHROPIC_MODEL
value: system.ai.claude-sonnet-5
# Pi routes to the same /anthropic gateway route as Claude Code; PI_MODEL is
# the serving-endpoint name it addresses (validated against in-geo models).
- name: PI_MODEL
value: system.ai.claude-sonnet-5
- name: GEMINI_MODEL
value: system.ai.gemini-3-flash
# The setup script discovers system.ai models served via the Responses API
# and replaces this request with the newest compatible model when needed.
# Codex speaks wire_api="responses"; chat-completions-only models are
# filtered out by gateway model discovery.
- name: CODEX_MODEL
value: system.ai.gpt-5
- name: HERMES_MODEL
value: databricks-claude-opus-4-8
- name: HERMES_FALLBACK_MODEL
value: databricks-claude-opus-4-8
# AI Gateway: pin the gateway for the workshop workspace, or leave commented
# to auto-derive. A set value is TRUSTED with no reachability probe (see
# utils.get_gateway_host tier 1), so it must be a real, reachable gateway on
# the workspace these instances deploy to β a token minted at one workspace is
# invalid at another's gateway ("400 Invalid Token" on every model call).
# Commented out: tier 2 derives it from the workspace and probes it, which is
# right for any workspace. Note `value: ""` would DISABLE the gateway rather
# than auto-derive, so uncomment with a real URL or leave it out entirely.
# - name: DATABRICKS_GATEWAY_HOST
# value: https://<your-workspace>.<region>.databricks.com/ai-gateway
# ββ Full agent fleet βββββββββββββββββββββββββββββββββββββββββββββββββββββ
# The workshop drives all agents; MLflow tracing covers every channel.
# Trade-off: more CLIs to install at boot β slower cold start, larger
# failure surface. Validate cold-boot on LARGE before the day (spec A-O1).
# Codex enabled by default; set false if the workshop workspace lacks a
# compatible Responses-API (*-codex) endpoint.
- name: ENABLE_CODEX
value: "true"
- name: ENABLE_OPENCODE
value: "true"
# Gemini enabled by default; set false if the workshop workspace lacks a
# compatible Google-native Gemini endpoint.
- name: ENABLE_GEMINI
value: "true"
- name: ENABLE_CLAUDE
value: "true"
- name: ENABLE_HERMES
value: "true"
- name: ENABLE_PI
value: "true"
- name: CLAUDE_CODE_DISABLE_AUTO_MEMORY
value: 0
# MLflow tracing spans every agent channel β the workshop observability
# story. Verified FLOWING per-channel (Part 3); the OTEL->UC path is NOT
# flowing yet (kept off below). See docs/part3-tracing-runbook.md.
- name: MLFLOW_TRACING_ENABLED
value: "true"
# OTEL export off β not flowing yet (Part 3: "MLflow FLOWING, OTEL NOT").
# To enable later, set "true" and point CLAUDE_CODE_OTEL_CATALOG_SCHEMA at a
# <catalog>.<schema> the app SP can write to.
- name: CLAUDE_CODE_OTEL_ENABLED
value: "false"
# - name: CLAUDE_CODE_OTEL_CATALOG_SCHEMA
# value: <catalog>.<schema>
# 10 concurrent browser-terminal sessions per instance (assumed for LARGE,
# validated by the day-of smoke test β A-O1/A-O2).
- name: MAX_CONCURRENT_SESSIONS
value: "10"
# ββ SP self-auth (no PAT paste) ββββββββββββββββββββββββββββββββββββββββββ
# The app authenticates as its OWN app service principal: at boot it writes
# the omnigents-host OAuth (M2M) profile from its captured SP creds, and
# Claude/Pi's apiKeyHelper mints a fresh SP token per-TTL from it. No human
# or injected PAT is ever pasted; setup also runs at boot (see
# initialize_app). Isolation rests on the APP SP's grants β it needs
# model-serving CAN_QUERY (LLM calls) and whatever UC the exercise touches.
- name: ENABLE_SP_APIKEYHELPER
value: "true"
# ββ Shared-app trust model βββββββββββββββββββββββββββββββββββββββββββββββ
# LESS-SECURE shared box: the single-user owner binding is switched OFF so
# every attendee can drive the terminal. With SP self-auth above, they act
# as the app SP (not a pasted identity). Isolation rests entirely on that
# SP's grants β scope them to the workshop, and clean up the app afterward.
# The owner-gated write endpoints (configure-pat, omnigent-host/share) stay
# owner-only even in this mode.
- name: CODA_DISABLE_OWNER_CHECK
value: "true"
# PAT rotation stretched to ~1h for the workshop: because that injected SP
# token is disposable and revoked post-workshop, the longer lifetime is an
# accepted trade for fewer mid-session rotations. token_lifetime must stay
# > rotation_interval so the token never expires between mints β 1h15m
# lifetime gives a 15-min overlap. Secure boxes keep the 600/900 default.
- name: PAT_ROTATION_INTERVAL
value: "3600" # 1h β mint a fresh token every hour
- name: PAT_TOKEN_LIFETIME
value: "4500" # 1h15m β outlives the interval so no expiry gap
# ββ Challenge repo (A-R7) β the one config spot βββββββββββββββββββββββββ
# PRIVATE repo cloned from its main branch at container startup into
# ~/projects/<name>; the terminal opens directly inside it. The read token
# is a repo-scoped READ-ONLY GitHub token stored in a Databricks secret and
# attached to the app as a secret resource named "challenge-repo-token"
# (`make workshop-secret` does both). Token is used for the clone only and
# is stripped from attendee terminal sessions.
# Set both for a workshop deploy. Leaving them out is a clean no-op: app.py
# only registers the "challenge" setup step when CHALLENGE_REPO_URL is set, and
# install_challenge_repo.sh exits 0 when it's unset. Keep them commented
# together β an unresolved CHALLENGE_REPO_READ_TOKEN valueFrom is what causes
# the "error resolving resource challenge-repo-token" boot warning.
# - name: CHALLENGE_REPO_URL
# value: https://github.com/<org>/<challenge-repo>
# - name: CHALLENGE_REPO_READ_TOKEN
# valueFrom: challenge-repo-token
# ββ Omnigent host (workshop deploys ALSO register as a host) βββββββββββββ
# initialize_app() -> start_host() dials the server as the app SP and
# registers this app as an Omnigent host, so agents can be driven INTO the
# container from the Omnigent side (in addition to the browser terminal).
# TRADE-OFF: this couples workshop boot to the Omnigent tunnel + host-wheel
# install (the reason it was previously OFF, spec A-R3). Install runs on a
# background thread so it won't block gunicorn, but it is added surface.
# The host is SP-owned β driveable by the app SP (MCP/session-create); NOT
# visible to human operators in the Omnigent Web UI (host-sharing is a 405
# in stock Omnigent). Requires the app SP to have: CAN_USE on the server app
# + READ_VOLUME on the wheel volume below (one-time IAM grants).
# Resolved from attached resources rather than committed values β same as the
# base app.yaml. Attach with `make attach-omnigent-resources`; an unresolved
# valueFrom yields an empty string and omnigents_host_enabled() returns False,
# so the host is simply off until the resources exist.
- name: OMNIGENTS_SERVER_URL
valueFrom: omnigent-server-url
- name: OMNIGENTS_WHEEL_SPEC
valueFrom: omnigent-wheels