veryfront 0.1.998 → 0.1.1001

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.
Files changed (35) hide show
  1. package/esm/cli/commands/pull/command.d.ts.map +1 -1
  2. package/esm/cli/commands/pull/command.js +5 -3
  3. package/esm/cli/commands/up/command.d.ts.map +1 -1
  4. package/esm/cli/commands/up/command.js +4 -3
  5. package/esm/cli/shared/config.d.ts.map +1 -1
  6. package/esm/cli/shared/config.js +22 -10
  7. package/esm/cli/shared/constants.d.ts +1 -0
  8. package/esm/cli/shared/constants.d.ts.map +1 -1
  9. package/esm/cli/shared/constants.js +16 -1
  10. package/esm/cli/templates/manifest.d.ts +1 -1
  11. package/esm/cli/templates/manifest.js +15 -15
  12. package/esm/deno.js +1 -1
  13. package/esm/src/discovery/transpiler.d.ts.map +1 -1
  14. package/esm/src/discovery/transpiler.js +6 -1
  15. package/esm/src/embedding/index.d.ts +0 -2
  16. package/esm/src/embedding/index.d.ts.map +1 -1
  17. package/esm/src/embedding/index.js +0 -1
  18. package/esm/src/embedding/upload-handler.d.ts +2 -13
  19. package/esm/src/embedding/upload-handler.d.ts.map +1 -1
  20. package/esm/src/embedding/upload-handler.js +24 -17
  21. package/esm/src/internal-agents/run-stream.d.ts +1 -0
  22. package/esm/src/internal-agents/run-stream.d.ts.map +1 -1
  23. package/esm/src/internal-agents/run-stream.js +5 -1
  24. package/esm/src/modules/import-map/default-import-map.d.ts.map +1 -1
  25. package/esm/src/modules/import-map/default-import-map.js +0 -5
  26. package/esm/src/server/handlers/request/agent-stream.handler.d.ts +1 -0
  27. package/esm/src/server/handlers/request/agent-stream.handler.d.ts.map +1 -1
  28. package/esm/src/server/handlers/request/agent-stream.handler.js +4 -0
  29. package/esm/src/utils/version-constant.d.ts +1 -1
  30. package/esm/src/utils/version-constant.d.ts.map +1 -1
  31. package/esm/src/utils/version-constant.js +1 -1
  32. package/package.json +1 -1
  33. package/esm/src/embedding/react/use-uploads.d.ts +0 -33
  34. package/esm/src/embedding/react/use-uploads.d.ts.map +0 -1
  35. package/esm/src/embedding/react/use-uploads.js +0 -76
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAK3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAOhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;GAY7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;GAUxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA2CD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAQjB;AA8ID;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGpE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/pull/command.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAM3E,OAAO,EACL,eAAe,EAIhB,MAAM,wBAAwB,CAAC;AAOhC;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;GAY7B,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;GAAgC,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;GAUxB,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAKlE;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA2CD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWjF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAoBxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAmBjG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EAC1C,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,CAAC,CAQjB;AA8ID;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuGpE"}
@@ -9,12 +9,13 @@
9
9
  import { defineSchema, lazySchema } from "../../../src/schemas/index.js";
10
10
  import { dirname, join, normalize, resolve } from "../../../src/platform/compat/path/index.js";
11
11
  import { cliLogger } from "../../utils/index.js";
12
+ import { resolveCliApiUrl } from "../../shared/constants.js";
12
13
  import { cwd } from "../../../src/platform/index.js";
13
14
  import { createFileSystem } from "../../../src/platform/index.js";
14
15
  import { createApiClient, readConfigFile, resolveConfigWithAuth, } from "../../shared/config.js";
15
16
  import { confirmPrompt, logInfo, logSuccess, logWarning } from "../../utils/index.js";
16
17
  import { createNoopSpinner, createSpinner } from "../../ui/index.js";
17
- import { getApiTokenEnv } from "../../../src/config/index.js";
18
+ import { getApiTokenEnv, getEnvironmentConfig } from "../../../src/config/index.js";
18
19
  import { withSpan } from "../../../src/observability/tracing/otlp-setup.js";
19
20
  import { CommonArgs, createArgParser } from "../../shared/args.js";
