veryfront 0.1.1224 → 0.1.1226
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/esm/cli/main.d.ts +1 -1
- package/esm/cli/main.js +1 -1
- package/esm/cli/shared/deployment/deploy-project.d.ts.map +1 -1
- package/esm/cli/shared/deployment/deploy-project.js +72 -10
- package/esm/cli/shared/update-check.d.ts +24 -9
- package/esm/cli/shared/update-check.d.ts.map +1 -1
- package/esm/cli/shared/update-check.js +74 -34
- package/esm/cli/templates/manifest.js +1 -1
- package/esm/deno.d.ts +1 -0
- package/esm/deno.js +2 -1
- package/esm/extensions/ext-llm-openai/src/openai-tool-input.d.ts.map +1 -1
- package/esm/extensions/ext-llm-openai/src/openai-tool-input.js +21 -7
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +26 -9
- package/esm/src/agent/runtime/run-runtime-context.d.ts +15 -0
- package/esm/src/agent/runtime/run-runtime-context.d.ts.map +1 -0
- package/esm/src/agent/runtime/run-runtime-context.js +60 -0
- package/esm/src/agent/types.d.ts +3 -2
- package/esm/src/agent/types.d.ts.map +1 -1
- package/esm/src/html/hydration-script-builder/hydration-runtime.generated.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts +2 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.js +4 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations.js +6 -1
- package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.js +15 -1
- package/esm/src/platform/compat/fs.d.ts.map +1 -1
- package/esm/src/platform/compat/fs.js +14 -1
- package/esm/src/platform/compat/http/pinned-fetch.d.ts +1 -1
- package/esm/src/proxy/control-plane-signature.d.ts.map +1 -1
- package/esm/src/proxy/control-plane-signature.js +1 -1
- package/esm/src/react/compat/ssr-adapter/string-renderer.d.ts.map +1 -1
- package/esm/src/react/compat/ssr-adapter/string-renderer.js +6 -5
- package/esm/src/react/compat/ssr-adapter/timeout.d.ts +7 -0
- package/esm/src/react/compat/ssr-adapter/timeout.d.ts.map +1 -1
- package/esm/src/react/compat/ssr-adapter/timeout.js +13 -0
- package/esm/src/runtime/runtime-bridge.d.ts.map +1 -1
- package/esm/src/runtime/runtime-bridge.js +20 -8
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ deno init --npm veryfront
|
|
|
37
37
|
The default starter is `ai-agent`. Choose another template directly:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
npx veryfront init <PROJECT_NAME> --template <TEMPLATE>
|
|
40
|
+
npx veryfront@latest init <PROJECT_NAME> --template <TEMPLATE>
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Available starters: `ai-agent`, `minimal`, `agentic-workflow`.
|
package/esm/cli/main.d.ts
CHANGED
package/esm/cli/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-project.d.ts","sourceRoot":"","sources":["../../../../src/cli/shared/deployment/deploy-project.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"deploy-project.d.ts","sourceRoot":"","sources":["../../../../src/cli/shared/deployment/deploy-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -456,10 +456,55 @@ function isMatchingVeryfrontHostedUrl(url, target) {
|
|
|
456
456
|
parsed.slug === target.projectSlug.toLowerCase() &&
|
|
457
457
|
parsed.environment === target.environmentName.toLowerCase();
|
|
458
458
|
}
|
|
459
|
+
const MAX_JWT_SEGMENT_CODE_UNITS = 8 * 1024;
|
|
460
|
+
/** Decode one base64url JWT segment into a plain object, or null if it is not one. */
|
|
461
|
+
function decodeJwtSegment(segment) {
|
|
462
|
+
if (segment === undefined)
|
|
463
|
+
return null;
|
|
464
|
+
if (segment.length === 0 || segment.length > MAX_JWT_SEGMENT_CODE_UNITS)
|
|
465
|
+
return null;
|
|
466
|
+
try {
|
|
467
|
+
const base64 = segment.replaceAll("-", "+").replaceAll("_", "/");
|
|
468
|
+
const binary = atob(base64 + "=".repeat((4 - base64.length % 4) % 4));
|
|
469
|
+
const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
470
|
+
const parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
471
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
472
|
+
}
|
|
473
|
+
catch {
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Whether a stored credential could satisfy the protected-environment gate.
|
|
479
|
+
*
|
|
480
|
+
* The gate reads `userId` from the verified JWT payload and has no API-key
|
|
481
|
+
* branch, so presenting an opaque key only leaks it. Reads what the gate
|
|
482
|
+
* reads, and withholds anything it cannot recognise.
|
|
483
|
+
*/
|
|
484
|
+
function isSessionCredential(apiToken) {
|
|
485
|
+
const segments = apiToken.split(".");
|
|
486
|
+
if (segments.length !== 3)
|
|
487
|
+
return false;
|
|
488
|
+
const header = decodeJwtSegment(segments[0]);
|
|
489
|
+
if (header === null || typeof readUntrustedOwnDataProperty(header, "alg") !== "string") {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
const payload = decodeJwtSegment(segments[1]);
|
|
493
|
+
if (payload === null)
|
|
494
|
+
return false;
|
|
495
|
+
const userId = readUntrustedOwnDataProperty(payload, "userId");
|
|
496
|
+
return typeof userId === "string" && userId.length > 0;
|
|
497
|
+
}
|
|
459
498
|
function buildEnvironmentReadinessProbes(target) {
|
|
460
499
|
const route = target.route === undefined ? "/" : target.route;
|
|
461
500
|
if (route === null)
|
|
462
501
|
return [];
|
|
502
|
+
// Without a session credential the probe cannot get past the gate. Its
|
|
503
|
+
// challenge still proves routing resolves and the proxy is serving this
|
|
504
|
+
// environment — the most this step can establish, and the deployment it
|
|
505
|
+
// would otherwise fail is already committed and verified. Same allowance the
|
|
506
|
+
// protected custom-domain probe below already makes.
|
|
507
|
+
const canAuthenticate = isSessionCredential(target.apiToken);
|
|
463
508
|
const targetUrl = buildEnvironmentProbeUrl(target.url, route);
|
|
464
509
|
if (target.protected && !isMatchingVeryfrontHostedUrl(new URL(targetUrl), target)) {
|
|
465
510
|
return [
|
|
@@ -470,15 +515,15 @@ function buildEnvironmentReadinessProbes(target) {
|
|
|
470
515
|
},
|
|
471
516
|
{
|
|
472
517
|
url: buildEnvironmentProbeUrl(buildCanonicalEnvironmentUrl(target.projectSlug, target.environmentName), route),
|
|
473
|
-
authenticate:
|
|
474
|
-
acceptAuthenticationChallenge:
|
|
518
|
+
authenticate: canAuthenticate,
|
|
519
|
+
acceptAuthenticationChallenge: !canAuthenticate,
|
|
475
520
|
},
|
|
476
521
|
];
|
|
477
522
|
}
|
|
478
523
|
return [{
|
|
479
524
|
url: target.protected ? secureEnvironmentProbeUrl(targetUrl) : targetUrl,
|
|
480
|
-
authenticate: target.protected,
|
|
481
|
-
acceptAuthenticationChallenge:
|
|
525
|
+
authenticate: target.protected && canAuthenticate,
|
|
526
|
+
acceptAuthenticationChallenge: target.protected && !canAuthenticate,
|
|
482
527
|
}];
|
|
483
528
|
}
|
|
484
529
|
function isVeryfrontSignInUrl(url) {
|
|
@@ -499,6 +544,16 @@ function isSignInRedirect(response, requestUrl) {
|
|
|
499
544
|
return false;
|
|
500
545
|
}
|
|
501
546
|
}
|
|
547
|
+
/** A challenge is a sign-in redirect, a 401, or a 403; say which one arrived. */
|
|
548
|
+
function describeAuthenticationChallenge(probe, status, signInRedirect) {
|
|
549
|
+
if (probe.authenticate) {
|
|
550
|
+
return `Could not authenticate the protected environment URL ${probe.url}. Run veryfront login and deploy again.`;
|
|
551
|
+
}
|
|
552
|
+
if (signInRedirect) {
|
|
553
|
+
return `Environment URL ${probe.url} redirected to sign-in. Check its protection settings and deploy again.`;
|
|
554
|
+
}
|
|
555
|
+
return `Environment URL ${probe.url} returned HTTP ${status}. Check its protection settings and deploy again.`;
|
|
556
|
+
}
|
|
502
557
|
function isTransientEnvironmentStatus(status) {
|
|
503
558
|
return status === 404 || status === 408 || status === 425 || status === 429 || status >= 500;
|
|
504
559
|
}
|
|
@@ -551,18 +606,25 @@ export async function waitForEnvironmentReady(target, options = {}) {
|
|
|
551
606
|
if (ready)
|
|
552
607
|
break;
|
|
553
608
|
if (authenticationChallenge) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
:
|
|
557
|
-
|
|
609
|
+
// A bare Error here reaches the operator as `unknown-error`.
|
|
610
|
+
throw DEPLOYMENT_ERROR.create({
|
|
611
|
+
detail: describeAuthenticationChallenge(probe, response.status, signInRedirect),
|
|
612
|
+
context: { url: probe.url, status: response.status },
|
|
613
|
+
});
|
|
558
614
|
}
|
|
559
615
|
if (!isTransientEnvironmentStatus(response.status)) {
|
|
560
|
-
throw
|
|
616
|
+
throw DEPLOYMENT_ERROR.create({
|
|
617
|
+
detail: `Environment URL ${probe.url} returned HTTP ${response.status}. Check the environment configuration and deploy again.`,
|
|
618
|
+
context: { url: probe.url, status: response.status },
|
|
619
|
+
});
|
|
561
620
|
}
|
|
562
621
|
}
|
|
563
622
|
const remainingMs = deadline - Date.now();
|
|
564
623
|
if (remainingMs <= 0) {
|
|
565
|
-
throw
|
|
624
|
+
throw DEPLOYMENT_ERROR.create({
|
|
625
|
+
detail: `Environment URL ${probe.url} did not become ready within ${Math.ceil(timeoutMs / 1000)}s (last response: ${lastResponse}). Check the deployment and run deploy again.`,
|
|
626
|
+
context: { url: probe.url, timeoutMs },
|
|
627
|
+
});
|
|
566
628
|
}
|
|
567
629
|
await wait(Math.min(pollIntervalMs, remainingMs));
|
|
568
630
|
}
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { type FileSystem } from "../../src/platform/index.js";
|
|
2
|
+
export declare const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/veryfront/latest";
|
|
3
|
+
export declare const UPDATE_INSTALL_COMMAND = "npm install -g veryfront@latest";
|
|
4
|
+
interface UpdateCacheLocation {
|
|
5
|
+
directory: string;
|
|
6
|
+
file: string;
|
|
7
|
+
}
|
|
8
|
+
type UpdateCheckFileSystem = Pick<FileSystem, "readTextFile" | "mkdir" | "writeTextFile">;
|
|
9
|
+
type UpdateCheckFetcher = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
10
|
+
export interface UpdateCheckOptions {
|
|
11
|
+
shouldSkip?: () => boolean;
|
|
12
|
+
cacheLocation?: UpdateCacheLocation | null;
|
|
13
|
+
fileSystem?: UpdateCheckFileSystem;
|
|
14
|
+
fetcher?: UpdateCheckFetcher;
|
|
15
|
+
now?: () => number;
|
|
16
|
+
printNotice?: (current: string, latest: string) => void;
|
|
17
|
+
debug?: (message: string) => void;
|
|
18
|
+
}
|
|
9
19
|
export declare function compareVersions(current: string, latest: string): boolean;
|
|
10
20
|
export declare function shouldSkip(): boolean;
|
|
11
|
-
export declare function
|
|
21
|
+
export declare function getUpdateInstallCommand(context?: {
|
|
22
|
+
standalone: boolean;
|
|
23
|
+
executablePath: string;
|
|
24
|
+
}): string;
|
|
25
|
+
export declare function checkForUpdates(currentVersion: string, options?: UpdateCheckOptions): Promise<void>;
|
|
26
|
+
export {};
|
|
12
27
|
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/update-check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/update-check.ts"],"names":[],"mappings":"AAYA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAShF,eAAO,MAAM,mBAAmB,gDAAgD,CAAC;AACjF,eAAO,MAAM,sBAAsB,oCAAoC,CAAC;AAUxE,UAAU,mBAAmB;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,qBAAqB,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,GAAG,eAAe,CAAC,CAAC;AAC1F,KAAK,kBAAkB,GAAG,CACxB,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC3C,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAWD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQxE;AAED,wBAAgB,UAAU,IAAI,OAAO,CAMpC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,GAAE;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAGrD,GACA,MAAM,CAkBR;AA+BD,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
|
@@ -6,23 +6,29 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module cli/shared/update-check
|
|
8
8
|
*/
|
|
9
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
9
10
|
import { getEnv } from "../../src/platform/index.js";
|
|
10
11
|
import { createFileSystem } from "../../src/platform/index.js";
|
|
11
12
|
import { join } from "../../src/platform/compat/path/index.js";
|
|
12
13
|
import { getEnvironmentConfig } from "../../src/config/index.js";
|
|
13
14
|
import { isJsonMode } from "./json-output.js";
|
|
14
15
|
import { brand, dim, warning as warningColor } from "../ui/colors.js";
|
|
15
|
-
import { isQuiet } from "../utils/index.js";
|
|
16
|
+
import { cliLogger, isQuiet } from "../utils/index.js";
|
|
16
17
|
import { detectCI } from "./interactive.js";
|
|
17
18
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
export const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/veryfront/latest";
|
|
20
|
+
export const UPDATE_INSTALL_COMMAND = "npm install -g veryfront@latest";
|
|
21
|
+
const HOMEBREW_UPDATE_COMMAND = "brew upgrade veryfront/tap/veryfront";
|
|
22
|
+
const INSTALL_SCRIPT_COMMAND = "curl -fsSL https://veryfront.com/install.sh | sh";
|
|
23
|
+
const STABLE_SEMVER_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
24
|
+
class UpdateCheckFailure extends Error {
|
|
25
|
+
}
|
|
26
|
+
function getCacheLocation() {
|
|
21
27
|
const env = getEnvironmentConfig();
|
|
22
28
|
if (!env.homeDir)
|
|
23
29
|
return null;
|
|
24
|
-
const
|
|
25
|
-
return join(
|
|
30
|
+
const directory = join(env.homeDir, ".cache", "veryfront");
|
|
31
|
+
return { directory, file: join(directory, "update-check.json") };
|
|
26
32
|
}
|
|
27
33
|
export function compareVersions(current, latest) {
|
|
28
34
|
const c = current.split(".").map(Number);
|
|
@@ -46,54 +52,88 @@ export function shouldSkip() {
|
|
|
46
52
|
return true;
|
|
47
53
|
return false;
|
|
48
54
|
}
|
|
55
|
+
export function getUpdateInstallCommand(context = {
|
|
56
|
+
standalone: dntShim.Deno.build.standalone ?? false,
|
|
57
|
+
executablePath: dntShim.Deno.execPath(),
|
|
58
|
+
}) {
|
|
59
|
+
if (!context.standalone)
|
|
60
|
+
return UPDATE_INSTALL_COMMAND;
|
|
61
|
+
const executablePath = context.executablePath.replaceAll("\\", "/").toLowerCase();
|
|
62
|
+
if (executablePath.includes("/node_modules/veryfront/bin/")) {
|
|
63
|
+
return UPDATE_INSTALL_COMMAND;
|
|
64
|
+
}
|
|
65
|
+
if (executablePath.includes("/cellar/") ||
|
|
66
|
+
executablePath.includes("/homebrew/") ||
|
|
67
|
+
executablePath.includes("/linuxbrew/")) {
|
|
68
|
+
return HOMEBREW_UPDATE_COMMAND;
|
|
69
|
+
}
|
|
70
|
+
if (!executablePath.endsWith(".exe"))
|
|
71
|
+
return INSTALL_SCRIPT_COMMAND;
|
|
72
|
+
return UPDATE_INSTALL_COMMAND;
|
|
73
|
+
}
|
|
49
74
|
function printUpdateNotice(current, latest) {
|
|
50
75
|
console.error();
|
|
51
76
|
console.error(` ${warningColor("!")} Update available: ${current} → ${latest}`);
|
|
52
|
-
console.error(` ${dim("Run:")} ${brand(
|
|
77
|
+
console.error(` ${dim("Run:")} ${brand(getUpdateInstallCommand())}`);
|
|
53
78
|
console.error();
|
|
54
79
|
}
|
|
55
|
-
|
|
56
|
-
|
|
80
|
+
async function fetchLatestVersion(fetcher) {
|
|
81
|
+
const response = await fetcher(UPDATE_REGISTRY_URL);
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
await response.body?.cancel();
|
|
84
|
+
throw new UpdateCheckFailure(`Veryfront could not check for updates: npm registry returned ${response.status}.`);
|
|
85
|
+
}
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
const latestVersion = data && typeof data === "object" && "version" in data
|
|
88
|
+
? data.version
|
|
89
|
+
: undefined;
|
|
90
|
+
if (typeof latestVersion !== "string" || !STABLE_SEMVER_PATTERN.test(latestVersion)) {
|
|
91
|
+
throw new UpdateCheckFailure("Veryfront could not check for updates: npm registry returned an invalid version.");
|
|
92
|
+
}
|
|
93
|
+
return latestVersion;
|
|
94
|
+
}
|
|
95
|
+
export async function checkForUpdates(currentVersion, options = {}) {
|
|
96
|
+
if ((options.shouldSkip ?? shouldSkip)())
|
|
57
97
|
return;
|
|
58
|
-
const
|
|
59
|
-
|
|
98
|
+
const cacheLocation = options.cacheLocation === undefined
|
|
99
|
+
? getCacheLocation()
|
|
100
|
+
: options.cacheLocation;
|
|
101
|
+
if (!cacheLocation)
|
|
60
102
|
return;
|
|
61
|
-
const fs = createFileSystem();
|
|
103
|
+
const fs = options.fileSystem ?? createFileSystem();
|
|
104
|
+
const now = options.now ?? Date.now;
|
|
105
|
+
const notice = options.printNotice ?? printUpdateNotice;
|
|
106
|
+
const debug = options.debug ?? ((message) => cliLogger.debug(message));
|
|
62
107
|
try {
|
|
63
|
-
const raw = await fs.readTextFile(
|
|
108
|
+
const raw = await fs.readTextFile(cacheLocation.file);
|
|
64
109
|
const cache = JSON.parse(raw);
|
|
65
|
-
if (
|
|
110
|
+
if (now() - cache.lastCheck < CHECK_INTERVAL_MS) {
|
|
66
111
|
if (cache.latestVersion &&
|
|
67
112
|
compareVersions(currentVersion, cache.latestVersion)) {
|
|
68
|
-
|
|
113
|
+
notice(currentVersion, cache.latestVersion);
|
|
69
114
|
}
|
|
70
115
|
return;
|
|
71
116
|
}
|
|
72
117
|
}
|
|
73
118
|
catch {
|
|
74
|
-
// No cache
|
|
119
|
+
// No cache. Continue with the registry check.
|
|
75
120
|
}
|
|
76
121
|
try {
|
|
77
|
-
const
|
|
78
|
-
if (!resp.ok) {
|
|
79
|
-
await resp.body?.cancel();
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const data = await resp.json();
|
|
83
|
-
const latestVersion = data.latest;
|
|
84
|
-
if (!latestVersion)
|
|
85
|
-
return;
|
|
86
|
-
const env = getEnvironmentConfig();
|
|
87
|
-
if (!env.homeDir)
|
|
88
|
-
return;
|
|
89
|
-
const cacheDir = join(env.homeDir, ".cache", "veryfront");
|
|
90
|
-
await fs.mkdir(cacheDir, { recursive: true });
|
|
91
|
-
await fs.writeTextFile(cacheFile, JSON.stringify({ lastCheck: Date.now(), latestVersion }));
|
|
122
|
+
const latestVersion = await fetchLatestVersion(options.fetcher ?? fetch);
|
|
92
123
|
if (compareVersions(currentVersion, latestVersion)) {
|
|
93
|
-
|
|
124
|
+
notice(currentVersion, latestVersion);
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
await fs.mkdir(cacheLocation.directory, { recursive: true });
|
|
128
|
+
await fs.writeTextFile(cacheLocation.file, JSON.stringify({ lastCheck: now(), latestVersion }));
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
debug("Veryfront could not cache the update check.");
|
|
94
132
|
}
|
|
95
133
|
}
|
|
96
|
-
catch {
|
|
97
|
-
|
|
134
|
+
catch (error) {
|
|
135
|
+
debug(error instanceof UpdateCheckFailure
|
|
136
|
+
? error.message
|
|
137
|
+
: "Veryfront could not complete the update check.");
|
|
98
138
|
}
|
|
99
139
|
}
|
|
@@ -66,7 +66,7 @@ export default {
|
|
|
66
66
|
"globals.css": "@import \"tailwindcss\";\n",
|
|
67
67
|
"globals.d.ts": "declare module \"*.css\";\n",
|
|
68
68
|
"public/favicon.svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n <rect width=\"64\" height=\"64\" fill=\"#fff\"/>\n <circle cx=\"32\" cy=\"32\" r=\"20\" fill=\"#000\"/>\n</svg>\n",
|
|
69
|
-
"README.md": "# Docs Agent\n\nA chatbot that answers questions from your own documents using Retrieval-Augmented Generation (RAG).\n\n## What's included\n\n- Q&A agent with source citation\n- Embedding-based semantic search with convention-based model selection\n- Document upload supporting PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and Markdown\n- `ragStore()` with local JSON storage by default, and Veryfront Cloud RAG when bootstrap is present\n- Veryfront Cloud AI Gateway routing for generation and embeddings when bootstrap is present\n- Original uploaded files stored in Veryfront Cloud project uploads when cloud bootstrap is present\n- Sample content in `/content` indexed through a dedicated ingestion route\n\n## Getting started\n\n1. Set your Veryfront Cloud bootstrap vars:\n\n ```bash\n export VERYFRONT_API_TOKEN=vf_...\n export VERYFRONT_PROJECT_SLUG=my-project\n ```\n\n2. Start the dev server:\n\n ```bash\n npx veryfront dev\n ```\n\n3. Index the sample docs in `content/`:\n\n ```bash\n curl -X POST http://localhost:3000/api/ingest\n ```\n\n4. Open the app and upload a document or ask a question.\n\nIf you are using a self-hosted Veryfront API, also set `VERYFRONT_API_URL`.\n\n## Cloud mode\n\nWith `VERYFRONT_API_TOKEN` and `VERYFRONT_PROJECT_SLUG` set, the template uses\nVeryfront Cloud automatically:\n\n- Agent generation routes through Veryfront Cloud model routing.\n- Query and document embeddings route through Veryfront Cloud embedding routing.\n- `veryfront-cloud/openai/...` and `veryfront-cloud/google/...` models use AI Gateway.\n- RAG documents, chunks, and embeddings are stored in the target project.\n\nThe default cloud embedding model is\n`veryfront-cloud/openai/text-embedding-3-small`. Set\n`VERYFRONT_DEFAULT_EMBEDDING_MODEL` only when you need a different embedding\nmodel.\n\n## Architecture\n\nRAG grounds LLM responses in your documents through three pipelines: **Ingestion**, **Query**, and **RAG**. These pipelines are orchestrated around a shared vector store.\n\n```mermaid\nflowchart LR\n ChatUI_L[\"Chat UI\"]\n\n subgraph IngestionFlow[\"Ingestion Pipeline\"]\n D[\"Documents\"] --> EXT[\"Extraction\"] --> DC[\"Chunking\"] --> DE[\"Document\\nEmbedding\"] --> ING[\"Storage\"]\n end\n\n subgraph QueryFlow[\"Query Pipeline\"]\n Q[\"Query\"] --> QE[\"Query\\nEmbedding\"] --> SS[\"Similarity\\nSearch\"]\n end\n\n subgraph RAGFlow[\"RAG Pipeline\"]\n BF[\"beforeStream\\nHook\"] --> RET[\"Retrieval\"] --> AUG[\"Augmentation\"] --> AG[\"Agent\"] --> GEN[\"Generation\"]\n end\n\n EMB((\"Embedding\\nModel\"))\n GEN_LLM((\"Generative\\nModel\"))\n VS[(\"Vector\\nStore\")]\n ChatUI_R[\"Chat UI\"]\n\n ChatUI_L --> D\n ChatUI_L --> Q\n\n QE -.- EMB\n DE -.- EMB\n\n SS --> VS\n ING --> VS\n\n Q --> BF\n VS --> RET\n AG -.- GEN_LLM\n GEN -.- GEN_LLM\n GEN --> ChatUI_R\n```\n\n### Pipelines\n\n**Ingestion**: Documents are parsed into plain text via the built-in kreuzberg extraction engine (supporting PDF, DOCX, XLSX, PPTX, HTML, RTF, EPUB, and 76+ formats), split into overlapping chunks (~1000 chars, 200 char overlap), and stored in the default `ragStore()`. In local mode that means `data/index.json`; with Veryfront Cloud bootstrap it upgrades to the cloud RAG backend automatically. The original uploaded binary is also stored in the project's Veryfront Cloud uploads store so remote projects retain the source file, not just the extracted text. Uploaded files are ingested by the upload route. Bundled files in `content/` are ingested by the `/api/ingest` route.\n\n**Query**: The user's query is embedded into the same vector space as the documents, then compared against all stored chunks using cosine similarity to find the top-*k* most relevant results.\n\n**RAG**: The `beforeStream` hook in the AG-UI route intercepts each message before it reaches the agent. It searches the document store for relevant chunks, assembles them into context, and prepends them as retrieved reference data. The agent then generates a cited response streamed back to the user.\n\n## Structure\n\n```\nstore.ts RAG store config\nagents/rag.ts Q&A agent with citation instructions\ncontent/\n getting-started.md Sample document\n architecture.md Sample document\napp/\n api/ag-ui/route.ts AG-UI endpoint\n api/ingest/route.ts Bundled content ingestion\n api/uploads/route.ts Upload, list, and delete uploads\n uploads/page.tsx Upload management panel\n page.tsx Chat UI\n layout.tsx Chat shell with sidebar and tabs\n```\n\n## Framework usage\n\n| What | Framework | Template code |\n|------|-----------|---------------|\n| Chat UI + streaming | app-mode `Chat` | `page.tsx` |\n| Upload management | `AttachmentsPanel`, `useUploadsRegistry` | `uploads/page.tsx` |\n| Source display | Built into the `Chat` preset | `page.tsx` |\n| Upload API route | `createUploadHandler` | 1 line in `route.ts` |\n| AG-UI route | `createAgUiHandler` | 1 line in `route.ts` |\n| Agent definition | `agent()` | Config object in `agents/rag.ts` |\n| RAG retrieval | `beforeStream` hook | Context injection in `api/ag-ui/route.ts` |\n| Vector store | `ragStore()` | Config in `store.ts` |\n\n## Adding documents\n\n- Drop files into `content/`, then run `curl -X POST http://localhost:3000/api/ingest`\n- Or use the upload panel in the UI for PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and MD files\n\n## Production notes\n\nThis is a starter template, not a production-ready setup. For production, consider:\n\n- **Vector store**: Replace the default store with pgvector, Pinecone, or Qdrant for datasets beyond ~10k chunks\n- **Reranking**: Add a cross-encoder reranker (e.g. Cohere Rerank) after retrieval to improve precision\n- **Hybrid search**: Combine dense vectors with BM25 keyword matching for better recall\n",
|
|
69
|
+
"README.md": "# Docs Agent\n\nA chatbot that answers questions from your own documents using Retrieval-Augmented Generation (RAG).\n\n## What's included\n\n- Q&A agent with source citation\n- Embedding-based semantic search with convention-based model selection\n- Document upload supporting PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and Markdown\n- `ragStore()` with local JSON storage by default, and Veryfront Cloud RAG when bootstrap is present\n- Veryfront Cloud AI Gateway routing for generation and embeddings when bootstrap is present\n- Original uploaded files stored in Veryfront Cloud project uploads when cloud bootstrap is present\n- Sample content in `/content` indexed through a dedicated ingestion route\n\n## Getting started\n\n1. Set your Veryfront Cloud bootstrap vars:\n\n ```bash\n export VERYFRONT_API_TOKEN=vf_...\n export VERYFRONT_PROJECT_SLUG=my-project\n ```\n\n2. Start the dev server:\n\n ```bash\n npx veryfront@latest dev\n ```\n\n3. Index the sample docs in `content/`:\n\n ```bash\n curl -X POST http://localhost:3000/api/ingest\n ```\n\n4. Open the app and upload a document or ask a question.\n\nIf you are using a self-hosted Veryfront API, also set `VERYFRONT_API_URL`.\n\n## Cloud mode\n\nWith `VERYFRONT_API_TOKEN` and `VERYFRONT_PROJECT_SLUG` set, the template uses\nVeryfront Cloud automatically:\n\n- Agent generation routes through Veryfront Cloud model routing.\n- Query and document embeddings route through Veryfront Cloud embedding routing.\n- `veryfront-cloud/openai/...` and `veryfront-cloud/google/...` models use AI Gateway.\n- RAG documents, chunks, and embeddings are stored in the target project.\n\nThe default cloud embedding model is\n`veryfront-cloud/openai/text-embedding-3-small`. Set\n`VERYFRONT_DEFAULT_EMBEDDING_MODEL` only when you need a different embedding\nmodel.\n\n## Architecture\n\nRAG grounds LLM responses in your documents through three pipelines: **Ingestion**, **Query**, and **RAG**. These pipelines are orchestrated around a shared vector store.\n\n```mermaid\nflowchart LR\n ChatUI_L[\"Chat UI\"]\n\n subgraph IngestionFlow[\"Ingestion Pipeline\"]\n D[\"Documents\"] --> EXT[\"Extraction\"] --> DC[\"Chunking\"] --> DE[\"Document\\nEmbedding\"] --> ING[\"Storage\"]\n end\n\n subgraph QueryFlow[\"Query Pipeline\"]\n Q[\"Query\"] --> QE[\"Query\\nEmbedding\"] --> SS[\"Similarity\\nSearch\"]\n end\n\n subgraph RAGFlow[\"RAG Pipeline\"]\n BF[\"beforeStream\\nHook\"] --> RET[\"Retrieval\"] --> AUG[\"Augmentation\"] --> AG[\"Agent\"] --> GEN[\"Generation\"]\n end\n\n EMB((\"Embedding\\nModel\"))\n GEN_LLM((\"Generative\\nModel\"))\n VS[(\"Vector\\nStore\")]\n ChatUI_R[\"Chat UI\"]\n\n ChatUI_L --> D\n ChatUI_L --> Q\n\n QE -.- EMB\n DE -.- EMB\n\n SS --> VS\n ING --> VS\n\n Q --> BF\n VS --> RET\n AG -.- GEN_LLM\n GEN -.- GEN_LLM\n GEN --> ChatUI_R\n```\n\n### Pipelines\n\n**Ingestion**: Documents are parsed into plain text via the built-in kreuzberg extraction engine (supporting PDF, DOCX, XLSX, PPTX, HTML, RTF, EPUB, and 76+ formats), split into overlapping chunks (~1000 chars, 200 char overlap), and stored in the default `ragStore()`. In local mode that means `data/index.json`; with Veryfront Cloud bootstrap it upgrades to the cloud RAG backend automatically. The original uploaded binary is also stored in the project's Veryfront Cloud uploads store so remote projects retain the source file, not just the extracted text. Uploaded files are ingested by the upload route. Bundled files in `content/` are ingested by the `/api/ingest` route.\n\n**Query**: The user's query is embedded into the same vector space as the documents, then compared against all stored chunks using cosine similarity to find the top-*k* most relevant results.\n\n**RAG**: The `beforeStream` hook in the AG-UI route intercepts each message before it reaches the agent. It searches the document store for relevant chunks, assembles them into context, and prepends them as retrieved reference data. The agent then generates a cited response streamed back to the user.\n\n## Structure\n\n```\nstore.ts RAG store config\nagents/rag.ts Q&A agent with citation instructions\ncontent/\n getting-started.md Sample document\n architecture.md Sample document\napp/\n api/ag-ui/route.ts AG-UI endpoint\n api/ingest/route.ts Bundled content ingestion\n api/uploads/route.ts Upload, list, and delete uploads\n uploads/page.tsx Upload management panel\n page.tsx Chat UI\n layout.tsx Chat shell with sidebar and tabs\n```\n\n## Framework usage\n\n| What | Framework | Template code |\n|------|-----------|---------------|\n| Chat UI + streaming | app-mode `Chat` | `page.tsx` |\n| Upload management | `AttachmentsPanel`, `useUploadsRegistry` | `uploads/page.tsx` |\n| Source display | Built into the `Chat` preset | `page.tsx` |\n| Upload API route | `createUploadHandler` | 1 line in `route.ts` |\n| AG-UI route | `createAgUiHandler` | 1 line in `route.ts` |\n| Agent definition | `agent()` | Config object in `agents/rag.ts` |\n| RAG retrieval | `beforeStream` hook | Context injection in `api/ag-ui/route.ts` |\n| Vector store | `ragStore()` | Config in `store.ts` |\n\n## Adding documents\n\n- Drop files into `content/`, then run `curl -X POST http://localhost:3000/api/ingest`\n- Or use the upload panel in the UI for PDF, DOCX, XLSX, PPTX, CSV, HTML, RTF, EPUB, TXT, and MD files\n\n## Production notes\n\nThis is a starter template, not a production-ready setup. For production, consider:\n\n- **Vector store**: Replace the default store with pgvector, Pinecone, or Qdrant for datasets beyond ~10k chunks\n- **Reranking**: Add a cross-encoder reranker (e.g. Cohere Rerank) after retrieval to improve precision\n- **Hybrid search**: Combine dense vectors with BM25 keyword matching for better recall\n",
|
|
70
70
|
"store.ts": "import { ragStore } from \"veryfront/embedding\";\n\nexport const store = ragStore({\n storagePath: \"data/index.json\",\n contentDir: \"content\",\n});\n",
|
|
71
71
|
"tsconfig.json": "{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"esModuleInterop\": true,\n \"noEmit\": true,\n \"allowImportingTsExtensions\": true,\n \"paths\": {\n \"@/*\": [\"./*\"],\n \"react-markdown@*\": [\"./node_modules/react-markdown\"],\n \"remark-gfm@*\": [\"./node_modules/remark-gfm\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
|
|
72
72
|
}
|
package/esm/deno.d.ts
CHANGED
package/esm/deno.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1226",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"minimumDependencyAge": {
|
|
@@ -463,6 +463,7 @@ export default {
|
|
|
463
463
|
"build": "deno task build:prepare && deno run -A scripts/build/compile-binary.ts --output ./bin/veryfront",
|
|
464
464
|
"build:proxy-lock": "deno cache --node-modules-dir=none --lock scripts/build/proxy-deno.lock cli/proxy-main.ts",
|
|
465
465
|
"build:npm": "deno run -A scripts/build/generate-integrations-module.ts && deno task generate && deno run --config=scripts/test.deno.json --frozen -A scripts/build/build-npm-dnt.ts",
|
|
466
|
+
"verify:dist": "deno task build && deno task build:npm",
|
|
466
467
|
"release": "deno run -A scripts/release.ts",
|
|
467
468
|
"test": "deno task generate && DENO_TESTING=1 VF_DISABLE_LRU_INTERVAL=1 SSR_TRANSFORM_PER_PROJECT_LIMIT=0 REVALIDATION_PER_PROJECT_LIMIT=0 NODE_ENV=production LOG_FORMAT=text deno test --preload=src/testing/preload.ts --no-check --parallel --allow-all '--ignore=tests/e2e,tests/integration/compiled-binary-e2e.test.ts,scripts' --unstable-worker-options --unstable-net",
|
|
468
469
|
"test:unit": "deno task generate && DENO_TESTING=1 VF_DISABLE_LRU_INTERVAL=1 SSR_TRANSFORM_PER_PROJECT_LIMIT=0 REVALIDATION_PER_PROJECT_LIMIT=0 NODE_ENV=production LOG_FORMAT=text deno test --preload=src/testing/preload.ts --no-check --parallel --allow-all --v8-flags=--max-old-space-size=8192 '--ignore=tests,src/workflow/__tests__' --unstable-worker-options --unstable-net $(find src cli -name '*.test.ts*' ! -name '*.integration.test.ts*')",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-tool-input.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-tool-input.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qCAAqC,UAAY,CAAC;AAC/D,eAAO,MAAM,yCAAyC,OAAQ,CAAC;AAE/D,MAAM,MAAM,8BAA8B,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,EACtC,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,GAAG,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"openai-tool-input.d.ts","sourceRoot":"","sources":["../../../../src/extensions/ext-llm-openai/src/openai-tool-input.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qCAAqC,UAAY,CAAC;AAC/D,eAAO,MAAM,yCAAyC,OAAQ,CAAC;AAE/D,MAAM,MAAM,8BAA8B,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,EACtC,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,GAAG,WAAW,GAAG,SAAS,CA+BnC;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAE/E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAOvD"}
|
|
@@ -2,18 +2,32 @@ export const MAX_OPENAI_STREAM_TOOL_ARGUMENT_BYTES = 1_048_576;
|
|
|
2
2
|
export const MAX_OPENAI_STREAM_TOOL_ARGUMENT_FRAGMENTS = 4_096;
|
|
3
3
|
const TOOL_ARGUMENT_ENCODER = new TextEncoder();
|
|
4
4
|
export function appendOpenAIStreamToolArgument(budget, chunks, fragment) {
|
|
5
|
-
if (budget.fragments >= MAX_OPENAI_STREAM_TOOL_ARGUMENT_FRAGMENTS) {
|
|
6
|
-
return "fragments";
|
|
7
|
-
}
|
|
8
5
|
const fragmentBytes = TOOL_ARGUMENT_ENCODER.encode(fragment).byteLength;
|
|
6
|
+
// Zero-byte fragments never advance the byte budget, so they are the only
|
|
7
|
+
// ones that can arrive without bound -- and they are what the fragment cap
|
|
8
|
+
// exists to stop. Both provider streams exercise it exactly that way, by
|
|
9
|
+
// flooding empty deltas.
|
|
10
|
+
//
|
|
11
|
+
// Counting non-empty fragments here too made the cap bind long before the
|
|
12
|
+
// byte budget: at typical delta sizes, 4096 fragments is roughly 2-8% of the
|
|
13
|
+
// 1 MiB a tool call is nominally allowed, which left the byte limit
|
|
14
|
+
// unreachable. Fragment count is chosen by the provider's tokenizer rather
|
|
15
|
+
// than by the caller, so the same tool call passed or failed depending on how
|
|
16
|
+
// the stream happened to be chunked.
|
|
17
|
+
if (fragmentBytes === 0) {
|
|
18
|
+
if (budget.fragments >= MAX_OPENAI_STREAM_TOOL_ARGUMENT_FRAGMENTS) {
|
|
19
|
+
return "fragments";
|
|
20
|
+
}
|
|
21
|
+
budget.fragments++;
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
9
24
|
if (fragmentBytes > MAX_OPENAI_STREAM_TOOL_ARGUMENT_BYTES - budget.bytes) {
|
|
10
25
|
return "bytes";
|
|
11
26
|
}
|
|
12
|
-
|
|
27
|
+
// Content is bounded by bytes: every fragment kept here is at least one byte,
|
|
28
|
+
// so the array cannot outgrow the byte budget.
|
|
13
29
|
budget.bytes += fragmentBytes;
|
|
14
|
-
|
|
15
|
-
chunks.push(fragment);
|
|
16
|
-
}
|
|
30
|
+
chunks.push(fragment);
|
|
17
31
|
return undefined;
|
|
18
32
|
}
|
|
19
33
|
export function joinOpenAIStreamToolArguments(chunks) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAGlB,KAAK,OAAO,EAIZ,KAAK,QAAQ,EAGd,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,7 @@ import { runWithRemoteIntegrationToolDiscoveryScope } from "../../integrations/r
|
|
|
38
38
|
import { prepareAgentRuntimeStep, withIntegrationToolDiscoveryStatus, } from "./agent-runtime-step.js";
|
|
39
39
|
import { buildStreamedAssistantMessage } from "./streamed-assistant-message.js";
|
|
40
40
|
import { flattenSystemInstructions, hasRuntimeToolInventory, withRuntimeToolInventory, } from "./tool-inventory.js";
|
|
41
|
+
import { captureAgentRunRuntimeContext, withAgentRunRuntimeContext, withAgentRunRuntimeContextMetadata, } from "./run-runtime-context.js";
|
|
41
42
|
// Re-export from submodules
|
|
42
43
|
export { closeSSEStream, generateMessageId, sendSSE } from "./sse-utils.js";
|
|
43
44
|
export { RunAlreadyExistsError, RunCancelledError, RunNotActiveError, RunResumeSessionManager, WaitConflictError, WaitNotPendingError, } from "./resume-session.js";
|
|
@@ -488,6 +489,7 @@ export class AgentRuntime {
|
|
|
488
489
|
*/
|
|
489
490
|
async generate(input, context, modelOverride, maxOutputTokensOverride, abortSignal, options) {
|
|
490
491
|
throwIfAborted(abortSignal);
|
|
492
|
+
const runRuntimeContext = captureAgentRunRuntimeContext();
|
|
491
493
|
const transport = await this.resolveModelTransport(context, modelOverride, "generate");
|
|
492
494
|
const requestedModel = transport.requestedModel;
|
|
493
495
|
const resolvedModelString = transport.resolvedModelString;
|
|
@@ -497,6 +499,8 @@ export class AgentRuntime {
|
|
|
497
499
|
setSpanAttributes(span, {
|
|
498
500
|
"agent.id": this.id,
|
|
499
501
|
"agent.model": resolvedModelString,
|
|
502
|
+
"run.started_at_utc": runRuntimeContext.runStartedAtUtc,
|
|
503
|
+
"run.current_date_utc": runRuntimeContext.currentDateUtc,
|
|
500
504
|
});
|
|
501
505
|
const inputMessages = normalizeInput(input);
|
|
502
506
|
const messages = await this.prepareTurnMessages(inputMessages);
|
|
@@ -512,7 +516,7 @@ export class AgentRuntime {
|
|
|
512
516
|
return chain.execute(agentContext, () => runWithRemoteIntegrationToolDiscoveryScope(() => this.executeAgentLoop(systemPrompt, messages, {
|
|
513
517
|
agentId: this.id,
|
|
514
518
|
projectId: tryGetCacheKeyContext()?.projectId,
|
|
515
|
-
}, context, supportsToolCalling, resolvedModelString, transport.languageModel, transport.headers, transport.providerOptions, transport.reasoning, maxOutputTokensOverride, requestedModel, this.createGenerateReplacementTools(options?.toolReplacements, options?.retainSkillLoaderTools), abortSignal)));
|
|
519
|
+
}, context, runRuntimeContext, supportsToolCalling, resolvedModelString, transport.languageModel, transport.headers, transport.providerOptions, transport.reasoning, maxOutputTokensOverride, requestedModel, this.createGenerateReplacementTools(options?.toolReplacements, options?.retainSkillLoaderTools), abortSignal)));
|
|
516
520
|
});
|
|
517
521
|
}
|
|
518
522
|
/**
|
|
@@ -520,6 +524,11 @@ export class AgentRuntime {
|
|
|
520
524
|
* Returns a ReadableStream in the veryfront stream event format.
|
|
521
525
|
*/
|
|
522
526
|
async stream(messages, context, callbacks, modelOverride, maxOutputTokensOverride, abortSignal) {
|
|
527
|
+
const runRuntimeContext = captureAgentRunRuntimeContext();
|
|
528
|
+
setOtelActiveSpanAttributes({
|
|
529
|
+
"run.started_at_utc": runRuntimeContext.runStartedAtUtc,
|
|
530
|
+
"run.current_date_utc": runRuntimeContext.currentDateUtc,
|
|
531
|
+
});
|
|
523
532
|
const transport = await this.resolveModelTransport(context, modelOverride, "stream");
|
|
524
533
|
const requestedModel = transport.requestedModel;
|
|
525
534
|
const resolvedModelString = transport.resolvedModelString;
|
|
@@ -593,7 +602,11 @@ export class AgentRuntime {
|
|
|
593
602
|
model: resolvedModelString,
|
|
594
603
|
},
|
|
595
604
|
});
|
|
596
|
-
|
|
605
|
+
sendSSE(controller, encoder, {
|
|
606
|
+
type: "data-veryfront.runtime_context",
|
|
607
|
+
data: runRuntimeContext,
|
|
608
|
+
});
|
|
609
|
+
inFlight = chain.execute(agentContext, () => runWithRemoteIntegrationToolDiscoveryScope(() => this.executeAgentLoopStreaming(systemPrompt, memoryMessages, controller, encoder, callbacks, textPartId, toolContext, context, runRuntimeContext, supportsToolCalling, resolvedModelString, languageModel, transport.headers, transport.providerOptions, transport.reasoning, maxOutputTokensOverride, streamAbortSignal, requestedModel)));
|
|
597
610
|
const response = await inFlight;
|
|
598
611
|
throwIfAborted(streamAbortSignal);
|
|
599
612
|
callbacks?.onFinish?.(response);
|
|
@@ -644,7 +657,7 @@ export class AgentRuntime {
|
|
|
644
657
|
/**
|
|
645
658
|
* Execute agent loop (with tool calling)
|
|
646
659
|
*/
|
|
647
|
-
async executeAgentLoop(systemPrompt, messages, toolContextBase, runtimeContext, supportsToolCalling, modelString, resolvedModel, headers, providerOptions, reasoning, maxOutputTokensOverride, temperatureModelString, toolReplacements, abortSignal) {
|
|
660
|
+
async executeAgentLoop(systemPrompt, messages, toolContextBase, runtimeContext, runRuntimeContext, supportsToolCalling, modelString, resolvedModel, headers, providerOptions, reasoning, maxOutputTokensOverride, temperatureModelString, toolReplacements, abortSignal) {
|
|
648
661
|
return withSpan("agent.execution_loop", async (loopSpan) => {
|
|
649
662
|
const { maxAgentSteps } = getPlatformCapabilities();
|
|
650
663
|
const maxSteps = this.computeMaxSteps(maxAgentSteps);
|
|
@@ -774,9 +787,10 @@ export class AgentRuntime {
|
|
|
774
787
|
"model.id": effectiveModel,
|
|
775
788
|
"messages.count": currentMessages.length,
|
|
776
789
|
});
|
|
790
|
+
const providerSystemPrompt = withAgentRunRuntimeContext(currentSystemPrompt, runRuntimeContext);
|
|
777
791
|
const result = await generateText({
|
|
778
792
|
model: languageModel,
|
|
779
|
-
system:
|
|
793
|
+
system: providerSystemPrompt,
|
|
780
794
|
messages: convertToTextGenerationRuntimeRequestMessages(currentMessages),
|
|
781
795
|
tools: runtimeTools,
|
|
782
796
|
experimental_repairToolCall: repairToolCall,
|
|
@@ -871,7 +885,7 @@ export class AgentRuntime {
|
|
|
871
885
|
toolCalls,
|
|
872
886
|
status: this.status,
|
|
873
887
|
usage: totalUsage,
|
|
874
|
-
metadata: response.finishReason ? { finishReason: response.finishReason } : undefined,
|
|
888
|
+
metadata: withAgentRunRuntimeContextMetadata(runRuntimeContext, response.finishReason ? { finishReason: response.finishReason } : undefined),
|
|
875
889
|
};
|
|
876
890
|
}
|
|
877
891
|
this.status = "tool_execution";
|
|
@@ -1141,7 +1155,9 @@ export class AgentRuntime {
|
|
|
1141
1155
|
toolCalls,
|
|
1142
1156
|
status: this.status,
|
|
1143
1157
|
usage: totalUsage,
|
|
1144
|
-
metadata:
|
|
1158
|
+
metadata: withAgentRunRuntimeContextMetadata(runRuntimeContext, {
|
|
1159
|
+
warning: `Max steps (${maxSteps}) reached`,
|
|
1160
|
+
}),
|
|
1145
1161
|
};
|
|
1146
1162
|
});
|
|
1147
1163
|
}
|
|
@@ -1150,7 +1166,7 @@ export class AgentRuntime {
|
|
|
1150
1166
|
* Emits veryfront stream events (message-start/message-finish + step-start/step-end)
|
|
1151
1167
|
* while consuming model-runtime `streamText()` parts internally.
|
|
1152
1168
|
*/
|
|
1153
|
-
async executeAgentLoopStreaming(systemPrompt, messages, controller, encoder, callbacks, textPartId, toolContextBase, runtimeContext, supportsToolCalling, modelString, resolvedModel, headers, providerOptions, reasoning, maxOutputTokensOverride, abortSignal, temperatureModelString) {
|
|
1169
|
+
async executeAgentLoopStreaming(systemPrompt, messages, controller, encoder, callbacks, textPartId, toolContextBase, runtimeContext, runRuntimeContext, supportsToolCalling, modelString, resolvedModel, headers, providerOptions, reasoning, maxOutputTokensOverride, abortSignal, temperatureModelString) {
|
|
1154
1170
|
const { maxAgentSteps } = getPlatformCapabilities();
|
|
1155
1171
|
const maxSteps = this.computeMaxSteps(maxAgentSteps);
|
|
1156
1172
|
const effectiveModel = resolveRuntimeModel(modelString || this.config.model);
|
|
@@ -1247,9 +1263,10 @@ export class AgentRuntime {
|
|
|
1247
1263
|
const temperature = this.resolveTemperature(temperatureModelString ?? effectiveModel, providerOptions);
|
|
1248
1264
|
const maxOutputTokens = this.resolveMaxOutputTokens(effectiveModel, maxOutputTokensOverride);
|
|
1249
1265
|
const genAiProviderName = resolveRuntimeGenAiProviderName(effectiveModel);
|
|
1266
|
+
const providerSystemPrompt = withAgentRunRuntimeContext(currentSystemPrompt, runRuntimeContext);
|
|
1250
1267
|
const streamSource = createRuntimeStreamSource((streamSignal) => streamText({
|
|
1251
1268
|
model: languageModel,
|
|
1252
|
-
system:
|
|
1269
|
+
system: providerSystemPrompt,
|
|
1253
1270
|
messages: convertToTextGenerationRuntimeRequestMessages(currentMessages),
|
|
1254
1271
|
tools: runtimeTools,
|
|
1255
1272
|
experimental_repairToolCall: repairToolCall,
|
|
@@ -1626,7 +1643,7 @@ export class AgentRuntime {
|
|
|
1626
1643
|
toolCalls,
|
|
1627
1644
|
status: "completed",
|
|
1628
1645
|
usage: totalUsage,
|
|
1629
|
-
metadata: finalFinishReason ? { finishReason: finalFinishReason } : undefined,
|
|
1646
|
+
metadata: withAgentRunRuntimeContextMetadata(runRuntimeContext, finalFinishReason ? { finishReason: finalFinishReason } : undefined),
|
|
1630
1647
|
};
|
|
1631
1648
|
}
|
|
1632
1649
|
/**
|