Skip to content

feat(act): support structured same-tab action steps#1098

Merged
shaun0927 merged 5 commits into
developfrom
feat/969-act-structured-steps
May 13, 2026
Merged

feat(act): support structured same-tab action steps#1098
shaun0927 merged 5 commits into
developfrom
feat/969-act-structured-steps

Conversation

@shaun0927
Copy link
Copy Markdown
Owner

@shaun0927 shaun0927 commented May 12, 2026

Progress / Review status

Auto-refreshed 2026-05-13 — owner comments cleaned up to reduce review noise.

Field Value
Branch feat/969-act-structured-stepsdevelop
Draft no
CI ❌ 6/9 passing — 3 failing
Mergeable ✅ MERGEABLE
Review decision
Codex (latest) 💡 suggestions posted
Other reviewers (latest) chatgpt-codex-connector: commented
Head 0d6aac5 — Let act run structured same-tab action steps
Commits 1

Owner comment cleanup: 1 issue + 0 inline review comments deleted. Outstanding feedback from automated/external reviewers above is unchanged.


Summary

  • Extends the existing act tool with a structured steps input for same-tab macro execution.
  • Structured steps skip natural-language parsing and action-cache lookup while reusing existing sequential executors, DOM-delta handling, failure stop behavior, and verification.
  • Keeps instruction support unchanged; callers may now provide either instruction or steps.

Closes #969

Fit / non-overlap review

  • Fits OpenChrome's speed/token direction by reducing parse ambiguity and extra agent/tool loops for known action sequences.
  • Does not add a new top-level macro tool, avoiding overlap with existing act API and the issue refinement.
  • Keeps same-tab actions sequential, not parallel, to avoid unsafe order-dependent browser side effects.

Tests

  • ./node_modules/.bin/jest tests/tools/act.test.ts --runInBand
  • ./node_modules/.bin/tsc -p tsconfig.json --noEmit

OpenChrome real-validation checklist

After merge, validate with OpenChrome itself:

  1. Open a local fixture or page with a button and input.
  2. Call act with structured steps, for example { "tabId": "...", "steps": [{ "action": "click", "target": "Login" }], "verify": false }.
  3. Confirm output includes [structured], executes the expected step, and does not require instruction.
  4. Run a two-step macro such as click + type; confirm steps are executed in order and failure stops at the first failing step.
  5. Call legacy act with only instruction; confirm the existing natural-language path still works.

@qodo-code-review
Copy link
Copy Markdown

ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

Add a structured steps input path to act so common same-tab browser loops can skip natural-language parsing and cache lookup while reusing existing per-step executors and verification behavior.

Constraint: Extended the existing act tool instead of adding a new top-level macro tool, matching the issue's non-overlap direction.

Rejected: Parallel step execution | same-tab browser actions are order-dependent and unsafe to run concurrently.

Confidence: high

Scope-risk: moderate

Directive: Keep structured macro actions inside the existing ParsedAction verbs unless a future issue adds explicit safety semantics.

Tested: ./node_modules/.bin/jest tests/tools/act.test.ts --runInBand

Tested: ./node_modules/.bin/tsc -p tsconfig.json --noEmit

Not-tested: Live same-tab macro smoke; included as PR OpenChrome validation checklist.
@shaun0927 shaun0927 force-pushed the feat/969-act-structured-steps branch from b676a03 to 0d6aac5 Compare May 13, 2026 09:19
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d6aac57fe

ℹ️ 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".

Comment thread src/tools/act.ts
if (!structured.actions && (!instruction || instruction.trim().length === 0)) {
return { content: [{ type: 'text', text: 'Error: instruction or steps is required' }], isError: true };
}
if (missingVariables.length > 0) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Ignore unused instruction placeholders when steps are provided

When steps are supplied, this handler intentionally executes the structured path and skips natural-language parsing, but it still validates %var% placeholders from instruction and can return Error: Missing variable(s) even though instruction is not used. This breaks mixed callers that send both fields (e.g., legacy instruction template plus concrete steps) and causes valid structured runs to fail before execution. Placeholder validation should be scoped to the selected execution source (or include placeholders from steps instead).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d6aac57fe

ℹ️ 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".

