Skip to content

feat(orchestration): add proactive collaboration - #2082

Open
yyhhyyyyyy wants to merge 56 commits into
devfrom
feat/workflow-runtime
Open

feat(orchestration): add proactive collaboration#2082
yyhhyyyyyy wants to merge 56 commits into
devfrom
feat/workflow-runtime

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add proactive multi-Agent collaboration to DeepChat while keeping orchestration policy, reasoning effort, and execution strategy independent.

This PR introduces:

  • a session-level explicit | proactive collaboration policy;
  • persistent live delegation with first-class child Sessions;
  • a durable JavaScript Workflow runtime backed by QuickJS;
  • native approval, progress, recovery, result handoff, and child-session UI;
  • shared admission, permission, effect-safety, and lifecycle infrastructure.

The parent Agent can now choose the appropriate execution path per task:

  1. execute directly;
  2. delegate adaptive tasks to live Subagents;
  3. prepare a durable Workflow for large, repeatable, programmatic, or recoverable work.

Product behavior

  • explicit: delegation requires an explicit user, project, or Skill instruction.
  • proactive: the parent may delegate when parallel or isolated work materially improves quality or latency.
  • Proactive collaboration does not force delegation for every request.
  • Reasoning effort, model settings, permissions, and collaboration policy remain independent.
  • Natural language is the user interface; Workflow JavaScript remains internal execution IR.

Before

Session mode
├── adaptive  → legacy Subagent executor
└── workflow  → durable Workflow executor

Selecting one executor removed the other.

After

Collaboration policy
├── explicit
└── proactive

Parent Agent
├── direct execution
├── live delegation
└── durable Workflow

Reasoning effort remains independent.

Live delegation

  • Add durable delegation, turn, and event storage.
  • Support spawn, follow-up, list, inspect, wait, interrupt, and paginated result reads.
  • Preserve every Subagent as a navigable first-class Session with its own context and Tape.
  • Add concise task-first titles and inline child activity cards.
  • Allow users to open child Sessions and respond to pending permissions or questions.
  • Store bounded semantic handoffs and stable references to immutable child results.
  • Reconcile active work after application restart.
  • Fence Session deletion against in-flight child creation and drain related work before removal.
  • Close child creation, interruption, terminal-state, and result-delivery races.

Durable Workflow runtime

  • Run one synchronous QuickJS WASM sandbox inside an Electron utility process per Workflow run.
  • Bridge concurrent guest promises through deferred promises and serialized pending-job draining.
  • Expose versioned orchestration helpers:
    • agent()
    • parallel()
    • pipeline()
    • mapLimit()
    • phase()
    • log()
  • Persist Workflow runs and invocations in SQLite.
  • Use stable logical call paths and immutable input hashes for safe replay.
  • Recover queued, interrupted, and partially completed runs after restart.
  • Enforce invocation, concurrency, token, duration, source-size, and result-size budgets.
  • Freeze generation settings and launch capabilities when a run starts.
  • Support structured child output and deterministic validation.
  • Add saved Workflows, bounded source outlines, native launch approval, progress projection, retry, resume, and cancellation.
  • Deliver completed results to the parent without automatically starting another model turn.

Reliability and safety

  • Add one cancellation-aware global admission layer shared by live delegation, Workflow children, and the legacy orchestrator.
  • Record write-ahead tool-effect evidence only after permission authorization and before actual dispatch.
  • Treat missing or untrusted effect metadata as unknown and fail closed during automatic recovery.
  • Keep child Tape lineage frozen and avoid copying full child transcripts into the parent.
  • Treat child and Workflow results as untrusted input when the parent synthesizes them.
  • Prevent guest access to Node.js, Electron, filesystem, network, shell, credentials, and database APIs.
  • Bound utility-process startup, execution, cancellation, and forced termination.
  • Preserve MCP App result metadata and the MCP permission contract from dev.

UX

  • Add a compact collaboration indicator without replacing the reasoning label.
  • Add a native Workflow approval card showing:
    • source outline and hash;
    • target Agents;
    • invocation and budget limits;
    • capability scope;
    • effect-risk warnings.
  • Add Workflow and saved-Workflow panels to the workspace side panel.
  • Add live Subagent cards with status, result preview, and child-Session navigation.
  • Keep advanced model sampling, output, context, timeout, and reasoning defaults available in model settings.
  • Preserve unsaved Workflow authoring state across panel and Session navigation.

Summary by CodeRabbit

  • New Features
    • Added durable Workflows with sandboxed execution, approvals, saved workflows, retries, cancellation, progress tracking, and result delivery.
    • Added live child-agent delegation with messaging, follow-ups, waiting, interruption, recovery, and activity panels.
    • Added explicit or proactive collaboration controls for supported sessions.
    • Added workflow slash commands, launch approvals, workflow panels, and localized interface text.
  • Bug Fixes
    • Improved session deletion coordination, delegation lifecycle handling, result safety, usage reporting, and memory projections.
  • Chores
    • Updated model and agent catalogs and increased renderer test memory limits.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aee1b23e-02c3-40d8-8cfc-33b32b02d496

📥 Commits

Reviewing files that changed from the base of the PR and between 0e233f9 and 85b2263.

📒 Files selected for processing (18)
  • src/main/workflow/launchApproval.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • test/main/workflow/workflowLaunchApproval.test.ts
🚧 Files skipped from review as they are similar to previous changes (18)
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • test/main/workflow/workflowLaunchApproval.test.ts
  • src/main/workflow/launchApproval.ts
  • src/renderer/src/i18n/da-DK/chat.json

📝 Walkthrough

Walkthrough

This PR replaces the adaptive|workflow executor switch with an explicit|proactive orchestration policy, adds live child-session delegation (spawn/send/wait/interrupt) with SQLite persistence, and introduces a durable, QuickJS-sandboxed Workflow runtime with launch approval, structured output, saved workflows, and result delivery. It wires these through main-process services, agent tools, shared contracts, renderer UI (composer, message cards, sidepanel), localization, docs, build config, and vendor data updates.

Changes

Documentation

