Flickinshots commited on
Commit
93e8468
·
verified ·
1 Parent(s): 200a73b

Deploy Project Epsilon Space bundle

Browse files
.env.app.example CHANGED
@@ -1,3 +1,11 @@
1
  OPENROUTER_API_KEY=
 
 
2
  OPENROUTER_SITE_URL=http://localhost:7860
3
  OPENROUTER_APP_NAME=Autonomous Executive Assistant Sandbox
 
 
 
 
 
 
 
1
  OPENROUTER_API_KEY=
2
+ OPENROUTER_MODEL=google/gemma-4-31b-it
3
+ OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
4
  OPENROUTER_SITE_URL=http://localhost:7860
5
  OPENROUTER_APP_NAME=Autonomous Executive Assistant Sandbox
6
+
7
+ # Hackathon-compatible aliases. Set OPENAI_API_KEY to the same OpenRouter key
8
+ # only when running inference.py under a validator that expects this name.
9
+ OPENAI_API_KEY=
10
+ API_BASE_URL=https://openrouter.ai/api/v1
11
+ MODEL_NAME=google/gemma-4-31b-it
.env.training.example CHANGED
@@ -1,6 +1,13 @@
1
  OPENROUTER_API_KEY=
2
  OPENROUTER_MODEL=google/gemma-4-31b-it
 
3
  OPENROUTER_SITE_URL=http://localhost:8888
4
  OPENROUTER_APP_NAME=Autonomous Executive Assistant Sandbox Training
5
  OPENROUTER_TEMPERATURE=0.1
6
  OPENROUTER_MAX_TOKENS=600
 
 
 
 
 
 
 
1
  OPENROUTER_API_KEY=
2
  OPENROUTER_MODEL=google/gemma-4-31b-it
3
+ OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
4
  OPENROUTER_SITE_URL=http://localhost:8888
5
  OPENROUTER_APP_NAME=Autonomous Executive Assistant Sandbox Training
6
  OPENROUTER_TEMPERATURE=0.1
7
  OPENROUTER_MAX_TOKENS=600
8
+
9
+ # Hackathon-compatible aliases for inference.py. OPENAI_API_KEY should contain
10
+ # the same OpenRouter API key when using the validator-facing script.
11
+ OPENAI_API_KEY=
12
+ API_BASE_URL=https://openrouter.ai/api/v1
13
+ MODEL_NAME=google/gemma-4-31b-it
README.md CHANGED
@@ -65,7 +65,7 @@ To make that possible under hackathon constraints, we replaced live services wit
65
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
66
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
67
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
68
- - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution
69
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
70
 
71
  ## Seeded Judge Tasks
@@ -95,6 +95,8 @@ The environment includes a stakeholder email asking for exact metrics from a loc
95
  - App port: `7860`
96
  - Entry point: `python app.py`
97
  - Optional secret: `OPENROUTER_API_KEY`
 
 
98
  - A trained RL checkpoint is bundled in `artifacts/checkpoints/` so the `rl` policy is available immediately in the demo.
99
  - The bundled RL artifact lives at `artifacts/checkpoints/q_policy_notebook.json`
100
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
 
65
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
66
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
67
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
68
+ - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution through the OpenAI client compatibility layer
69
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
70
 
71
  ## Seeded Judge Tasks
 
95
  - App port: `7860`
96
  - Entry point: `python app.py`
97
  - Optional secret: `OPENROUTER_API_KEY`
98
+ - OpenAI-compatible base URL: `https://openrouter.ai/api/v1`
99
+ - Model: `google/gemma-4-31b-it`
100
  - A trained RL checkpoint is bundled in `artifacts/checkpoints/` so the `rl` policy is available immediately in the demo.
101
  - The bundled RL artifact lives at `artifacts/checkpoints/q_policy_notebook.json`
102
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
docs/HF_SPACE_README.md CHANGED
@@ -65,7 +65,7 @@ To make that possible under hackathon constraints, we replaced live services wit
65
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
66
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
67
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
68
- - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution
69
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
70
 
71
  ## Seeded Judge Tasks
@@ -95,6 +95,8 @@ The environment includes a stakeholder email asking for exact metrics from a loc
95
  - App port: `7860`
96
  - Entry point: `python app.py`
97
  - Optional secret: `OPENROUTER_API_KEY`
 
 
98
  - Bundled RL checkpoint path: `artifacts/checkpoints/q_policy_notebook.json`
99
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
100
 
 
65
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
66
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
67
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
68
+ - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution through the OpenAI client compatibility layer
69
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
70
 
71
  ## Seeded Judge Tasks
 
95
  - App port: `7860`
96
  - Entry point: `python app.py`
97
  - Optional secret: `OPENROUTER_API_KEY`
98
+ - OpenAI-compatible base URL: `https://openrouter.ai/api/v1`
99
+ - Model: `google/gemma-4-31b-it`
100
  - Bundled RL checkpoint path: `artifacts/checkpoints/q_policy_notebook.json`
