AgentGenerator Output Assembly Contract¶
Status: CANONICAL — describes what actually exists Last verified: 2026-05-31 Source files: - factory_app/workflows/AgentGenerator/tools/generate_and_download.py - factory_app/workflows/AgentGenerator/tools/workflow_converter.py - factory_app/workflows/AgentGenerator/structured_outputs.yaml - factory_app/workflows/AgentGenerator/agents.yaml - factory_app/workflows/AgentGenerator/extended_orchestration/task_batches.yaml
Related:
structured-output-extraction-contract.md— the general runtime contract for structured outputs and auto-tool-call. This document covers the AgentGenerator-specific pattern where a task batch worker agent produces all workflow bundle files in a single structured output.
How This Works¶
AgentGenerator uses the task batch pattern:
PackBuildCoordinatorcollects the user's workflow pack specification intopack_spec(context variable)- The
workflow_bundle_taskstask batch fires — oneWorkflowBundleBuilderAgentinstance per workflow in the pack, running in parallel - Each worker emits a
WorkflowBundleBuilderOutputwith afileslist ofCodeFileentries - The runtime collects all results into
context_variables["workflow_bundle_results"], keyed by task_id generate_and_downloadreadsworkflow_bundle_results, writes each bundle to disk, zips them, and presents the download UI
There are no sequential planning agents scraping MongoDB. Each WorkflowBundleBuilderAgent instance owns its full bundle output end-to-end.
Generated workflow bundles are staged at:
They do not become active runtime-loaded workflows until an explicit promotion step copies them into an active app root's workflows/ directory.
Agent Roster¶
| Agent | Role |
|---|---|
PatternAgent | Selects orchestration pattern; output available to WorkflowBundleBuilderAgent via context |
PackBuildCoordinator | Interviews the user, populates pack_spec, seeds the task batch |
WorkflowBundleBuilderAgent | Task batch worker — generates all YAML and code files for one workflow bundle |
DownloadCenterAgent | Triggers generate_and_download after the task batch completes |
Task Batch: workflow_bundle_tasks¶
Declared in extended_orchestration/task_batches.yaml.
source:
kind: context_variable
path: pack_spec.workflows
task_model: WorkflowInPack
worker:
mode: ag2_agent
agent_field: initial_agent # WorkflowBundleBuilderAgent
prompt_field: initial_message
result:
context_key: workflow_bundle_results
status_key: workflow_bundle_status
Each task receives one WorkflowInPack entry from pack_spec.workflows. The runtime injects it as context_variables["structured_output"] for the worker.
WorkflowBundleBuilderOutput¶
The worker emits a single WorkflowBundleBuilderOutput structured output:
workflow_name: str
files:
- filename: orchestrator.yaml
content: "..."
- filename: agents.yaml
content: "..."
- filename: handoffs.yaml
content: "..."
- filename: context_variables.yaml
content: "..."
- filename: structured_outputs.yaml
content: "..."
- filename: tools.yaml
content: "..."
- filename: hooks.yaml
content: "..."
- filename: ui_config.yaml
content: "..."
- filename: tools/some_tool.py
content: "..."
- filename: ui/index.js
content: "..."
Each CodeFile has: - filename — workflow-local relative path (e.g., tools/save_result.py, ui/index.js) - content — full file content as a string
workflow_bundle_results Structure¶
After the task batch completes, context_variables["workflow_bundle_results"] is a dict:
{
"task_id_1": {
"workflow_name": "StoryCreator",
"files": [
{"filename": "orchestrator.yaml", "content": "..."},
{"filename": "agents.yaml", "content": "..."},
...
]
},
"task_id_2": {
"workflow_name": "ReviewWorkflow",
"files": [ ... ]
}
}
Keys starting with _ are internal meta entries and are skipped during assembly.
Assembly: generate_and_download¶
Reads workflow_bundle_results directly from context. For each bundle entry:
_write_bundle_to_disk(wf_name, files, base_dir)— writes allCodeFileentries underbase_dir/{wf_name}/_build_pack_zip(bundle_dirs, output_path)— zips all workflow directories into a single archiveuse_ui_tool("DownloadCenter", ...)— presents the download UI to the user
No MongoDB scraping. No create_workflow_files() assembly step.
Files Written¶
$MOZAIKS_GENERATED_ARTIFACTS_PATH/workflows/{app_id}/
├── {WorkflowName}/
│ ├── orchestrator.yaml
│ ├── agents.yaml
│ ├── handoffs.yaml
│ ├── context_variables.yaml
│ ├── structured_outputs.yaml
│ ├── tools.yaml
│ ├── hooks.yaml
│ ├── ui_config.yaml
│ ├── extended_orchestration/
│ │ └── task_batches.yaml ← if workflow uses task batches
│ ├── tools/
│ │ └── *.py ← tool implementations
│ └── ui/
│ ├── index.js ← component barrel
│ └── *.jsx ← workflow-local React components
└── {PackName}.zip ← all workflows bundled together
Generated workflow tools are workflow-local. Generated bundles must not reference workflows/_shared, sibling workflow tool folders, or root-level shared paths. Reusable framework-owned support code belongs under mozaiksai.core.*.
Workflow Name and Pack Name¶
bundle_nameis derived fromcontext_variables["pack_name"]if set, otherwise from the first workflow'sworkflow_name- All names are converted to PascalCase for the output folder and zip file name
Normalization Utilities in workflow_converter.py¶
workflow_converter.py is a contract normalization helper — it does NOT do assembly. Functions exported:
| Function | Purpose |
|---|---|
promote_generated_workflow(source_dir, target_root) | Copy a generated workflow into the active workflows root |
_normalize_handoff_rules(raw_rules) | Normalize handoff rule list; rejects LLM-evaluated conditions |
_normalize_tools_manifest(output, wf_logger) | Normalize tools + lifecycle_tools with UI realization stamps |
_normalize_visual_agents(value, startup_mode) | Normalize visual_agents list per startup_mode |
_collect_ui_code_files(output, tools_config, wf_logger) | Collect UIFileGenerator output, skip shipped primitives, synthesize barrel |
_normalize_runtime_extensions(extensions, workflow_name, wf_logger) | Keep extensions workflow-local |
_normalize_orchestrator_triggers(triggers, wf_logger) | Validate trigger types against declared schema |
These are used by tests and by WorkflowBundleBuilderAgent implementations as reference for what a well-formed bundle looks like.
What Does NOT Exist¶
| Concept | Reality |
|---|---|
gather_latest_agent_jsons() | Removed — was MongoDB scraping; replaced by task batch result collection |
create_workflow_files() | Removed — was the old per-agent-output assembly function |
ContextVariablesAgent | Removed — its work is done inline by WorkflowBundleBuilderAgent |
HandoffsAgent | Removed — its work is done inline by WorkflowBundleBuilderAgent |
AgentsAgent | Removed — its work is done inline by WorkflowBundleBuilderAgent |
ToolsManagerAgent | Removed — its work is done inline by WorkflowBundleBuilderAgent |
OrchestratorAgent | Removed — its work is done inline by WorkflowBundleBuilderAgent |
DownloadAgent | Replaced by DownloadCenterAgent |
| Sequential 18-agent chain | Replaced by 4-agent workflow with parallel task batch workers |
Cross References¶
- structured-output-extraction-contract.md — general auto-tool-call pattern
- workflow-authoring-contracts.md —
extended_orchestration/task_batches.yamlformat factory_app/workflows/AgentGenerator/tools/generate_and_download.py— assembly and downloadfactory_app/workflows/AgentGenerator/tools/workflow_converter.py— normalization utilitiesfactory_app/workflows/AgentGenerator/extended_orchestration/task_batches.yaml— task batch configfactory_app/workflows/AgentGenerator/structured_outputs.yaml—WorkflowBundleBuilderOutputmodel