Context
Issue #34 recently established a clean separation between Config (openloop.json) and Workflow JSON fields. The log_dir field currently lives only in Config — it cannot be overridden per workflow or via CLI.
The current cheat-sheet from #34:
| Config (openloop.json) |
Workflow JSON |
agents_dir, workflows_dir, opencode_binary, log_dir, default_max_loops, default_timeout |
loop_agents, preparation_agents, finalization_agents, end_state_condition, max_loops, workdir, init_script, opencode_defaults, name |
Problem
- No per-workflow override —
log_dir is hard-wired to the global config value. A user running different workflows from different projects cannot point logs to different directories without editing openloop.json each time.
- No CLI flag — There is
--log-file (full path to a single file), but no --log-dir (directory only, letting the engine generate the filename from the workflow name and timestamp). These serve different use cases.
- Undocumented in schema —
log_dir and no_log_file exist in Config (defaults ".openloop" and false) but are missing from the field table in docs/configuration.md.
Proposed Solution
1. Data Model — Config (openloop.json)
Already present: Config.log_dir: str = ".openloop". No change needed.
2. Data Model — Workflow JSON
Add optional log_dir field to the workflow schema:
{
"name": "my-workflow",
"log_dir": "./logs/my-project",
"loop_agents": ["amala"],
...
}
- Optional (null/absent = use Config value)
- If relative, resolved against the effective
workdir (same behaviour as the current Config-based log_dir)
- Added to
WorkflowConfig dataclass (from_dict / to_dict)
3. CLI
New flag --log-dir <path>:
- Highest priority (overrides both workflow and config)
- Accepts relative or absolute paths
- Documented in
docs/cli.md
4. Engine (core/engine.py:_init_log())
Override chain (highest to lowest):
CLI --log-dir -- highest
Workflow JSON log_dir
Config (openloop.json) log_dir -- lowest
This mirrors the existing pattern for workdir and init_script.
5. GUI (ui/app.py)
The existing Log Directory field in Settings > Environment already exists. It currently reads/writes the Config value. That stays — it acts as the global default. Additionally, the workflow JSON should be able to carry its own log_dir, loaded/saved via _get_workflow_data() / _load_workflow_into_ui().
When a workflow is loaded, its log_dir fills the field (overriding the Config default temporarily). The field always saves back to both: the Config for the next fresh start, and the workflow data if the user saves the workflow.
Implementation options:
- Option A (simpler): The field always writes to both
cfg.log_dir and data["log_dir"] on save. The engine's override chain ensures correctness.
- Option B (more explicit): Add a separate "Workflow log dir" field. Probably over-engineered.
6. Documentation
- Add
log_dir and no_log_file to the field table in docs/configuration.md
- Add
log_dir to the field table in docs/workflows.md
- Add
--log-dir to docs/cli.md
Not in Scope
no_log_file per workflow is intentionally excluded — it's a system-level preference. If a use case arises later it can be added.
- The existing
--log-file CLI flag remains as-is (direct file path override).
Implementation Plan
Context
Issue #34 recently established a clean separation between Config (
openloop.json) and Workflow JSON fields. Thelog_dirfield currently lives only in Config — it cannot be overridden per workflow or via CLI.The current cheat-sheet from #34:
agents_dir,workflows_dir,opencode_binary,log_dir,default_max_loops,default_timeoutloop_agents,preparation_agents,finalization_agents,end_state_condition,max_loops,workdir,init_script,opencode_defaults,nameProblem
log_diris hard-wired to the global config value. A user running different workflows from different projects cannot point logs to different directories without editingopenloop.jsoneach time.--log-file(full path to a single file), but no--log-dir(directory only, letting the engine generate the filename from the workflownameand timestamp). These serve different use cases.log_dirandno_log_fileexist inConfig(defaults".openloop"andfalse) but are missing from the field table indocs/configuration.md.Proposed Solution
1. Data Model — Config (
openloop.json)Already present:
Config.log_dir: str = ".openloop". No change needed.2. Data Model — Workflow JSON
Add optional
log_dirfield to the workflow schema:{ "name": "my-workflow", "log_dir": "./logs/my-project", "loop_agents": ["amala"], ... }workdir(same behaviour as the current Config-basedlog_dir)WorkflowConfigdataclass (from_dict/to_dict)3. CLI
New flag
--log-dir <path>:docs/cli.md4. Engine (
core/engine.py:_init_log())Override chain (highest to lowest):
This mirrors the existing pattern for
workdirandinit_script.5. GUI (
ui/app.py)The existing Log Directory field in Settings > Environment already exists. It currently reads/writes the Config value. That stays — it acts as the global default. Additionally, the workflow JSON should be able to carry its own
log_dir, loaded/saved via_get_workflow_data()/_load_workflow_into_ui().When a workflow is loaded, its
log_dirfills the field (overriding the Config default temporarily). The field always saves back to both: the Config for the next fresh start, and the workflow data if the user saves the workflow.Implementation options:
cfg.log_diranddata["log_dir"]on save. The engine's override chain ensures correctness.6. Documentation
log_dirandno_log_fileto the field table indocs/configuration.mdlog_dirto the field table indocs/workflows.md--log-dirtodocs/cli.mdNot in Scope
no_log_fileper workflow is intentionally excluded — it's a system-level preference. If a use case arises later it can be added.--log-fileCLI flag remains as-is (direct file path override).Implementation Plan
log_dir: Optional[str] = NonetoWorkflowConfig(core/engine.py)log_dirserialization toWorkflowConfig.from_dict()/to_dict()--log-dir(openloop.py)execute_workflow_data()before calling_init_log()_init_log()to accept explicitlog_dirlog_dirinto field, save back to both config and workflow datadocs/configuration.md,docs/workflows.md,docs/cli.md