101
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
102
 
inference.py CHANGED
@@ -17,15 +17,25 @@ TASKS = [
17
 
18
 
19
  def build_openai_compatible_policy() -> OpenRouterPolicy:
20
- api_key = os.environ.get("OPENAI_API_KEY", "").strip()
21
- base_url = os.environ.get("API_BASE_URL", "").strip()
22
- model_name = os.environ.get("MODEL_NAME", "").strip()
 
 
 
 
 
 
 
 
 
 
23
  if not api_key:
24
- raise RuntimeError("OPENAI_API_KEY is required.")
25
  if not base_url:
26
- raise RuntimeError("API_BASE_URL is required.")
27
  if not model_name:
28
- raise RuntimeError("MODEL_NAME is required.")
29
  config = OpenRouterConfig(
30
  api_key=api_key,
31
  base_url=base_url,
 
17
 
18
 
19
  def build_openai_compatible_policy() -> OpenRouterPolicy:
20
+ api_key = os.environ.get("OPENROUTER_API_KEY", "").strip() or os.environ.get(
21
+ "OPENAI_API_KEY", ""
22
+ ).strip()
23
+ base_url = (
24
+ os.environ.get("OPENROUTER_BASE_URL", "").strip()
25
+ or os.environ.get("API_BASE_URL", "").strip()
26
+ or "https://openrouter.ai/api/v1"
27
+ )
28
+ model_name = (
29
+ os.environ.get("OPENROUTER_MODEL", "").strip()
30
+ or os.environ.get("MODEL_NAME", "").strip()
31
+ or "google/gemma-4-31b-it"
32
+ )
33
  if not api_key:
34
+ raise RuntimeError("OPENROUTER_API_KEY or OPENAI_API_KEY is required.")
35
  if not base_url:
36
+ raise RuntimeError("API_BASE_URL or OPENROUTER_BASE_URL is required.")
37
  if not model_name:
38
+ raise RuntimeError("MODEL_NAME or OPENROUTER_MODEL is required.")
39
  config = OpenRouterConfig(
40
  api_key=api_key,
41
  base_url=base_url,
scripts/deploy_hf_space.py CHANGED
@@ -40,14 +40,14 @@ def build_parser() -> argparse.ArgumentParser:
40
  )
41
  parser.add_argument(
42
  "--team-name",
43
- default=os.environ.get("HF_SPACE_TEAM_NAME", "Project Epsilon"),
44
  help="Team name shown in the generated HF README.",
45
  )
46
  parser.add_argument(
47
  "--hf-usernames",
48
  default=os.environ.get(
49
  "HF_SPACE_TEAM_USERNAMES",
50
- "HF_USERNAME_1,HF_USERNAME_2,HF_USERNAME_3",
51
  ),
52
  help="Comma-separated HF usernames for the HF README placeholders.",
53
  )
@@ -61,6 +61,16 @@ def build_parser() -> argparse.ArgumentParser:
61
  default=os.environ.get("OPENROUTER_API_KEY", "").strip(),
62
  help="Optional secret to set on the Space during deployment.",
63
  )
 
 
 
 
 
 
 
 
 
 
64
  parser.add_argument(
65
  "--private",
66
  action="store_true",
@@ -159,6 +169,9 @@ def main() -> int:
159
  if checkpoint_path is not None:
160
  messages.append(f"Bundled RL checkpoint: {checkpoint_path.relative_to(stage_dir)}")
161
  messages.append(maybe_set_space_secret(api, config.repo_id, "OPENROUTER_API_KEY", args.openrouter_api_key))
 
 
 
162
  messages.append(maybe_set_space_variable(api, config.repo_id, "OPENROUTER_APP_NAME", config.title))
163
  messages.append(maybe_set_space_variable(api, config.repo_id, "OPENROUTER_SITE_URL", config.app_url))
164
 
 
40
  )
41
  parser.add_argument(
42
  "--team-name",
43
+ default=os.environ.get("HF_SPACE_TEAM_NAME", "Team Epsilon"),
44
  help="Team name shown in the generated HF README.",
45
  )
46
  parser.add_argument(
47
  "--hf-usernames",
48
  default=os.environ.get(
49
  "HF_SPACE_TEAM_USERNAMES",
50
+ "flickinshots,ShreyaKhatik,itsayushdey",
51
  ),
52
  help="Comma-separated HF usernames for the HF README placeholders.",
53
  )
 
61
  default=os.environ.get("OPENROUTER_API_KEY", "").strip(),
62
  help="Optional secret to set on the Space during deployment.",
63
  )
