Ship local task demo workflow#19
Conversation
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
Reviewing PR metadata, current diff, prior comments, and CI status from GitHub without checking out or executing the PR branch. [important] Summary: CI currently shows GitGuardian passing and only this review workflow pending; no prior inline findings were present to re-check. |
There was a problem hiding this comment.
Important
Existing persisted editor state can hide the new demo workflow for returning users.
Reviewed changes — This PR ships a local /task workflow demo that exercises Generate, local table writes, and dry-run WhatsApp confirmation behavior without external services.
- Seed the task demo workflow — The initial
WorkflowJsonnow extracts task data, creates a row intasks, and produces a quoted reply intent. - Add deterministic dry-run Generate output —
generateDryRunOutputlets/api/workflow-runnerrun Generate blocks in dry-run mode without AI credentials. - Improve Test Chat diagnostics — The page now displays trigger matching, block steps, Generate output, table patches, outbound intents, and recent local table rows.
- Cover the demo path —
src/lib/workflow-runner.test.tsadds an end-to-end dry-run test for extraction, row creation, table patching, and quoted replies.
⚠️ Returning browsers can keep the old workflow instead of the task demo
The new demo is only the default for a fresh localStorage state. Anyone who opened the previous editor keeps loading their saved normal.workflow-editor-shell.v1 workflow, so after deploy they can land on the old placeholder flow and never exercise the /task extraction/table/quoted-reply path unless they know to reset or clear storage.
Technical details
# Returning browsers can keep the old workflow instead of the task demo
## Affected sites
- `src/app/page.tsx:40` — The workflow storage key remains `normal.workflow-editor-shell.v1`.
- `src/app/page.tsx:73` — The seeded `initialWorkflow` now contains the new task demo, but `safeStoredWorkflow()` continues to prefer any existing v1 saved workflow.
- `src/app/page.tsx:961` — `resetWorkflow()` can reveal the new demo, but only if the user already knows to click it.
## Required outcome
- Returning users and reviewers with existing local editor state should see the shipped task demo, or the UI should make the migration/reset path explicit enough that the demo is not hidden.
## Suggested approach
Bump the workflow storage namespace for this seeded demo, or add a small migration/seed-version check that replaces only the old placeholder workflow while preserving intentionally edited workflows if that matters.GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review the PR using GitHub’s diff and metadata only, keeping the local checkout on the trusted base and avoiding any PR-head execution. [important] [important] CI context: GitGuardian is passing; the review workflow is still in progress, and no app CI check results were available from the inspected commit status endpoints. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ab43dcec7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| message: payload.message, | ||
| tableState: payload.tableState ?? null, | ||
| mode: payload.mode, | ||
| generate: payload.mode === "dry-run" ? generateDryRunOutput : undefined, |
There was a problem hiding this comment.
Preserve Generate tool execution in dry runs
When the editor/API dry-runs any workflow containing a Generate block with toolsJson edges, this override routes the block through generateDryRunOutput, but that adapter returns a canned output without ever invoking request.tools[].execute. The runner’s tool-chain side effects (table writes and send intents behind tool:* edges) only occur when the Generate adapter calls those tool functions, so Test Chat dry-runs of existing tool-based workflows now silently skip those blocks and report a successful Generate step with no table patches or outbound intent. Consider falling back to the AI adapter when tools are present, or have the dry-run adapter execute a deterministic tool path rather than ignoring tools.
Useful? React with 👍 / 👎.
| if (request.outputMode === "array") { | ||
| return { mode: "array", array: [taskObject] }; |
There was a problem hiding this comment.
Honor array element schemas in dry runs
When a dry-run Generate block is configured with outputMode: "array", this always returns an array containing the task object and ignores request.elementSchema entirely. For example, the editor’s default array schema is { "type": "string" }, so any downstream block that interpolates the generated array into a text/select column or expects strings will receive objects instead and can fail validation or show misleading dry-run output. Build the placeholder from the element schema (or at least return a schema-compatible primitive for primitive schemas) before exposing dry-run arrays.
Useful? React with 👍 / 👎.
| ) { | ||
| const sourceText = prompt.match(/\/task[^\n]*/i)?.[0] ?? `/task ${title}`; |
There was a problem hiding this comment.
Return schema-compatible object fields
For dry-run Generate blocks using object mode with any schema outside the seeded task fields, this fills those properties with null. The editor’s own added Generate block seeds a required string response field, so switching it to object mode and then using {{blocks.<id>.output.object.response}} in a text/select table column causes the dry-run table action to reject the value even though a real structured generation should produce a string. Populate unknown properties according to their declared JSON-schema type instead of defaulting them to null.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
ℹ️ No new issues found in the new commit; the prior review's persisted-state concern still applies.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which generalizes deterministic dry-run Generate placeholders.
- Generalized fallback dry-run text —
generateDryRunOutputnow uses non-/taskprompts instead ofUntitled taskand updates text-mode wording. - Filled schema-shaped object placeholders — Unknown object properties now receive type-shaped deterministic placeholder values, with additional
name,text, andsummarydefaults.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review PR 19 from GitHub’s diff and metadata only, then inspect the corresponding base-side files and nearby code without checking out or executing the PR branch. [important] Summary: the earlier persisted-storage finding appears fixed by the |
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Important
Dry-run array output can now diverge from the configured element schema.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which refreshes the seeded editor storage namespace and further generalizes deterministic dry-run Generate output.
- Bumped the workflow storage key —
src/app/page.tsxnow usesnormal.workflow-editor-shell.v2, so returning browsers no longer keep loading the old saved workflow over the seeded/taskdemo. - Reworked dry-run object reuse —
generateDryRunOutputnow routes object, JSON, and array outputs throughdryRunObject, adds avaluefallback, and useselementSchemafor array mode.
GPT | 𝕏
|
I’ll review the PR using GitHub CLI diff/metadata only, then inspect relevant base files and prior comments without checking out or executing PR code. [important] CI context: GitGuardian passed; only the review workflow was still in progress, with no app CI statuses reported by the inspected endpoints. |
There was a problem hiding this comment.
Important
The newest commit makes tool-enabled dry runs depend on the live AI adapter.
Reviewed changes — I reviewed the commit pushed while the previous review was being submitted, which changes generateDryRunOutput behavior for Generate blocks with inline tools.
- Delegated tool-enabled dry runs to the AI SDK —
generateDryRunOutputnow callsgenerateWithAiSdkwhenever the request includes tools, while keeping deterministic output for tool-less Generate blocks.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review the PR using GitHub’s diff and metadata as the source of truth, then validate any findings against the current base checkout without running PR code. [important] Previously raised storage-key and array primitive schema findings appear fixed in the latest diff. CI context: GitGuardian passed; no app CI statuses were reported by the inspected commit status endpoints, and only the review workflow was still in progress. |
There was a problem hiding this comment.
ℹ️ No new issues found in
589383e; the earlier tool-enabled dry-run finding remains open.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which aligns deterministic dry-run array output with primitive element schemas.
- Matched primitive array elements —
generateDryRunOutputnow usesdryRunArrayItemso primitiveelementSchemavalues produce primitive dry-run items. - Covered the array regression —
src/lib/workflow-runner.test.tsnow asserts that{ "type": "string" }resolves to a string array in dry-run mode.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review this strictly from GitHub’s PR metadata and diff, without checking out or executing PR code. I’ll first collect the PR description, changed files, previous comments, and check status, then inspect only the relevant base files/dependencies for context. [important] Previously raised storage-key, schema-shaped object fields, primitive array elements, and live-AI fallback findings appear fixed in the current diff. CI context: GitGuardian passed; no app CI statuses were reported by the provided commit status endpoints, and only this review workflow was in progress. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which keeps tool-enabled Generate dry-runs local while preserving deterministic demo behavior.
- Kept tool dry-runs local —
generateDryRunOutputnow synthesizes schema-shaped tool inputs and executes configured tool chains without delegating to the live AI SDK. - Surfaced dry-run tool execution — Text dry-run output now names the locally executed tools, while object and JSON outputs can include
toolResultsfor diagnostics. - Covered tool-enabled dry-run behavior —
src/lib/workflow-runner.test.tsnow exercises a Generate block with configured tools usinggenerateDryRunOutputand no AI credentials.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review using GitHub CLI outputs only, avoiding checkout or execution of PR head code, then verify any prior findings against the current diff. [important] Previously raised storage-key, schema-field, primitive-array, and tool dry-run findings appear fixed in the current diff. CI context: GitGuardian passed; no app CI statuses were reported by the provided endpoints, and only the review workflow was still in progress. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7c66ea8cf0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| const object: Record<string, JsonValue> = {}; | ||
| for (const [key, property] of Object.entries(properties)) { | ||
| object[key] = defaults[key] ?? dryRunValueForSchemaProperty(property); |
There was a problem hiding this comment.
Honor schema constraints before demo defaults
When a schema property has tighter constraints or a name that collides with these demo defaults, this picks the hard-coded value before inspecting the property schema. For example, an object schema with status: { type: "string", enum: ["todo", "done"] } followed by a Create Row into a select column with those options will dry-run as status: "open", causing the table action to reject the value even though real structured generation is constrained to the enum. Please derive the placeholder from enum/const/type constraints before applying defaults.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which narrows deterministic dry-run Generate tool execution to the first configured tool.
- Limited deterministic tool execution —
generateDryRunOutputnow invokes onlytools[0]during dry-run mode instead of automatically executing every configured Generate tool. - Covered first-tool dry-run behavior —
src/lib/workflow-runner.test.tsnow asserts that a second configured dry-run tool is not executed implicitly.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll inspect the PR metadata, diff, prior comments, and check statuses using GitHub CLI only, keeping the trusted local checkout untouched. [important] CI context: GitGuardian passed; no app CI statuses were reported by the inspected commit status endpoints, and only this review workflow was in progress. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which aligns the seeded task demo status schema with the local table’s select options.
- Constrained task status output —
src/app/page.tsxnow declares the Generate schema’sstatusproperty as an enum of"open"or"done", matching thetaskstable options used by the demo row write.
Verification: bun test src/lib/workflow-runner.test.ts passed.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review using GitHub’s PR diff and metadata only, keeping the trusted checkout on the base revision and avoiding any PR-head execution. [important] Previously raised storage-key, primitive array, live-AI tool fallback, status enum, and schema-constraint findings appear fixed in the current diff. CI context: GitGuardian passed; no app CI statuses were reported by the provided commit status endpoints, and only this review workflow was in progress. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which makes deterministic dry-run Generate output honor explicit schema constraints before demo defaults.
- Honored schema constraints in dry-runs —
generateDryRunOutputnow returns JSON-compatibleconstand firstenumvalues before falling back to seeded demo defaults or type-shaped placeholders. - Covered enum precedence —
src/lib/workflow-runner.test.tsnow asserts that an enum-constrainedstatusfield returns the schema value instead of the built-in task demo default.
Verification: bun test src/lib/workflow-runner.test.ts passed.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review the PR using GitHub’s diff and metadata only, keeping the local checkout on the trusted base revision and avoiding execution of PR code. [important] Previously raised findings around persisted storage, primitive arrays, tool dry-runs, status enums, schema constraints, and object-mode |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — I reviewed the commit pushed after the prior Pullfrog review, which keeps dry-run Generate object output aligned with the configured schema when tools run.
- Preserved schema-shaped object output —
generateDryRunOutputnow returns only the generated object forobjectmode while still executing configured dry-run tools locally for side effects. - Covered tool-enabled object dry-runs —
src/lib/workflow-runner.test.tsnow asserts that object output with tools stays shaped like the requested schema instead of adding diagnostictoolResults.
Verification: bun test src/lib/workflow-runner.test.ts passed.
GPT | 𝕏
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
|
I’ll review the PR using GitHub CLI only for the untrusted head diff and metadata, then inspect only relevant checked-out base files for context. [suggestion] Previously raised findings around storage migration, primitive array schemas, live-AI fallback, enum constraints, object-mode CI context: GitGuardian passed; only this review workflow was still in progress, and no app CI check results were reported by the provided status endpoints. |
There was a problem hiding this comment.
Important
Nested array dry-run placeholders can still lose command-derived values.
Reviewed changes — I reviewed the new commit since the prior Pullfrog review, which extends dry-run schema placeholders into nested object and array properties.
- Recursed nested placeholders —
generateDryRunOutputnow fills nested object properties and array schema properties instead of returning empty objects or arrays. - Covered nested schema output —
src/lib/workflow-runner.test.tsnow asserts nested object and enum-constrained array placeholders in object output mode.
Verification: bun test src/lib/workflow-runner.test.ts passed.
GPT | 𝕏
|
|
||
| if (type === "array") { | ||
| const items = (property as Record<string, unknown>).items; | ||
| const item = dryRunValueForSchemaProperty(items); |
There was a problem hiding this comment.
items is evaluated with the helper's default fallback, so labels: { type: "array", items: { type: "string" } } produces ["Dry-run value"] while top-level primitive arrays produce ["buy milk"]. That keeps the new recursive path from matching the deterministic behavior callers get elsewhere and can break downstream templates or local table writes that read those nested array values.
| const item = dryRunValueForSchemaProperty(items); | |
| const item = dryRunValueForSchemaProperty(items, fallbackText); |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c939a0e05a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| object[key] = | ||
| dryRunSchemaConstraintValue(property) ?? | ||
| defaults[key] ?? | ||
| dryRunValueForSchemaProperty(property, extractedText); |
There was a problem hiding this comment.
Validate demo defaults against the schema type
When a schema property name matches one of these demo defaults, the dry-run output uses the default without checking the property's declared type. For example, an object-mode Generate with title: { type: "number" } followed by a Create Row into a number column will dry-run title as the extracted string (e.g. "buy milk"), and isValueValidForColumn then rejects the table action even though the schema says the generated value should be numeric. Please only apply these name-based defaults when they satisfy the property schema, otherwise fall through to dryRunValueForSchemaProperty.
Useful? React with 👍 / 👎.

Summary
Tests
Closes #9