-
Notifications
You must be signed in to change notification settings - Fork 2
fix: preserve resume target when spawning agent #74
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -217,7 +217,7 @@ export function sendHtmlFileOrFallback( | |||||
| statusIfMissing = 404, | ||||||
| ): void { | ||||||
| if (fs.existsSync(filePath)) { | ||||||
| res.sendFile(path.resolve(filePath)); | ||||||
| res.type('html').send(fs.readFileSync(path.resolve(filePath), 'utf-8')); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 File serving changed from async to synchronous, losing Express built-in features The change from
For a dashboard serving a handful of small HTML files, these are unlikely to cause real problems, but the tradeoffs should be intentional. Was this helpful? React with 👍 or 👎 to provide feedback. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Replacing Express Prompt for AI agents
Suggested change
|
||||||
| return; | ||||||
|
Comment on lines
219
to
221
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Map the relevant files and inspect the function/call sites with line numbers.
git ls-files packages/dashboard-server/src/lib/utils.ts packages/dashboard-server/src/proxy-server.ts
echo "---- utils.ts outline ----"
ast-grep outline packages/dashboard-server/src/lib/utils.ts --view expanded || true
echo "---- proxy-server.ts outline ----"
ast-grep outline packages/dashboard-server/src/proxy-server.ts --view expanded || true
echo "---- utils.ts relevant lines ----"
sed -n '180,260p' packages/dashboard-server/src/lib/utils.ts | cat -n
echo "---- proxy-server.ts relevant routes ----"
sed -n '430,520p' packages/dashboard-server/src/proxy-server.ts | cat -nRepository: AgentWorkforce/relay-dashboard Length of output: 9779 🌐 Web query:
💡 Result: The res.sendFile method in Express is used to transfer a file at a given path, automatically setting the Content-Type header based on the file extension [1][2]. ETag and Last-Modified Handling Express automatically handles ETag generation and Last-Modified headers when using res.sendFile [3][4]. These mechanisms allow browsers and clients to perform conditional requests, improving performance by validating whether a cached version of the file is still current. Range Requests The method includes built-in support for HTTP Range requests [4]. This allows clients to request specific portions of a file, which is essential for tasks like resuming interrupted downloads or streaming media. Support for range requests is enabled by default [5]. In the options object, you can configure the acceptRanges property (defaults to true) to control this behavior [1][2]. Callback Function The res.sendFile method accepts an optional callback function, fn(err), which is invoked when the transfer is complete or if an error occurs [1][6]. Important Behaviors: 1. Error Handling: If a callback is provided and an error occurs, you are responsible for handling the response process [1][2]. This means you must explicitly end the request-response cycle (e.g., via res.end or res.status.send) or pass control to the next route using next(err) [1][2]. 2. Default Behavior: If you do not provide a callback, Express will automatically pass errors to your error-handling middleware via next(err) [2][4]. Usage Example: app.get('/file/:name', (req, res, next) => { const options = { root: path.join(dirname, 'public'), dotfiles: 'deny' }; res.sendFile(req.params.name, options, (err) => { if (err) { // You must handle the error explicitly when a callback is provided next(err); } else { console.log('Transfer complete'); } }); }); [1], [2] Official Express API documentation for res.sendFile [3] Express repository documentation on ETag support [5] Express release notes regarding range handling [4] Technical overview of file operation error handling in Express Citations:
Avoid synchronous reads for these HTML responses. 🧰 Tools🪛 ast-grep (0.44.1)[warning] 219-219: Filesystem path is not a string literal; a request-/variable-derived path can enable path traversal. Validate and normalize the path before use. (detect-non-literal-fs-filename-typescript) 🤖 Prompt for AI Agents |
||||||
| } | ||||||
|
|
||||||
|
|
||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Architect spawn route does not forward continueFrom The (Refers to lines 127-144) Was this helpful? React with 👍 or 👎 to provide feedback. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -109,11 +109,13 @@ export function registerBrokerProxyRoutes(app: Express, ctx: RouteContext): void | |
| typeof rawBody.model === 'string' ? rawBody.model : undefined, | ||
| ); | ||
| const model = parsed.model; | ||
| const continueFrom = typeof rawBody.continueFrom === 'string' ? rawBody.continueFrom : undefined; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The explicit Prompt for AI agents |
||
| return { | ||
| ...rawBody, | ||
| cli: parsed.cli, | ||
| args: parsed.args, | ||
| model, | ||
| continueFrom, | ||
| includeWorkflowConventions, | ||
| task: withWorkflowConventions(task, includeWorkflowConventions), | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,22 +63,22 @@ describe('BUG 7 — Resume session loses context', () => { | |
|
|
||
| if (res.status === 200) { | ||
| const data = await res.json(); | ||
| // BUG: The response doesn't indicate whether session was resumed | ||
| // because the server never processes continueFrom | ||
| expect(data.success).toBeDefined(); | ||
| expect(data.continueFrom).toBe('test-resume-agent'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The key regression assertions ( Prompt for AI agents |
||
| expect(data.resumed).toBe(true); | ||
| } | ||
|
Comment on lines
64
to
69
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚩 Bug-7 test assertions are conditional on status 200, silently passing on failure The test at Was this helpful? React with 👍 or 👎 to provide feedback.
Comment on lines
66
to
69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect the target test and nearby related files.
git ls-files test/bugs/bug7-resume-session.test.ts
wc -l test/bugs/bug7-resume-session.test.ts
cat -n test/bugs/bug7-resume-session.test.ts | sed -n '1,220p'
# Find the endpoint handler and any resume-session related code paths.
rg -n "continueFrom|resumed|resume-session|res.status === 200|status === 200" test src .Repository: AgentWorkforce/relay-dashboard Length of output: 11363 Fail the test on non-200 responses. The 🤖 Prompt for AI Agents |
||
| }); | ||
|
|
||
| it('spawn.ts should destructure continueFrom from request body', () => { | ||
| it('broker-proxy.ts should explicitly forward continueFrom from request body', () => { | ||
| // This is a static code analysis test | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| const spawnRouteCode = fs.readFileSync( | ||
| path.resolve(__dirname, '../../packages/dashboard-server/src/routes/spawn.ts'), | ||
| path.resolve(__dirname, '../../packages/dashboard-server/src/routes/broker-proxy.ts'), | ||
| 'utf-8' | ||
| ); | ||
|
|
||
| // FIX: continueFrom is now read from req.body and forwarded to spawn | ||
| // FIX: continueFrom is now read from req.body and forwarded to the broker spawn endpoint | ||
| // Verify the fix is in place by checking the source contains continueFrom | ||
| expect(spawnRouteCode).toContain('continueFrom'); | ||
| }); | ||
|
|
||
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.
Using synchronous file system operations (
fs.readFileSync) inside an Express request handler or response helper blocks the Node.js event loop. This can severely degrade server performance and throughput under concurrent load.Unless there is a specific reason to avoid
res.sendFile, it is highly recommended to keep using it as it is asynchronous, non-blocking, and handles streaming and caching headers efficiently. If you must read the file manually, please use asynchronous file system methods (e.g.,fs.promises.readFile).