black-yt commited on
Commit
4aa8f49
·
1 Parent(s): b4eb71d

Sync runtime dotenv loading

Browse files
README.md CHANGED
@@ -38,29 +38,80 @@ Maintenance rule:
38
  it is genuinely general-purpose.
39
  - Public documentation should be updated in the main repo, not duplicated here.
40
 
41
- ## Copied From The Main Repository
42
 
43
- These files/directories are copied from the main repo and should be refreshed
44
- when their corresponding upstream implementation changes:
 
45
 
46
- - `agent_base/`: core ReAct runtime, prompts, tool registry, provider
47
- compatibility, trace/session state, image handling, compaction logic, and
48
- imported runtime helpers required by that core.
49
- - `agent_base/tools/`: hosted-safe tool implementations used by the frontend.
50
- - `frontend/static/`: shared browser UI assets, styles, and client logic.
51
- - `frontend/local_server.py`: WebSocket streaming frontend server base, with
52
- Space-specific managed-workspace behavior preserved.
53
- - `requirements.txt`: Python runtime dependencies needed by the hosted app.
54
 
55
- When updating these files from the main repo, inspect the diff and preserve the
56
- Space-specific changes listed below.
57
 
58
- ## Space-Specific Changes
59
-
60
- These behaviors are intentional Space-only deltas:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- - `app.py` is the Hugging Face entrypoint and owns Space startup, cleanup, and
63
- trajectory collection configuration.
64
  - Users cannot select arbitrary server folders. Each new chat gets an isolated
65
  managed run directory under `RH_SPACE_RUNS_DIR`.
66
  - The runtime layout is always:
@@ -81,21 +132,6 @@ These behaviors are intentional Space-only deltas:
81
  - Old inactive runs are cleaned periodically so the Space does not grow without
82
  bound.
83
 
84
- ## Intentionally Removed From The Space
85
-
86
- The Space intentionally does not keep the full main-repo surface area:
87
-
88
- - `run_agent.py`, `run_server.py`, `run_frontend.py`
89
- - OpenAI-compatible API server code under `api/`
90
- - benchmark adapters and benchmark documentation under `benchmarks/`
91
- - long-form tutorials under `docs/`
92
- - local placeholder directories such as `workspace/`, `api_runs/`, and `traces/`
93
- - test fixtures and local test suites
94
- - `.env.example`
95
-
96
- Removing these files keeps the deployed app small and avoids stale code or
97
- misleading documentation drifting away from the main repository.
98
-
99
  ## Required Secrets
100
 
101
  Configure these as Hugging Face Space secrets before starting the app:
 
38
  it is genuinely general-purpose.
39
  - Public documentation should be updated in the main repo, not duplicated here.
40
 
41
+ ## Sync Policy
42
 
43
+ The Space should stay small and deployment-focused. When the main repository
44
+ changes, sync only the files needed by the hosted browser app, then inspect the
45
+ diff manually. Do not copy the whole main repository into this Space.
46
 
47
+ ### Fully Synced From The Main Repository
 
 
 
 
 
 
 
48
 
49
+ These files/directories should normally match the main repo exactly, unless a
50
+ future Space-specific need is documented here:
51
 