64
+ parser.add_argument(
65
+ "--api-base-url",
66
+ default=os.environ.get("API_BASE_URL", "https://openrouter.ai/api/v1").strip(),
67
+ help="OpenAI-compatible API base URL for inference.py. Defaults to OpenRouter.",
68
+ )
69
+ parser.add_argument(
70
+ "--model-name",
71
+ default=os.environ.get("MODEL_NAME", "google/gemma-4-31b-it").strip(),
72
+ help="OpenRouter model id for inference.py. Defaults to Gemma 4.",
73
+ )
74
  parser.add_argument(
75
  "--private",
76
  action="store_true",
 
169
  if checkpoint_path is not None:
170
  messages.append(f"Bundled RL checkpoint: {checkpoint_path.relative_to(stage_dir)}")
171
  messages.append(maybe_set_space_secret(api, config.repo_id, "OPENROUTER_API_KEY", args.openrouter_api_key))
172
+ messages.append(maybe_set_space_secret(api, config.repo_id, "OPENAI_API_KEY", args.openrouter_api_key))
173
+ messages.append(maybe_set_space_variable(api, config.repo_id, "API_BASE_URL", args.api_base_url))
174
+ messages.append(maybe_set_space_variable(api, config.repo_id, "MODEL_NAME", args.model_name))
175
  messages.append(maybe_set_space_variable(api, config.repo_id, "OPENROUTER_APP_NAME", config.title))
176
  messages.append(maybe_set_space_variable(api, config.repo_id, "OPENROUTER_SITE_URL", config.app_url))
177
 
src/executive_assistant/deployment.py CHANGED
@@ -155,7 +155,7 @@ To make that possible under hackathon constraints, we replaced live services wit
155
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
156
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
157
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
158
- - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution
159
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
160
 
161
  ## Seeded Judge Tasks
@@ -185,6 +185,8 @@ The environment includes a stakeholder email asking for exact metrics from a loc
185
  - App port: `{config.app_port}`
186
  - Entry point: `python app.py`
187
  - Optional secret: `OPENROUTER_API_KEY`
 
 
188
  - {checkpoint_note}
189
  - The bundled RL artifact lives at `artifacts/checkpoints/{config.checkpoint_name}`
190
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
 
155
  - **Environment state:** in-memory SQLite workspace simulating emails, todos, files, and action history
156
  - **OpenEnv contract:** Pydantic models defining observations, actions, rewards, and policy decisions
157
  - **Execution loop:** shared `EpisodeRunner` used by tests, scripts, notebook experiments, and the Gradio app
158
+ - **Policies:** deterministic baseline, tabular RL checkpoint replay, and optional OpenRouter-backed live policy execution through the OpenAI client compatibility layer
159
  - **UI layer:** Gradio control room plus visible workspace snapshots for judges
160
 
161
  ## Seeded Judge Tasks
 
185
  - App port: `{config.app_port}`
186
  - Entry point: `python app.py`
187
  - Optional secret: `OPENROUTER_API_KEY`
188
+ - OpenAI-compatible base URL: `https://openrouter.ai/api/v1`
189
+ - Model: `google/gemma-4-31b-it`
190
  - {checkpoint_note}
191
  - The bundled RL artifact lives at `artifacts/checkpoints/{config.checkpoint_name}`
192
  - The Space is deployed from the same repository used for local tests and notebook-backed experiments
tests/test_inference.py CHANGED
@@ -4,6 +4,19 @@ from inference import build_openai_compatible_policy
4
  from src.executive_assistant.config import OpenRouterConfig
5
 
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  def test_openrouter_config_accepts_hackathon_env_names(monkeypatch) -> None:
8
  monkeypatch.delenv("OPENROUTER_API_KEY", raising=False)
9
  monkeypatch.delenv("OPENROUTER_BASE_URL", raising=False)
 
4
  from src.executive_assistant.config import OpenRouterConfig
5
 
6
 
7
+ def test_inference_prefers_openrouter_api_with_openai_client(monkeypatch) -> None:
8
+ monkeypatch.setenv("OPENROUTER_API_KEY", "openrouter-key")
9
+ monkeypatch.setenv("OPENROUTER_BASE_URL", "https://openrouter.ai/api/v1")
10
+ monkeypatch.setenv("OPENROUTER_MODEL", "google/gemma-4-31b-it")
11
+ monkeypatch.setenv("OPENAI_API_KEY", "wrong-openai-key")
12
+ monkeypatch.setenv("API_BASE_URL", "https://api.openai.com/v1")
13
+ monkeypatch.setenv("MODEL_NAME", "wrong-model")
14
+ policy = build_openai_compatible_policy()
15
+ assert policy.config.api_key == "openrouter-key"
16
+ assert policy.config.base_url == "https://openrouter.ai/api/v1"
17
+ assert policy.config.model_name == "google/gemma-4-31b-it"
18
+
19
+
20
  def test_openrouter_config_accepts_hackathon_env_names(monkeypatch) -> None:
21
  monkeypatch.delenv("OPENROUTER_API_KEY", raising=False)
22
  monkeypatch.delenv("OPENROUTER_BASE_URL", raising=False)