Layer / File(s) Summary
Architecture and issue specifications
docs/architecture/..., docs/features/workflow-runtime/*, docs/issues/live-delegation-*
Adds plans, specs, and task records that define the orchestration policy replacement, live delegation lifecycle, and Workflow runtime design. Documents hardening fixes for deletion coordination, interaction closure, and terminal races.

Build, Dependencies & Vendor Data

Layer / File(s) Summary
Build config, dependencies and CI
.github/workflows/prcheck.yml, electron-builder.yml, electron.vite.config.ts, package.json, test/main/build/..., test/main/scripts/...
Adds a QuickJS unpack rule, a new workflow utility host build entry, QuickJS/acorn/ajv dependencies, and an increased renderer test memory limit, with matching test assertions.
ACP registry and model catalog updates
resources/acp-registry/registry.json, resources/model-db/providers.json
Updates agent versions and checksums in the ACP registry. Adds, renames, and removes model entries in the provider catalog.

Proactive Orchestration & Workflow Runtime Feature

Layer / File(s) Summary
Shared contracts, domain types & policy schemas
src/shared/**
Defines OrchestrationPolicy, live-delegation, tool-effect, and workflow domain/runtime/service Zod schemas. Registers route and event contracts.
Session orchestration policy, lifecycle & deletion coordination
src/main/session/**, src/main/agent/shared/appSessionService.ts, src/main/app/composition.ts, src/main/data/schemaCatalog.ts
Persists orchestration policy on sessions. Adds a SessionDeletionGate. Validates subagent workflow and live-delegation metadata. Wires new tables into the schema catalog and app composition.
Agent tool dispatch, prompt orchestration & invocation admission
src/main/agent/**, src/main/tool/**
Adds AgentInvocationAdmission, orchestration-policy-aware system prompts, LiveDelegationAgentTool/WorkflowAgentTool, tool-effect classification, and session-tool routing.
Live delegation persistence and service
src/main/orchestration/**
Adds SQLite tables, LiveDelegationRepository, LiveDelegationService, a capability resolver, and orchestration routes for spawn/send/wait/interrupt operations.
Workflow runtime engine, persistence and service
src/main/workflow/**
Implements the QuickJS-sandboxed runtime, durable run/invocation persistence, launch approval and scope validation, structured output, saved workflows, and WorkflowService.
Renderer API clients and chat composer UI
src/renderer/api/**, src/renderer/src/components/chat*, ModelConfigDialog.vue
Adds OrchestrationClient/WorkflowClient, workflow slash commands, and orchestration/generation-settings controls in ChatStatusBar.
Renderer message cards and activity presentation
src/renderer/src/components/message/**, src/renderer/src/lib/{liveDelegation,workflow}*
Adds LiveDelegationToolCallCard and WorkflowLaunchApprovalCard. Excludes these blocks from activity-group grouping and adds parsing helpers.
Renderer sidepanel panels, pages and stores
src/renderer/src/components/sidepanel/**, src/renderer/src/stores/**, NewThreadPage.vue, ChatPage.vue
Adds LiveDelegationPanel, SavedWorkflowPanel, WorkflowPanel, workflow events, and store/page wiring for workflow selection and orchestration policy.
Localization strings for orchestration and workflow UI
src/renderer/src/i18n/**, src/types/i18n.d.ts
Adds orchestration and workflow translation keys across all supported locales.

Estimated code review effort: 5 (Critical) | ~180 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ChatInputBox
  participant AgentToolManager
  participant LiveDelegationService
  participant LiveDelegationRepository
  participant ChildSession

  User->>ChatInputBox: Submit "deepchat_subagents" spawn request
  ChatInputBox->>AgentToolManager: call live delegation tool
  AgentToolManager->>LiveDelegationService: spawn(slotId, title, prompt)
  LiveDelegationService->>LiveDelegationRepository: create delegation + turn
  LiveDelegationService->>ChildSession: create/bind child session
  ChildSession-->>LiveDelegationService: runtime updates (running/waiting/complete)
  LiveDelegationService->>LiveDelegationRepository: settle turn (result ref, tape receipt)
  LiveDelegationService-->>AgentToolManager: delegation summary
  AgentToolManager-->>ChatInputBox: tool result
Loading
sequenceDiagram
  participant Renderer
  participant WorkflowClient
  participant WorkflowRoutes
  participant WorkflowService
  participant QuickJSWorkflowRuntime
  participant WorkflowRepository

  Renderer->>WorkflowClient: prepareLaunch(script, input)
  WorkflowClient->>WorkflowRoutes: workflowPrepareLaunchRoute
  WorkflowRoutes->>WorkflowService: prepare launch approval
  WorkflowService-->>WorkflowRoutes: approval card
  WorkflowRoutes-->>Renderer: WorkflowLaunchApproval
  Renderer->>WorkflowClient: launch(approvalId)
  WorkflowClient->>WorkflowRoutes: workflowLaunchRoute
  WorkflowRoutes->>WorkflowService: launch(request)
  WorkflowService->>WorkflowRepository: create run
  WorkflowService->>QuickJSWorkflowRuntime: start(source, input)
  QuickJSWorkflowRuntime-->>WorkflowService: INVOKE_AGENT / PHASE / LOG events
  WorkflowService->>WorkflowRepository: persist invocation results
  QuickJSWorkflowRuntime-->>WorkflowService: COMPLETE/FAILED
  WorkflowService-->>Renderer: workflow.run.changed event
Loading

Possibly related PRs

  • ThinkInAIXYZ/deepchat#1982: Extends the same centralized subagent capability-policy model into orchestration policy, live delegation, and workflow tooling.
  • ThinkInAIXYZ/deepchat#1980: Both PRs implement durable child-agent Tape linkage with lineage and receipt persistence across workflow, live-delegation, and subagent orchestration paths.
  • ThinkInAIXYZ/deepchat#1412: Both PRs modify the subagent orchestration system, including session metadata, delegation tools, and runtime handling.

Suggested reviewers: zerob13, zhangmo8

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change by identifying the addition of proactive collaboration orchestration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/workflow-runtime

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (23)
src/renderer/src/i18n/vi-VN/chat.json-578-652 (1)

578-652: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Translate the remaining English workflow strings.

The workflow keys in lines 578-652 and the saved keys in lines 667-698 hold English copy, while orchestration (563-577) and workflow.approval (653-666) are Vietnamese. The Vietnamese UI would mix two languages in the same panel. The zh-CN, zh-HK, and zh-TW files translate the same keys, so this gap looks unintended.

Provide Vietnamese copy for workflow.title, loading, runLabel, empty, status, fields, actions, states, invocations, interactions, effects, effectWarning, duration, budget, and the whole saved subtree.

As per coding guidelines: "Use vue-i18n for user-facing copy".

Also applies to: 667-698

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/vi-VN/chat.json` around lines 578 - 652, Translate
every English user-facing string in the Vietnamese locale’s workflow
section—including title, loading, run labels, empty state, statuses, fields,
actions, states, invocations, interactions, effects, effect warnings, duration,
budget, and the entire saved subtree—into natural Vietnamese while preserving
all existing keys and interpolation placeholders. Use the corresponding
translated locale entries as semantic references and keep the existing vue-i18n
key structure unchanged.

Source: Coding guidelines

src/main/workflow/launchApproval.ts-76-81 (1)

76-81: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Report the limit that was actually exceeded.

The condition fails for two different limits. The message always names request.limits.maxScriptBytes. If the request limit is larger than WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES, the message reports a limit that the source did not exceed.

🔧 Proposed fix
-    if (
-      sourceBytes > WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES ||
-      sourceBytes > request.limits.maxScriptBytes
-    ) {
-      throw new Error(`Workflow source exceeds its ${request.limits.maxScriptBytes}-byte limit.`)
-    }
+    const effectiveMaxScriptBytes = Math.min(
+      WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES,
+      request.limits.maxScriptBytes
+    )
+    if (sourceBytes > effectiveMaxScriptBytes) {
+      throw new Error(`Workflow source exceeds its ${effectiveMaxScriptBytes}-byte limit.`)
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/launchApproval.ts` around lines 76 - 81, Update the error
handling in the source-size validation around WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES
and request.limits.maxScriptBytes to report the specific limit that was
exceeded. Distinguish the runtime maximum from the request-specific limit,
preserving the existing rejection behavior while naming the applicable byte
limit in each case.
src/renderer/src/pages/NewThreadPage.vue-855-858 (1)

855-858: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Apply the submission guard before consuming the workflow slash command.

onSubmit consumes the workflow slash command on line 856, before the guard on line 857. If a submission is already in flight, or the ACP workspace is unavailable, the composer still consumes the command and clears its authoring state. Move the consume call after the guard.

🐛 Proposed fix
 async function onSubmit() {
-  if (chatInputRef.value?.consumeWorkflowSlashCommand?.()) return
   if (isAcpWorkdirUnavailable.value || isSubmittingInput.value) return
+  if (chatInputRef.value?.consumeWorkflowSlashCommand?.()) return
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/pages/NewThreadPage.vue` around lines 855 - 858, In
onSubmit, evaluate the isAcpWorkdirUnavailable and isSubmittingInput guard
before calling consumeWorkflowSlashCommand. Keep the existing early return for
the workflow command after that guard so unavailable or in-flight submissions do
not consume or clear the command state.
src/main/workflow/runtime/quickjsWorkflowRuntime.ts-505-563 (1)

505-563: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Skip terminal emission when the run entry no longer exists.

handleHostEvent drops events once terminalizing is set, but cancel still emits FAILED from quickjsWorkflowRuntime if the cancellation happens after the host dropped the event or after the active entry was removed. Store terminalizing in the runtime host or add runFinalizer/exited-aware guard logic there.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/runtime/quickjsWorkflowRuntime.ts` around lines 505 - 563,
Update cancel in quickjsWorkflowRuntime to skip the terminal FAILED emission
when the run is already terminalizing, exited, or its active host entry no
longer exists. Reuse the runtime host’s terminal-state/run-entry guard used by
handleHostEvent, such as terminalizing or runFinalizer state, while preserving
cancellation cleanup and emission for active runs.
src/main/workflow/runtime/quickjsWorkflowRuntime.ts-100-111 (1)

100-111: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add catch and finally to the agent thenable.

agent() returns an object with only then. await works, but guest code that writes agent(...).catch(handler) or .finally(handler) fails with a TypeError. The guest cannot work around this, because Promise and Promise.prototype are frozen and Promise.prototype.constructor is removed. Route both methods through the same observation path.

🐛 Proposed fix inside the bootstrap source
       let observed = false
-      return Object.freeze({
-        constructor: undefined,
-        then: (onFulfilled, onRejected) => {
-          if (!observed) {
-            observeAgentHost(callPath)
-            observed = true
-          }
-          return hostPromise.then(onFulfilled, onRejected)
-        }
-      })
+      const observe = () => {
+        if (!observed) {
+          observeAgentHost(callPath)
+          observed = true
+        }
+      }
+      return Object.freeze({
+        constructor: undefined,
+        then: (onFulfilled, onRejected) => {
+          observe()
+          return hostPromise.then(onFulfilled, onRejected)
+        },
+        catch: (onRejected) => {
+          observe()
+          return hostPromise.then(undefined, onRejected)
+        },
+        finally: (onFinally) => {
+          observe()
+          return hostPromise.then(
+            (value) => {
+              onFinally()
+              return value
+            },
+            (error) => {
+              onFinally()
+              return promiseReject(error)
+            }
+          )
+        }
+      })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/runtime/quickjsWorkflowRuntime.ts` around lines 100 - 111,
Extend the frozen thenable returned by the agent runtime around the existing
then method to expose catch and finally methods. Route both methods through the
same observeAgentHost(callPath) guard before delegating to hostPromise,
preserving single observation and native promise chaining behavior for guest
calls.
src/main/workflow/runtime/workflowSourceValidator.ts-309-309 (1)

309-309: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Lines exceed the 100-column limit.

Lines 309, 369, and 380 are longer than 100 columns. Run the formatter so these lines wrap.

As per coding guidelines: "Follow Oxfmt formatting: single quotes, no semicolons, and a 100-column width."

Also applies to: 369-369, 380-380

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/runtime/workflowSourceValidator.ts` at line 309, Run the
project formatter on the affected workflow source validator code, including the
calls around rejectHelper and the corresponding lines near 369 and 380, so all
lines comply with Oxfmt’s 100-column width while preserving behavior.

Source: Coding guidelines

src/renderer/src/i18n/da-DK/chat.json-578-652 (1)

578-652: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Translate the remaining workflow strings in the non-English chat.json locale files.

Each non-English locale still copies many workflow keys from en-US, including the nested saved values. Translate workflow.title, workflow.loading, workflow.runLabel, workflow.empty, workflow.status, workflow.fields, workflow.actions, workflow.states, workflow.invocations, workflow.interactions, workflow.effects, workflow.effectWarning, workflow.duration, workflow.budget, workflow.saved, and workflow.saved.approval in all affected locales. Keep interpolation placeholders unchanged.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/da-DK/chat.json` around lines 578 - 652, Translate the
complete workflow localization content, including workflow.title, loading,
runLabel, empty, status, fields, actions, states, invocations, interactions,
effects, effectWarning, duration, budget, saved, and saved.approval, in
src/renderer/src/i18n/da-DK/chat.json ranges 578-652 and 667-698 and
src/renderer/src/i18n/de-DE/chat.json ranges 578-652 and 667-698. Replace copied
en-US text with the appropriate Danish or German translations while preserving
every interpolation placeholder exactly.
src/renderer/src/i18n/es-ES/chat.json-578-652 (1)

578-652: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Workflow copy stays English in five locales. The new workflow block was copied from en-US into each locale, and only workflow.approval.* was localized. workflow.title, workflow.loading, workflow.empty.*, workflow.status.*, workflow.fields.*, workflow.actions.*, workflow.states.*, workflow.invocations.*, workflow.interactions.*, workflow.effects.*, workflow.effectWarning.*, workflow.duration.*, workflow.budget.*, and workflow.saved.* remain English in all five files.

  • src/renderer/src/i18n/es-ES/chat.json#L578-L652: translate the workflow keys into Spanish, and also workflow.saved.* at L667-L699.
  • src/renderer/src/i18n/fa-IR/chat.json#L578-L652: translate the workflow keys into Persian, and also workflow.saved.* at L667-L699.
  • src/renderer/src/i18n/fr-FR/chat.json#L578-L652: translate the workflow keys into French, and also workflow.saved.* at L667-L699.
  • src/renderer/src/i18n/he-IL/chat.json#L578-L652: translate the workflow keys into Hebrew, and also workflow.saved.* at L667-L699.
  • src/renderer/src/i18n/id-ID/chat.json#L578-L652: translate the workflow keys into Indonesian, and also workflow.saved.* at L667-L699.

If a follow-up localization pass owns these keys, state that in the PR description so reviewers do not treat it as an omission.

As per coding guidelines: "Use vue-i18n for user-facing copy".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/es-ES/chat.json` around lines 578 - 652, Translate all
user-facing workflow strings, including workflow.title, loading, empty, status,
fields, actions, states, invocations, interactions, effects, effectWarning,
duration, budget, and saved, instead of leaving English fallbacks. Apply the
appropriate translations in src/renderer/src/i18n/es-ES/chat.json#L578-L652 and
`#L667-L699`, fa-IR/chat.json#L578-L652 and `#L667-L699`, fr-FR/chat.json#L578-L652
and `#L667-L699`, he-IL/chat.json#L578-L652 and `#L667-L699`, and
id-ID/chat.json#L578-L652 and `#L667-L699`; if deferred to a follow-up
localization pass, explicitly document that in the PR description.

Source: Coding guidelines

src/renderer/src/i18n/it-IT/chat.json-578-652 (1)

578-652: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Translate the new workflow and workflow.saved strings. In all four locales the orchestration block and the workflow.approval block are translated, but the workflow core keys and the workflow.saved keys remain English. Users of these locales see mixed-language workflow panels.

  • src/renderer/src/i18n/it-IT/chat.json#L578-L652: translate workflow.title through workflow.budget into Italian, and also workflow.saved at L667-L699.
  • src/renderer/src/i18n/ja-JP/chat.json#L578-L652: translate the same workflow keys into Japanese, and also workflow.saved at L667-L699.
  • src/renderer/src/i18n/ko-KR/chat.json#L578-L652: translate the same workflow keys into Korean, and also workflow.saved at L667-L699.
  • src/renderer/src/i18n/ms-MY/chat.json#L578-L652: translate the same workflow keys into Malay, and also workflow.saved at L667-L699.

Keep all placeholders unchanged: {id}, {version}, {current}, {count}, {minutes}, {seconds}, {hours}, {duration}, {attempt}.

As per coding guidelines "Use vue-i18n for user-facing copy".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/it-IT/chat.json` around lines 578 - 652, Translate the
workflow core keys from workflow.title through workflow.budget, plus
workflow.saved, while preserving every existing key and placeholder. Apply the
same translations in src/renderer/src/i18n/it-IT/chat.json:578-652 and
workflow.saved:667-699 (Italian), src/renderer/src/i18n/ja-JP/chat.json:578-652
and workflow.saved:667-699 (Japanese),
src/renderer/src/i18n/ko-KR/chat.json:578-652 and workflow.saved:667-699
(Korean), and src/renderer/src/i18n/ms-MY/chat.json:578-652 and
workflow.saved:667-699 (Malay); keep placeholders {id}, {version}, {current},
{count}, {minutes}, {seconds}, {hours}, {duration}, and {attempt} unchanged.

Source: Coding guidelines

src/renderer/src/i18n/pl-PL/chat.json-578-652 (1)

578-652: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Translate the remaining workflow.* strings; they are still in English.

In all four locale files, the orchestration block and workflow.approval block are translated correctly. The rest of the workflow object is not translated. It still contains the English source text, for example "title": "Workflows" and "loading": "Loading workflows...". The workflow.saved subtree has the same problem, for example "title": "Saved workflows" and "workspaceRequired": "Open a project workspace to create and run saved workflows.". Users of these locales see English text mixed with translated text in the same panel.

  • src/renderer/src/i18n/pl-PL/chat.json#L578-L652: Translate workflow.title, loading, runLabel, empty, status, fields, actions, states, invocations, interactions, effects, effectWarning, duration, and budget into Polish.
  • src/renderer/src/i18n/pl-PL/chat.json#L667-L699: Translate workflow.saved (title, workspaceRequired, selectPlaceholder, empty, unsaved, runTitle, agentPlaceholder, fields, actions, approval) into Polish.
  • src/renderer/src/i18n/pt-BR/chat.json#L578-L652: Translate the same workflow.* keys into Portuguese.
  • src/renderer/src/i18n/pt-BR/chat.json#L667-L699: Translate workflow.saved into Portuguese.
  • src/renderer/src/i18n/ru-RU/chat.json#L578-L652: Translate the same workflow.* keys into Russian.
  • src/renderer/src/i18n/ru-RU/chat.json#L667-L699: Translate workflow.saved into Russian.
  • src/renderer/src/i18n/tr-TR/chat.json#L578-L652: Translate the same workflow.* keys into Turkish.
  • src/renderer/src/i18n/tr-TR/chat.json#L667-L699: Translate workflow.saved into Turkish.

Check whether other locales outside this review batch (da-DK, de-DE, es-ES, fa-IR, fr-FR, he-IL, id-ID, it-IT, ja-JP, ko-KR, ms-MY, vi-VN, zh-CN, zh-HK, zh-TW) have the same gap, since the pattern is identical across every file in this batch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/i18n/pl-PL/chat.json` around lines 578 - 652, Translate
every remaining workflow object string and workflow.saved subtree into the
target locale languages, preserving all keys and interpolation placeholders:
Polish in src/renderer/src/i18n/pl-PL/chat.json at lines 578-652 and 667-699,
Portuguese in src/renderer/src/i18n/pt-BR/chat.json at lines 578-652 and
667-699, Russian in src/renderer/src/i18n/ru-RU/chat.json at lines 578-652 and
667-699, and Turkish in src/renderer/src/i18n/tr-TR/chat.json at lines 578-652
and 667-699. Also inspect the listed additional locales for the same
untranslated workflow and workflow.saved keys and translate them if the gap
exists.
src/renderer/src/components/chat/ChatStatusBar.vue-1342-1351 (1)

1342-1351: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add translation keys for the unavailable orchestration reasons.

orchestrationCapabilityMessage uses dynamic keys like chat.orchestration.proactive.reasons.${capability.reason}, but capability.reason can be one of several values and the chat.orchestration.proactive.reasons.* keys are missing from the locale files. Add the matching keys in all locales so the UI does not show raw key paths for unavailable orchestration capability states.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/components/chat/ChatStatusBar.vue` around lines 1342 - 1351,
Add the missing chat.orchestration.proactive.reasons.* translation entries for
every possible capability.reason value to every locale file, keeping the keys
consistent across locales so orchestrationCapabilityMessage resolves localized
text instead of raw paths.
src/renderer/src/components/chat/ChatStatusBar.vue-341-377 (1)

341-377: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Associate the ACP option label with its control.

The <label> element at Line 341 has no for attribute and does not wrap the control. Screen readers announce only the current value for the SelectTrigger and for the boolean Button. Add an accessible name to each control.

♿ Proposed fix
                 <SelectTrigger
                   :disabled="acpConfigReadOnly || isAcpOptionSaving(option.id)"
                   class="h-8 w-[9rem] text-xs"
+                  :aria-label="option.label"
                 >
                 <Button
                   v-else
                   type="button"
                   variant="outline"
                   size="sm"
                   class="h-8 min-w-[6rem] text-xs"
+                  :aria-label="option.label"
                   :disabled="acpConfigReadOnly || isAcpOptionSaving(option.id)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/components/chat/ChatStatusBar.vue` around lines 341 - 377,
Add accessible labeling for each ACP option in the option-rendering block:
associate the visible label with the corresponding SelectTrigger or boolean
Button using a stable option-specific identifier, and ensure both control
variants expose that label to assistive technologies. Update the label and
control markup around the option label, Select, and Button without changing
their existing behavior.
src/renderer/src/lib/liveDelegationPresentation.ts-75-79 (1)

75-79: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Return a fallback presentation for an unknown status.

LiveDelegationSummary carries schemaVersion, so a persisted or IPC-delivered row can hold a status string that this map does not contain. In that case the lookup returns undefined, and a caller that reads labelKey or dotClass throws during render. Add a terminal-neutral fallback.

🛡️ Proposed fix
+const UNKNOWN_PRESENTATION: LiveDelegationStatusPresentation = {
+  labelKey: 'chat.toolCall.subagents.status.error',
+  dotClass: 'bg-muted-foreground',
+  badgeClass: 'bg-muted text-muted-foreground',
+  active: false,
+  actionRequired: false
+}
+
 export function getLiveDelegationStatusPresentation(
   status: LiveDelegationDisplayStatus
 ): LiveDelegationStatusPresentation {
-  return STATUS_PRESENTATIONS[status]
+  return STATUS_PRESENTATIONS[status] ?? UNKNOWN_PRESENTATION
 }

The Record type still keeps the map exhaustive for every known LiveDelegationStatus member at compile time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/lib/liveDelegationPresentation.ts` around lines 75 - 79,
Update getLiveDelegationStatusPresentation to return a terminal-neutral fallback
presentation when STATUS_PRESENTATIONS[status] is undefined, while preserving
the exhaustive Record typing for known LiveDelegationStatus members and ensuring
callers always receive valid labelKey and dotClass values.
src/renderer/src/lib/workflowLaunchApproval.ts-20-20 (1)

20-20: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

z.string().max() counts characters, not bytes.

WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES is a byte limit. The producer in src/main/workflow/launchApproval.ts enforces it with Buffer.byteLength(request.scriptSource, 'utf8'). z.string().max() counts UTF-16 code units, so for non-ASCII sources this renderer bound is looser than the producer bound. The fallback is safe because the approval already passed main-process validation, so this is a clarity issue. Add a comment that the constant is reused as a character ceiling, or derive an explicit character bound.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/renderer/src/lib/workflowLaunchApproval.ts` at line 20, Clarify the
validation in the workflow launch approval schema around scriptSource by
documenting that WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES is reused as a character
ceiling, since z.string().max() does not enforce the producer’s UTF-8 byte
limit. Keep the existing main-process byte validation and renderer max
constraint unchanged.
src/shared/workflow/serviceContracts.ts-149-152 (1)

149-152: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clarify the meaning of an explicit budget: null.

WorkflowLaunchDraftSchema accepts budget: null, and WorkflowLaunchRequestSchema declares budget as nullable. This resolver always produces a non-null budget, because it injects maxExecutionMs: WORKFLOW_DEFAULT_EXECUTION_TIMEOUT_MS when the caller omits it or passes null. A caller that passes null to request no budget receives a two-hour execution cap. Either document that every run carries a default execution budget and drop nullable() from the request schema, or preserve null when the caller sets it.

♻️ Option: preserve an explicit null
-  const budget = WorkflowRunBudgetSchema.parse({
-    ...(parsed.budget ?? {}),
-    maxExecutionMs: parsed.budget?.maxExecutionMs ?? WORKFLOW_DEFAULT_EXECUTION_TIMEOUT_MS
-  })
+  const budget =
+    parsed.budget === null
+      ? null
+      : WorkflowRunBudgetSchema.parse({
+          ...(parsed.budget ?? {}),
+          maxExecutionMs: parsed.budget?.maxExecutionMs ?? WORKFLOW_DEFAULT_EXECUTION_TIMEOUT_MS
+        })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/workflow/serviceContracts.ts` around lines 149 - 152, Update the
budget resolution around WorkflowRunBudgetSchema.parse to preserve an explicitly
provided budget: null instead of replacing it with the default execution budget.
Keep applying WORKFLOW_DEFAULT_EXECUTION_TIMEOUT_MS only when the budget is
omitted, and ensure WorkflowLaunchDraftSchema and WorkflowLaunchRequestSchema
remain consistent with the resulting nullable behavior.
src/shared/lib/deepchatSubagents.ts-10-10 (1)

10-10: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Surface the title limit in the model guidance.

Line 10 defines an 80-character limit. Line 24 does not state it. If the tool layer rejects longer titles, the model learns the bound only from a failed call. Interpolate the constant into the guidance sentence.

✏️ Proposed change
-  'Name each spawned task with a concise user-language action-and-scope title; keep sibling titles distinct and do not use role-only, ordinal, or person-like names.',
+  `Name each spawned task with a concise user-language action-and-scope title of at most ${DEEPCHAT_SUBAGENT_TASK_TITLE_LIMIT} characters; keep sibling titles distinct and do not use role-only, ordinal, or person-like names.`,

Also applies to: 24-24

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/lib/deepchatSubagents.ts` at line 10, Update the model guidance
sentence near the tool definition to interpolate
DEEPCHAT_SUBAGENT_TASK_TITLE_LIMIT, explicitly stating the maximum title length
while preserving the existing guidance.
src/main/agent/shared/appSessionService.ts-33-46 (1)

33-46: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Preserve subagent identity when the stored contexts conflict.

Line 36 returns null for the whole metadata record. The caller then reports subagentMeta: null, so slotId and displayName are lost and the session stops looking like a subagent. src/main/app/composition.ts lines 1604-1613 and 1714-1726 resolve children through subagentMeta, so those lookups miss the row. Drop only the conflicting contexts and keep the identity fields.

🛡️ Proposed change
     const liveDelegation = parseLiveDelegationSubagentContext(parsed.liveDelegation)
-    if (correlatedWorkflow && liveDelegation) return null
+    const conflicting = Boolean(correlatedWorkflow && liveDelegation)
     return {
       slotId: parsed.slotId,
       displayName: typeof parsed.displayName === 'string' ? parsed.displayName : parsed.slotId,
       targetAgentId:
         parsed.targetAgentId === null || typeof parsed.targetAgentId === 'string'
           ? parsed.targetAgentId
           : undefined,
-      ...(correlatedWorkflow ? { workflow: correlatedWorkflow } : {}),
-      ...(liveDelegation ? { liveDelegation } : {})
+      ...(!conflicting && correlatedWorkflow ? { workflow: correlatedWorkflow } : {}),
+      ...(!conflicting && liveDelegation ? { liveDelegation } : {})
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/agent/shared/appSessionService.ts` around lines 33 - 46, Update the
conflict handling in the metadata construction around
parseWorkflowSubagentContext and parseLiveDelegationSubagentContext: when both
contexts are present, omit both conflicting context fields but still return the
record with slotId, displayName, and targetAgentId. Remove the early null return
while preserving the existing correlated-context and live-delegation fields when
they do not conflict.
src/shared/workflow/savedWorkflow.ts-36-46 (1)

36-46: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enforce byte budgets in the shared schemas.

WORKFLOW_SAVED_MAX_SOURCE_BYTES and WORKFLOW_SAVED_MAX_ARGS_BYTES name byte limits, but Zod’s string().max() only checks UTF-16 length. A workflow source or args string using multi-byte characters can pass these schemas while exceeding the intended byte cap. Add a byte-length refinement before .max(), or rename the constants to character limits.

♻️ Byte-accurate refinement
-  source: z.string().min(1).max(WORKFLOW_SAVED_MAX_SOURCE_BYTES)
+  source: z
+    .string()
+    .min(1)
+    .refine((value) => Buffer.byteLength(value, 'utf8') <= WORKFLOW_SAVED_MAX_SOURCE_BYTES, {
+      error: 'Workflow source exceeds the maximum byte size'
+    })
-export const WorkflowSavedArgsTextSchema = z.string().max(WORKFLOW_SAVED_MAX_ARGS_BYTES)
+export const WorkflowSavedArgsTextSchema = z
+  .string()
+  .refine((value) => Buffer.byteLength(value, 'utf8') <= WORKFLOW_SAVED_MAX_ARGS_BYTES, {
+    error: 'Workflow args exceed the maximum byte size'
+  })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shared/workflow/savedWorkflow.ts` around lines 36 - 46, Update
WorkflowSavedSourceSchema and WorkflowSavedArgsTextSchema to validate UTF-8 byte
length against WORKFLOW_SAVED_MAX_SOURCE_BYTES and WORKFLOW_SAVED_MAX_ARGS_BYTES
before retaining their existing character-length max checks. Use a Zod
refinement based on encoded byte length, preserving the current non-empty source
requirement and schema behavior otherwise.
src/main/orchestration/routes.ts-44-63 (1)

44-63: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

session_unavailable is handled only for the proactive policy. The guard at src/main/orchestration/routes.ts Line 48 requires input.policy === 'proactive'. A request for explicit against a deleted session therefore reaches options.setPolicy, which throws, and the route rejects with a raw persistence error instead of the stable applied: false result. The test mirrors the same narrow scope, so the gap is not detected.

  • src/main/orchestration/routes.ts#L44-L63: return { applied: false, policy: DEFAULT_ORCHESTRATION_POLICY, capability } whenever capability.reason === 'session_unavailable', before the proactive check, and keep await options.getPolicy(input.sessionId) for the remaining unavailable reasons.
  • test/main/orchestration/orchestrationRoutes.test.ts#L92-L116: add an assertion that updatePolicy({ sessionId: 'deleted-session', policy: 'explicit' }, context) also resolves to applied: false and does not call setPolicy.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/orchestration/routes.ts` around lines 44 - 63, Update the
orchestrationSetPolicyRoute handler so session_unavailable returns applied:
false with DEFAULT_ORCHESTRATION_POLICY for every requested policy, before
checking whether input.policy is proactive; retain options.getPolicy for other
unavailable reasons and preserve normal setPolicy behavior otherwise. In
test/main/orchestration/orchestrationRoutes.test.ts lines 92-116, add coverage
for updatePolicy with deleted-session and explicit, asserting applied: false and
that options.setPolicy is not called.
src/main/agent/invocationAdmission.ts-78-96 (1)

78-96: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Return rejected promises for invalid admission options.

acquire() calls normalizeOwnerId() and normalizeOwnerLimit() directly, and both throw plain Error values before returning a promise. The current direct caller is caught via await, but WorkflowRunAdmission.acquire() forwards the same promise-returning API, so promise-chain callers can still receive an unhandled synchronous throw. Wrap the option validation in try/catch and reject the promise before checking closedError or queuing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/agent/invocationAdmission.ts` around lines 78 - 96, Update acquire
in AgentInvocationAdmission to wrap normalizeOwnerId and normalizeOwnerLimit
validation in a try/catch, returning a rejected promise for validation errors.
Perform this rejection before checking closedError or admission state, while
preserving the existing behavior for valid options.
src/main/tool/agentTools/workflowTool.ts-96-156 (1)

96-156: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The advertised parameter list omits namedWorkflowPath.

workflowAgentToolSchema accepts namedWorkflowPath, and execute forwards it to prepareLaunch. The JSON parameters object does not declare it, so the model cannot discover or use saved workflow paths through this tool. Add the property, or remove it from the schema if the field is set by another caller only.

♻️ Proposed schema addition
             parentMessageId: {
               type: ['string', 'null'],
               description: 'Optional parent message identity used as workflow provenance.'
             },
+            namedWorkflowPath: {
+              type: ['string', 'null'],
+              description: 'Optional saved workflow path recorded with the prepared launch.'
+            },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/tool/agentTools/workflowTool.ts` around lines 96 - 156, Update
workflowAgentToolSchema’s properties to declare the namedWorkflowPath parameter
already accepted by the schema and forwarded by execute to prepareLaunch,
including its appropriate type and description; preserve the existing
prepare_launch behavior and do not remove the field from the execution path.
test/main/orchestration/liveDelegationService.test.ts-55-66 (1)

55-66: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enable PRAGMA foreign_keys = ON to match production and the repository test.

liveDelegationRepository.test.ts sets PRAGMA foreign_keys = ON before creating the tables. This setup does not. Foreign key enforcement is therefore off, so ON DELETE CASCADE and the live_delegation_turns and live_delegation_events references behave differently than in the application database. A service-level regression that violates a foreign key would pass here.

💚 Proposed test setup fix
     db.exec(`
+      PRAGMA foreign_keys = ON;
       CREATE TABLE new_sessions (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/main/orchestration/liveDelegationService.test.ts` around lines 55 - 66,
Enable SQLite foreign-key enforcement in the test database setup before creating
tables, matching the setup used by liveDelegationRepository.test.ts. Update the
initialization around DatabaseCtor and the LiveDelegationsTableCtor,
LiveDelegationTurnsTableCtor, and LiveDelegationEventsTableCtor calls so PRAGMA
foreign_keys is set to ON before schema creation.
src/main/tool/agentTools/workflowTool.ts-28-28 (1)

28-28: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Enforce scriptSource as UTF-8 bytes before parsing.

WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES is a byte limit, but z.string().max(...) limits UTF-16 code units. A multi-byte script can pass this validation and still fail later with a runtime byte-limit error instead of a clear tool validation error. Use a UTF-8 Buffer.byteLength() refinement here, or enforce byte length downstream before parsing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/tool/agentTools/workflowTool.ts` at line 28, Update the scriptSource
validation schema to enforce WORKFLOW_RUNTIME_MAX_SCRIPT_BYTES using UTF-8 byte
length rather than z.string().max’s UTF-16 code-unit count. Add a refinement
based on Buffer.byteLength() before parsing, while preserving the existing
optional and non-empty constraints.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dad86131-cfb3-45b5-9c09-627870802aec

📥 Commits

Reviewing files that changed from the base of the PR and between 7a4b1ed and 23656df.

⛔ Files ignored due to path filters (3)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/renderer/src/lib/icons/icon-collections.generated.ts is excluded by !**/*.generated.*
  • src/renderer/src/lib/icons/icon-whitelist.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (279)
  • .github/workflows/prcheck.yml
  • docs/architecture/proactive-multi-agent-orchestration/plan.md
  • docs/architecture/proactive-multi-agent-orchestration/spec.md
  • docs/architecture/proactive-multi-agent-orchestration/tasks.md
  • docs/features/workflow-runtime/plan.md
  • docs/features/workflow-runtime/spec.md
  • docs/features/workflow-runtime/tasks.md
  • docs/issues/live-delegation-deletion-coordination/spec.md
  • docs/issues/live-delegation-interaction-closure/spec.md
  • docs/issues/live-delegation-terminal-races/spec.md
  • electron-builder.yml
  • electron.vite.config.ts
  • package.json
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • src/main/agent/deepchat/harness/createDeepChatAgentHarness.ts
  • src/main/agent/deepchat/harness/deepChatAgentHarness.ts
  • src/main/agent/deepchat/memory/memoryRuntimeCoordinator.ts
  • src/main/agent/deepchat/resources/systemPromptBuilder.ts
  • src/main/agent/deepchat/runtime/contextBuilder.ts
  • src/main/agent/deepchat/runtime/dispatch.ts
  • src/main/agent/deepchat/runtime/generationSettings.ts
  • src/main/agent/deepchat/runtime/interactionCoordinator.ts
  • src/main/agent/deepchat/runtime/promptAssemblyService.ts
  • src/main/agent/deepchat/runtime/providerPermissionCoordinator.ts
  • src/main/agent/deepchat/runtime/runLifecycleCoordinator.ts
  • src/main/agent/deepchat/runtime/sessionStatusPublisher.ts
  • src/main/agent/deepchat/runtime/sessionUpdates.ts
  • src/main/agent/deepchat/runtime/toolResolver.ts
  • src/main/agent/deepchat/runtime/turnCoordinator.ts
  • src/main/agent/invocationAdmission.ts
  • src/main/agent/promptSettings.ts
  • src/main/agent/settings.ts
  • src/main/agent/shared/appSessionService.ts
  • src/main/app/composition.ts
  • src/main/data/schemaCatalog.ts
  • src/main/memory/data/tables/deepchatMemoryIngestionProjection.ts
  • src/main/orchestration/capability.ts
  • src/main/orchestration/data/database.ts
  • src/main/orchestration/data/tables/liveDelegationEvents.ts
  • src/main/orchestration/data/tables/liveDelegationTurns.ts
  • src/main/orchestration/data/tables/liveDelegations.ts
  • src/main/orchestration/liveDelegationRepository.ts
  • src/main/orchestration/liveDelegationService.ts
  • src/main/orchestration/routes.ts
  • src/main/session/assignment.ts
  • src/main/session/contracts.ts
  • src/main/session/data/tables/deepchatAssistantBlocks.ts
  • src/main/session/data/tables/deepchatMessages.ts
  • src/main/session/data/tables/newSessions.ts
  • src/main/session/data/transcript.ts
  • src/main/session/deletion.ts
  • src/main/session/deletionGate.ts
  • src/main/session/lifecycle.ts
  • src/main/session/runtimeEvents.ts
  • src/main/tool/agentTools/agentToolManager.ts
  • src/main/tool/agentTools/liveDelegationTool.ts
  • src/main/tool/agentTools/subagentOrchestratorTool.ts
  • src/main/tool/agentTools/workflowTool.ts
  • src/main/tool/effectClassification.ts
  • src/main/tool/effectObserver.ts
  • src/main/tool/index.ts
  • src/main/tool/runtimePorts.ts
  • src/main/tool/sessionToolProvider.ts
  • src/main/tool/toolMapper.ts
  • src/main/workflow/childExecutor.ts
  • src/main/workflow/childIdentity.ts
  • src/main/workflow/childRuntimeTracker.ts
  • src/main/workflow/data/database.ts
  • src/main/workflow/data/tables/workflowInvocations.ts
  • src/main/workflow/data/tables/workflowRuns.ts
  • src/main/workflow/domain/executionSnapshot.ts
  • src/main/workflow/domain/json.ts
  • src/main/workflow/effectObserver.ts
  • src/main/workflow/interactionProjection.ts
  • src/main/workflow/invocationContextRegistry.ts
  • src/main/workflow/launchApproval.ts
  • src/main/workflow/launchScope.ts
  • src/main/workflow/projection.ts
  • src/main/workflow/repository.ts
  • src/main/workflow/resultDelivery.ts
  • src/main/workflow/routes.ts
  • src/main/workflow/runAdmission.ts
  • src/main/workflow/runtime/quickjsWorkflowRuntime.ts
  • src/main/workflow/runtime/workflowSourceOutline.ts
  • src/main/workflow/runtime/workflowSourceValidator.ts
  • src/main/workflow/runtime/workflowUtilityHost.ts
  • src/main/workflow/runtime/workflowUtilityProcessHost.ts
  • src/main/workflow/savedWorkflowArgs.ts
  • src/main/workflow/savedWorkflowStore.ts
  • src/main/workflow/service.ts
  • src/main/workflow/structuredOutput/contracts.ts
  • src/main/workflow/structuredOutput/errors.ts
  • src/main/workflow/structuredOutput/registry.ts
  • src/main/workflow/structuredOutput/resultSchema.ts
  • src/main/workflowUtilityHostEntry.ts
  • src/renderer/api/OrchestrationClient.ts
  • src/renderer/api/WorkflowClient.ts
  • src/renderer/api/index.ts
  • src/renderer/src/apps/chat-main/ChatTabView.vue
  • src/renderer/src/components/chat-input/McpIndicator.vue
  • src/renderer/src/components/chat/ChatInputBox.vue
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/chat/composables/useChatInputMentions.ts
  • src/renderer/src/components/chat/mentions/SuggestionList.vue
  • src/renderer/src/components/chat/mentions/utils.ts
  • src/renderer/src/components/message/LiveDelegationToolCallCard.vue
  • src/renderer/src/components/message/MessageBlockActivityGroup.vue
  • src/renderer/src/components/message/MessageBlockToolCall.vue
  • src/renderer/src/components/message/MessageItemAssistant.vue
  • src/renderer/src/components/message/WorkflowLaunchApprovalCard.vue
  • src/renderer/src/components/message/messageActivityGroups.ts
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/renderer/src/components/sidepanel/ChatSidePanel.vue
  • src/renderer/src/components/sidepanel/LiveDelegationPanel.vue
  • src/renderer/src/components/sidepanel/SavedWorkflowPanel.vue
  • src/renderer/src/components/sidepanel/WorkflowPanel.vue
  • src/renderer/src/components/sidepanel/WorkspacePanel.vue
  • src/renderer/src/events.ts
  • src/renderer/src/features/chat-page/ChatPage.vue
  • src/renderer/src/features/chat-page/composables/useChatPageEventBridge.ts
  • src/renderer/src/features/chat-page/composables/useDisplayMessages.ts
  • src/renderer/src/features/chat-page/composables/useToolInteraction.ts
  • src/renderer/src/features/chat-page/model/displayMessage.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/lib/liveDelegationPresentation.ts
  • src/renderer/src/lib/liveDelegationToolCall.ts
  • src/renderer/src/lib/workflowAuthoringDraftStore.ts
  • src/renderer/src/lib/workflowLaunchApproval.ts
  • src/renderer/src/lib/workflowOutline.ts
  • src/renderer/src/lib/workflowSupport.ts
  • src/renderer/src/pages/NewThreadPage.vue
  • src/renderer/src/stores/ui/draft.ts
  • src/renderer/src/stores/ui/liveDelegation.ts
  • src/renderer/src/stores/ui/session.ts
  • src/renderer/src/stores/ui/sidepanel.ts
  • src/shared/agentTools.ts
  • src/shared/chat.d.ts
  • src/shared/contracts/common.ts
  • src/shared/contracts/events.ts
  • src/shared/contracts/events/orchestration.events.ts
  • src/shared/contracts/events/workflow.events.ts
  • src/shared/contracts/routes.ts
  • src/shared/contracts/routes/orchestration.routes.ts
  • src/shared/contracts/routes/sessions.routes.ts
  • src/shared/contracts/routes/workflow.routes.ts
  • src/shared/lib/assistantDeliverySegments.ts
  • src/shared/lib/deepchatSubagents.ts
  • src/shared/orchestration/liveDelegation.ts
  • src/shared/orchestration/toolEffect.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/types/core/chat.ts
  • src/shared/types/workspace.ts
  • src/shared/workflow/authoringContract.ts
  • src/shared/workflow/domain.ts
  • src/shared/workflow/orchestrationPolicy.ts
  • src/shared/workflow/outline.ts
  • src/shared/workflow/projection.ts
  • src/shared/workflow/resultDelivery.ts
  • src/shared/workflow/runtimeProtocol.ts
  • src/shared/workflow/savedWorkflow.ts
  • src/shared/workflow/serviceContracts.ts
  • src/shared/workflow/subagent.ts
  • src/types/i18n.d.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
  • test/main/agent/deepchat/memory/memoryRuntimeCoordinator.test.ts
  • test/main/agent/deepchat/resources/systemPromptBuilder.test.ts
  • test/main/agent/deepchat/runtime/contextBuilder.test.ts
  • test/main/agent/deepchat/runtime/dispatch.test.ts
  • test/main/agent/deepchat/runtime/generationSettings.test.ts
  • test/main/agent/deepchat/runtime/promptAssemblyService.test.ts
  • test/main/agent/deepchat/runtime/sessionStatusPublisher.test.ts
  • test/main/agent/deepchat/runtime/toolResolver.test.ts
  • test/main/agent/invocationAdmission.test.ts
  • test/main/agent/promptSettings.test.ts
  • test/main/agent/settings.test.ts
  • test/main/agent/shared/appSessionService.test.ts
  • test/main/build/electronBuilderConfig.test.ts
  • test/main/data/mainDatabase.migrationSqlSplit.test.ts
  • test/main/memory/deepchatMemoryIngestionProjection.test.ts
  • test/main/memory/memoryNativeMigration.test.ts
  • test/main/orchestration/liveDelegationMigration.test.ts
  • test/main/orchestration/liveDelegationRepository.test.ts
  • test/main/orchestration/liveDelegationService.test.ts
  • test/main/orchestration/orchestrationCapability.test.ts
  • test/main/orchestration/orchestrationRoutes.test.ts
  • test/main/routes/dispatcher.test.ts
  • test/main/scripts/prcheckWorkflow.test.ts
  • test/main/session/assignment.test.ts
  • test/main/session/data/tables/deepchatMessagesTable.test.ts
  • test/main/session/data/tables/newSessionsTable.test.ts
  • test/main/session/data/transcript.test.ts
  • test/main/session/deletion.test.ts
  • test/main/session/deletionGate.test.ts
  • test/main/session/lifecycle.test.ts
  • test/main/session/runtimeEvents.test.ts
  • test/main/session/session.integration.test.ts
  • test/main/session/sessionFixture.ts
  • test/main/shared/orchestrationPolicy.test.ts
  • test/main/tool/agentTools/agentToolDependencies.ts
  • test/main/tool/agentTools/agentToolManagerSettings.test.ts
  • test/main/tool/agentTools/liveDelegationTool.test.ts
  • test/main/tool/agentTools/subagentOrchestratorTool.test.ts
  • test/main/tool/agentTools/workflowTool.test.ts
  • test/main/tool/toolService.test.ts
  • test/main/workflow/quickjsWorkflowRuntime.test.ts
  • test/main/workflow/runtimeProtocol.test.ts
  • test/main/workflow/workflowChildExecutor.test.ts
  • test/main/workflow/workflowEffectObserver.test.ts
  • test/main/workflow/workflowInteractionProjection.test.ts
  • test/main/workflow/workflowInvocationContextRegistry.test.ts
  • test/main/workflow/workflowJson.test.ts
  • test/main/workflow/workflowLaunchApproval.test.ts
  • test/main/workflow/workflowLaunchScope.test.ts
  • test/main/workflow/workflowMigration.test.ts
  • test/main/workflow/workflowPersistence.test.ts
  • test/main/workflow/workflowProjection.test.ts
  • test/main/workflow/workflowResultDelivery.test.ts
  • test/main/workflow/workflowResultSchema.test.ts
  • test/main/workflow/workflowRoutes.test.ts
  • test/main/workflow/workflowRunAdmission.test.ts
  • test/main/workflow/workflowSavedStore.test.ts
  • test/main/workflow/workflowService.test.ts
  • test/main/workflow/workflowServiceContracts.test.ts
  • test/main/workflow/workflowSourceOutline.test.ts
  • test/main/workflow/workflowSourceValidator.test.ts
  • test/main/workflow/workflowStructuredOutputRegistry.test.ts
  • test/main/workflow/workflowTestFixtures.ts
  • test/main/workflow/workflowUtilityHost.test.ts
  • test/main/workflow/workflowUtilityProcessHost.test.ts
  • test/renderer/api/OrchestrationClient.test.ts
  • test/renderer/api/WorkflowClient.test.ts
  • test/renderer/components/ChatInputBox.test.ts
  • test/renderer/components/ChatPage.test.ts
  • test/renderer/components/ChatSidePanel.test.ts
  • test/renderer/components/ChatStatusBar.test.ts
  • test/renderer/components/LiveDelegationPanel.test.ts
  • test/renderer/components/McpIndicator.test.ts
  • test/renderer/components/ModelConfigDialog.test.ts
  • test/renderer/components/NewThreadPage.test.ts
  • test/renderer/components/SavedWorkflowPanel.test.ts
  • test/renderer/components/WorkflowPanel.test.ts
  • test/renderer/components/WorkspacePanel.test.ts
  • test/renderer/components/message/LiveDelegationToolCallCard.test.ts
  • test/renderer/components/message/MessageBlockToolCall.test.ts
  • test/renderer/components/message/MessageItemAssistant.test.ts
  • test/renderer/components/message/WorkflowLaunchApprovalCard.test.ts
  • test/renderer/components/message/messageActivityGroups.test.ts
  • test/renderer/composables/useChatInputMentions.test.ts
  • test/renderer/composables/useChatInputSkillScope.test.ts
  • test/renderer/features/chat-page/composables/useChatPageEventBridge.test.ts
  • test/renderer/features/chat-page/composables/useToolInteraction.test.ts
  • test/renderer/lib/liveDelegationToolCall.test.ts
  • test/renderer/lib/workflowAuthoringDraftStore.test.ts
  • test/renderer/lib/workflowLaunchApproval.test.ts
  • test/renderer/lib/workflowSupport.test.ts
  • test/renderer/stores/draft.test.ts
  • test/renderer/stores/liveDelegationStore.test.ts
  • test/renderer/stores/sessionStore.test.ts
  • test/renderer/stores/sidepanel.test.ts

