Skip to content

[APPS][WIP] Prototype direct action execution in local dev server - #483

Draft
sdkennedy2 wants to merge 1 commit into
masterfrom
sdkennedy2/prototype-direct-action-execution
Draft

[APPS][WIP] Prototype direct action execution in local dev server#483
sdkennedy2 wants to merge 1 commit into
masterfrom
sdkennedy2/prototype-direct-action-execution

Conversation

@sdkennedy2

@sdkennedy2 sdkennedy2 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Motivation

Explore executing Apps backend functions directly in the local Vite dev server while routing action-catalog calls through Datadog's App Builder query execution API. This draft is intended to make the prototype concrete enough for design feedback before the implementation is completed.

Changes

The local __dd/executeAction handler now imports the requested backend module and invokes its exported function with the request arguments. Before invoking it, the handler installs an action-catalog execution adapter so calls made by the backend function can be forwarded to the App Builder preview-async API and resolved through the existing long-polling flow.

The adapter builds an action query from the action FQN and inputs, starts the query, validates the returned receipt ID, and reuses the current polling implementation to return the action output.

This is intentionally a WIP prototype. The action-catalog dependency and callback wiring are incomplete, and the Apps plugin does not currently typecheck with these changes.

QA Instructions

No manual QA yet because the prototype wiring is incomplete. For this draft, review the proposed execution flow and where the action-catalog adapter is installed in the local dev-server request lifecycle.

Blast Radius

The change is limited to the Apps plugin's local Vite development server and its backend-function execution endpoint. It is not production-ready and has no released customer impact unless completed and merged.

Documentation

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@sdkennedy2 sdkennedy2 changed the title Prototype direct action execution in local dev server [APPS][WIP] Prototype direct action execution in local dev server Aug 7, 2026
@sdkennedy2

Copy link
Copy Markdown
Collaborator Author

@codex review
@cursor review

@datadog-official

datadog-official Bot commented Aug 7, 2026

Copy link
Copy Markdown

Pipelines

Unblock PR with BitsAI

⚠️ Warnings

🚦 3 Pipeline jobs failed

Continuous Integration | End to End   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. Compilation error in /home/runner/work/build-plugins/build-plugins/packages/plugins/apps/src/vite/dev-server.ts:167:26: 'await' can only be used inside an 'async' function.

Continuous Integration | Linting   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. Error: 'await' can only be used inside an 'async' function in dev-server.ts:167:26.

Continuous Integration | Unit tests   View in Datadog   GitHub Actions

🔧 Fix in code. This looks caused by changes in this PR. Transform failed: 'await' can only be used inside an 'async' function in dev-server.ts:167
📋 Copy prompt for your agent
CI on my pull request is failing. Help me find and fix the root cause of each failing job below — they were flagged as caused by changes in this PR, so focus on the diff. For each job, explain the failure and propose a fix.

Branch: sdkennedy2/prototype-direct-action-execution

Continuous Integration | End to End
Commit: 61072dbcacf98bb7b1116690015db57afe2be72b
Error (code / build):
Compilation error in /home/runner/work/build-plugins/build-plugins/packages/plugins/apps/src/vite/dev-server.ts:167:26: 'await' can only be used inside an 'async' function.
CI job: https://github.com/DataDog/build-plugins/actions/runs/31205776887/job/92956325695

Continuous Integration | Linting
Commit: 61072dbcacf98bb7b1116690015db57afe2be72b
Error (code / build):
Error: 'await' can only be used inside an 'async' function in dev-server.ts:167:26.
CI job: https://github.com/DataDog/build-plugins/actions/runs/31205776887/job/92956325548

Continuous Integration | Unit tests
Commit: 61072dbcacf98bb7b1116690015db57afe2be72b
Error (code / build):
Transform failed: 'await' can only be used inside an 'async' function in dev-server.ts:167
CI job: https://github.com/DataDog/build-plugins/actions/runs/31205776887/job/92956325660

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 61072db | Docs | Datadog PR Page | Give us feedback!

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

Copy link
Copy Markdown

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: 61072dbcac

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

});
});
// Loading the module todos.backend.ts
const functions = await import(func?.absolutePath);

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 Load backend source through Vite instead of native import

For the normal .backend.ts/.backend.tsx inputs accepted by BACKEND_FILE_RE, absolutePath points to the uncompiled source file, but this native dynamic import bypasses Vite's TypeScript transpilation and module resolution. Under the repository's supported Node runtime, invoking any such backend function therefore fails with an unknown-file-extension or unresolved-import error; it also uses Node's module cache rather than Vite's HMR graph. Load the module through Vite's server-side loader or execute a generated bundle instead.

Useful? React with 👍 / 👎.


res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ success: true, result } satisfies ExecuteActionResponse));

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 Preserve the response data wrapper

When a directly invoked backend function returns a normal value such as { value: 42 }, this serializes that raw value as result, while dev-server-transport.ts:72 unconditionally returns executeActionResponse.result.data. Successful local calls will consequently resolve to undefined (or throw when the function returns undefined) instead of their actual value. Wrap the direct result as { data: result } to retain the established ExecuteActionResponse contract.

Useful? React with 👍 / 👎.

Comment on lines +383 to +384
const { functionName, args = [] } = await parseRequestBody(req);
const func = functionsByName.get(functionName);

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 Restore request validation before importing the function

For a request with a missing or unknown functionName, this lookup yields undefined and the subsequent import/invocation is caught as a generic 500. Previously validateAndBundle explicitly returned 400 for an invalid name and 404 for an unknown function, and the existing execute-action tests rely on those responses. Validate the parsed name and lookup result before attempting the direct import.

Useful? React with 👍 / 👎.

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