Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/test-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ jobs:
nuq-fdb-core:
name: NuQ FoundationDB core tests
runs-on: blacksmith-4vcpu-ubuntu-2404
services:
redis:
image: redis
ports:
- 6379:6379
env:
FDB_VERSION: 7.3.63
steps:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,5 @@ apps/api/src/lib/scrape-interact/*.md

# stray test runner logs
vitest.out

tmp/
20 changes: 13 additions & 7 deletions apps/api/requests/v2/browser.requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Authorization: Bearer {{$dotenv TEST_API_KEY}}
content-type: application/json

{
"ttlTotal": 600,
"ttlWithoutActivity": 120,
"ttl": 600,
"activityTtl": 120,
"streamWebView": false
}

Expand All @@ -26,7 +26,7 @@ Authorization: Bearer {{$dotenv TEST_API_KEY}}
content-type: application/json

{
"ttlTotal": 300,
"ttl": 300,
"streamWebView": true
}

Expand Down Expand Up @@ -58,7 +58,7 @@ content-type: application/json

{
"code": "await page.goto('https://example.com');\nconst title = await page.title();\nconsole.log(title);",
"language": "js"
"language": "node"
}

### Execute Code — screenshot to base64
Expand All @@ -85,10 +85,16 @@ content-type: application/json
GET {{baseUrl}}/v2/interact/{{sessionId}}/replay HTTP/1.1
Authorization: Bearer {{$dotenv TEST_API_KEY}}

### Get Session Replay HLS playlist for tab 0
### Replay keeps pages/pageCount; Hangar's desktop recording is page "0".
### pageUrl is empty because the stream spans tabs; timestamps describe the video.
### Get the single HLS playlist (segments load directly from Hangar)
GET {{baseUrl}}/v2/interact/{{sessionId}}/replay/0 HTTP/1.1
Authorization: Bearer {{$dotenv TEST_API_KEY}}

### Get Hangar lifecycle status
GET {{baseUrl}}/v2/browser/{{sessionId}} HTTP/1.1
Authorization: Bearer {{$dotenv TEST_API_KEY}}

### Create Browser Session without recording
POST {{baseUrl}}/v2/browser HTTP/1.1
Authorization: Bearer {{$dotenv TEST_API_KEY}}
Expand All @@ -99,10 +105,10 @@ content-type: application/json
}

### Delete Browser Session — replace sessionId with actual id
### Waits for final duration and billing; retry if cleanup exceeds the wait deadline.
DELETE {{baseUrl}}/v2/browser/{{sessionId}} HTTP/1.1
Authorization: Bearer {{$dotenv TEST_API_KEY}}
content-type: application/json


### WebSocket — webview stream (use a WS client, e.g. wscat)
# wscat -c "ws://localhost:3002/v2/browser/{{sessionId}}" -H "Authorization: Bearer YOUR_API_KEY"
# Open liveViewUrl or interactiveLiveViewUrl returned by creation in a browser.
6 changes: 3 additions & 3 deletions apps/api/src/__tests__/nuq-fdb/router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
scrapeQueue,
crawlGroup,
crawlFinishedQueue,
mirrorExternalSlotAcquire,
reserveExternalSlot,
mirrorExternalSlotRelease,
} from "../../services/worker/nuq-router";
import { scrapeQueueFdb } from "../../services/worker/nuq-fdb";
Expand Down Expand Up @@ -308,10 +308,10 @@ describeIf("NuQ router (forced FDB mode)", () => {
test("external slot mirror consumes and releases FDB capacity", async () => {
const teamId = randomUUID();
const holder = randomUUID();
await mirrorExternalSlotAcquire(teamId, holder, 30_000);
await reserveExternalSlot(teamId, holder, 30_000, 10);
expect(await scrapeQueueFdb.getTeamActiveCount(teamId)).toBe(1);
// re-acquire (heartbeat) must not double-count
await mirrorExternalSlotAcquire(teamId, holder, 30_000);
await reserveExternalSlot(teamId, holder, 30_000, 10);
expect(await scrapeQueueFdb.getTeamActiveCount(teamId)).toBe(1);
await mirrorExternalSlotRelease(teamId, holder);
expect(await scrapeQueueFdb.getTeamActiveCount(teamId)).toBe(0);
Expand Down
15 changes: 15 additions & 0 deletions apps/api/src/__tests__/snips/v2/agent-thread.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@ describe("Agent thread parameter validation", () => {
scrapeTimeout,
);

it(
"rejects an unknown exchange.onTermsRequired",
async () => {
const response = await agentRaw({
urls: [TEST_SUITE_WEBSITE],
prompt: "What does this page offer?",
exchange: { onTermsRequired: "fail" },
});

expect(response.statusCode).toBe(400);
expect(response.body.success).toBe(false);
},
scrapeTimeout,
);

it(
"rejects an unknown mode",
async () => {
Expand Down
Loading
Loading