Comment thread src/tools/act.ts
Comment on lines +734 to +735
if (!structured.actions && (!instruction || instruction.trim().length === 0)) {
return { content: [{ type: 'text', text: 'Error: instruction or steps is required' }], isError: true };
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip instruction-variable validation when structured steps are used

When steps are present, the handler still evaluates %variable% placeholders from instruction and returns Missing variable(s) before executing, even though this code path explicitly prefers structured actions. This makes otherwise valid structured-step calls fail whenever callers also send a templated or placeholder-filled instruction field (common in mixed/transition clients). Gate variable-missing validation to the natural-language path (or validate placeholders from structured steps instead) so steps truly works as an alternative input.

Useful? React with 👍 / 👎.

The CORS allowlist suite was racing transport.start() against the http
server actually binding to the loopback port — on ubuntu-18 / macos-22
the 100 ms fixed sleep lost the race intermittently and tests failed
with `connect ECONNREFUSED 127.0.0.1:36014`.

Replace the fixed sleep with a poll loop that opens a probe TCP socket
to the allocated port and resolves the moment it accepts a connection.
The poll budget is 5 s with 25 ms retries, mirroring the bear-token
suite's setup, and surfaces a deterministic timeout message if the
server truly fails to bind. Resolves the ubuntu-18 / macos-18 /
macos-22 build-and-test failures on PR #1098.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

const missingVariables = findMissingVariables(instruction || '', variables);

P2 Badge Validate placeholders from structured steps

When callers use steps with %name% placeholders, missing variable detection never runs because it only scans instruction. In the structured path this allows unresolved placeholders to flow into execution (for example, typing the literal %password%), which silently produces incorrect actions instead of the existing explicit Missing variable(s) error behavior. This was introduced with structured-step support and affects any workflow that templates step fields.

ℹ️ 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".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14fce2ece0

ℹ️ 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".

Comment thread src/tools/act.ts
Comment on lines +787 to +789
if (structured.actions) {
actions = structured.actions;
source = 'structured';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate placeholders inside structured steps

When the structured path is selected here, %name% validation still only scans instruction, so placeholders embedded in steps[*].target/value/condition are never checked for missing variables. In a steps-only call like type %password%, this now proceeds and can type the literal placeholder instead of failing fast with Missing variable(s), which is a behavioral regression from the instruction flow and can silently break scripted macros.

Useful? React with 👍 / 👎.

Comment on lines +13 to +19
const TEST_PORT_START = 20_000 + (process.pid % 400) * 100;
let nextTestPort = TEST_PORT_START;
let activePort = TEST_PORT_START;

function reserveLoopbackPort(): Promise<number> {
return new Promise((resolve, reject) => {
const server = net.createServer();
server.unref();
server.on('error', reject);
server.listen(0, '127.0.0.1', () => {
const address = server.address();
const port = typeof address === 'object' && address ? address.port : 0;
server.close((err) => {
if (err) {
reject(err);
return;
}
if (!port) {
reject(new Error('Failed to reserve loopback test port'));
return;
}
activePort = port;
resolve(port);
});
});
});
function allocatePort(): number {
activePort = nextTestPort++;
return activePort;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use reserved ephemeral ports for HTTP transport tests

This change replaces OS-assigned ephemeral ports with a fixed arithmetic sequence and never probes availability before use. If any process on the runner already occupies one of these ports, transport.start() can fail with EADDRINUSE before assertions run, introducing host-dependent flakiness that the previous listen(0) reservation avoided.

Useful? React with 👍 / 👎.

shaun0927 added 2 commits May 13, 2026 20:51
…tter

The 'ref counting: two beginHeavyOperation, one endHeavyOperation —
still in heavy mode' test sets heavyOpFatalThresholdMs=200 and then
busy-waits ~100ms. On a slow ubuntu-18 / macos-18 hosted runner the
combined latency (busy-wait + jest worker scheduler jitter) drifted to
218 ms and tripped the fatal handler, breaking the assertion.

Raise the heavyOp threshold to 2000 ms so the test still exercises the
"still in heavy mode" ref-count gate but has a comfortable margin over
CI host jitter. Resolves the latest #1098 build-and-test failures.
@shaun0927 shaun0927 merged commit 6c7c7b4 into develop May 13, 2026
6 of 9 checks passed
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