Comment thread docs/features/workflow-runtime/plan.md Outdated
Comment thread docs/features/workflow-runtime/spec.md
Comment thread docs/features/workflow-runtime/spec.md Outdated
Comment thread src/main/app/composition.ts
Comment thread src/main/session/assignment.ts
Comment thread src/main/tool/index.ts
Comment thread src/main/workflow/launchScope.ts
Comment thread src/main/workflow/runtime/workflowSourceValidator.ts
Comment thread src/main/workflow/structuredOutput/registry.ts
Comment thread test/renderer/components/WorkspacePanel.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/workflow/launchApproval.ts (1)

97-105: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Bound the retained approval objects before adding to pendingBytes.

approvalBytes does not include the full retained approval/request objects, so they can exceed maxPendingBytes for large inputs, scripts, capabilities, agent allowlists, limits, or budgets. Add the serialized size of the stored entry, or add strict byte/structural limits for all retained fields.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/launchApproval.ts` around lines 97 - 105, Update the
approval-size calculation in the workflow launch approval path before the
pendingBytes check so it accounts for the complete retained approval/request
entry, including large inputs, scripts, capabilities, agent allowlists, limits,
and budgets. Serialize the stored entry using the existing canonical
representation where applicable, add its byte length to approvalBytes, and
ensure the maxPendingBytes checks bound the actual object retained in pending
state.
🧹 Nitpick comments (1)
src/main/workflow/launchApproval.ts (1)

124-147: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Keep the stored approval immutable.

prepare stores approval in pending and returns the same mutable object. A caller can change expiresAt or summary after prepare; later prune() and get() then observe the changed state. Store a deep clone and return a separate clone, or deep-freeze the complete approval before storing it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/workflow/launchApproval.ts` around lines 124 - 147, The approval
stored by prepare must not share mutable state with the object returned to
callers. Update the approval handling around WorkflowLaunchApprovalSchema.parse
and this.pending.set to deep-clone before storage and return a separate deep
clone, or deep-freeze the complete approval before both storage and return,
ensuring prune() and get() always observe immutable approval data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/main/workflow/launchApproval.ts`:
- Around line 97-105: Update the approval-size calculation in the workflow
launch approval path before the pendingBytes check so it accounts for the
complete retained approval/request entry, including large inputs, scripts,
capabilities, agent allowlists, limits, and budgets. Serialize the stored entry
using the existing canonical representation where applicable, add its byte
length to approvalBytes, and ensure the maxPendingBytes checks bound the actual
object retained in pending state.

---

Nitpick comments:
In `@src/main/workflow/launchApproval.ts`:
- Around line 124-147: The approval stored by prepare must not share mutable
state with the object returned to callers. Update the approval handling around
WorkflowLaunchApprovalSchema.parse and this.pending.set to deep-clone before
storage and return a separate deep clone, or deep-freeze the complete approval
before both storage and return, ensuring prune() and get() always observe
immutable approval data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 512759c9-002f-49fd-bfa8-cc962fa720f5

📥 Commits

Reviewing files that changed from the base of the PR and between 23656df and 0e233f9.

📒 Files selected for processing (37)
  • docs/features/workflow-runtime/plan.md
  • docs/features/workflow-runtime/spec.md
  • docs/features/workflow-runtime/tasks.md
  • src/main/agent/invocationAdmission.ts
  • src/main/agent/shared/appSessionService.ts
  • src/main/app/composition.ts
  • src/main/orchestration/routes.ts
  • src/main/session/assignment.ts
  • src/main/session/data/tables/newSessions.ts
  • src/main/session/deletionGate.ts
  • src/main/tool/agentTools/workflowTool.ts
  • src/main/workflow/launchApproval.ts
  • src/main/workflow/launchScope.ts
  • src/main/workflow/runtime/workflowSourceValidator.ts
  • src/main/workflow/structuredOutput/registry.ts
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/lib/liveDelegationPresentation.ts
  • src/renderer/src/lib/workflowLaunchApproval.ts
  • src/renderer/src/pages/NewThreadPage.vue
  • src/shared/lib/deepchatSubagents.ts
  • src/shared/workflow/savedWorkflow.ts
  • src/shared/workflow/serviceContracts.ts
  • test/main/agent/invocationAdmission.test.ts
  • test/main/agent/shared/appSessionService.test.ts
  • test/main/memory/memoryNativeMigration.test.ts
  • test/main/orchestration/liveDelegationService.test.ts
  • test/main/orchestration/orchestrationRoutes.test.ts
  • test/main/session/assignment.test.ts
  • test/main/session/deletionGate.test.ts
  • test/main/tool/agentTools/workflowTool.test.ts
  • test/main/workflow/workflowLaunchScope.test.ts
  • test/main/workflow/workflowServiceContracts.test.ts
  • test/main/workflow/workflowSourceValidator.test.ts
  • test/main/workflow/workflowStructuredOutputRegistry.test.ts
  • test/renderer/components/NewThreadPage.test.ts
  • test/renderer/components/WorkspacePanel.test.ts
  • test/renderer/lib/liveDelegationPresentation.test.ts
🚧 Files skipped from review as they are similar to previous changes (28)
  • test/main/agent/shared/appSessionService.test.ts
  • test/main/agent/invocationAdmission.test.ts
  • test/renderer/components/WorkspacePanel.test.ts
  • test/main/orchestration/orchestrationRoutes.test.ts
  • src/main/orchestration/routes.ts
  • src/shared/lib/deepchatSubagents.ts
  • test/main/memory/memoryNativeMigration.test.ts
  • src/main/session/assignment.ts
  • test/renderer/components/NewThreadPage.test.ts
  • src/renderer/src/lib/workflowLaunchApproval.ts
  • test/main/tool/agentTools/workflowTool.test.ts
  • src/shared/workflow/savedWorkflow.ts
  • test/main/workflow/workflowLaunchScope.test.ts
  • test/main/workflow/workflowStructuredOutputRegistry.test.ts
  • src/main/workflow/launchScope.ts
  • src/main/agent/shared/appSessionService.ts
  • src/main/workflow/runtime/workflowSourceValidator.ts
  • src/main/tool/agentTools/workflowTool.ts
  • docs/features/workflow-runtime/plan.md
  • src/shared/workflow/serviceContracts.ts
  • src/renderer/src/pages/NewThreadPage.vue
  • test/main/workflow/workflowSourceValidator.test.ts
  • src/main/workflow/structuredOutput/registry.ts
  • test/main/orchestration/liveDelegationService.test.ts
  • src/main/agent/invocationAdmission.ts
  • src/main/app/composition.ts
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • docs/features/workflow-runtime/spec.md

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