-
Notifications
You must be signed in to change notification settings - Fork 12
Background Job to Run a Command in Headless Chrome #4024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tintinthong
wants to merge
34
commits into
main
Choose a base branch
from
get-bot-runner-to-run-headless-command
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
ac64abb
temporarily add submission bot to newly created rooms
tintinthong f55043a
build architecture to run in headless chrome
tintinthong a284ca5
update bot runner
tintinthong 55753c5
update setup-submissions
tintinthong c2e1202
add test
tintinthong 0197023
add command requests in experiments
tintinthong 16cc21a
introduce bot-request-demo in experiments harness
tintinthong 4c10b2f
fix lint
tintinthong 00585a4
update log naming
tintinthong bc38e7e
return a serialized result no matter what
tintinthong f8eb802
refactor bot-request-utils
tintinthong ecd9392
fix nonce scope
tintinthong cb54b80
fix lint
tintinthong 2d78dd9
add submission bot to every room
tintinthong f5499de
clean up create-show-card-requests
tintinthong 36d7498
since there is no more filter we remove this test
tintinthong b2d4eb1
remove test that checks for filter types
tintinthong 5382690
race condition for submission bot is fixed
tintinthong 59fa926
refactor CommandInvocation to explicitly call .value as .cardResult
tintinthong a605a05
Rename .result to .resultString
tintinthong 9613119
add command parsing separately
tintinthong b40ed28
add cardResultString
tintinthong e1175ce
add error handling for prerender server
tintinthong fced14f
refactor queryParam to pathParam. Change codeRef json to url encoded url
tintinthong b7be7cd
fix lint
tintinthong b938140
add doc
tintinthong 9b2a309
update with new archtiecture
tintinthong f468a43
fix bot request
tintinthong 3452f40
remove bad realm-guessing function from card-id
tintinthong 50b1e96
add error throw
tintinthong 6c58415
add new test assertion
tintinthong a1d91df
remove unused variables
tintinthong 425a74d
fix test
tintinthong ca69404
fix test
tintinthong File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| ## Demo | ||
|
|
||
| https://www.loom.com/share/2fe9a3e58a7c459ba574b2c0f747a667 | ||
|
|
||
| ## Testing Locally | ||
|
|
||
| 1. Start `bot-runner` with `pnpm start:development`. | ||
| 2. Start realm server with `pnpm start:all`. | ||
| 3. Inside `packages/matrix`, run `pnpm setup-submission-bot`. | ||
| 4. Open http://localhost:4200/experiments/BotRequestDemo/bot-request-demo. | ||
| 5. Click **Send Show Card Bot Request** on the demo card. | ||
|
|
||
| ## Flow Diagram | ||
|
|
||
| ### User issuing task | ||
|
|
||
| Example source is the experiments demo card, but the same flow is used for any `app.boxel.bot-trigger` event. | ||
|
|
||
| ```mermaid | ||
| flowchart TD | ||
|
|
||
| B["Trigger 'Send Show Card Bot Request' from UI"] | ||
| B --> D["CreateShowCardRequestCommand.execute()"] | ||
| D --> E["SendBotTriggerEventCommand.execute()"] | ||
| E --> F["sendEvent('app.boxel.bot-trigger')"] | ||
| F --> G["bot-runner receives timeline event"] | ||
| G --> H["enqueueRunCommandJob() to jobs table"] | ||
| ``` | ||
|
|
||
| ### Command runner architecture | ||
|
|
||
| ```mermaid | ||
| flowchart TD | ||
|
|
||
| A["bot-runner"] | ||
| A -->|enqueue run-command job with command string| B["jobs table"] | ||
| B --> C["runtime-common worker"] | ||
| C -->|runCommand task| D["remote prerenderer"] | ||
| D -->|POST /run-command| E["prerender manager"] | ||
| E -->|proxy| F["prerender server app"] | ||
| F -->|transitionTo command-runner route| G["headless Chrome tab"] | ||
| G --> H["host command-runner route"] | ||
| H -->|command executes + DOM status| G | ||
| G -->|capture data-prerender + data-command-result| F | ||
| F --> D | ||
| D --> C | ||
| C --> B | ||
| ``` | ||
|
|
||
| ## Matrix Event Payload (`app.boxel.bot-trigger`) | ||
|
|
||
| ```ts | ||
| const event = { | ||
| type: 'app.boxel.bot-trigger', | ||
| content: { | ||
| type: 'show-card', | ||
| realm: 'http://localhost:4201/experiments/', | ||
| input: { | ||
| cardId: 'http://localhost:4201/experiments/Author/jane-doe', | ||
| format: 'isolated', | ||
| }, | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| ## Bot Trigger Data Structures | ||
|
|
||
| ```ts | ||
| type SendBotTriggerEventInput = { | ||
| roomId: string; | ||
| type: string; | ||
| realm: string; | ||
| input: Record<string, unknown>; | ||
| }; | ||
|
|
||
| type BotTriggerContent = { | ||
| type: string; | ||
| realm: string; | ||
| input: unknown; | ||
| }; | ||
| ``` | ||
|
|
||
| ## Submission Bot Commands (DB) | ||
|
|
||
| `setup-submission-bot` now writes canonical scoped command specifiers into `bot_commands.command`. | ||
|
|
||
| ```json | ||
| [ | ||
| { | ||
| "name": "create-listing-pr", | ||
| "command": "@cardstack/boxel-host/commands/create-listing-pr/default", | ||
| "filter": { | ||
| "type": "matrix-event", | ||
| "event_type": "app.boxel.bot-trigger", | ||
| "content_type": "create-listing-pr" | ||
| } | ||
| }, | ||
| { | ||
| "name": "show-card", | ||
| "command": "@cardstack/boxel-host/commands/show-card/default", | ||
| "filter": { | ||
| "type": "matrix-event", | ||
| "event_type": "app.boxel.bot-trigger", | ||
| "content_type": "show-card" | ||
| } | ||
| }, | ||
| { | ||
| "name": "patch-card-instance", | ||
| "command": "@cardstack/boxel-host/commands/patch-card-instance/default", | ||
| "filter": { | ||
| "type": "matrix-event", | ||
| "event_type": "app.boxel.bot-trigger", | ||
| "content_type": "patch-card-instance" | ||
| } | ||
| } | ||
| ] | ||
| ``` | ||
|
|
||
| ## Run Command Job Payload | ||
|
|
||
| `RunCommandArgs.realmURL` is derived from `event.content.realm`. | ||
|
|
||
| ```json | ||
| { | ||
| "realmURL": "http://localhost:4201/experiments/", | ||
| "realmUsername": "@alice:localhost", | ||
| "runAs": "@alice:localhost", | ||
| "command": "@cardstack/boxel-host/commands/show-card/default", | ||
| "commandInput": { | ||
| "cardId": "http://localhost:4201/experiments/Author/jane-doe", | ||
| "format": "isolated" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Command Normalization in `run-command` task | ||
|
|
||
| - Command stays a `string` across bot-runner, job queue, and prerender request. | ||
| - `runtime-common/tasks/run-command.ts` normalizes legacy realm-server URL forms (`/commands/<name>/<export>`) into a realm-local module specifier path when needed. | ||
| - String -> `ResolvedCodeRef` conversion happens in the host `command-runner` route when it parses `:command`. | ||
|
|
||
| ## Host `command-runner` Route | ||
|
|
||
| ```ts | ||
| route: /command-runner/:command/:input/:nonce | ||
|
|
||
| type CommandRunnerRouteParams = { | ||
| command: string; | ||
| input: string; | ||
| nonce: string; | ||
| }; | ||
| ``` | ||
|
|
||
| ### Example (`command` and `input` as path params) | ||
|
|
||
| ```ts | ||
| const command = '@cardstack/boxel-host/commands/show-card/default'; | ||
| const input = JSON.stringify({ | ||
| cardId: 'http://localhost:4201/experiments/Author/jane-doe', | ||
| format: 'isolated', | ||
| }); | ||
| const nonce = '2'; | ||
|
|
||
| const url = `http://localhost:4200/command-runner/${encodeURIComponent(command)}/${encodeURIComponent(input)}/${encodeURIComponent(nonce)}`; | ||
| ``` | ||
|
|
||
| ```txt | ||
| http://localhost:4200/command-runner/%40cardstack%2Fboxel-host%2Fcommands%2Fshow-card%2Fdefault/%7B%22cardId%22%3A%22http%3A%2F%2Flocalhost%3A4201%2Fexperiments%2FAuthor%2Fjane-doe%22%2C%22format%22%3A%22isolated%22%7D/2 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the worker task requires a realm to be known to check for permissions. So we just constantly send a realm from UI