52
+ | Path | Purpose |
53
+ | --- | --- |
54
+ | `agent_base/base.py` | Base agent interface. |
55
+ | `agent_base/console_utils.py` | Shared console/event formatting helpers. |
56
+ | `agent_base/context_compact.py` | Context compaction logic. |
57
+ | `agent_base/model_profiles.py` | Provider/model profile helpers. |
58
+ | `agent_base/prompt.py` | Base system prompt. |
59
+ | `agent_base/prompts/system_base.md` | Shared base prompt text. |
60
+ | `agent_base/provider_compat.py` | Provider compatibility normalization. |
61
+ | `agent_base/session_state.py` | Session state serialization. |
62
+ | `agent_base/tools/*.py` | Tool implementations exposed by the Space app. |
63
+ | `agent_base/trace_utils.py` | Trace writing utilities. |
64
+ | `agent_base/utils.py` | Shared runtime utilities, including default `.env` loading. |
65
+ | `VERSION` | Version marker shown by the app/runtime when needed. |
66
+
67
+ ### Partially Synced And Space-Modified
68
+
69
+ These files are related to main-repo files, but must be merged manually because
70
+ the hosted Space has different deployment semantics:
71
+
72
+ | Path | Maintenance rule |
73
+ | --- | --- |
74
+ | `agent_base/react_agent.py` | Keep core ReAct/runtime behavior aligned with main. Preserve Space compatibility only when it is genuinely required by the hosted app. |
75
+ | `frontend/local_server.py` | Based on the main local frontend server, but Space-modified for managed temporary workspaces, forced `agent_workspace/` + `agent_trace/` layout, workspace zip download, automatic cleanup, trajectory collection hooks, and no arbitrary server-folder picker semantics. Never overwrite this file blindly from main. |
76
+ | `frontend/static/index.html` | Starts from the main frontend HTML, but removes the local workspace picker and adds hosted workspace download UI. |
77
+ | `frontend/static/app.js` | Starts from the main frontend client, but removes local folder selection and adds download-token / workspace-zip handling. |
78
+ | `frontend/static/app.css` | Starts from the main frontend CSS, but includes Space-only hosted workspace/download styling and omits local folder picker modal styles. |
79
+ | `requirements.txt` | Starts from the main runtime dependencies, but keeps Space-only hosted dependencies such as `huggingface_hub` and `uvicorn[standard]`. |
80
+ | `app.py` | Space-only FastAPI/Hugging Face entrypoint. It owns startup, cleanup scheduling, static mounting, and hosted defaults. |
81
+ | `check_space_runtime.py` | Space-only smoke test for deployment import/runtime sanity. |
82
+ | `Dockerfile` | Space-only Docker build. |
83
+ | `.dockerignore` | Space-only Docker context pruning. |
84
+ | `.gitattributes` | Space repository metadata. |
85
+ | `.gitignore` | Space-only generated files, cache, and temporary run ignores. |
86
+ | `README.md` | Space maintenance notes only. Public project docs belong in the main repo. |
87
+
88
+ ### Out Of Scope For The Space
89
+
90
+ These main-repo areas should not be copied into this Space unless the hosted app
91
+ explicitly starts using them:
92
+
93
+ | Main-repo path | Reason |
94
+ | --- | --- |
95
+ | `pyproject.toml`, `MANIFEST.in`, `researchharness/` | PyPI packaging belongs to the main open-source repo, not the hosted app mirror. |
96
+ | `.github/` | GitHub CI/release automation does not run in the Hugging Face Space repo. |
97
+ | `run_agent.py`, `run_server.py`, `run_frontend.py` | Local CLI/API/frontend entrypoints are not how the Space is launched. |
98
+ | `api/` | OpenAI-compatible API server is not part of the Space app. |
99
+ | `benchmarks/` | Benchmark adapters and benchmark docs belong to the main repo. |
100
+ | `docs/` | Long-form tutorials belong to the main repo. |
101
+ | `tests/` | Main local/CI tests belong to the main repo; Space keeps only focused smoke checks. |
102
+ | `.env.example` | Public environment template belongs to the main repo. |
103
+ | `agent_base/tools/README.md` | Tool documentation belongs to the main repo; Space keeps only runtime code. |
104
+ | `agent_base/prompts/plugins/` | Plugin prompt assets are not used by the hosted app unless a future Space feature explicitly needs them. |
105
+ | `workspace/`, `api_runs/`, `traces/` | Local placeholder/runtime directories are not checked into Space. |
106
+ | local benchmark helpers such as `benchmarks/**/local_*` | Local development helpers must not be deployed. |
107
+
108
+ Keeping these files out prevents stale code paths and misleading documentation
109
+ from accumulating in the Space.
110
+
111
+ ## Space-Specific Runtime Behavior
112
+
113
+ These behaviors are intentional hosted-app deltas:
114
 
 
 
115
  - Users cannot select arbitrary server folders. Each new chat gets an isolated
116
  managed run directory under `RH_SPACE_RUNS_DIR`.
117
  - The runtime layout is always:
 
132
  - Old inactive runs are cleaned periodically so the Space does not grow without
133
  bound.
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  ## Required Secrets
136
 
137
  Configure these as Hugging Face Space secrets before starting the app:
agent_base/react_agent.py CHANGED
@@ -27,12 +27,11 @@ from agent_base.tools.tool_runtime import Bash, TerminalInterrupt, TerminalKill,
27
  from agent_base.tools.tool_user import AskUser
28
  from agent_base.tools.tool_web import ScholarSearch, WebFetch, WebSearch
29
  from agent_base.utils import (
30
- PROJECT_ROOT,
31
  MissingRequiredEnvError,
32
  append_saved_image_paths_to_prompt,
33
  env_flag,
34
  image_input_content_parts,
35
- load_dotenv,
36
  read_role_prompt_files,
37
  require_required_env,
38
  safe_jsonable,
@@ -1494,7 +1493,7 @@ def _parse_cli_args(argv: list[str]) -> tuple[str, Optional[str], Optional[str],
1494
 
1495
 
1496
  def main(argv: Optional[list[str]] = None) -> int:
1497
- load_dotenv(PROJECT_ROOT / ".env")
1498
  try:
1499
  require_required_env("ResearchHarness agent")
1500
  prompt_text, trace_dir, workspace_root, role_prompt, role_prompt_files, image_paths, chat_arg, extra_tools = _parse_cli_args(argv or sys.argv[1:])
 
27
  from agent_base.tools.tool_user import AskUser
28
  from agent_base.tools.tool_web import ScholarSearch, WebFetch, WebSearch
29
  from agent_base.utils import (
 
30
  MissingRequiredEnvError,
31
  append_saved_image_paths_to_prompt,
32
  env_flag,
33
  image_input_content_parts,
34
+ load_default_dotenvs,
35
  read_role_prompt_files,
36
  require_required_env,
37
  safe_jsonable,
 
1493
 
1494
 
1495
  def main(argv: Optional[list[str]] = None) -> int:
1496
+ load_default_dotenvs()
1497
  try:
1498
  require_required_env("ResearchHarness agent")
1499
  prompt_text, trace_dir, workspace_root, role_prompt, role_prompt_files, image_paths, chat_arg, extra_tools = _parse_cli_args(argv or sys.argv[1:])
agent_base/utils.py CHANGED
@@ -69,6 +69,15 @@ def load_dotenv(path: Union[str, Path]) -> None:
69
  _DOTENV_LAST_LOADED[marker] = parsed_value
70
 
71
 
 
 
 
 
 
 
 
 
 
72
  def env_flag(name: str) -> bool:
73
  return os.getenv(name, "").lower() in {"1", "true", "yes", "on"}
74
 
 
69
  _DOTENV_LAST_LOADED[marker] = parsed_value
70
 
71
 
72
+ def load_default_dotenvs() -> None:
73
+ """Load dotenv files for both installed and source-tree usage."""
74
+ cwd_env = Path.cwd() / ".env"
75
+ project_env = PROJECT_ROOT / ".env"
76
+ load_dotenv(cwd_env)
77
+ if cwd_env.resolve() != project_env.resolve():
78
+ load_dotenv(project_env)
79
+
80
+
81
  def env_flag(name: str) -> bool:
82
  return os.getenv(name, "").lower() in {"1", "true", "yes", "on"}
83
 
frontend/local_server.py CHANGED
@@ -27,7 +27,7 @@ from agent_base.utils import (
27
  PROJECT_ROOT,
28
  append_saved_image_paths_to_prompt,
29
  image_input_content_parts,
30
- load_dotenv,
31
  require_required_env,
32
  safe_jsonable,
33
  stage_image_bytes_for_input,
@@ -608,7 +608,7 @@ def _run_agent_thread(
608
  model_name: str = "",
609
  ) -> None:
610
  try:
611
- load_dotenv(PROJECT_ROOT / ".env")
612
  require_required_env("ResearchHarness frontend")
613
  agent = FrontendInteractiveAgent(
614
  bridge=bridge,
 
27
  PROJECT_ROOT,
28
  append_saved_image_paths_to_prompt,
29
  image_input_content_parts,
30
+ load_default_dotenvs,
31
  require_required_env,
32
  safe_jsonable,
33
  stage_image_bytes_for_input,
 
608
  model_name: str = "",
609
  ) -> None:
610
  try:
611
+ load_default_dotenvs()
612
  require_required_env("ResearchHarness frontend")
613
  agent = FrontendInteractiveAgent(
614
  bridge=bridge,