@paradigma-inc/flywheel 0.1.16 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/flywheel/SKILL.md +1 -0
- package/skills/flywheel/compute/managed-compute.md +111 -2
- package/skills/flywheel/references/flywheel-mcp-tool-map.md +135 -142
- package/skills/flywheel-auto/SKILL.md +14 -6
- package/skills/flywheel-auto/evals/evals.json +6 -0
- package/skills/flywheel-auto/references/ARTIFACTS.md +47 -216
- package/skills/flywheel-auto/references/INTERFACES.md +192 -195
- package/skills/flywheel-auto/references/experiment-design-protocol-autonomous.md +62 -0
- package/skills/flywheel-auto/references/flywheel-mcp-tool-map.md +135 -142
- package/skills/flywheel-lookahead/SKILL.md +1 -0
- package/skills/flywheel-lookahead/references/ARTIFACTS.md +47 -216
- package/skills/flywheel-lookahead/references/INTERFACES.md +192 -195
- package/skills/flywheel-lookahead/references/flywheel-mcp-tool-map.md +135 -142
- package/skills/flywheel-reproduce/SKILL.md +4 -1
- package/skills/flywheel-reproduce/references/ARTIFACTS.md +47 -216
- package/skills/flywheel-reproduce/references/INTERFACES.md +192 -195
- package/skills/flywheel-reproduce/references/flywheel-mcp-tool-map.md +135 -142
- package/skills/flywheel-to-graph/SKILL.md +1 -0
- package/skills/flywheel-to-graph/references/ARTIFACTS.md +47 -216
- package/skills/flywheel-to-graph/references/INTERFACES.md +192 -195
- package/skills/flywheel-to-graph/references/flywheel-mcp-tool-map.md +135 -142
|
@@ -1,160 +1,153 @@
|
|
|
1
1
|
# Flywheel MCP Tool Map
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
contract expected by the public Flywheel skill.
|
|
3
|
+
Contract-aligned routing guide for Flywheel MCP tool usage.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
tool surface exposed by your current MCP host before executing critical flows.
|
|
5
|
+
Flywheel is a graph-based system for tracking research work, decisions, and evidence over time. Flywheel MCP is the tool interface for reading and updating that graph. You can discover, create, and manage nodes. You can collaborate with other users and use managed compute.
|
|
8
6
|
|
|
9
7
|
## Core Contract Expectations
|
|
10
8
|
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
- Node
|
|
14
|
-
- `
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
- Use `flywheel_get_contract` + `flywheel_get_contract_section` as canonical contract references.
|
|
10
|
+
- Node state is canonical durable state; avoid relying on ephemeral transcript state.
|
|
11
|
+
- Node kind (`untyped`, `empirical`, `insight`) is an explicit durable field.
|
|
12
|
+
- Node references include immutable `node_id` and optional immutable `slug_name`; prefer communicating both together for human clarity and disambiguation.
|
|
13
|
+
- Insight nodes should represent conceptual observations (theoretical insights, intuitions, motivations, decision-relevant framing); empirical nodes should represent experiments with explicit hypotheses and measured outcomes.
|
|
14
|
+
- Graph topology should encode logical/causal relations between concepts and experiments. Avoid defaulting to shallow root-only branching unless work items are truly independent.
|
|
15
|
+
- Node lifecycle semantics are interface-agnostic (`stage_node_create`, `stage_node_update`, `commit_node`); MCP tools are one projection of this shared contract.
|
|
16
|
+
- Mutating node writes are optimistic-locking operations: read latest state, pass `expected_revision`, and handle `409 conflict` with explicit reconciliation.
|
|
17
|
+
- Mutating operations are idempotent; MCP tool transport auto-manages `Idempotency-Key` on mutating tool calls.
|
|
18
|
+
- Commit is finalize-only: commit requests require `expected_revision` and may optionally override `summary`; committed node state must still satisfy strict contract (`summary`/`outcome`, `empirical+completed` requires artifacts or `no_artifacts_reason`, `insight` requires non-empty insights).
|
|
19
|
+
- When code is involved, pass `repo_url`/`branch_name`/`head_commit_sha` and align git structure with graph topology where practical (without forcing one-to-one mapping).
|
|
20
|
+
- Summaries, hypotheses, and artifacts should be reproduction-grade: enough setup, method, evidence, and interpretation for another reader to reproduce or audit results.
|
|
21
|
+
- Empirical workflow is hypothesis-driven: launch execution, inspect outcomes, publish evidence artifacts, and commit only after terminal status.
|
|
22
|
+
- For empirical work, publish evidence with `flywheel_prepare_artifact_uploads`, upload raw file bytes, then `flywheel_finalize_artifact_uploads` before commit.
|
|
23
|
+
- Artifact metadata records expose a non-empty `title` suitable for display labels; title normalization must never derive from `storage_url`.
|
|
21
24
|
|
|
22
25
|
## Tool Families
|
|
23
26
|
|
|
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
|
-
### Tags and Graph Annotation
|
|
60
|
-
|
|
61
|
-
- `mcp__flywheel__flywheel_create_node_tag`
|
|
62
|
-
- `mcp__flywheel__flywheel_update_node_tag`
|
|
63
|
-
- `mcp__flywheel__flywheel_delete_node_tag`
|
|
64
|
-
- `mcp__flywheel__flywheel_set_node_tag_assignments`
|
|
27
|
+
### Discovery and sharing
|
|
28
|
+
|
|
29
|
+
- `flywheel_auth_status` (read; scopes: `read`; HTTP: `GET /auth/status`; core surface): Return Flywheel auth status for the current access token.
|
|
30
|
+
- `flywheel_get_credits_balance` (read; scopes: `read`; HTTP: `GET /credits`; core surface): Return current user credits balance and lifetime counters.
|
|
31
|
+
- `flywheel_updates_list` (read; scopes: `read`; HTTP: `GET /mcp/updates`; core surface): List in-app updates/announcements for the signed-in user.
|
|
32
|
+
- `flywheel_updates_hide` (mutating; scopes: `write`; HTTP: `POST /mcp/updates/{announcement_id}/hide`; core surface): Mark one update as hidden for the current user (Don't show again).
|
|
33
|
+
- `flywheel_updates_hide_all_active` (mutating; scopes: `write`; HTTP: `POST /mcp/updates/hide-all-active`; core surface): Hide all active updates for the current user (Don't show all active again).
|
|
34
|
+
- `flywheel_updates_unhide` (mutating; scopes: `write`; HTTP: `DELETE /mcp/updates/{announcement_id}/hide`; core surface): Restore one hidden update for the current user.
|
|
35
|
+
- `flywheel_list_nodes` (read; scopes: `read`; HTTP: `GET /mcp/nodes`; full-surface only): List nodes with optional owners/writers/visibility filters and projection control (`core`, `topology`, `full`).
|
|
36
|
+
- `flywheel_resolve_node_slug` (read; scopes: `read`; HTTP: `GET /mcp/nodes/resolve-by-slug`; core surface): Resolve a node by slug_name with explicit conflict handling (`unique`, `context_resolved`, `ambiguous`, `not_found`).
|
|
37
|
+
- `flywheel_get_node_sharing` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/sharing`; full-surface only): Get node sharing for one node (owner/collaborators/visibility).
|
|
38
|
+
- `flywheel_set_sharing_for_node` (mutating; scopes: `write`; HTTP: `PUT /mcp/nodes/{node_id}/sharing`; full-surface only): Set sharing for one owned node (collaborators/private-unlisted-public visibility).
|
|
39
|
+
- `flywheel_set_sharing_for_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/sharing/bulk`; full-surface only): Apply one sharing configuration across multiple owned nodes in bulk.
|
|
40
|
+
- `flywheel_get_node` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}`; core surface): Get one node by node_id.
|
|
41
|
+
- `flywheel_create_node_tag` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{root_node_id}/tags`; full-surface only): Create one graph tag from a root node.
|
|
42
|
+
- `flywheel_update_node_tag` (mutating; scopes: `write`; HTTP: `PATCH /mcp/nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Update one graph tag from a root node.
|
|
43
|
+
- `flywheel_delete_node_tag` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{root_node_id}/tags/{tag_id}`; full-surface only): Delete one graph tag from a root node.
|
|
44
|
+
- `flywheel_set_node_tag_assignments` (mutating; scopes: `write`; HTTP: `PUT /mcp/nodes/{node_id}/tags`; full-surface only): Set graph tag assignments for one node.
|
|
45
|
+
- `flywheel_get_node_tree` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/tree`; full-surface only): Get a root-aware bounded tree/DAG projection for an anchor node.
|
|
46
|
+
- `flywheel_get_node_ancestry` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/ancestry`; full-surface only): Get ordered ancestry metadata from an anchor node to root boundaries.
|
|
47
|
+
- `flywheel_get_campaign_snapshot` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/campaign/snapshot`; core surface): Read the current campaign snapshot for a node's root campaign, including configured views and derived records.
|
|
48
|
+
- `flywheel_list_audit` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/audit`; full-surface only): List node MCP audit events.
|
|
49
|
+
|
|
50
|
+
### Node lifecycle
|
|
51
|
+
|
|
52
|
+
- `flywheel_stage_node_create` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/stage/create`; full-surface only): Stage creation of a new Flywheel node.
|
|
53
|
+
- `flywheel_stage_node_update` (mutating; scopes: `write`; HTTP: `PATCH /mcp/nodes/{node_id}/stage/update`; core surface): Stage mutable node fields, including content/readme text, with optimistic locking; use `no_artifacts_reason` when empirical completed nodes intentionally have no artifacts.
|
|
54
|
+
- `flywheel_commit_node` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/commit`; core surface): Commit a node with contract validation.
|
|
55
|
+
- `flywheel_branch_node` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/branch`; full-surface only): Create a child branch node.
|
|
56
|
+
- `flywheel_merge_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/merge`; full-surface only): Merge nodes with caller-resolved node payload.
|
|
57
|
+
- `flywheel_add_parent` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/parents/add`; full-surface only): Attach an additional parent edge to an existing node (keeps node identity, validates against cycles).
|
|
58
|
+
- `flywheel_remove_parent` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/parents/remove`; full-surface only): Detach one parent edge from a node without deleting the node.
|
|
59
|
+
- `flywheel_delete_node` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{node_id}`; full-surface only): Delete a node subtree.
|
|
60
|
+
- `flywheel_bulk_delete_nodes` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/bulk-delete`; full-surface only): Delete multiple node subtrees in one operation.
|
|
65
61
|
|
|
66
62
|
### Artifacts
|
|
67
63
|
|
|
68
|
-
- `
|
|
69
|
-
- `
|
|
70
|
-
- `
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
73
|
-
- `
|
|
74
|
-
- `mcp__flywheel__flywheel_delete_artifact`
|
|
75
|
-
|
|
76
|
-
Common artifact types include:
|
|
77
|
-
`text`, `table`, `json`, `image`, `banner`, `html`, `plotly_html`, `vega`,
|
|
78
|
-
`checkpoint`, and `diff_carousel`.
|
|
79
|
-
|
|
80
|
-
### Export and Import
|
|
81
|
-
|
|
82
|
-
- `mcp__flywheel__flywheel_export_subgraph`
|
|
83
|
-
- `mcp__flywheel__flywheel_import_subgraph`
|
|
84
|
-
- `mcp__flywheel__flywheel_export_summary`
|
|
85
|
-
- `mcp__flywheel__flywheel_export_summary_stream`
|
|
86
|
-
- `mcp__flywheel__flywheel_export_summary_pdf`
|
|
87
|
-
- `mcp__flywheel__flywheel_export_summary_render_pdf`
|
|
64
|
+
- `flywheel_prepare_artifact_uploads` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/artifacts/uploads/prepare`; core surface): Prepare one or more raw-file artifact uploads (returns batch token + signed upload URLs). Upload must send raw file bytes to the returned URLs (do not upload JSON metadata wrappers).
|
|
65
|
+
- `flywheel_finalize_artifact_uploads` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/artifacts/uploads/finalize`; core surface): Finalize a prepared artifact upload batch and append all staged artifacts to the node in one revision bump.
|
|
66
|
+
- `flywheel_list_artifacts` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/artifacts`; core surface): List node artifacts.
|
|
67
|
+
- `flywheel_get_artifact` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/artifacts/{artifact_id}`; core surface): Get one artifact by id.
|
|
68
|
+
- `flywheel_delete_artifact` (mutating; scopes: `write`; HTTP: `DELETE /mcp/nodes/{node_id}/artifacts/{artifact_id}`; core surface): Delete one artifact by id with optimistic locking.
|
|
69
|
+
- `flywheel_set_artifact_note` (mutating; scopes: `write`; HTTP: `PATCH /mcp/nodes/{node_id}/artifacts/{artifact_id}/note`; core surface): Set or clear one artifact note with optimistic locking.
|
|
88
70
|
|
|
89
71
|
### Executions
|
|
90
72
|
|
|
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
|
-
|
|
73
|
+
- `flywheel_launch_execution` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/executions`; core surface): Launch node execution.
|
|
74
|
+
- `flywheel_list_executions` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/executions`; core surface): List node executions.
|
|
75
|
+
- `flywheel_terminate_execution` (mutating; scopes: `write`; HTTP: `POST /mcp/nodes/{node_id}/executions/{execution_id}/terminate`; core surface): Terminate a node execution.
|
|
76
|
+
|
|
77
|
+
### Compute and budgets
|
|
78
|
+
|
|
79
|
+
- `flywheel_compute_list_options` (read; scopes: `compute`; HTTP: `GET /mcp/nodes/{node_id}/compute/options`; core surface): List managed compute options allowed for a node. When using grant-backed compute, pass the same compute_grant_id you will use for acquire.
|
|
80
|
+
- `flywheel_compute_status` (read; scopes: `compute`; HTTP: `GET /mcp/compute/status`; core surface): Read managed compute lease status for the current user. Lease rows include ownership flags so hosts can distinguish user-owned leases from sponsor-visible campaign leases. When checking a grant-backed lease, reuse the same compute_grant_id passed to acquire.
|
|
81
|
+
- `flywheel_compute_connection` (read; scopes: `compute`; HTTP: `GET /mcp/compute/connection`; core surface): Read SSH connection material for an active managed compute lease once flywheel_compute_status indicates the lease is usable. Only leases owned by the current user are connectable. Pass lease_id or node_id to disambiguate when needed.
|
|
82
|
+
- `flywheel_approval_session_heartbeat` (read; scopes: `compute`; HTTP: `POST /mcp/approval-sessions/heartbeat`; core surface): Create or refresh a compute-grant approval session for the current MCP host session.
|
|
83
|
+
- `flywheel_list_approval_sessions` (read; scopes: `compute`; HTTP: `GET /mcp/approval-sessions`; core surface): List approval sessions visible to the current user. Optionally include grant approval bindings for each session.
|
|
84
|
+
- `flywheel_expire_approval_session` (mutating; scopes: `compute`; HTTP: `POST /mcp/approval-sessions/expire`; core surface): Expire the current compute-grant approval session and release its active leases.
|
|
85
|
+
- `flywheel_request_compute_grant_approval` (mutating; scopes: `compute`; HTTP: `tool-mediated`; core surface): Request budget approval and return approval_url + request_id for user confirmation before managed compute acquisition.
|
|
86
|
+
- `flywheel_list_compute_grants` (read; scopes: `compute`; HTTP: `GET /mcp/compute/grants`; core surface): List active/exhausted compute grants available to the current user.
|
|
87
|
+
- `flywheel_list_campaign_budgets` (read; scopes: `compute`; HTTP: `GET /mcp/nodes/{root_node_id}/campaign-budgets`; full-surface only): List campaign compute budgets for a campaign root. Organizer-only management view.
|
|
88
|
+
- `flywheel_create_campaign_budget` (mutating; scopes: `compute`; HTTP: `POST /mcp/nodes/{root_node_id}/campaign-budgets`; full-surface only): Create an organizer-funded campaign compute budget shared with participants.
|
|
89
|
+
- `flywheel_update_campaign_budget` (mutating; scopes: `compute`; HTTP: `PATCH /mcp/nodes/{root_node_id}/campaign-budgets/{compute_budget_id}`; full-surface only): Update hard caps or metadata for an organizer-funded campaign compute budget.
|
|
90
|
+
- `flywheel_revoke_campaign_budget` (mutating; scopes: `compute`; HTTP: `DELETE /mcp/nodes/{root_node_id}/campaign-budgets/{compute_budget_id}`; full-surface only): Revoke an organizer-funded campaign compute budget.
|
|
91
|
+
- `flywheel_compute_acquire` (mutating; scopes: `compute`; HTTP: `POST /mcp/nodes/{node_id}/compute/acquire`; core surface): Acquire managed compute for a node with explicit SKU + region and required compute_grant_id (returns accepted/completed lease state only; poll flywheel_compute_status for readiness, not SSH key material). This tool heartbeats and forwards approval_session_id.
|
|
92
|
+
- `flywheel_compute_release` (mutating; scopes: `compute`; HTTP: `POST /mcp/compute/release`; core surface): Asynchronously release one managed compute lease by lease_id.
|
|
93
|
+
- `flywheel_compute_release_all` (mutating; scopes: `compute`; HTTP: `POST /mcp/compute/release-all`; core surface): Asynchronously release all active managed compute leases for the current user.
|
|
94
|
+
|
|
95
|
+
### Contract, audit, and export
|
|
96
|
+
|
|
97
|
+
- `flywheel_get_contract` (read; scopes: `read`; HTTP: `GET /mcp/contract`; core surface): Return Flywheel MCP contract overview (scopes, write safety, operation catalog, and section index).
|
|
98
|
+
- `flywheel_get_contract_section` (read; scopes: `read`; HTTP: `GET /mcp/contract/sections/{section_id}`; core surface): Return one contract section by section_id (for example `graph` or `campaign/template_v1`).
|
|
99
|
+
- `flywheel_export_subgraph` (read; scopes: `read`; HTTP: `POST /mcp/export`; full-surface only): Export selected graph/subgraph nodes as JSON.
|
|
100
|
+
- `flywheel_import_subgraph` (mutating; scopes: `write`; HTTP: `POST /mcp/import`; full-surface only): Import graph/subgraph JSON payload into new node IDs. Set normalize_cycles=true to drop cycle/self-loop edges; default rejects cyclic payloads.
|
|
101
|
+
- `flywheel_summarize_node_tree` (read; scopes: `read`; HTTP: `GET /mcp/nodes/{node_id}/summary`; full-surface only): Summarize a node tree using node fields only.
|
|
102
|
+
- `flywheel_export_summary` (read; scopes: `read`; HTTP: `POST /mcp/export-summary`; full-surface only): Generate markdown summary for selected nodes.
|
|
103
|
+
- `flywheel_export_summary_stream` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-stream`; full-surface only): Generate summary stream events for selected nodes.
|
|
104
|
+
- `flywheel_export_summary_pdf` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-pdf`; full-surface only): Generate PDF summary for selected nodes.
|
|
105
|
+
- `flywheel_export_summary_render_pdf` (read; scopes: `read`; HTTP: `POST /mcp/export-summary-render-pdf`; full-surface only): Render provided markdown to PDF and embed export metadata.
|
|
121
106
|
|
|
122
107
|
## Practical Tool Sequences
|
|
123
108
|
|
|
124
|
-
###
|
|
125
|
-
|
|
126
|
-
1. `
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
109
|
+
### List Owned Nodes
|
|
110
|
+
|
|
111
|
+
1. `flywheel_list_nodes` with `{'owners': ['me'], 'projection': 'core'}`.
|
|
112
|
+
|
|
113
|
+
### Safe Node Update
|
|
114
|
+
|
|
115
|
+
1. `flywheel_get_node`: Read latest node state before mutating fields.
|
|
116
|
+
2. `flywheel_stage_node_update`: Stage changes with fresh expected_revision and resolve 409 conflicts explicitly.
|
|
117
|
+
3. `flywheel_commit_node`: Commit once terminal and contract-complete.
|
|
118
|
+
|
|
119
|
+
### Empirical Workflow
|
|
120
|
+
|
|
121
|
+
1. `flywheel_stage_node_create`: Create a staged node, then set empirical fields before execution.
|
|
122
|
+
2. `flywheel_stage_node_update`: Set `kind=empirical`, `hypothesis`, and summary fields with fresh `expected_revision`.
|
|
123
|
+
3. `flywheel_request_compute_grant_approval`: If compute is needed, request budget approval first. Response status is `approval_required`.
|
|
124
|
+
4. Branch on `flywheel_request_compute_grant_approval.status`: Branch by response status. `approval_required` is a response state, not a request parameter.. if `approval_required` then `present_approval_url_to_user`: Present `approval_url` to the user; the user opens it and confirms budget approval.; `flywheel_list_approval_sessions`: After approval, list approval sessions with include_approvals=true and use the active `compute_grant_id` for the current approval_session_id.
|
|
125
|
+
5. `flywheel_compute_acquire`: Acquire lease with `compute_grant_id`; include `approval_session_id` from approval response.
|
|
126
|
+
6. `flywheel_compute_status`: Poll until the active lease is ready; follow `recommended_next_action`.
|
|
127
|
+
7. `flywheel_launch_execution`: Launch execution once compute and inputs are ready.
|
|
128
|
+
8. `flywheel_list_executions`: Poll until execution reaches terminal status.
|
|
129
|
+
9. `flywheel_prepare_artifact_uploads`: Prepare signed upload URLs for empirical evidence.
|
|
130
|
+
10. `raw_file_upload`: Upload raw bytes to each signed URL with required headers.
|
|
131
|
+
11. `flywheel_finalize_artifact_uploads`: Finalize prepared uploads before commit, or set `no_artifacts_reason` when intentionally artifact-free.
|
|
132
|
+
12. `flywheel_commit_node`: Commit terminal empirical node once contract requirements are satisfied.
|
|
133
|
+
|
|
134
|
+
## Runtime Guidance
|
|
135
|
+
|
|
136
|
+
- `flywheel_resolve_node_slug`: resolve human-facing slug references. If response status is `ambiguous`, ask the user to confirm the intended node_id before mutating anything.
|
|
137
|
+
- `flywheel_get_node`: read the current node state before writes.
|
|
138
|
+
- `flywheel_stage_node_update`: update in-progress node fields (title/content/summary, kind/outcome/hypothesis/insights/no_artifacts_reason), always with fresh `expected_revision`.
|
|
139
|
+
- `flywheel_get_campaign_snapshot`: read the current derived campaign state for this node's root campaign instead of inferring standings from freeform text.
|
|
140
|
+
- `flywheel_get_node_sharing`: after sharing writes, verify with flywheel_get_node_sharing before reporting private/shared/public state.
|
|
141
|
+
- `flywheel_compute_status`: check first when work may need managed compute (GPU), to detect any active user lease state.
|
|
142
|
+
- `flywheel_list_compute_grants`: list active compute grants (funded by user/root budgets) and select one `compute_grant_id` for acquisition.
|
|
143
|
+
- `flywheel_request_compute_grant_approval`: request/confirm budget before acquire and choose a budget source (`user` or `root`); this returns `approval_url` + `request_id` when interactive approval is needed.
|
|
144
|
+
- `flywheel_compute_connection`: read SSH connection material for the active user lease once status indicates the lease is usable.
|
|
145
|
+
- `flywheel_compute_list_options`: use when a lease is needed and no suitable active lease exists, then select explicit provider-qualified `offer_id` (`provider::offer_id`) and `region`. Consider each option's `availability_mode`: `live_capacity` means provider-reported capacity, `allocation_time` means capacity is confirmed only when `flywheel_compute_acquire` attempts provisioning.
|
|
146
|
+
- `flywheel_compute_acquire`: provision compute once requirements are clear. This requires a valid `compute_grant_id` and returns lease/provisioning state only (not SSH key material).
|
|
147
|
+
- `flywheel_compute_release`: release compute when no longer needed.
|
|
148
|
+
- `flywheel_launch_execution`, `flywheel_list_executions`, `flywheel_terminate_execution`: manage execution lifecycle.
|
|
149
|
+
- `flywheel_prepare_artifact_uploads`: prepare one or more signed raw-file upload requests for concrete deliverables/evidence produced by the work.
|
|
150
|
+
- `flywheel_finalize_artifact_uploads`: finalize a staged artifact batch and append all uploaded artifacts in one revision bump.
|
|
151
|
+
- `flywheel_delete_artifact`: remove an accidental/obsolete node artifact.
|
|
152
|
+
- `flywheel_list_artifacts`, `flywheel_get_artifact`: inspect node artifact metadata (`title` is the display label) and consume `storage_url` for raw artifact bytes only.
|
|
153
|
+
- `flywheel_commit_node`: finalize staged node state once terminal and contract-complete (optional summary override only).
|
|
@@ -141,5 +141,6 @@ The `Start nodes` line is the recovery anchor for later replans. If multiple fro
|
|
|
141
141
|
|
|
142
142
|
- Build the graph explicitly with nodes, artifacts, and selected edges.
|
|
143
143
|
- Do not request compute approval, acquire managed compute, or launch execution just to do planning.
|
|
144
|
+
- These planning-only execution prohibitions apply only when $flywheel-lookahead is the active skill.
|
|
144
145
|
|
|
145
146
|
See also: invoke `$flywheel-to-graph` to port source material into Flywheel without implicit execution, invoke `$flywheel-reproduce` to graphify claim-bearing sources and run budgeted validation branches, and invoke `$flywheel-auto` to advance a frontier autonomously under an explicit budget and persisted stop condition.
|
|
@@ -1,218 +1,49 @@
|
|
|
1
1
|
# Flywheel Artifacts
|
|
2
2
|
|
|
3
|
-
Canonical
|
|
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
|
-
- direct HTTP callers must provide `Idempotency-Key` on mutating MCP
|
|
51
|
-
endpoints.
|
|
52
|
-
|
|
53
|
-
`artifact_type=banner` is supported for campaign root visuals. It follows the
|
|
54
|
-
same raw image upload validation path as `artifact_type=image` and is intended
|
|
55
|
-
for zoomed-out canvas visibility.
|
|
56
|
-
|
|
57
|
-
## Prepare Request Shape
|
|
58
|
-
|
|
59
|
-
`POST /mcp/nodes/{node_id}/artifacts/uploads/prepare`
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"expected_revision": 7,
|
|
64
|
-
"items": [
|
|
65
|
-
{
|
|
66
|
-
"artifact_type": "image",
|
|
67
|
-
"title": "Loss curve",
|
|
68
|
-
"execution_id": "optional-execution-id",
|
|
69
|
-
"metadata": {
|
|
70
|
-
"source": "training-run"
|
|
71
|
-
},
|
|
72
|
-
"filename": "loss_curve.png",
|
|
73
|
-
"media_type": "image/png"
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Notes:
|
|
80
|
-
|
|
81
|
-
- `items` must contain at least one structured object item.
|
|
82
|
-
- String or JSON-encoded item payloads are invalid at the tool boundary.
|
|
83
|
-
- `filename` and `media_type` are required for each item.
|
|
84
|
-
- `metadata` is caller-defined JSON.
|
|
85
|
-
|
|
86
|
-
## Prepare Response Shape
|
|
87
|
-
|
|
88
|
-
```json
|
|
89
|
-
{
|
|
90
|
-
"batch": {
|
|
91
|
-
"batch_token": "uuid",
|
|
92
|
-
"expires_at": "2026-03-09T16:00:00+00:00",
|
|
93
|
-
"max_upload_bytes": 10485760,
|
|
94
|
-
"items": [
|
|
95
|
-
{
|
|
96
|
-
"upload_id": "uuid",
|
|
97
|
-
"upload_url": "https://.../mcp/artifacts/uploads/{upload_id}?ticket=...",
|
|
98
|
-
"method": "PUT",
|
|
99
|
-
"headers": {
|
|
100
|
-
"Content-Type": "image/png",
|
|
101
|
-
"X-Flywheel-Artifact-Filename": "loss_curve.png"
|
|
102
|
-
},
|
|
103
|
-
"curl_command": "curl -sS -X PUT '...' -H 'Content-Type: image/png' -H 'X-Flywheel-Artifact-Filename: loss_curve.png' --data-binary @/absolute/path/to/file"
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Raw Upload Step
|
|
111
|
-
|
|
112
|
-
Execute each returned request exactly:
|
|
113
|
-
|
|
114
|
-
- Method: `PUT`
|
|
115
|
-
- URL: `batch.items[i].upload_url`
|
|
116
|
-
- Body: raw file bytes
|
|
117
|
-
- Headers:
|
|
118
|
-
- `Content-Type` (media type)
|
|
119
|
-
- `X-Flywheel-Artifact-Filename` (filename hint)
|
|
120
|
-
|
|
121
|
-
A successful upload:
|
|
122
|
-
|
|
123
|
-
- validates the uploaded bytes against the requested artifact type
|
|
124
|
-
- stages canonical payload JSON in blob storage
|
|
125
|
-
- returns `202 Accepted`
|
|
126
|
-
- does not yet append an artifact record to the node
|
|
127
|
-
|
|
128
|
-
## Finalize Request and Response
|
|
129
|
-
|
|
130
|
-
`POST /mcp/nodes/{node_id}/artifacts/uploads/finalize`
|
|
131
|
-
|
|
132
|
-
```json
|
|
133
|
-
{
|
|
134
|
-
"batch_token": "uuid"
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Successful finalize:
|
|
139
|
-
|
|
140
|
-
- validates the batch is complete and still revision-compatible
|
|
141
|
-
- appends all staged artifacts to the node
|
|
142
|
-
- persists canonical payload JSON to `artifacts/nodes/{node_id}/{artifact_id}.json`
|
|
143
|
-
- bumps node revision once
|
|
144
|
-
- returns `{ "node": ..., "artifacts": [...] }`
|
|
145
|
-
|
|
146
|
-
## Artifact Preview Behavior
|
|
147
|
-
|
|
148
|
-
Artifact preview endpoint:
|
|
149
|
-
`GET /mcp/nodes/{node_id}/artifacts/{artifact_id}/preview`.
|
|
150
|
-
MCP tool: `flywheel_get_artifact_preview`.
|
|
151
|
-
|
|
152
|
-
- Preview reads canonical persisted payload blob (`storage_path`) only.
|
|
153
|
-
- No workspace dependency or local-file fallback is required.
|
|
154
|
-
- `data_url` in preview responses is render output only; never upload JSON
|
|
155
|
-
metadata wrappers.
|
|
156
|
-
- Preview-normalized types:
|
|
157
|
-
- `image` -> image payload with `data_url`
|
|
158
|
-
- `html` / `plotly_html` -> HTML payload
|
|
159
|
-
- `json` -> JSON payload
|
|
160
|
-
- `text` / `diff_carousel` and common text/code extensions -> text payload
|
|
161
|
-
|
|
162
|
-
## WebUI Artifact Payload Reads
|
|
163
|
-
|
|
164
|
-
When artifacts are projected through node responses, the server returns
|
|
165
|
-
normalized storage references for each artifact payload:
|
|
166
|
-
|
|
167
|
-
- `storage_path`: canonical blob path (for example
|
|
168
|
-
`artifacts/nodes/{node_id}/{artifact_id}.json`).
|
|
169
|
-
- `storage_url`: the single client/host read URL for that payload.
|
|
170
|
-
- All blob backends: `/blobs/{storage_path}` authenticated byte-serving
|
|
171
|
-
proxy after access checks.
|
|
172
|
-
|
|
173
|
-
Clients should read artifact bytes from `storage_url` only. `storage_path`
|
|
174
|
-
remains metadata/debug context and must not be reconstructed into fetch URLs by
|
|
175
|
-
clients. Payload loads are coordinated through a shared loader with in-flight
|
|
176
|
-
deduplication, cache reuse, and bounded fetch concurrency to avoid bursty
|
|
177
|
-
request storms and `429` backpressure under artifact-heavy nodes.
|
|
178
|
-
|
|
179
|
-
The node overview panel additionally avoids eager load spikes by defaulting to
|
|
180
|
-
collapsed mode for artifact-heavy nodes and deferring artifact rendering until
|
|
181
|
-
cards approach the viewport.
|
|
182
|
-
|
|
183
|
-
## Artifact Load Telemetry
|
|
184
|
-
|
|
185
|
-
The WebUI emits a batched first-party product analytics event,
|
|
186
|
-
`web_artifact_payload_batch`, through `POST /analytics/events`.
|
|
187
|
-
|
|
188
|
-
This event is intended for aggregate artifact read-path observability and
|
|
189
|
-
includes fields such as:
|
|
190
|
-
|
|
191
|
-
- load volume (`loads_started`, `loads_completed`, `loads_failed`)
|
|
192
|
-
- rate-limit incidence (`loads_429`)
|
|
193
|
-
- queue/load latency aggregates
|
|
194
|
-
- source mix (`/blobs/*` authenticated proxy)
|
|
195
|
-
- top per-node load/failure summaries in the batch window
|
|
196
|
-
|
|
197
|
-
## File Inventory Surfaces
|
|
198
|
-
|
|
199
|
-
Artifacts and attachments are exposed through two HTTP inventory endpoints:
|
|
200
|
-
|
|
201
|
-
- `GET /users/me/files` for account-wide browsing in Settings.
|
|
202
|
-
- `GET /nodes/{node_id}/files` for node lineage-scoped browsing in the node
|
|
203
|
-
details panel.
|
|
204
|
-
|
|
205
|
-
Inventory entries include source context (`node_id`, `execution_id`) so the UI
|
|
206
|
-
can jump directly to the originating node or execution.
|
|
207
|
-
|
|
208
|
-
## Common Invalid Payload Causes
|
|
209
|
-
|
|
210
|
-
- stale `expected_revision` at prepare or finalize time
|
|
211
|
-
- missing/invalid upload ticket
|
|
212
|
-
- expired upload ticket or batch
|
|
213
|
-
- upload body exceeds configured size limit
|
|
214
|
-
- uploaded bytes do not match requested artifact format (for example invalid
|
|
215
|
-
JSON)
|
|
216
|
-
- finalize called before every prepared upload is staged
|
|
217
|
-
- commit contract violations (for example empirical `completed` without
|
|
218
|
-
artifacts or `no_artifacts_reason`)
|
|
3
|
+
Canonical artifact upload/finalize contract derived from `mcp_contract.py`.
|
|
4
|
+
|
|
5
|
+
## Upload Contract
|
|
6
|
+
|
|
7
|
+
- Prepare tool: `flywheel_prepare_artifact_uploads`.
|
|
8
|
+
- Finalize tool: `flywheel_finalize_artifact_uploads`.
|
|
9
|
+
- Raw file upload required between prepare/finalize: `True`.
|
|
10
|
+
- Upload transport step: `PUT` to `prepare.items[].upload_url`.
|
|
11
|
+
- Required headers source: `prepare.items[].upload_headers`.
|
|
12
|
+
- Upload body contract: `raw_file_bytes`.
|
|
13
|
+
- Prepare item required fields: `artifact_type`, `filename`, `media_type`.
|
|
14
|
+
- Prepare item optional fields: `title`, `execution_id`, `metadata`, `note`.
|
|
15
|
+
- Prepare item note: prepare.items[] is structured object input at the tool boundary; stringified JSON payloads are invalid.
|
|
16
|
+
- Raw upload stage success code: `202`.
|
|
17
|
+
- Stage semantics: `accepted_and_staged`.
|
|
18
|
+
- Finalize appends the batch with a single revision bump: `True`.
|
|
19
|
+
- Forbidden upload payload kinds: `json_metadata_wrapper`.
|
|
20
|
+
- Optional note field `note` applies to `artifact_metadata_record` (markdown allowed: `True`).
|
|
21
|
+
|
|
22
|
+
## Supported Artifact Types
|
|
23
|
+
|
|
24
|
+
- `text`, `table`, `json`, `image`, `banner`, `html`, `plotly_html`, `vega`, `checkpoint`, `binary`, `diff_carousel`
|
|
25
|
+
|
|
26
|
+
## Metadata Contract
|
|
27
|
+
|
|
28
|
+
- `title` required non-empty: `True`.
|
|
29
|
+
- Display label field: `title`.
|
|
30
|
+
- Title normalization priority: `explicit_title` -> `payload.title` -> `payload.name` -> `basename(payload.path|payload.filename|payload.file)` -> `basename(filename)` -> `basename(storage_path)` -> `artifact_type` -> `artifact`.
|
|
31
|
+
- Title must not derive from: `storage_url`.
|
|
32
|
+
- `storage_url` purpose: `raw_artifact_byte_read_url`.
|
|
33
|
+
- `storage_url` cannot be used as display label: `True`.
|
|
34
|
+
|
|
35
|
+
## Preview and Read Contract
|
|
36
|
+
|
|
37
|
+
- `flywheel_list_artifacts`: List node artifacts.
|
|
38
|
+
- `flywheel_get_artifact`: Get one artifact by id.
|
|
39
|
+
- No dedicated artifact preview tool exists in the current MCP operation catalog.
|
|
40
|
+
- Guidance: use flywheel_prepare_artifact_uploads, raw-file upload, and flywheel_finalize_artifact_uploads to publish experiment evidence before empirical completed commits
|
|
41
|
+
|
|
42
|
+
## Failure Causes to Handle Explicitly
|
|
43
|
+
|
|
44
|
+
- Stale `expected_revision` on mutating calls returns `409` and requires explicit reconciliation.
|
|
45
|
+
- Reusing an idempotency key with a different payload hash causes `409_conflict`.
|
|
46
|
+
- Empirical `completed` commits must satisfy one of: `artifacts_non_empty`, `no_artifacts_reason_non_empty`.
|
|
47
|
+
- Prepare item payloads must be structured objects; stringified JSON item payloads are invalid.
|
|
48
|
+
- Uploading metadata wrappers instead of raw file bytes violates the upload contract.
|
|
49
|
+
- Finalize requires a valid prepared batch token and staged uploads from that batch.
|