Anonymous View
Skip to content

fix: embedded sub-workflow link cards reflect live child status#215

Merged
jakobklippel merged 1 commit into
developfrom
fix/213-embedded-subworkflow-collapse
Jun 15, 2026
Merged

fix: embedded sub-workflow link cards reflect live child status#215
jakobklippel merged 1 commit into
developfrom
fix/213-embedded-subworkflow-collapse

Conversation

@jakobklippel

Copy link
Copy Markdown
Contributor
  • Add slim GET /workflows/:id/status endpoint and useWorkflowStatus hook
  • LinkCard auto-collapses on terminal status; defers initial expanded value until live status arrives (no expand-then-collapse flicker on reload)
  • WORKFLOW_UPDATED SSE payload carries parentId so children-list caches invalidate live in execution timeline, workflow list, history list
  • CallbackSchema gains hasError + errorMessage; orchestrator populates them on dispatch so parents can branch on failure without parsing status strings
  • Drop framework auto-ErrorDocument on caught exceptions; failures surface via workflow.errorMessage and the Retry affordance instead
  • run-sub-workflow-example: add failing-sub, error-handling, show-modes workflows + tests (existing tests updated for new callback fields)

Closes #213

- Add slim GET /workflows/:id/status endpoint and useWorkflowStatus hook
- LinkCard auto-collapses on terminal status; defers initial expanded value
  until live status arrives (no expand-then-collapse flicker on reload)
- WORKFLOW_UPDATED SSE payload carries parentId so children-list caches
  invalidate live in execution timeline, workflow list, history list
- CallbackSchema gains hasError + errorMessage; orchestrator populates them
  on dispatch so parents can branch on failure without parsing status strings
- Drop framework auto-ErrorDocument on caught exceptions; failures surface
  via workflow.errorMessage and the Retry affordance instead
- run-sub-workflow-example: add failing-sub, error-handling, show-modes
  workflows + tests (existing tests updated for new callback fields)

