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
40 changes: 38 additions & 2 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,25 @@ jobs:
persist-credentials: false
- uses: ./.github/actions/setup-deno
timeout-minutes: 5
- run: deno task build:prepare
# Caches npm packages from the registry. A truncated response
# ("error reading a body from connection") fails the whole leg, so retry
# before giving up rather than reddening a build on registry weather.
- name: Prepare build dependencies
shell: bash
run: |
set -uo pipefail
for attempt in 1 2 3; do
if deno task build:prepare; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
delay=$((attempt * 10))
echo "build:prepare failed (attempt ${attempt}/3); retrying in ${delay}s" >&2
sleep "$delay"
fi
done
echo "build:prepare failed after 3 attempts" >&2
exit 1
- name: Verify proxy dependency lock is current
run: |
deno task build:proxy-lock
Expand Down Expand Up @@ -632,7 +650,25 @@ jobs:
- uses: ./.github/actions/setup-deno
timeout-minutes: 5

- run: deno task build:prepare
# Caches npm packages from the registry. A truncated response
# ("error reading a body from connection") fails the whole leg, so retry
# before giving up rather than reddening a build on registry weather.
- name: Prepare build dependencies
shell: bash
run: |
set -uo pipefail
for attempt in 1 2 3; do
if deno task build:prepare; then
exit 0
fi
if [ "$attempt" -lt 3 ]; then
delay=$((attempt * 10))
echo "build:prepare failed (attempt ${attempt}/3); retrying in ${delay}s" >&2
sleep "$delay"
fi
done
echo "build:prepare failed after 3 attempts" >&2
exit 1

- name: Verify proxy dependency lock is current
if: matrix.profile == 'proxy'
Expand Down
30 changes: 27 additions & 3 deletions src/agent/runtime/refresh.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "#veryfront/schemas/_test-setup.ts";
import { FakeTime } from "#std/testing/time";
import { assertEquals, assertExists } from "#veryfront/testing/assert.ts";
import { describe, it } from "#veryfront/testing/bdd.ts";
import { withMockFetch } from "#veryfront/testing/mock-fetch.ts";
import { type ModelRuntime } from "#veryfront/provider";
import { type RemoteToolSource, tool } from "#veryfront/tool";
import { defineSchema } from "#veryfront/schemas/index.ts";
Expand Down Expand Up @@ -2556,9 +2557,32 @@ describe("agent runtime refresh hooks", () => {
}),
});

const generated = await assistant.generate({ input: "Load foo_bar" });
const streamed = await (await assistant.stream({ input: "Load ReleaseNotes" }))
.toDataStreamResponse().text();
// Runtime tool discovery fires whenever the run context carries a token, and
// `apiBaseUrl` falls back to the production API when VERYFRONT_API_BASE_URL is
// unset. Unmocked, generate() and stream() each POST /integrations/tools/list
// to api.veryfront.com and the test is at the mercy of a 30s fetch timeout.
// This test is about project skills, so answer discovery with no tools.
const { generated, streamed } = await withMockFetch(
(input) => {
const url = input instanceof Request ? input.url : String(input);
// Match the whole pathname, not a substring: a loose test also accepts
// a neighbouring route like `/integrations/tools/listing`, so a call to
// the wrong endpoint would be answered with an empty catalogue and the
// test would still pass. Anchored at the end rather than compared whole
// because VERYFRONT_API_BASE_URL may carry a path prefix, and the client
// concatenates base and path (`${baseUrl}${path}`).
if (!new URL(url).pathname.endsWith("/integrations/tools/list")) {
throw new Error(`Unexpected network call from a unit test: ${url}`);
}
return Promise.resolve(Response.json({ tools: [] }));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
async () => {
const generated = await assistant.generate({ input: "Load foo_bar" });
const streamed = await (await assistant.stream({ input: "Load ReleaseNotes" }))
.toDataStreamResponse().text();
return { generated, streamed };
},
);

assertEquals(catalog.map((skill) => skill.id), ["foo_bar", "ReleaseNotes"]);
assertEquals(generated.toolCalls[0]?.status, "completed");
Expand Down