20
21
  /**
@@ -268,12 +269,13 @@ export function pullCommand(options = {}) {
268
269
  spinner.stop();
269
270
  if (!projects?.length)
270
271
  throw error;
271
- const token = getApiTokenEnv() ?? configFile?.apiToken;
272
+ const env = getEnvironmentConfig();
273
+ const token = getApiTokenEnv(env) ?? configFile?.apiToken;
272
274
  if (!token) {
273
275
  throw new Error("VERYFRONT_API_TOKEN environment variable or apiToken in veryfront.json is required when using --projects");
274
276
  }
275
277
  config = {
276
- apiUrl: configFile?.apiUrl ?? "https://api.veryfront.com",
278
+ apiUrl: resolveCliApiUrl(env, configFile?.apiUrl),
277
279
  apiToken: token,
278
280
  projectSlug: "",
279
281
  };
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/up/command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAO3E,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,8BAA8B,CAAC;AAQ5F,eAAO,MAAM,eAAe;;;GAK3B,CAAC;AAEF,eAAO,MAAM,YAAY;;;GAA8B,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC;AAExE,eAAO,MAAM,WAAW;;;GAGtB,CAAC;AAyEH,wBAAsB,SAAS,CAC7B,OAAO,GAAE,OAAO,CAAC,SAAS,CAAM,EAChC,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,IAAI,CAAC,CA+Gf"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/up/command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAO3E,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,8BAA8B,CAAC;AAS5F,eAAO,MAAM,eAAe;;;GAK3B,CAAC;AAEF,eAAO,MAAM,YAAY;;;GAA8B,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC;AAExE,eAAO,MAAM,WAAW;;;GAGtB,CAAC;AAyEH,wBAAsB,SAAS,CAC7B,OAAO,GAAE,OAAO,CAAC,SAAS,CAAM,EAChC,GAAG,GAAE,iBAA0C,GAC9C,OAAO,CAAC,IAAI,CAAC,CA+Gf"}
@@ -10,6 +10,7 @@ import { createSpinner, shouldUseColor } from "../../ui/index.js";
10
10
  import { isTTY, promptUser } from "../../utils/index.js";
11
11
  import { CommonArgs, createArgParser } from "../../shared/args.js";
12
12
  import { readConfigFile } from "../../shared/config.js";
13
+ import { resolveCliApiUrl } from "../../shared/constants.js";
13
14
  import { pushCommand } from "../push/index.js";
14
15
  import { deployCommand } from "../deploy/index.js";
15
16
  export const getUpArgsSchema = defineSchema((v) => v.object({
@@ -77,7 +78,7 @@ export async function upCommand(options = {}, env = getEnvironmentConfig()) {
77
78
  const useColor = shouldUseColor();
78
79
  const c = (fn, s) => (useColor ? fn(s) : s);
79
80
  const projectDir = cwd();
80
- const userInfo = await ensureAuthenticated();
81
+ const userInfo = await ensureAuthenticated(env);
81
82
  if (!userInfo)
82
83
  return;
83
84
  const spinner = createSpinner("Analyzing project...");
@@ -114,8 +115,8 @@ export async function upCommand(options = {}, env = getEnvironmentConfig()) {
114
115
  else {
115
116
  const projectSpinner = createSpinner(`Creating project "${slug}"...`);
116
117
  try {
117
- const apiUrl = env.apiUrl ?? "https://api.veryfront.com";
118
- const resolvedToken = env.apiToken ?? (await readToken());
118
+ const apiUrl = resolveCliApiUrl(env);
119
+ const resolvedToken = env.apiToken ?? (await readToken(env));
119
120
  if (!resolvedToken) {
120
121
  projectSpinner.stop();
121
122
  cliLogger.error("Not authenticated");
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/config.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAGxE,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AA6BzF,eAAO,MAAM,wBAAwB;;IAGjC,mDAAmD;;;;GAKtD,CAAC;AACF,eAAO,MAAM,qBAAqB;;IAN9B,mDAAmD;;;;GAMkB,CAAC;AAC1E,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC;AAEvF,eAAO,MAAM,uBAAuB;;;;GAMnC,CAAC;AACF,eAAO,MAAM,oBAAoB;;;;GAAsC,CAAC;AACxE,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC;AAErF,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA6BxF;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatF;AA4ED,eAAO,MAAM,aAAa,gBAJH,MAAM,QAAQ,iBAAiB,KAAG,OAAO,CAAC,cAAc,CAIvB,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,gBAZX,MAAM,QAAQ,iBAAiB,KAAG,OAAO,CAAC,cAAc,CAYhB,CAAC;AAUhE,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,iBAAiB;;;;GAM7B,CAAC;AACF,eAAO,MAAM,cAAc;;;;GAAgC,CAAC;AAC5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CA+GjE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/config.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAGxE,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AA6BzF,eAAO,MAAM,wBAAwB;;IAGjC,mDAAmD;;;;GAKtD,CAAC;AACF,eAAO,MAAM,qBAAqB;;IAN9B,mDAAmD;;;;GAMkB,CAAC;AAC1E,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC;AAEvF,eAAO,MAAM,uBAAuB;;;;GAMnC,CAAC;AACF,eAAO,MAAM,oBAAoB;;;;GAAsC,CAAC;AACxE,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,CAAC;AAErF,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA2CxF;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatF;AA4ED,eAAO,MAAM,aAAa,gBAJH,MAAM,QAAQ,iBAAiB,KAAG,OAAO,CAAC,cAAc,CAIvB,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,gBAZX,MAAM,QAAQ,iBAAiB,KAAG,OAAO,CAAC,cAAc,CAYhB,CAAC;AAUhE,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrC;AAED,eAAO,MAAM,iBAAiB;;;;GAM7B,CAAC;AACF,eAAO,MAAM,cAAc;;;;GAAgC,CAAC;AAC5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC;AAEzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CA+GjE"}
@@ -12,7 +12,7 @@ import { getEnvironmentConfig } from "../../src/config/index.js";
12
12
  import { cliLogger, VERSION } from "../utils/index.js";
13
13
  import { readToken } from "../auth/token-store.js";
14
14
  import { ensureAuthenticated } from "../auth/login.js";
15
- import { DEFAULT_API_URL } from "./constants.js";
15
+ import { resolveCliApiUrl } from "./constants.js";
16
16
  import { isRetryableConnectionError } from "../../src/proxy/retry.js";
17
17
  // Delays for exponential backoff with jitter: attempt 1 = ~300ms, 2 = ~1s, 3 = ~3s
18
18
  const API_RETRY_DELAYS_MS = [300, 1000, 3000];
@@ -49,6 +49,7 @@ export const getResolvedConfigSchema = defineSchema((v) => v.object({
49
49
  export const ResolvedConfigSchema = lazySchema(getResolvedConfigSchema);
50
50
  export async function readConfigFile(projectDir) {
51
51
  const fs = createFileSystem();
52
+ let moduleProjectSlug;
52
53
  for (const ext of [".ts", ".js"]) {
53
54
  const configPath = join(projectDir, `veryfront.config${ext}`);
54
55
  try {
@@ -56,25 +57,36 @@ export async function readConfigFile(projectDir) {
56
57
  continue;
57
58
  const module = await import(`file://${configPath}`);
58
59
  const config = module.default ?? module;
59
- if (config?.projectSlug)
60
- return { projectSlug: config.projectSlug };
60
+ if (config?.projectSlug) {
61
+ moduleProjectSlug = config.projectSlug;
62
+ break;
63
+ }
61
64
  }
62
65
  catch (error) {
63
66
  cliLogger.debug(`Failed to import config file ${configPath}:`, error);
64
67
  }
65
68
  }
69
+ // veryfront.json is always merged in: veryfront.config.ts owns the
70
+ // projectSlug when both define one, but apiUrl/apiToken only live in
71
+ // veryfront.json and must not be dropped because a TS config exists.
66
72
  const configJsonPath = join(projectDir, "veryfront.json");
73
+ let jsonConfig = null;
67
74
  try {
68
- if (!(await fs.exists(configJsonPath)))
69
- return null;
70
- const content = await fs.readTextFile(configJsonPath);
71
- const parsed = VeryfrontConfigSchema.safeParse(JSON.parse(content));
72
- return parsed.success ? parsed.data : null;
75
+ if (await fs.exists(configJsonPath)) {
76
+ const content = await fs.readTextFile(configJsonPath);
77
+ const parsed = VeryfrontConfigSchema.safeParse(JSON.parse(content));
78
+ jsonConfig = parsed.success ? parsed.data : null;
79
+ }
73
80
  }
74
81
  catch (error) {
75
82
  cliLogger.debug(`Failed to read veryfront.json:`, error);
76
- return null;
77
83
  }
84
+ if (!moduleProjectSlug && !jsonConfig)
85
+ return null;
86
+ return {
87
+ ...jsonConfig,
88
+ ...(moduleProjectSlug ? { projectSlug: moduleProjectSlug } : {}),
89
+ };
78
90
  }
79
91
  export async function writeProjectSlug(projectDir, slug) {
80
92
  const fs = createFileSystem();
@@ -121,7 +133,7 @@ function resolveTenantProjectReference() {
121
133
  async function resolveConfigBase(projectDir, env, interactive) {
122
134
  const dir = projectDir ?? cwd();
123
135
  const configFile = await readConfigFile(dir);
124
- const apiUrl = env.apiUrl ?? configFile?.apiUrl ?? DEFAULT_API_URL;
136
+ const apiUrl = resolveCliApiUrl(env, configFile?.apiUrl);
125
137
  let apiToken = env.apiToken ?? configFile?.apiToken ?? (await readToken(env));
126
138
  if (!apiToken && interactive) {
127
139
  const userInfo = await ensureAuthenticated(env);
@@ -12,6 +12,7 @@ export declare const DEFAULT_CALLBACK_PORT = 9876;
12
12
  export declare const MAX_PORT_ATTEMPTS = 100;
13
13
  export declare const DEFAULT_API_URL = "https://api.veryfront.com";
14
14
  export declare const DEFAULT_LOCAL_API_URL = "https://api.veryfront.com";
15
+ export declare function resolveCliApiUrl(env?: EnvironmentConfig, configApiUrl?: string): string;
15
16
  export declare function getApiUrl(env?: EnvironmentConfig): string;
16
17
  export declare const DEFAULT_LOGIN_TIMEOUT_MS = 120000;
17
18
  export declare const SHUTDOWN_TIMEOUT_MS = 3000;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AAEzF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAC3E,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,eAAO,MAAM,eAAe,8BAA8B,CAAC;AAC3D,eAAO,MAAM,qBAAqB,8BAA8B,CAAC;AAEjE,wBAAgB,SAAS,CAAC,GAAG,GAAE,iBAA0C,GAAG,MAAM,CAEjF;AAED,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAChD,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AAExC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,sBAAsB,MAAQ,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AAEzF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAC3E,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,eAAO,MAAM,eAAe,8BAA8B,CAAC;AAC3D,eAAO,MAAM,qBAAqB,8BAA8B,CAAC;AAOjE,wBAAgB,gBAAgB,CAC9B,GAAG,GAAE,iBAA0C,EAC/C,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CASR;AAED,wBAAgB,SAAS,CAAC,GAAG,GAAE,iBAA0C,GAAG,MAAM,CAEjF;AAED,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAChD,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AAExC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,sBAAsB,MAAQ,CAAC"}
@@ -12,8 +12,23 @@ export const DEFAULT_CALLBACK_PORT = 9876;
12
12
  export const MAX_PORT_ATTEMPTS = 100;
13
13
  export const DEFAULT_API_URL = "https://api.veryfront.com";
14
14
  export const DEFAULT_LOCAL_API_URL = "https://api.veryfront.com";
15
+ function getExplicitApiBaseUrl(env) {
16
+ if (!env.apiBaseUrl || env.apiBaseUrl === DEFAULT_API_URL)
17
+ return undefined;
18
+ return env.apiBaseUrl;
19
+ }
20
+ export function resolveCliApiUrl(env = getEnvironmentConfig(), configApiUrl) {
21
+ // VERYFRONT_API_URL wins. A non-default VERYFRONT_API_BASE_URL is an
22
+ // operator override, so it wins over a checked-in veryfront.json apiUrl.
23
+ // The default production apiBaseUrl stays below project config.
24
+ return env.apiUrl ??
25
+ getExplicitApiBaseUrl(env) ??
26
+ configApiUrl ??
27
+ env.apiBaseUrl ??
28
+ DEFAULT_API_URL;
29
+ }
15
30
  export function getApiUrl(env = getEnvironmentConfig()) {
16
- return env.apiUrl ?? DEFAULT_API_URL;
31
+ return resolveCliApiUrl(env);
17
32
  }
18
33
  export const DEFAULT_LOGIN_TIMEOUT_MS = 120_000;
19
34
  export const SHUTDOWN_TIMEOUT_MS = 3_000;
@@ -50,10 +50,10 @@ declare namespace _default {
50
50
  "agents/rag.ts": string;
51
51
  "app/api/ag-ui/route.ts": string;
52
52
  "app/api/ingest/route.ts": string;
53
- "app/api/uploads/[id]/route.ts": string;
54
53
  "app/api/uploads/route.ts": string;
55
54
  "app/layout.tsx": string;
56
55
  "app/page.tsx": string;
56
+ "app/uploads/page.tsx": string;
57
57
  "content/architecture.md": string;
58
58
  "content/getting-started.md": string;
59
59
  "globals.css": string;
@@ -21,22 +21,22 @@ export default {
21
21
  },
22
22
  "ai-agent": {
23
23
  "files": {
24
- "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n system: \"You are a helpful assistant. Answer questions clearly and concisely.\",\n tools: true,\n maxSteps: 10,\n});\n",
24
+ "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n name: \"AI Agent\",\n description: \"Ask questions and use tools.\",\n system: \"You are a helpful assistant. Answer questions clearly and concisely.\",\n tools: true,\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Draft a plan\",\n prompt: \"Help me make a concise plan for \",\n },\n {\n type: \"prompt\",\n title: \"Explain a topic\",\n prompt: \"Explain this clearly: \",\n },\n ],\n },\n});\n",
25
25
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"assistant\");\n",
26
26
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI Chat</title>\n </Head>\n <div className=\"flex flex-col h-screen bg-white dark:bg-neutral-900\">\n {children}\n </div>\n </>\n );\n}\n",
27
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function ChatPage(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Message\" />\n}\n",
27
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function ChatPage(): React.JSX.Element {\n return <Chat agentId=\"assistant\" api=\"/api/ag-ui\" className=\"flex-1 min-h-0\" placeholder=\"Message\" />\n}\n",
28
28
  "globals.css": "@import \"tailwindcss\";\n",
29
- "README.md": "# AI Agent\n\nA simple conversational AI with tool support.\n\n## What's included\n\n- Single assistant agent with streaming chat UI\n- Example calculator tool\n- `useChat` hook for real-time responses\n\n## Structure\n\n```\nagents/assistant.ts Agent definition\ntools/calculator.ts Example tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
29
+ "README.md": "# AI Agent\n\nA simple conversational AI with tool support.\n\n## What's included\n\n- Single assistant agent with streaming chat UI\n- Example calculator tool\n- App-mode `Chat` component for real-time responses\n\n## Structure\n\n```\nagents/assistant.ts Agent definition\ntools/calculator.ts Example tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
30
30
  "tools/calculator.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\n\nexport default tool({\n id: \"calculator\",\n description: \"Perform basic arithmetic operations\",\n inputSchema: defineSchema((v) => v.object({\n operation: v.enum([\"add\", \"subtract\", \"multiply\", \"divide\"]),\n a: v.number(),\n b: v.number(),\n }))(),\n execute: ({ operation, a, b }) => {\n if (operation === \"divide\" && b === 0) {\n throw new Error(\"Cannot divide by zero\");\n }\n\n if (operation === \"add\") return { result: a + b };\n if (operation === \"subtract\") return { result: a - b };\n if (operation === \"multiply\") return { result: a * b };\n return { result: a / b };\n },\n});\n",
31
31
  "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 \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
32
32
  }
33
33
  },
34
34
  "coding-agent": {
35
35
  "files": {
36
- "agents/coder.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"coder\",\n system: `You are an expert coding assistant. You can read, search, and modify code files in the project.\n\nWhen asked to make changes:\n1. First read the relevant files to understand the codebase\n2. Explain what you'll change and why\n3. Make the changes\n4. Verify the result\n\nAlways explain your reasoning before making edits.`,\n tools: true,\n maxSteps: 15,\n});\n",
36
+ "agents/coder.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"coder\",\n name: \"Code Agent\",\n description: \"Read, search, and edit project files.\",\n system: `You are an expert coding assistant. You can read, search, and modify code files in the project.\n\nWhen asked to make changes:\n1. First read the relevant files to understand the codebase\n2. Explain what you'll change and why\n3. Make the changes\n4. Verify the result\n\nAlways explain your reasoning before making edits.`,\n tools: true,\n maxSteps: 15,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Explain the codebase\",\n prompt: \"Explain how this project is organized.\",\n },\n {\n type: \"prompt\",\n title: \"Make a change\",\n prompt: \"Make this code change: \",\n },\n ],\n },\n});\n",
37
37
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"coder\");\n",
38
38
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>Code Agent</title>\n </Head>\n <div className=\"dark\">\n <div className=\"flex flex-col h-screen bg-neutral-950\">\n <header className=\"flex-shrink-0 border-b border-neutral-800\">\n <div className=\"max-w-4xl mx-auto flex items-center gap-3 px-4 py-3\">\n <div className=\"w-8 h-8 rounded-lg bg-emerald-500/10 flex items-center justify-center\">\n <svg\n className=\"w-4 h-4 text-emerald-400\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5\"\n />\n </svg>\n </div>\n <div>\n <h1 className=\"font-medium text-white text-sm font-mono\">\n code-agent\n </h1>\n <p className=\"text-xs text-neutral-500\">\n read, search, edit project files\n </p>\n </div>\n <div className=\"ml-auto flex items-center gap-1.5\">\n <span className=\"w-2 h-2 rounded-full bg-emerald-400 animate-pulse\" />\n <span className=\"text-xs text-neutral-500 font-mono\">ready</span>\n </div>\n </div>\n </header>\n {children}\n </div>\n </div>\n </>\n );\n}\n",
39
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function CodeAgent(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return (\n <Chat\n {...chat}\n className=\"flex-1 min-h-0\"\n placeholder=\"Describe what you want to build or fix...\"\n />\n )\n}\n",
39
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function CodeAgent(): React.JSX.Element {\n return (\n <Chat\n agentId=\"coder\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Describe what you want to build or fix...\"\n />\n )\n}\n",
40
40
  "globals.css": "@import \"tailwindcss\";\n",
41
41
  "README.md": "# Coding Agent\n\nAn AI assistant that can read, understand, and modify project files.\n\n## What's included\n\n- Coder agent with file system tools\n- Read, list, and edit files through conversation\n- Safe search/replace editing pattern\n\n## Structure\n\n```\nagents/coder.ts Agent with coding instructions\ntools/\n read-file.ts Read file contents\n list-files.ts List directory contents\n edit-file.ts Search and replace in files\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
42
42
  "tools/edit-file.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\nimport { cwd, readTextFile, realPath, resolve, writeTextFile } from \"veryfront/fs\";\n\n/** True when `target` is the same as, or nested under, `root` (both canonical). */\nfunction isWithin(root: string, target: string): boolean {\n const r = root.replace(/\\\\/g, \"/\");\n const t = target.replace(/\\\\/g, \"/\");\n return t === r || t.startsWith(`${r}/`);\n}\n\nexport default tool({\n id: \"edit-file\",\n description: \"Edit a file by replacing a specific string with new content\",\n inputSchema: defineSchema((v) => v.object({\n path: v.string().describe(\"File path relative to the project root\"),\n search: v.string().describe(\"Exact string to find in the file\"),\n replace: v.string().describe(\"String to replace it with\"),\n }))(),\n execute: async ({ path, search, replace }) => {\n let projectDir: string;\n let absolute: string;\n try {\n // Canonicalize both sides so a symlink that points outside the project\n // is resolved to its real target before the containment check.\n projectDir = await realPath(cwd());\n absolute = await realPath(resolve(projectDir, path));\n } catch {\n return { error: `File not found: ${path}` };\n }\n if (!isWithin(projectDir, absolute)) {\n return { error: `Path escapes project directory: ${path}` };\n }\n\n const content = await readTextFile(absolute);\n if (!content.includes(search)) {\n return { error: \"Search string not found in file\" };\n }\n\n const updated = content.replace(search, replace);\n await writeTextFile(absolute, updated);\n return { path, success: true };\n },\n});\n",
@@ -47,17 +47,17 @@ export default {
47
47
  },
48
48
  "docs-agent": {
49
49
  "files": {
50
- "agents/rag.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"rag\",\n system:\n `You answer questions using the provided documents. ` +\n `Always cite your sources by referencing the document title. ` +\n `If the search results don't contain a clear answer, say so honestly.`,\n});\n",
50
+ "agents/rag.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"rag\",\n name: \"Docs Agent\",\n description: \"Upload files and ask questions.\",\n system:\n `You answer questions using the provided documents. ` +\n `Always cite your sources by referencing the document title. ` +\n `If the search results don't contain a clear answer, say so honestly.`,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Ask Question\",\n prompt: \"I have a question about this document: \",\n },\n {\n type: \"prompt\",\n title: \"Extract Insights\",\n prompt: \"Extract the key insights from the uploaded documents.\",\n },\n {\n type: \"prompt\",\n title: \"Find Sources\",\n prompt: \"Find relevant sources and references in the documents for: \",\n },\n ],\n },\n});\n",
51
51
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\nimport { store } from \"../../../store.ts\";\n\nexport const POST = createAgUiHandler(\"rag\", {\n beforeStream: async ({ lastUserText }) => {\n const query = lastUserText.trim();\n if (!query) return;\n\n try {\n const results = await store.search(query, { topK: 5 });\n if (results.length === 0) return;\n\n const contextBlock = results\n .map(\n (result) =>\n `[${result.title}] (score: ${\n result.score.toFixed(2)\n })\\n${result.text}`,\n )\n .join(\"\\n\\n---\\n\\n\");\n\n return {\n prepend: [\n {\n role: \"system\",\n parts: [\n {\n type: \"text\",\n text:\n `Here are relevant documents retrieved for your question:\\n\\n${contextBlock}\\n\\n` +\n \"Use these documents to answer. Cite the document title when referencing information.\",\n },\n ],\n },\n ],\n };\n } catch (e) {\n console.error(\"[RAG] Retrieval failed:\", e);\n return;\n }\n },\n});\n",
52
52
  "app/api/ingest/route.ts": "import { store } from \"../../../store.ts\";\n\nexport async function POST() {\n await store.indexContentDir();\n return Response.json({ ok: true });\n}\n",
53
- "app/api/uploads/[id]/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../../store.ts\";\n\nexport const { DELETE } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
54
- "app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
55
- "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }): React.ReactNode {\n return (\n <>\n <Head><title>Docs Agent</title></Head>\n <div className=\"flex flex-col h-screen\">\n {children}\n </div>\n </>\n );\n}\n",
56
- "app/page.tsx": "'use client'\n\nimport { useCallback, useMemo } from 'react'\nimport {\n Chat,\n ChatSidebar,\n ChatThemeScope,\n ConversationsProvider,\n useChat,\n useUploadsRegistry,\n} from 'veryfront/chat'\n\nconst UPLOAD_API = '/api/uploads'\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nconst SUGGESTIONS = [\n {\n label: 'Ask Question',\n prompt: 'I have a question about this document: ',\n },\n {\n label: 'Extract Insights',\n prompt: 'Extract the key insights from the uploaded documents.',\n },\n {\n label: 'Find Sources',\n prompt: 'Find relevant sources and references in the documents for: ',\n },\n]\n\nconst MODELS = [\n {\n value: 'anthropic/claude-sonnet-4-6',\n label: 'Claude Sonnet',\n },\n {\n value: 'openai/gpt-4.1-mini',\n label: 'GPT-4.1 Mini',\n },\n {\n value: 'google/gemini-2.5-flash',\n label: 'Gemini 2.5 Flash',\n badge: 'Fast',\n },\n]\n\nfunction DocsChatSurface() {\n const chat = useChat({ api: '/api/ag-ui' })\n const uploads = useUploadsRegistry({ url: UPLOAD_API, storageKey: 'rag-uploads' })\n\n const suggestionLabels = useMemo(\n () => SUGGESTIONS.map((suggestion) => suggestion.label),\n [],\n )\n\n const handleSuggestionClick = useCallback((label: string) => {\n const suggestion = SUGGESTIONS.find((item) => item.label === label)\n chat.setInput(suggestion?.prompt ?? label)\n }, [chat.setInput])\n\n return (\n <ChatThemeScope className=\"flex h-screen min-h-0\">\n <ChatSidebar className=\"w-72 shrink-0 border-r border-[var(--border)]\" />\n <Chat\n chat={chat}\n showSteps\n showTabs\n showSources\n agent={{\n name: 'Docs Agent',\n description: 'Upload files and ask questions',\n models: MODELS,\n }}\n suggestions={suggestionLabels}\n onSuggestionClick={handleSuggestionClick}\n uploads={uploads.items}\n onRemoveUpload={uploads.remove}\n onAttach={uploads.upload}\n onDrop={uploads.upload}\n attachAccept={ACCEPT}\n className=\"flex-1 min-h-0\"\n placeholder=\"Ask anything about your documents...\"\n emptyState={{ title: 'Docs Agent', description: 'Upload files and ask questions' }}\n />\n </ChatThemeScope>\n )\n}\n\nexport default function DocsChat() {\n return (\n <ConversationsProvider storageKey=\"rag-conversations\">\n <DocsChatSurface />\n </ConversationsProvider>\n )\n}\n",
53
+ "app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET, DELETE } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
54
+ "app/layout.tsx": "'use client'\n\nimport \"../globals.css\";\nimport {\n AppShell,\n ChatSidebar,\n ChatThemeScope,\n ConversationsProvider,\n Tabs,\n TabsItem,\n} from \"veryfront/chat\";\nimport { Head } from \"veryfront/head\";\nimport { useRouter } from \"veryfront/router\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }): React.ReactNode {\n const router = useRouter();\n const activeTab = router.pathname.startsWith(\"/uploads\") ? \"uploads\" : \"chat\";\n\n return (\n <>\n <Head><title>Docs Agent</title></Head>\n <ChatThemeScope className=\"flex flex-col h-screen\">\n <ConversationsProvider storageKey=\"rag-conversations\">\n <AppShell className=\"flex-1 min-h-0\">\n <AppShell.Sidebar side=\"left\" className=\"border-r border-[var(--outline-border)]\">\n <AppShell.SidebarContent className=\"p-0\">\n <ChatSidebar fill />\n </AppShell.SidebarContent>\n </AppShell.Sidebar>\n <AppShell.Main>\n <AppShell.Header border className=\"h-16 gap-3 px-3\">\n <AppShell.Trigger side=\"left\" />\n <div className=\"flex flex-1 justify-center\">\n <Tabs\n value={activeTab}\n onValueChange={(value) => router.push(value === \"uploads\" ? \"/uploads\" : \"/\")}\n >\n <TabsItem value=\"chat\">Chat</TabsItem>\n <TabsItem value=\"uploads\">Uploads</TabsItem>\n </Tabs>\n </div>\n </AppShell.Header>\n <AppShell.Content className=\"flex flex-col min-h-0 pt-3\">\n {children}\n </AppShell.Content>\n </AppShell.Main>\n </AppShell>\n </ConversationsProvider>\n </ChatThemeScope>\n </>\n );\n}\n",
55
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nexport default function DocsChat() {\n return (\n <Chat\n agentId=\"rag\"\n api=\"/api/ag-ui\"\n uploadApi=\"/api/uploads\"\n showSteps\n showSources\n attachAccept={ACCEPT}\n className=\"flex-1 min-h-0\"\n placeholder=\"Ask anything about your documents...\"\n />\n )\n}\n",
56
+ "app/uploads/page.tsx": "'use client'\n\nimport { AttachmentsPanel, useUploadsRegistry } from 'veryfront/chat'\n\nconst UPLOAD_API = '/api/uploads'\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nexport default function UploadsPage(): React.JSX.Element {\n const uploads = useUploadsRegistry({ url: UPLOAD_API, storageKey: 'rag-uploads' })\n\n return (\n <AttachmentsPanel\n uploads={uploads.items}\n loading={uploads.isLoading}\n onAttach={uploads.upload}\n onRemoveUpload={uploads.remove}\n attachAccept={ACCEPT}\n className=\"flex-1 min-h-0\"\n />\n )\n}\n",
57
57
  "content/architecture.md": "# Architecture\n\nAcme Platform uses a modular, event-driven architecture.\n\n## Core Components\n\n### API Gateway\nRoutes incoming requests to the appropriate microservice. Handles authentication, rate limiting, and request validation.\n\n### Event Bus\nAsynchronous message broker connecting all services. Supports pub/sub and point-to-point messaging patterns.\n\n### Data Layer\nMulti-tenant data storage with automatic sharding. Supports PostgreSQL for relational data and Redis for caching.\n\n## Request Flow\n\n1. Client sends request to API Gateway\n2. Gateway validates authentication token\n3. Request is routed to the target service\n4. Service processes request and publishes events\n5. Response is returned through the gateway\n\n## Scaling\n\nEach component scales independently. The API Gateway uses horizontal scaling with load balancing. Services auto-scale based on queue depth and CPU utilization.\n\n## Security\n\n- All inter-service communication uses mTLS\n- API tokens are rotated every 24 hours\n- Data at rest is encrypted with AES-256\n- Audit logs are retained for 90 days\n",
58
58
  "content/getting-started.md": "# Getting Started\n\nWelcome to Acme Platform. This guide covers initial setup and core concepts.\n\n## Installation\n\nInstall the CLI globally:\n\n```bash\nnpm install -g @acme/cli\n```\n\n## Creating a Project\n\nRun the init command to scaffold a new project:\n\n```bash\nacme init my-project\ncd my-project\n```\n\n## Project Structure\n\n- `src/`: Application source code\n- `config/`: Configuration files\n- `tests/`: Test suite\n- `docs/`: Documentation\n\n## Configuration\n\nCreate an `acme.config.ts` file in your project root:\n\n```ts\nexport default {\n name: \"my-project\",\n region: \"us-east-1\",\n features: [\"auth\", \"storage\"],\n};\n```\n\n## Next Steps\n\n- Read the [Architecture Guide](./architecture) to understand the system design\n- Check [API Reference](./api-reference) for available endpoints\n- Join our Discord community for support\n",
59
59
  "globals.css": "@import \"tailwindcss\";\n",
60
- "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 (POST) and list (GET) uploads\n api/uploads/[id]/route.ts Delete upload\n page.tsx Chat UI with document upload panel\n layout.tsx Root layout with header\n```\n\n## Framework usage\n\n| What | Framework | Template code |\n|------|-----------|---------------|\n| Chat UI + streaming | `Chat`, `useChat` | `page.tsx` |\n| Upload management | `useUploads` hook | `page.tsx` |\n| Source display | `showSources` prop on `Chat` | `page.tsx` |\n| Upload API routes | `createUploadHandler` | 1-line per route file |\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",
60
+ "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 | `showSources` prop on `Chat` | `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",
61
61
  "store.ts": "import { ragStore } from \"veryfront/embedding\";\n\nexport const store = ragStore({\n storagePath: \"data/index.json\",\n contentDir: \"content\",\n});\n",
62
62
  "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 \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"exclude\": [\"node_modules\"]\n}\n"
63
63
  }
@@ -72,12 +72,12 @@ export default {
72
72
  },
73
73
  "multi-agent-system": {
74
74
  "files": {
75
- "agents/orchestrator.ts": "import { agent, getAgentsAsTools } from \"veryfront/agent\";\n\nexport default agent({\n id: \"orchestrator\",\n system:\n \"You coordinate a team of AI agents. \" +\n \"Delegate research tasks to the researcher and writing tasks to the writer. \" +\n \"Combine their outputs into a polished response.\",\n tools: getAgentsAsTools([\"researcher\", \"writer\"]),\n maxSteps: 10,\n});\n",
75
+ "agents/orchestrator.ts": "import { agent, getAgentsAsTools } from \"veryfront/agent\";\n\nexport default agent({\n id: \"orchestrator\",\n name: \"Agent Team\",\n description: \"Coordinate research and writing agents.\",\n system:\n \"You coordinate a team of AI agents. \" +\n \"Delegate research tasks to the researcher and writing tasks to the writer. \" +\n \"Combine their outputs into a polished response.\",\n tools: getAgentsAsTools([\"researcher\", \"writer\"]),\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Research a topic\",\n prompt: \"Research this topic and summarize the key findings: \",\n },\n {\n type: \"prompt\",\n title: \"Write a brief\",\n prompt: \"Research and write a concise brief about \",\n },\n ],\n },\n});\n",
76
76
  "agents/researcher.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"researcher\",\n system:\n \"You are a research specialist. \" +\n \"Gather comprehensive information on the given topic. \" +\n \"Present findings as structured bullet points with key facts and data.\",\n tools: true,\n maxSteps: 5,\n});\n",
77
77
  "agents/writer.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"writer\",\n system:\n \"You are a writing specialist. \" +\n \"Take research notes and transform them into clear, engaging prose. \" +\n \"Use a professional but approachable tone.\",\n maxSteps: 3,\n});\n",
78
78
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"orchestrator\");\n",
79
79
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>Multi-Agent System</title>\n </Head>\n <div className=\"flex flex-col h-screen bg-white dark:bg-neutral-950\">\n <header className=\"flex-shrink-0 border-b border-neutral-200 dark:border-neutral-800\">\n <div className=\"max-w-3xl mx-auto flex items-center gap-3 px-4 py-3\">\n <div className=\"flex -space-x-2\">\n <div className=\"w-7 h-7 rounded-full bg-blue-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n O\n </div>\n <div className=\"w-7 h-7 rounded-full bg-amber-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n R\n </div>\n <div className=\"w-7 h-7 rounded-full bg-violet-500 ring-2 ring-white dark:ring-neutral-950 flex items-center justify-center text-[10px] font-bold text-white\">\n W\n </div>\n </div>\n <div>\n <h1 className=\"font-medium text-neutral-900 dark:text-white text-sm\">\n Agent Team\n </h1>\n <p className=\"text-xs text-neutral-500 dark:text-neutral-400\">\n Orchestrator, Researcher, Writer\n </p>\n </div>\n </div>\n </header>\n {children}\n </div>\n </>\n );\n}\n",
80
- "app/page.tsx": "'use client'\n\nimport { Chat, useChat } from 'veryfront/chat'\n\nexport default function MultiAgentChat(): React.JSX.Element {\n const chat = useChat({ api: '/api/ag-ui' })\n\n return <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Give the team a task...\" />\n}\n",
80
+ "app/page.tsx": "'use client'\n\nimport { Chat } from 'veryfront/chat'\n\nexport default function MultiAgentChat(): React.JSX.Element {\n return (\n <Chat\n agentId=\"orchestrator\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Give the team a task...\"\n />\n )\n}\n",
81
81
  "globals.css": "@import \"tailwindcss\";\n",
82
82
  "README.md": "# Multi-Agent System\n\nA team of specialized agents that collaborate on tasks.\n\n## What's included\n\n- Orchestrator that delegates to researcher and writer agents\n- Agent-as-tool composition via `getAgentsAsTools()`\n- Web search tool (placeholder, configure your own API)\n\n## Structure\n\n```\nagents/\n orchestrator.ts Coordinates the team\n researcher.ts Gathers information\n writer.ts Produces polished content\ntools/web-search.ts Placeholder search tool\napp/\n api/ag-ui/route.ts AG-UI endpoint\n page.tsx Chat interface\n```\n\nThis starter is not production-ready.\n",
83
83
  "tools/web-search.ts": "import { tool } from \"veryfront/tool\";\nimport { defineSchema } from \"veryfront/schemas\";\n\nexport default tool({\n id: \"web-search\",\n description: \"Search the web for information on a topic\",\n inputSchema: defineSchema((v) => v.object({\n query: v.string().describe(\"Search query\"),\n }))(),\n execute: async ({ query: _query }) => {\n // Connect a real search API to use this tool.\n // Popular options: Tavily, SerpAPI, Brave Search\n throw new Error(\n \"No search API configured. \" +\n \"See https://veryfront.com/docs/code/guides/tools for setup instructions.\",\n );\n },\n});\n",
@@ -86,9 +86,9 @@ export default {
86
86
  },
87
87
  "saas-starter": {
88
88
  "files": {
89
- "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n system: \"You are a helpful AI assistant. Be concise and direct.\",\n tools: true,\n memory: { type: \"conversation\", maxMessages: 50 },\n maxSteps: 10,\n});\n",
89
+ "agents/assistant.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"assistant\",\n name: \"SaaS Assistant\",\n description: \"Answer product and customer questions.\",\n system: \"You are a helpful AI assistant. Be concise and direct.\",\n tools: true,\n memory: { type: \"conversation\", maxMessages: 50 },\n maxSteps: 10,\n suggestions: {\n suggestions: [\n {\n type: \"prompt\",\n title: \"Summarize account\",\n prompt: \"Summarize the latest account activity.\",\n },\n {\n type: \"prompt\",\n title: \"Find customers\",\n prompt: \"Find customers who need attention.\",\n },\n ],\n },\n});\n",
90
90
  "app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\n\nexport const POST = createAgUiHandler(\"assistant\");\n",
91
- "app/dashboard/page.tsx": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Chat, useChat } from \"veryfront/chat\";\n\ninterface Conversation {\n id: string;\n title: string;\n updatedAt: string;\n}\n\nconst INITIAL_CONVERSATIONS: Conversation[] = [\n { id: \"1\", title: \"Getting started\", updatedAt: \"Just now\" },\n];\n\nexport default function Dashboard(): React.JSX.Element {\n const [conversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);\n const [activeId, setActiveId] = useState(\"1\");\n const chat = useChat({ api: \"/api/ag-ui\" });\n\n return (\n <div className=\"flex h-screen bg-white dark:bg-neutral-950\">\n {/* Sidebar */}\n <aside className=\"w-64 border-r border-neutral-200 dark:border-neutral-800 flex flex-col bg-neutral-50 dark:bg-neutral-900\">\n <div className=\"p-4 border-b border-neutral-200 dark:border-neutral-800\">\n <button className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium text-neutral-700 dark:text-neutral-300 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-colors\">\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 4.5v15m7.5-7.5h-15\"\n />\n </svg>\n New chat\n </button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2 space-y-0.5\">\n {conversations.map((conv) => (\n <button\n key={conv.id}\n onClick={() => setActiveId(conv.id)}\n className={`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${\n activeId === conv.id\n ? \"bg-neutral-200 dark:bg-neutral-800 text-neutral-900 dark:text-white\"\n : \"text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800/50\"\n }`}\n >\n <p className=\"truncate\">{conv.title}</p>\n <p className=\"text-xs text-neutral-400 mt-0.5\">\n {conv.updatedAt}\n </p>\n </button>\n ))}\n </nav>\n\n <div className=\"p-4 border-t border-neutral-200 dark:border-neutral-800\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-full bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center text-xs font-medium text-neutral-600 dark:text-neutral-300\">\n U\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white truncate\">\n User\n </p>\n <p className=\"text-xs text-neutral-500 truncate\">\n user@example.com\n </p>\n </div>\n </div>\n </div>\n </aside>\n\n {/* Chat */}\n <main className=\"flex-1 flex flex-col\">\n <Chat {...chat} className=\"flex-1 min-h-0\" placeholder=\"Message...\" />\n </main>\n </div>\n );\n}\n",
91
+ "app/dashboard/page.tsx": "\"use client\";\n\nimport { useState } from \"react\";\nimport { Chat } from \"veryfront/chat\";\n\ninterface Conversation {\n id: string;\n title: string;\n updatedAt: string;\n}\n\nconst INITIAL_CONVERSATIONS: Conversation[] = [\n { id: \"1\", title: \"Getting started\", updatedAt: \"Just now\" },\n];\n\nexport default function Dashboard(): React.JSX.Element {\n const [conversations] = useState<Conversation[]>(INITIAL_CONVERSATIONS);\n const [activeId, setActiveId] = useState(\"1\");\n\n return (\n <div className=\"flex h-screen bg-white dark:bg-neutral-950\">\n {/* Sidebar */}\n <aside className=\"w-64 border-r border-neutral-200 dark:border-neutral-800 flex flex-col bg-neutral-50 dark:bg-neutral-900\">\n <div className=\"p-4 border-b border-neutral-200 dark:border-neutral-800\">\n <button className=\"w-full flex items-center gap-2 px-3 py-2 text-sm font-medium text-neutral-700 dark:text-neutral-300 bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-700 transition-colors\">\n <svg\n className=\"w-4 h-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M12 4.5v15m7.5-7.5h-15\"\n />\n </svg>\n New chat\n </button>\n </div>\n\n <nav className=\"flex-1 overflow-y-auto p-2 space-y-0.5\">\n {conversations.map((conv) => (\n <button\n key={conv.id}\n onClick={() => setActiveId(conv.id)}\n className={`w-full text-left px-3 py-2 rounded-lg text-sm transition-colors ${\n activeId === conv.id\n ? \"bg-neutral-200 dark:bg-neutral-800 text-neutral-900 dark:text-white\"\n : \"text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800/50\"\n }`}\n >\n <p className=\"truncate\">{conv.title}</p>\n <p className=\"text-xs text-neutral-400 mt-0.5\">\n {conv.updatedAt}\n </p>\n </button>\n ))}\n </nav>\n\n <div className=\"p-4 border-t border-neutral-200 dark:border-neutral-800\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-8 h-8 rounded-full bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center text-xs font-medium text-neutral-600 dark:text-neutral-300\">\n U\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-neutral-900 dark:text-white truncate\">\n User\n </p>\n <p className=\"text-xs text-neutral-500 truncate\">\n user@example.com\n </p>\n </div>\n </div>\n </div>\n </aside>\n\n {/* Chat */}\n <main className=\"flex-1 flex flex-col\">\n <Chat\n agentId=\"assistant\"\n api=\"/api/ag-ui\"\n className=\"flex-1 min-h-0\"\n placeholder=\"Message...\"\n />\n </main>\n </div>\n );\n}\n",
92
92
  "app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({\n children,\n}: {\n children: React.ReactNode;\n}): React.ReactNode {\n return (\n <>\n <Head>\n <title>AI SaaS</title>\n </Head>\n <div className=\"antialiased\">\n {children}\n </div>\n </>\n );\n}\n",
93
93
  "app/login/page.tsx": "\"use client\";\n\n// Demo sign-in: the buttons below pass straight through to /dashboard so the\n// starter is usable out of the box. To wire up real OAuth, scaffold provider\n// routes at app/api/auth/google/route.ts and app/api/auth/github/route.ts and\n// point the hrefs there. See https://veryfront.com/docs/code/guides/oauth.\nexport default function LoginPage(): React.JSX.Element {\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-neutral-50 dark:bg-neutral-950 px-4\">\n <div className=\"w-full max-w-sm\">\n <div className=\"text-center mb-8\">\n <h1 className=\"text-xl font-bold text-neutral-900 dark:text-white\">\n Welcome back\n </h1>\n <p className=\"text-sm text-neutral-500 dark:text-neutral-400 mt-1\">\n Sign in to continue\n </p>\n </div>\n\n <div className=\"bg-white dark:bg-neutral-900 rounded-2xl border border-neutral-200 dark:border-neutral-800 p-6 space-y-3\">\n <a\n href=\"/dashboard\"\n className=\"flex items-center justify-center gap-2 w-full px-4 py-2.5 border border-neutral-200 dark:border-neutral-800 rounded-xl text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n <svg className=\"w-4 h-4\" viewBox=\"0 0 24 24\">\n <path\n fill=\"#4285F4\"\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.76h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n />\n <path\n fill=\"#34A853\"\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n />\n <path\n fill=\"#FBBC05\"\n d=\"M5.84 14.09a7.12 7.12 0 010-4.18V7.07H2.18A11.99 11.99 0 001 12c0 1.94.46 3.77 1.18 5.43l3.66-3.34z\"\n />\n <path\n fill=\"#EA4335\"\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n />\n </svg>\n Continue with Google\n </a>\n <a\n href=\"/dashboard\"\n className=\"flex items-center justify-center gap-2 w-full px-4 py-2.5 border border-neutral-200 dark:border-neutral-800 rounded-xl text-sm font-medium text-neutral-700 dark:text-neutral-300 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors\"\n >\n <svg className=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.51 11.51 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z\" />\n </svg>\n Continue with GitHub\n </a>\n </div>\n\n <p className=\"mt-6 text-center text-xs text-neutral-400\">\n <a\n href=\"/\"\n className=\"hover:text-neutral-600 dark:hover:text-neutral-300\"\n >\n &larr; Back to home\n </a>\n </p>\n </div>\n </div>\n );\n}\n",
94
94
  "app/page.tsx": "export default function LandingPage(): React.JSX.Element {\n return (\n <div className=\"min-h-screen bg-white dark:bg-neutral-950\">\n {/* Nav */}\n <nav className=\"border-b border-neutral-100 dark:border-neutral-900\">\n <div className=\"max-w-5xl mx-auto flex items-center justify-between px-6 h-14\">\n <span className=\"font-semibold text-neutral-900 dark:text-white\">\n AI SaaS\n </span>\n <div className=\"flex items-center gap-4\">\n <a\n href=\"/login\"\n className=\"text-sm text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors\"\n >\n Sign in\n </a>\n <a\n href=\"/login\"\n className=\"text-sm px-4 py-1.5 bg-neutral-900 dark:bg-white text-white dark:text-neutral-900 rounded-full font-medium hover:opacity-90 transition-opacity\"\n >\n Get started\n </a>\n </div>\n </div>\n </nav>\n\n {/* Hero */}\n <main className=\"max-w-5xl mx-auto px-6\">\n <div className=\"pt-24 pb-16 text-center\">\n <h1 className=\"text-4xl md:text-5xl font-bold tracking-tight text-neutral-900 dark:text-white\">\n Your AI-powered platform\n </h1>\n <p className=\"mt-4 text-lg text-neutral-500 dark:text-neutral-400 max-w-lg mx-auto\">\n Built with Veryfront. Agents, tools, and memory are ready for\n production.\n </p>\n <div className=\"mt-8 flex gap-3 justify-center\">\n <a\n href=\"/login\"\n className=\"px-6 py-2.5 bg-neutral-900 dark:bg-white text-white dark:text-neutral-900 rounded-full font-medium hover:opacity-90 transition-opacity\"\n >\n Start free\n </a>\n <a\n href=\"https://veryfront.com/docs/code/guides\"\n className=\"px-6 py-2.5 border border-neutral-200 dark:border-neutral-800 text-neutral-700 dark:text-neutral-300 rounded-full font-medium hover:bg-neutral-50 dark:hover:bg-neutral-900 transition-colors\"\n >\n Documentation\n </a>\n </div>\n </div>\n\n {/* Features */}\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6 py-16 border-t border-neutral-100 dark:border-neutral-900\">\n {[\n {\n title: \"AI Agents\",\n desc: \"Define agents with tools, memory, and streaming. Veryfront auto-discovers them from your project.\",\n },\n {\n title: \"Per-User Memory\",\n desc: \"Each user gets their own conversation history, persisted across sessions.\",\n },\n {\n title: \"Production Ready\",\n desc: \"Use auth, rate limiting, and deployment to ship to production with one command.\",\n },\n ].map(({ title, desc }) => (\n <div key={title}>\n <h3 className=\"font-medium text-neutral-900 dark:text-white\">\n {title}\n </h3>\n <p className=\"mt-1 text-sm text-neutral-500 dark:text-neutral-400\">\n {desc}\n </p>\n </div>\n ))}\n </div>\n </main>\n </div>\n );\n}\n",
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.998",
3
+ "version": "0.1.1001",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -1 +1 @@
1
- {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA6IvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAkGlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
1
+ {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA6IvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAuGlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -191,7 +191,12 @@ export async function importModule(file, context) {
191
191
  contents: source,
192
192
  loader,
193
193
  resolveDir: fileDir,
194
- sourcefile: filePath,
194
+ // Must be a basename: esbuild joins resolveDir + sourcefile to form the
195
+ // entry module path when sourcefile is relative. Passing the full
196
+ // relative filePath (e.g. "tools/foo.ts") on VFS runs (baseDir === "")
197
+ // doubles the prefix to "tools/tools/foo.ts", which anchors ../ imports
198
+ // one directory too deep.
199
+ sourcefile: pathHelper.basename(filePath),
195
200
  },
196
201
  });
197
202
  if (result.errors.length > 0) {
@@ -21,8 +21,6 @@ export { vectorStore } from "./vector-store.js";
21
21
  export { ragStore } from "./rag-store.js";
22
22
  export { createUploadHandler } from "./upload-handler.js";
23
23
  export { loadUpload } from "./upload-loader.js";
24
- export { useUploads } from "./react/use-uploads.js";
25
- export type { UseUploadsOptions, UseUploadsResult } from "./react/use-uploads.js";
26
24
  export { clearEmbeddingProviders, registerEmbeddingProvider, resolveEmbeddingModel, } from "./resolve.js";
27
25
  export type { ChunkOptions, Embedding, EmbeddingConfig, RagChunk, RagDocumentMeta, RagRefreshOptions, RagSearchOptions, RagSearchResult, RagStore, RagStoreBackend, RagStoreConfig, RagStoreData, SearchOptions, SearchResult, VectorStore, VectorStoreConfig, } from "./types.js";
28
26
  export type { UploadAuthorizationResult, UploadAuthorize, UploadHandlerAuthConfig, UploadHandlerConfig, } from "./upload-handler.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
@@ -21,5 +21,4 @@ export { vectorStore } from "./vector-store.js";
21
21
  export { ragStore } from "./rag-store.js";
22
22
  export { createUploadHandler } from "./upload-handler.js";
23
23
  export { loadUpload } from "./upload-loader.js";
24
- export { useUploads } from "./react/use-uploads.js";
25
24
  export { clearEmbeddingProviders, registerEmbeddingProvider, resolveEmbeddingModel, } from "./resolve.js";
@@ -25,7 +25,7 @@ export interface UploadHandlerConfig {
25
25
  * `loadUpload`, and ingests into the provided RAG store. When Veryfront Cloud
26
26
  * bootstrap is present, the original binary is also stored in the project's
27
27
  * uploads store via the cloud adapter. GET returns the upload list. DELETE
28
- * removes an upload by ID from route params.
28
+ * removes an upload by ID from the `id` query parameter or route params.
29
29
  *
30
30
  * @example
31
31
  * ```ts
@@ -34,7 +34,7 @@ export interface UploadHandlerConfig {
34
34
  * import { getEnv } from "veryfront";
35
35
  * import { store } from "lib/store.ts";
36
36
  *
37
- * export const { POST, GET } = createUploadHandler(store, {
37
+ * export const { POST, GET, DELETE } = createUploadHandler(store, {
38
38
  * auth: {
39
39
  * authorize: (request) => {
40
40
  * const token = getEnv("UPLOAD_TOKEN");
@@ -44,17 +44,6 @@ export interface UploadHandlerConfig {
44
44
  * },
45
45
  * });
46
46
  * ```
47
- *
48
- * @example
49
- * ```ts
50
- * // app/api/uploads/[id]/route.ts
51
- * import { createUploadHandler } from "veryfront/embedding";
52
- * import { store } from "lib/store.ts";
53
- *
54
- * export const { DELETE } = createUploadHandler(store, {
55
- * auth: { type: "none", allowUnauthenticated: true },
56
- * });
57
- * ```
58
47
  */
59
48
  export declare function createUploadHandler(store: RagStore, config?: UploadHandlerConfig): {
60
49
  POST: (request: Request) => Promise<Response>;
@@ -1 +1 @@
1
- {"version":3,"file":"upload-handler.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/upload-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqF3C,MAAM,MAAM,yBAAyB,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;AAE9E,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,OAAO,KACb,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAEpE,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,IAAI,CAAA;CAAE,GAC5C;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,uBAAuB,CAAC;CAChC;AA6FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,mBAAmB;oBAKC,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;oBAiF3B,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;sBAc7C,OAAO,WACP;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KAC1C,OAAO,CAAC,QAAQ,CAAC;EA6BrB"}
1
+ {"version":3,"file":"upload-handler.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/upload-handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqF5D,MAAM,MAAM,yBAAyB,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;AAE9E,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,OAAO,KACb,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAEpE,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,IAAI,CAAA;CAAE,GAC5C;IAAE,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,uBAAuB,CAAC;CAChC;AAuHD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,mBAAmB;oBAKC,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;oBAmF3B,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;sBAc7C,OAAO,WACP;QAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KAC1C,OAAO,CAAC,QAAQ,CAAC;EA6BrB"}
@@ -145,6 +145,22 @@ function getSourceBlobStorage() {
145
145
  ? new VeryfrontCloudBlobStorage({ prefix: CLOUD_UPLOAD_PREFIX })
146
146
  : null;
147
147
  }
148
+ function toUploadRegistryItem(upload) {
149
+ return {
150
+ id: upload.id,
151
+ name: upload.title,
152
+ mediaType: typeToMime(upload.type),
153
+ size: 0,
154
+ ...(upload.url ? { url: upload.url } : {}),
155
+ };
156
+ }
157
+ function resolveDeleteId(request, context) {
158
+ const fromParams = context.params.id;
159
+ if (fromParams)
160
+ return fromParams;
161
+ const fromQuery = new URL(request.url).searchParams.get("id");
162
+ return fromQuery ?? "";
163
+ }
148
164
  /**
149
165
  * Creates HTTP route handlers for upload, listing, and deletion.
150
166
  *
@@ -159,7 +175,7 @@ function getSourceBlobStorage() {
159
175
  * `loadUpload`, and ingests into the provided RAG store. When Veryfront Cloud
160
176
  * bootstrap is present, the original binary is also stored in the project's
161
177
  * uploads store via the cloud adapter. GET returns the upload list. DELETE
162
- * removes an upload by ID from route params.
178
+ * removes an upload by ID from the `id` query parameter or route params.
163
179
  *
164
180
  * @example
165
181
  * ```ts
@@ -168,7 +184,7 @@ function getSourceBlobStorage() {
168
184
  * import { getEnv } from "veryfront";
169
185
  * import { store } from "lib/store.ts";
170
186
  *
171
- * export const { POST, GET } = createUploadHandler(store, {
187
+ * export const { POST, GET, DELETE } = createUploadHandler(store, {
172
188
  * auth: {
173
189
  * authorize: (request) => {
174
190
  * const token = getEnv("UPLOAD_TOKEN");
@@ -178,17 +194,6 @@ function getSourceBlobStorage() {
178
194
  * },
179
195
  * });
180
196
  * ```
181
- *
182
- * @example
183
- * ```ts
184
- * // app/api/uploads/[id]/route.ts
185
- * import { createUploadHandler } from "veryfront/embedding";
186
- * import { store } from "lib/store.ts";
187
- *
188
- * export const { DELETE } = createUploadHandler(store, {
189
- * auth: { type: "none", allowUnauthenticated: true },
190
- * });
191
- * ```
192
197
  */
193
198
  export function createUploadHandler(store, config) {
194
199
  const maxSize = config?.maxFileSize ?? MAX_FILE_SIZE;
@@ -247,8 +252,10 @@ export function createUploadHandler(store, config) {
247
252
  }
248
253
  }
249
254
  return Response.json({
250
- success: true,
251
- upload: { id, title: safeName, type: fileType },
255
+ id,
256
+ name: safeName,
257
+ mediaType: file.type || typeToMime(fileType),
258
+ size: file.size,
252
259
  });
253
260
  }
254
261
  catch (error) {
@@ -262,7 +269,7 @@ export function createUploadHandler(store, config) {
262
269
  if (unauthorized)
263
270
  return unauthorized;
264
271
  const uploads = await enrichUploadsWithSourceUrls(await store.listDocuments());
265
- return Response.json({ uploads });
272
+ return Response.json({ items: uploads.map(toUploadRegistryItem) });
266
273
  }
267
274
  catch (error) {
268
275
  serverLogger.error("Upload list failed:", error);
@@ -274,7 +281,7 @@ export function createUploadHandler(store, config) {
274
281
  const unauthorized = await authorizeUploadRequest(request, authorize);
275
282
  if (unauthorized)
276
283
  return unauthorized;
277
- const id = context.params.id;
284
+ const id = resolveDeleteId(request, context);
278
285
  if (!id) {
279
286
  return Response.json({ error: "Missing upload ID" }, { status: 400 });
280
287
  }
@@ -5,6 +5,7 @@ import { type AgentRunSessionManager } from "./session-manager.js";
5
5
  import type { RuntimeRunAgentInput } from "./schema.js";
6
6
  export interface RuntimeAgentStreamExecutionDeps {
7
7
  sessionManager: AgentRunSessionManager;
8
+ localTools?: Record<string, Tool | boolean>;
8
9
  projectAgentSandbox?: {
9
10
  apiUrl?: string;
10
11
  authToken?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EACV,+BAA+B,EAC/B,8BAA8B,EAC/B,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAmB,KAAK,IAAI,EAAgB,MAAM,kBAAkB,CAAC;AAU5E,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAsCxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,mBAAmB,CAAC,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE,+BAA+B,CAAC,gBAAgB,CAAC,CAAC;IACnE,8BAA8B,CAAC,EAAE,CAC/B,KAAK,EAAE,+BAA+B,KACnC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,EACD,aAAa,CAAC,EAAE,MAAM,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AAoCD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,sBAAsB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EAAE,EACtC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;;cAsFrD;AA2KD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CA8TnB"}
1
+ {"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EACV,+BAA+B,EAC/B,8BAA8B,EAC/B,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAmB,KAAK,IAAI,EAAgB,MAAM,kBAAkB,CAAC;AAU5E,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAsCxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC;IAC5C,mBAAmB,CAAC,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE,+BAA+B,CAAC,gBAAgB,CAAC,CAAC;IACnE,8BAA8B,CAAC,EAAE,CAC/B,KAAK,EAAE,+BAA+B,KACnC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,EACD,aAAa,CAAC,EAAE,MAAM,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AAoCD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,sBAAsB,EACtC,2BAA2B,CAAC,EAAE,MAAM,EAAE,EACtC,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;;cAsFrD;AA2KD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CAkUnB"}
@@ -263,7 +263,11 @@ export async function createRuntimeAgentStreamResponse(input, agent, deps) {
263
263
  const forwardedIntegrationToolDefs = getForwardedIntegrationToolDefinitions(input.forwardedProps);
264
264
  const availableForwardedToolNames = forwardedIntegrationToolDefs?.map((tool) => tool.name);
265
265
  const sandboxTools = await buildProjectAgentSandboxTools({ agent, deps });
266
- const mergedTools = buildMergedTools(agent, input, deps.sessionManager, availableForwardedToolNames, sandboxTools.tools);
266
+ const availableLocalTools = {
267
+ ...(deps.localTools ?? {}),
268
+ ...(sandboxTools.tools ?? {}),
269
+ };
270
+ const mergedTools = buildMergedTools(agent, input, deps.sessionManager, availableForwardedToolNames, Object.keys(availableLocalTools).length > 0 ? availableLocalTools : undefined);
267
271
  const runtimeAgent = {
268
272
  ...agent,
269
273
  config: {
@@ -1 +1 @@
1
- {"version":3,"file":"default-import-map.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/import-map/default-import-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyDlD,wBAAgB,mBAAmB,IAAI,eAAe,CAIrD"}
1
+ {"version":3,"file":"default-import-map.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/import-map/default-import-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAmDlD,wBAAgB,mBAAmB,IAAI,eAAe,CAIrD"}
@@ -25,10 +25,6 @@ function getVeryfrontSsrImportMap() {
25
25
  const workflowReact = `${base}/workflow/react/index.js${ssr}`;
26
26
  // veryfront/react is a barrel that re-exports all browser-side modules.
27
27
  const react = `${base}/react/public.js${ssr}`;
28
- // Map veryfront/embedding to the React hooks submodule for SSR.
29
- // The full embedding/index.ts imports heavy server-side code (vectorStore, ragStore)
30
- // that fails to transform. SSR only needs the React hook (useUploads).
31
- const embedding = `${base}/embedding/react/index.js${ssr}`;
32
28
  return {
33
29
  "veryfront/react": react,
34
30
  "veryfront/head": head,
@@ -38,7 +34,6 @@ function getVeryfrontSsrImportMap() {
38
34
  "veryfront/markdown": markdown,
39
35
  "veryfront/chat": chat,
40
36
  "veryfront/mdx": mdx,
41
- "veryfront/embedding": embedding,
42
37
  "veryfront/workflow": workflowReact,
43
38
  "veryfront/react/head": head,
44
39
  "veryfront/react/router": router,
@@ -5,6 +5,7 @@ import { BaseHandler } from "../response/base.js";
5
5
  import type { HandlerContext, HandlerMetadata, HandlerResult } from "../types.js";
6
6
  export interface AgentStreamHandlerDeps extends RuntimeAgentDiscoveryDeps, RuntimeAgentStreamExecutionDeps {
7
7
  resolveRuntimeOwnerInvokeUrl?: typeof resolveRuntimeOwnerInvokeUrl;
8
+ getLocalTools?: (agentId: string) => RuntimeAgentStreamExecutionDeps["localTools"];
8
9
  }
9
10
  export declare class AgentStreamHandler extends BaseHandler {
10
11
  private readonly deps;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-stream.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/agent-stream.handler.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,wCAAwC,CAAC;AAQhD,OAAO,EACL,4BAA4B,EAE7B,MAAM,2CAA2C,CAAC;AAyBnD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAanG,MAAM,WAAW,sBACf,SAAQ,yBAAyB,EAAE,+BAA+B;IAClE,4BAA4B,CAAC,EAAE,OAAO,4BAA4B,CAAC;CACpE;AAkfD,qBAAa,kBAAmB,SAAQ,WAAW;IASrC,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,QAAQ,EAAE,eAAe,CAMvB;gBAE2B,IAAI,GAAE,sBAAoC;IAIvE,OAAO,CAAC,sBAAsB;IAwBxB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA0LxE"}
1
+ {"version":3,"file":"agent-stream.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/agent-stream.handler.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAEpF,OAAO,EAEL,KAAK,+BAA+B,EACrC,MAAM,wCAAwC,CAAC;AAQhD,OAAO,EACL,4BAA4B,EAE7B,MAAM,2CAA2C,CAAC;AAyBnD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAanG,MAAM,WAAW,sBACf,SAAQ,yBAAyB,EAAE,+BAA+B;IAClE,4BAA4B,CAAC,EAAE,OAAO,4BAA4B,CAAC;IACnE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,+BAA+B,CAAC,YAAY,CAAC,CAAC;CACpF;AAofD,qBAAa,kBAAmB,SAAQ,WAAW;IASrC,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,QAAQ,EAAE,eAAe,CAMvB;gBAE2B,IAAI,GAAE,sBAAoC;IAIvE,OAAO,CAAC,sBAAsB;IAwBxB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA4LxE"}
@@ -1,5 +1,6 @@
1
1
  import { createRemoteMCPToolSource, toolRegistry, } from "../../../tool/index.js";
2
2
  import { defaultChannelInvokeDeps } from "../../../channels/invoke.js";
3
+ import { getDiscoveredHostTools } from "../../../agent/hosted/veryfront-cloud-agent-service.js";
3
4
  import { createRuntimeAgentStreamResponse, } from "../../../internal-agents/run-stream.js";
4
5
  import { createRuntimeAgentFromMarkdownDefinition } from "../../../agent/runtime/agent-markdown-adapter.js";
5
6
  import { buildStudioMcpHeaders } from "../../../agent/project/live-studio-mcp-tools.js";
@@ -21,6 +22,7 @@ const defaultDeps = {
21
22
  ...defaultChannelInvokeDeps,
22
23
  sessionManager: agentRunSessionManager,
23
24
  resolveRuntimeOwnerInvokeUrl,
25
+ getLocalTools: (agentId) => getDiscoveredHostTools({ agentId }),
24
26
  };
25
27
  const logger = serverLogger.component("agent-stream-handler");
26
28
  const RUN_STREAM_PATH_REGEX = /^\/api\/control-plane\/runs\/([^/]+)\/stream$/;
@@ -450,6 +452,7 @@ export class AgentStreamHandler extends BaseHandler {
450
452
  ? createRuntimeAgentFromMarkdownDefinition(payload.agentConfig)
451
453
  : agent;
452
454
  const runtimeInput = sanitizeRuntimeRunAgentInput(toRuntimeRunAgentInput(payload));
455
+ const localTools = this.deps.getLocalTools?.(runtimeBaseAgent.id);
453
456
  const apiAuthToken = payload.credentials?.authToken || ctx.proxyToken ||
454
457
  getHostEnv("VERYFRONT_API_TOKEN") || "";
455
458
  const platformRuntimeAgent = await withVeryfrontPlatformRemoteTools({
@@ -486,6 +489,7 @@ export class AgentStreamHandler extends BaseHandler {
486
489
  }
487
490
  const runAgentStream = () => createRuntimeAgentStreamResponse(runtimeInput, runtimeAgent, {
488
491
  ...this.deps,
492
+ localTools,
489
493
  projectAgentSandbox: {
490
494
  apiUrl: getHostEnv("VERYFRONT_API_URL") ?? "https://api.veryfront.com",
491
495
  authToken: apiAuthToken || undefined,
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.998";
2
+ export declare const VERSION = "0.1.1001";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-constant.d.ts","sourceRoot":"","sources":["../../../src/src/utils/version-constant.ts"],"names":[],"mappings":"AAEA,4BAA4B;AAC5B,eAAO,MAAM,OAAO,YAAY,CAAC"}
1
+ {"version":3,"file":"version-constant.d.ts","sourceRoot":"","sources":["../../../src/src/utils/version-constant.ts"],"names":[],"mappings":"AAEA,4BAA4B;AAC5B,eAAO,MAAM,OAAO,aAAa,CAAC"}
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.998";
4
+ export const VERSION = "0.1.1001";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.998",
3
+ "version": "0.1.1001",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
@@ -1,33 +0,0 @@
1
- /**
2
- * useUploads Hook
3
- *
4
- * Manages upload, deletion, and listing for RAG applications.
5
- * Pairs with `createUploadHandler` on the server side.
6
- */
7
- import type { RagDocumentMeta } from "../types.js";
8
- /** Options accepted by use uploads. */
9
- export interface UseUploadsOptions {
10
- /** API endpoint, e.g. "/API/uploads" */
11
- api: string;
12
- }
13
- /** Result returned from use uploads. */
14
- export interface UseUploadsResult {
15
- /** All uploads from the server */
16
- uploads: RagDocumentMeta[];
17
- /** True while an upload is in progress */
18
- uploading: boolean;
19
- /** User-facing error message, cleared on next action */
20
- error: string | null;
21
- /** Upload a file (multipart POST) */
22
- upload: (file: File) => Promise<void>;
23
- /** Delete an upload by ID */
24
- remove: (id: string) => Promise<void>;
25
- /** Re-fetch the upload list */
26
- refresh: () => Promise<void>;
27
- }
28
- export declare function buildUploadResourceUrl(api: string, id: string): string;
29
- /**
30
- * useUploads hook for managing RAG upload lifecycle.
31
- */
32
- export declare function useUploads(options: UseUploadsOptions): UseUploadsResult;
33
- //# sourceMappingURL=use-uploads.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-uploads.d.ts","sourceRoot":"","sources":["../../../../src/src/embedding/react/use-uploads.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,uCAAuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,qCAAqC;IACrC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,6BAA6B;IAC7B,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+BAA+B;IAC/B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAmEvE"}
@@ -1,76 +0,0 @@
1
- /**
2
- * useUploads Hook
3
- *
4
- * Manages upload, deletion, and listing for RAG applications.
5
- * Pairs with `createUploadHandler` on the server side.
6
- */
7
- import { useCallback, useEffect, useRef, useState } from "../../../react/react.js";
8
- import { API_ERROR } from "../../errors/index.js";
9
- export function buildUploadResourceUrl(api, id) {
10
- return `${api}/${encodeURIComponent(id)}`;
11
- }
12
- /**
13
- * useUploads hook for managing RAG upload lifecycle.
14
- */
15
- export function useUploads(options) {
16
- const [uploads, setUploads] = useState([]);
17
- const [uploading, setUploading] = useState(false);
18
- const [error, setError] = useState(null);
19
- const abortControllerRef = useRef(null);
20
- const refresh = useCallback(async () => {
21
- try {
22
- const res = await fetch(options.api);
23
- if (!res.ok)
24
- return;
25
- const data = await res.json();
26
- setUploads(data.uploads ?? []);
27
- }
28
- catch (error) {
29
- console.debug("useUploads: failed to load uploads", error);
30
- setError("Failed to load uploads");
31
- }
32
- }, [options.api]);
33
- useEffect(() => {
34
- refresh();
35
- }, [refresh]);
36
- const upload = useCallback(async (file) => {
37
- setError(null);
38
- setUploading(true);
39
- const abortController = new AbortController();
40
- abortControllerRef.current = abortController;
41
- try {
42
- const formData = new FormData();
43
- formData.append("file", file);
44
- const res = await fetch(options.api, {
45
- method: "POST",
46
- body: formData,
47
- signal: abortController.signal,
48
- });
49
- const data = await res.json();
50
- if (!res.ok)
51
- throw API_ERROR.create({ detail: data.error ?? "Upload failed" });
52
- await refresh();
53
- }
54
- catch (err) {
55
- if (err instanceof Error && err.name === "AbortError")
56
- return;
57
- setError(err instanceof Error ? err.message : "Upload failed");
58
- }
59
- finally {
60
- setUploading(false);
61
- abortControllerRef.current = null;
62
- }
63
- }, [options.api, refresh]);
64
- const remove = useCallback(async (id) => {
65
- setError(null);
66
- try {
67
- await fetch(buildUploadResourceUrl(options.api, id), { method: "DELETE" });
68
- await refresh();
69
- }
70
- catch (error) {
71
- console.debug("useUploads: failed to delete upload", error);
72
- setError("Failed to delete upload");
73
- }
74
- }, [options.api, refresh]);
75
- return { uploads, uploading, error, upload, remove, refresh };
76
- }