Closes #213

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jakobklippel jakobklippel merged commit a14b571 into develop Jun 15, 2026
@jakobklippel jakobklippel deleted the fix/213-embedded-subworkflow-collapse branch June 15, 2026 12:34
jakobklippel added a commit that referenced this pull request Jun 15, 2026
* docs(getting-started): document zod v4 peer requirement (#201)

Adds a reference section explaining why Loopstack pins zod ^4 (uses
z.toJSONSchema) and that npm auto-installs it as a peer, so users
who saw zod imports in the docs don't reach for zod@^3 and trip
ERESOLVE.

Closes #191

* fix(llm-provider-module): allow bare import without forRoot (#204)

Wire the global LlmProviderRootModule from LlmProviderModule's static
@module decorator so a bare `LlmProviderModule` import registers the
provider registry, helpers, and tools with default config. `forRoot()`
and `forFeature()` are unchanged.

- Add unit tests covering bare, forRoot({}), forRoot(config), and the
  bare + forRoot(config) overlap
- Switch the package's test runner from a stale jest config to vitest +
  swc to match other feature modules
- Simplify 7 example workflow specs to use bare LlmProviderModule
- Drop the now-redundant `LlmProviderModule.forRoot({})` from
  docs/build/ai/llm-providers.md

Closes #187

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci: only run on PRs targeting main (#205)

Drop `develop` from the pull_request.branches list so CI no longer
runs on PRs into develop. workflow_dispatch is kept so the workflow
can still be triggered manually on any branch.

Closes #203

* fix(remote-client): allow bare RemoteClientModule import (#206)

Mirror the LlmProviderModule fix from #187: move the actual wiring
onto an internal `@Global() RemoteClientRootModule` and have
`RemoteClientModule`'s static `@Module` decorator import the root.
Bare `RemoteClientModule` imports now boot with `RemoteClient`,
`EnvironmentService`, `EnvironmentConfigService`, `ENVIRONMENT_CONFIG`,
and the file/exec tools registered globally. `forRoot(options)`
overrides the global config (available environments) and
`forFeature(options)` is unchanged.

Closes #202

* feat(llm-provider)!: expose text and blocks on LlmNormalizedMessage (#207)

`result.message.text` is the plain-text projection (always populated by
providers). `result.message.blocks` is the structured content. `LlmMessageDocument`
and inline `LlmMessage` args accept either field — `text` for plain content,
`blocks` for structured blocks like tool results.

Closes #190

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(common): rename MessageDocument.content to text, separate from LLM history (#208)

- MessageDocument: `content: string` → `text?: string`; tag changed from
  ['message'] to ['ui-message'] so plain UI bubbles no longer leak into LLM
  conversation history (messagesSearchTag defaults to 'message').
- LlmMessageDocument now extends MessageDocument; field shape unchanged.
- Updated frontend renderer, all registry examples, READMEs, docs, and tests.

Closes #189

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(common): auto-render sub-workflows in parent view via show option (#209)

Add `show?: 'inline' | 'link' | 'hidden'` (default `'inline'`) and `label?: string`
to `RunOptions`. The orchestrator now auto-saves a `LinkDocument` from `queue()`
based on `show`, so the parent's run view never goes blank when a sub-workflow
is launched. Studio's `LinkCard` reads live status from `useChildWorkflows`
rather than a denormalized field, and `LinkDocumentSchema.status` is removed.

All registry features, examples, and sandbox call sites drop their manual
`documentStore.save(LinkDocument, …)` pairs around `subWorkflow.run()` in favor
of `show` + `label` on the `.run()` call.

Closes #188

* fix tests

* feat(core): add FanOutWorkflow and SequenceWorkflow for sub-workflow coordination (#212)

FanOutWorkflow runs N sub-workflows in parallel; SequenceWorkflow runs them
one at a time. Both share a single aggregated callback with `'all'` /
`'allSettled'` failure modes and accept items as an array or keyed record.
Reuses the proven self-loop wait pattern from AgentWorkflow; no core changes.

- Switch FanOut/Sequence items to canonical workflow-name strings to align
  with how AgentWorkflow.args.tools already references tools.
- Add explicit `name` to framework-shipped workflows (agent, chat_agent,
  ask_user, confirm_user, oauth, connect_github, secrets_request) matching
  their auto-derived snake_case identifiers.
- New `hitl-example-module` consolidates the HITL ask/confirm examples into
  a side-by-side comparison of custom-document, sub-workflow, and agent-tool
  patterns, replacing two narrower example packages.

Closes #186

* fix: embedded sub-workflow link cards reflect live child status (#215)

- Add slim GET /workflows/:id/status endpoint and useWorkflowStatus hook
- LinkCard auto-collapses on terminal status; defers initial expanded value
  until live status arrives (no expand-then-collapse flicker on reload)
- WORKFLOW_UPDATED SSE payload carries parentId so children-list caches
  invalidate live in execution timeline, workflow list, history list
- CallbackSchema gains hasError + errorMessage; orchestrator populates them
  on dispatch so parents can branch on failure without parsing status strings
- Drop framework auto-ErrorDocument on caught exceptions; failures surface
  via workflow.errorMessage and the Retry affordance instead
- run-sub-workflow-example: add failing-sub, error-handling, show-modes
  workflows + tests (existing tests updated for new callback fields)

Closes #213

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(workflows): cluster transition types and surface guards (#216)

Move `Wait Transition` under `Transition Types` alongside Initial/Standard/Final, and add a sibling `Guarding Transitions` section right after with explicit priority and fallback rules plus a complete two-branch example. Previously both sections were standalone and buried below storage/templates content, hiding guards as a first-class branching concept. Adds a cross-link from the Wait subsection to the Human-in-the-Loop pattern doc.

Closes #197

* docs(patterns): document CallbackSchema, sub-workflow errors, and HITL patterns (#217)

- sub-workflows: add Typing the Callback Payload section (CallbackSchema field
  reference + .extend({ data }) pattern) and Error Handling section
  (branching on payload.hasError / payload.errorMessage)
- human-in-the-loop: add Choosing a HITL Pattern decision matrix, expand the
  sub-workflow shortcut section (AskUserWorkflow text/options/confirm,
  ConfirmUserWorkflow), and add Agent-Driven HITL section for the
  ask_clarification / ask_for_approval tools
- refresh frontmatter descriptions and registry references on both pages

Closes #196

* bump versions

* fix tests

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jakobklippel added a commit that referenced this pull request Jun 15, 2026
* docs(getting-started): document zod v4 peer requirement (#201)

Adds a reference section explaining why Loopstack pins zod ^4 (uses
z.toJSONSchema) and that npm auto-installs it as a peer, so users
who saw zod imports in the docs don't reach for zod@^3 and trip
ERESOLVE.

Closes #191

* fix(llm-provider-module): allow bare import without forRoot (#204)

Wire the global LlmProviderRootModule from LlmProviderModule's static
@module decorator so a bare `LlmProviderModule` import registers the
provider registry, helpers, and tools with default config. `forRoot()`
and `forFeature()` are unchanged.

- Add unit tests covering bare, forRoot({}), forRoot(config), and the
  bare + forRoot(config) overlap
- Switch the package's test runner from a stale jest config to vitest +
  swc to match other feature modules
- Simplify 7 example workflow specs to use bare LlmProviderModule
- Drop the now-redundant `LlmProviderModule.forRoot({})` from
  docs/build/ai/llm-providers.md

Closes #187

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ci: only run on PRs targeting main (#205)

Drop `develop` from the pull_request.branches list so CI no longer
runs on PRs into develop. workflow_dispatch is kept so the workflow
can still be triggered manually on any branch.

Closes #203

* fix(remote-client): allow bare RemoteClientModule import (#206)

Mirror the LlmProviderModule fix from #187: move the actual wiring
onto an internal `@Global() RemoteClientRootModule` and have
`RemoteClientModule`'s static `@Module` decorator import the root.
Bare `RemoteClientModule` imports now boot with `RemoteClient`,
`EnvironmentService`, `EnvironmentConfigService`, `ENVIRONMENT_CONFIG`,
and the file/exec tools registered globally. `forRoot(options)`
overrides the global config (available environments) and
`forFeature(options)` is unchanged.

Closes #202

* feat(llm-provider)!: expose text and blocks on LlmNormalizedMessage (#207)

`result.message.text` is the plain-text projection (always populated by
providers). `result.message.blocks` is the structured content. `LlmMessageDocument`
and inline `LlmMessage` args accept either field — `text` for plain content,
`blocks` for structured blocks like tool results.

Closes #190

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(common): rename MessageDocument.content to text, separate from LLM history (#208)

- MessageDocument: `content: string` → `text?: string`; tag changed from
  ['message'] to ['ui-message'] so plain UI bubbles no longer leak into LLM
  conversation history (messagesSearchTag defaults to 'message').
- LlmMessageDocument now extends MessageDocument; field shape unchanged.
- Updated frontend renderer, all registry examples, READMEs, docs, and tests.

Closes #189

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(common): auto-render sub-workflows in parent view via show option (#209)

Add `show?: 'inline' | 'link' | 'hidden'` (default `'inline'`) and `label?: string`
to `RunOptions`. The orchestrator now auto-saves a `LinkDocument` from `queue()`
based on `show`, so the parent's run view never goes blank when a sub-workflow
is launched. Studio's `LinkCard` reads live status from `useChildWorkflows`
rather than a denormalized field, and `LinkDocumentSchema.status` is removed.

All registry features, examples, and sandbox call sites drop their manual
`documentStore.save(LinkDocument, …)` pairs around `subWorkflow.run()` in favor
of `show` + `label` on the `.run()` call.

Closes #188

* fix tests

* feat(core): add FanOutWorkflow and SequenceWorkflow for sub-workflow coordination (#212)

FanOutWorkflow runs N sub-workflows in parallel; SequenceWorkflow runs them
one at a time. Both share a single aggregated callback with `'all'` /
`'allSettled'` failure modes and accept items as an array or keyed record.
Reuses the proven self-loop wait pattern from AgentWorkflow; no core changes.

- Switch FanOut/Sequence items to canonical workflow-name strings to align
  with how AgentWorkflow.args.tools already references tools.
- Add explicit `name` to framework-shipped workflows (agent, chat_agent,
  ask_user, confirm_user, oauth, connect_github, secrets_request) matching
  their auto-derived snake_case identifiers.
- New `hitl-example-module` consolidates the HITL ask/confirm examples into
  a side-by-side comparison of custom-document, sub-workflow, and agent-tool
  patterns, replacing two narrower example packages.

Closes #186

* fix: embedded sub-workflow link cards reflect live child status (#215)

- Add slim GET /workflows/:id/status endpoint and useWorkflowStatus hook
- LinkCard auto-collapses on terminal status; defers initial expanded value
  until live status arrives (no expand-then-collapse flicker on reload)
- WORKFLOW_UPDATED SSE payload carries parentId so children-list caches
  invalidate live in execution timeline, workflow list, history list
- CallbackSchema gains hasError + errorMessage; orchestrator populates them
  on dispatch so parents can branch on failure without parsing status strings
- Drop framework auto-ErrorDocument on caught exceptions; failures surface
  via workflow.errorMessage and the Retry affordance instead
- run-sub-workflow-example: add failing-sub, error-handling, show-modes
  workflows + tests (existing tests updated for new callback fields)

Closes #213

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(workflows): cluster transition types and surface guards (#216)

Move `Wait Transition` under `Transition Types` alongside Initial/Standard/Final, and add a sibling `Guarding Transitions` section right after with explicit priority and fallback rules plus a complete two-branch example. Previously both sections were standalone and buried below storage/templates content, hiding guards as a first-class branching concept. Adds a cross-link from the Wait subsection to the Human-in-the-Loop pattern doc.

Closes #197

* docs(patterns): document CallbackSchema, sub-workflow errors, and HITL patterns (#217)

- sub-workflows: add Typing the Callback Payload section (CallbackSchema field
  reference + .extend({ data }) pattern) and Error Handling section
  (branching on payload.hasError / payload.errorMessage)
- human-in-the-loop: add Choosing a HITL Pattern decision matrix, expand the
  sub-workflow shortcut section (AskUserWorkflow text/options/confirm,
  ConfirmUserWorkflow), and add Agent-Driven HITL section for the
  ask_clarification / ask_for_approval tools
- refresh frontmatter descriptions and registry references on both pages

Closes #196

* bump versions

* fix tests

* feat(monorepo) create pg back to develop in case of failed ff

* fix changesets

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant