veryfront 0.1.157 → 0.1.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/cli/mcp/remote-file-tools.d.ts.map +1 -1
- package/esm/cli/mcp/remote-file-tools.js +16 -9
- package/esm/deno.js +1 -1
- package/esm/src/agent/human-input.d.ts +298 -0
- package/esm/src/agent/human-input.d.ts.map +1 -0
- package/esm/src/agent/human-input.js +112 -0
- package/esm/src/agent/index.d.ts +2 -1
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +1 -0
- package/esm/src/agent/runtime/index.d.ts +2 -12
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +62 -25
- package/esm/src/agent/types.d.ts +37 -0
- package/esm/src/agent/types.d.ts.map +1 -1
- package/esm/src/mcp/http-transport.d.ts +33 -0
- package/esm/src/mcp/http-transport.d.ts.map +1 -0
- package/esm/src/mcp/http-transport.js +97 -0
- package/esm/src/mcp/server.d.ts +2 -1
- package/esm/src/mcp/server.d.ts.map +1 -1
- package/esm/src/mcp/server.js +20 -106
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/stat-operations.js +13 -45
- package/esm/src/routing/api/module-loader/loader.d.ts +7 -0
- package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
- package/esm/src/routing/api/module-loader/loader.js +104 -94
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/cli/mcp/remote-file-tools.ts +24 -13
- package/src/deno.js +1 -1
- package/src/src/agent/human-input.ts +152 -0
- package/src/src/agent/index.ts +24 -0
- package/src/src/agent/runtime/index.ts +118 -11
- package/src/src/agent/types.ts +47 -0
- package/src/src/mcp/http-transport.ts +163 -0
- package/src/src/mcp/server.ts +21 -120
- package/src/src/platform/adapters/fs/veryfront/stat-operations.ts +19 -49
- package/src/src/routing/api/module-loader/loader.ts +127 -100
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -255,7 +255,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
255
255
|
this.cache.set(cacheKey, files);
|
|
256
256
|
return files;
|
|
257
257
|
}
|
|
258
|
-
buildResolveSearchPatterns(normalizedPath, options) {
|
|
258
|
+
buildResolveSearchPatterns(normalizedPath, options, knownExtensionFallback = "exact") {
|
|
259
259
|
const patterns = new Set();
|
|
260
260
|
const pathWithoutExt = stripKnownExtension(normalizedPath, EXTENSION_PRIORITY);
|
|
261
261
|
const allowPagesPrefix = options?.allowPagesPrefix !== false;
|
|
@@ -264,7 +264,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
264
264
|
patterns.add(pattern);
|
|
265
265
|
};
|
|
266
266
|
if (EXTENSION_PRIORITY.some((ext) => normalizedPath.endsWith(ext))) {
|
|
267
|
-
addPattern(normalizedPath);
|
|
267
|
+
addPattern(knownExtensionFallback === "wildcard" ? `${pathWithoutExt}.*` : normalizedPath);
|
|
268
268
|
return [...patterns];
|
|
269
269
|
}
|
|
270
270
|
addPattern(`${pathWithoutExt}.*`);
|
|
@@ -282,7 +282,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
282
282
|
path: normalizeIndexedFilePath(match).normalizedPath,
|
|
283
283
|
}));
|
|
284
284
|
}
|
|
285
|
-
async tryResolveViaApiSearch(normalizedPath, options) {
|
|
285
|
+
async tryResolveViaApiSearch(normalizedPath, options, knownExtensionFallback = "exact") {
|
|
286
286
|
if (isFrameworkSourcePath(normalizedPath)) {
|
|
287
287
|
logger.debug("Skipping API search for framework path", { normalizedPath });
|
|
288
288
|
return null;
|
|
@@ -291,7 +291,7 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
291
291
|
logger.warn("API search circuit breaker open, skipping", { normalizedPath });
|
|
292
292
|
return undefined;
|
|
293
293
|
}
|
|
294
|
-
const patterns = this.buildResolveSearchPatterns(normalizedPath, options);
|
|
294
|
+
const patterns = this.buildResolveSearchPatterns(normalizedPath, options, knownExtensionFallback);
|
|
295
295
|
let sawSuccessfulSearch = false;
|
|
296
296
|
for (const pattern of patterns) {
|
|
297
297
|
try {
|
|
@@ -459,49 +459,17 @@ export class StatOperations extends VeryfrontOperationsBase {
|
|
|
459
459
|
logger.debug("Skipping API search for framework path", { normalizedPath });
|
|
460
460
|
return null;
|
|
461
461
|
}
|
|
462
|
-
// NOTE:
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
|
|
466
|
-
if (
|
|
467
|
-
|
|
468
|
-
return
|
|
469
|
-
}
|
|
470
|
-
const searchPattern = `${pathWithoutExt}.*`;
|
|
471
|
-
logger.debug("Searching for file via API", {
|
|
472
|
-
pattern: searchPattern,
|
|
473
|
-
normalizedPath,
|
|
474
|
-
});
|
|
475
|
-
try {
|
|
476
|
-
const matches = await this.client.searchFiles(searchPattern);
|
|
477
|
-
this.apiSearchCircuitBreaker.recordSuccess();
|
|
478
|
-
logger.debug("API search result", {
|
|
479
|
-
pattern: searchPattern,
|
|
480
|
-
matchCount: matches.length,
|
|
481
|
-
matches: matches.map((m) => m.path).slice(0, 5),
|
|
482
|
-
});
|
|
483
|
-
const sortedMatches = sortPathsByExtensionPriority(matches, EXTENSION_PRIORITY);
|
|
484
|
-
const first = sortedMatches[0];
|
|
485
|
-
if (first) {
|
|
486
|
-
logger.debug("resolveFile found via API search", { path: first.path });
|
|
487
|
-
this.cache.set(cacheKey, first.path);
|
|
488
|
-
return first.path;
|
|
489
|
-
}
|
|
462
|
+
// NOTE: Keep the post-index API fallback aligned with the pre-index helper for extensionless
|
|
463
|
+
// paths, while preserving the older wildcard sibling-extension lookup for known-extension
|
|
464
|
+
// paths. Incomplete file-list snapshots otherwise hide valid files until the cache refreshes.
|
|
465
|
+
const apiResolved = await this.tryResolveViaApiSearch(normalizedPath, options, "wildcard");
|
|
466
|
+
if (typeof apiResolved === "string") {
|
|
467
|
+
this.cache.set(cacheKey, apiResolved);
|
|
468
|
+
return apiResolved;
|
|
490
469
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
if (result.tripped) {
|
|
494
|
-
logger.warn("API search circuit breaker tripped", {
|
|
495
|
-
failures: result.failures,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
logger.error("API pattern search failed", { pattern: searchPattern, error });
|
|
470
|
+
if (apiResolved === null) {
|
|
471
|
+
this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
|
|
499
472
|
}
|
|
500
|
-
logger.debug("resolveFile not found after API search", {
|
|
501
|
-
normalizedPath,
|
|
502
|
-
pathWithoutExt,
|
|
503
|
-
});
|
|
504
|
-
this.cache.set(cacheKey, NOT_FOUND_SENTINEL);
|
|
505
473
|
return null;
|
|
506
474
|
}
|
|
507
475
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { APIRoute, LoadModuleOptions } from "./types.js";
|
|
2
|
+
import type { FileSystem } from "../../../platform/compat/fs.js";
|
|
2
3
|
export declare function toCjsDestructureBindings(bindings: string): string;
|
|
3
4
|
export declare function loadHandlerModule(options: LoadModuleOptions): Promise<APIRoute | null>;
|
|
5
|
+
export declare function getNodeExternalPackagesToResolve(userDeps: Map<string, string>): string[];
|
|
6
|
+
export declare function resolveNodePackageToFileUrl(projectDir: string, packageName: string, fs: FileSystem, pathToFileURL: typeof import("node:url").pathToFileURL): Promise<string | null>;
|
|
7
|
+
export declare function loadVeryfrontExportsMap(projectDir: string, fs: FileSystem): Promise<Record<string, {
|
|
8
|
+
import?: string;
|
|
9
|
+
}>>;
|
|
10
|
+
export declare function rewriteNodeExternalImports(code: string, projectDir: string, fs: FileSystem, userDeps: Map<string, string>): Promise<string>;
|
|
4
11
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/routing/api/module-loader/loader.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/routing/api/module-loader/loader.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AA4KjE,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAejE;AAgBD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyBtF;AAuaD,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAUxF;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,UAAU,EACd,aAAa,EAAE,cAAc,UAAU,EAAE,aAAa,GACrD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,UAAU,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAW9C;AAED,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,UAAU,EACd,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,MAAM,CAAC,CA6EjB"}
|
|
@@ -512,105 +512,115 @@ async function loadModuleFromCode(code, projectDir, fs, userDeps = new Map()) {
|
|
|
512
512
|
await fs.remove(tempDir, { recursive: true });
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
|
-
|
|
515
|
+
export function getNodeExternalPackagesToResolve(userDeps) {
|
|
516
|
+
const externalPackagesToResolve = ["zod"];
|
|
517
|
+
for (const name of userDeps.keys()) {
|
|
518
|
+
if (!externalPackagesToResolve.includes(name)) {
|
|
519
|
+
externalPackagesToResolve.push(name);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return externalPackagesToResolve;
|
|
523
|
+
}
|
|
524
|
+
export async function resolveNodePackageToFileUrl(projectDir, packageName, fs, pathToFileURL) {
|
|
525
|
+
const packagePath = pathHelper.join(projectDir, "node_modules", packageName);
|
|
526
|
+
const packageJsonPath = pathHelper.join(packagePath, "package.json");
|
|
527
|
+
try {
|
|
528
|
+
const pkgJson = JSON.parse(await fs.readTextFile(packageJsonPath));
|
|
529
|
+
let entryPoint;
|
|
530
|
+
if (pkgJson.exports) {
|
|
531
|
+
entryPoint = resolveExportEntry(pkgJson.exports["."]);
|
|
532
|
+
}
|
|
533
|
+
entryPoint ||= pkgJson.module || pkgJson.main || "index.js";
|
|
534
|
+
if (!entryPoint)
|
|
535
|
+
return null;
|
|
536
|
+
return pathToFileURL(pathHelper.join(packagePath, entryPoint)).href;
|
|
537
|
+
}
|
|
538
|
+
catch (_) {
|
|
539
|
+
/* expected: package.json may not exist or be invalid */
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
export async function loadVeryfrontExportsMap(projectDir, fs) {
|
|
544
|
+
const vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
|
|
545
|
+
const vfPackageJsonPath = pathHelper.join(vfPackagePath, "package.json");
|
|
546
|
+
try {
|
|
547
|
+
const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));
|
|
548
|
+
return pkgJson.exports || {};
|
|
549
|
+
}
|
|
550
|
+
catch (_error) {
|
|
551
|
+
logger.debug("Could not read veryfront package.json");
|
|
552
|
+
return {};
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
export async function rewriteNodeExternalImports(code, projectDir, fs, userDeps) {
|
|
556
|
+
const { pathToFileURL } = await import("node:url");
|
|
516
557
|
let transformed = code;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
/* expected: package.json may not exist or be invalid */
|
|
537
|
-
return null;
|
|
538
|
-
}
|
|
539
|
-
};
|
|
540
|
-
const externalPackagesToResolve = ["zod"];
|
|
541
|
-
for (const name of userDeps.keys()) {
|
|
542
|
-
if (!externalPackagesToResolve.includes(name)) {
|
|
543
|
-
externalPackagesToResolve.push(name);
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
for (const pkg of externalPackagesToResolve) {
|
|
547
|
-
const escapedPkg = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
548
|
-
// Match both exact imports (from "pkg") and subpath imports (from "pkg/sub")
|
|
549
|
-
const staticImportRegex = new RegExp(`from\\s*["']${escapedPkg}(/[^"']*)?["']`, "g");
|
|
550
|
-
const dynamicImportRegex = new RegExp(`import\\s*\\(\\s*["']${escapedPkg}(/[^"']*)?["']\\s*\\)`, "g");
|
|
551
|
-
const needsStatic = staticImportRegex.test(transformed);
|
|
552
|
-
staticImportRegex.lastIndex = 0;
|
|
553
|
-
const needsDynamic = dynamicImportRegex.test(transformed);
|
|
554
|
-
dynamicImportRegex.lastIndex = 0;
|
|
555
|
-
if (!needsStatic && !needsDynamic)
|
|
556
|
-
continue;
|
|
557
|
-
const packageDir = pathToFileURL(pathHelper.join(projectDir, "node_modules", pkg)).href;
|
|
558
|
-
const resolvedUrl = await resolvePackageToFileUrl(pkg);
|
|
559
|
-
if (needsStatic) {
|
|
560
|
-
transformed = transformed.replace(staticImportRegex, (_, subpath) => {
|
|
561
|
-
if (subpath) {
|
|
562
|
-
const subUrl = `${packageDir}${subpath}`;
|
|
563
|
-
logger.debug(`Resolved ${pkg}${subpath} -> ${subUrl}`);
|
|
564
|
-
return `from "${subUrl}"`;
|
|
565
|
-
}
|
|
566
|
-
if (!resolvedUrl)
|
|
567
|
-
return `from "${pkg}"`;
|
|
568
|
-
logger.debug(`Resolved ${pkg} -> ${resolvedUrl}`);
|
|
569
|
-
return `from "${resolvedUrl}"`;
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
if (needsDynamic) {
|
|
573
|
-
transformed = transformed.replace(dynamicImportRegex, (_, subpath) => {
|
|
574
|
-
if (subpath) {
|
|
575
|
-
const subUrl = `${packageDir}${subpath}`;
|
|
576
|
-
return `import("${subUrl}")`;
|
|
577
|
-
}
|
|
578
|
-
if (!resolvedUrl)
|
|
579
|
-
return `import("${pkg}")`;
|
|
580
|
-
return `import("${resolvedUrl}")`;
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
const vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
|
|
585
|
-
const vfPackageJsonPath = pathHelper.join(vfPackagePath, "package.json");
|
|
586
|
-
let exportsMap = {};
|
|
587
|
-
try {
|
|
588
|
-
const pkgJson = JSON.parse(await fs.readTextFile(vfPackageJsonPath));
|
|
589
|
-
exportsMap = pkgJson.exports || {};
|
|
590
|
-
}
|
|
591
|
-
catch (_error) {
|
|
592
|
-
logger.debug(`Could not read veryfront package.json: `);
|
|
593
|
-
}
|
|
594
|
-
transformed = transformed.replace(/from\s+["'](veryfront\/[^"']+)["']/g, (match, fullSpecifier) => {
|
|
595
|
-
const subpath = "./" + fullSpecifier.replace("veryfront/", "");
|
|
596
|
-
const exportEntry = exportsMap[subpath];
|
|
597
|
-
if (!exportEntry?.import) {
|
|
598
|
-
logger.warn(`No export found for ${subpath}`);
|
|
599
|
-
return match;
|
|
558
|
+
logger.debug(`Rewriting external imports for Node.js, projectDir: ${projectDir}`);
|
|
559
|
+
for (const pkg of getNodeExternalPackagesToResolve(userDeps)) {
|
|
560
|
+
const escapedPkg = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
561
|
+
const staticImportRegex = new RegExp(`from\\s*["']${escapedPkg}(/[^"']*)?["']`, "g");
|
|
562
|
+
const dynamicImportRegex = new RegExp(`import\\s*\\(\\s*["']${escapedPkg}(/[^"']*)?["']\\s*\\)`, "g");
|
|
563
|
+
const needsStatic = staticImportRegex.test(transformed);
|
|
564
|
+
staticImportRegex.lastIndex = 0;
|
|
565
|
+
const needsDynamic = dynamicImportRegex.test(transformed);
|
|
566
|
+
dynamicImportRegex.lastIndex = 0;
|
|
567
|
+
if (!needsStatic && !needsDynamic)
|
|
568
|
+
continue;
|
|
569
|
+
const packageDir = pathToFileURL(pathHelper.join(projectDir, "node_modules", pkg)).href;
|
|
570
|
+
const resolvedUrl = await resolveNodePackageToFileUrl(projectDir, pkg, fs, pathToFileURL);
|
|
571
|
+
if (needsStatic) {
|
|
572
|
+
transformed = transformed.replace(staticImportRegex, (_, subpath) => {
|
|
573
|
+
if (subpath) {
|
|
574
|
+
const subUrl = `${packageDir}${subpath}`;
|
|
575
|
+
logger.debug(`Resolved ${pkg}${subpath} -> ${subUrl}`);
|
|
576
|
+
return `from "${subUrl}"`;
|
|
600
577
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
578
|
+
if (!resolvedUrl)
|
|
579
|
+
return `from "${pkg}"`;
|
|
580
|
+
logger.debug(`Resolved ${pkg} -> ${resolvedUrl}`);
|
|
581
|
+
return `from "${resolvedUrl}"`;
|
|
604
582
|
});
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
583
|
+
}
|
|
584
|
+
if (needsDynamic) {
|
|
585
|
+
transformed = transformed.replace(dynamicImportRegex, (_, subpath) => {
|
|
586
|
+
if (subpath) {
|
|
587
|
+
return `import("${packageDir}${subpath}")`;
|
|
588
|
+
}
|
|
589
|
+
if (!resolvedUrl)
|
|
590
|
+
return `import("${pkg}")`;
|
|
591
|
+
return `import("${resolvedUrl}")`;
|
|
612
592
|
});
|
|
613
593
|
}
|
|
594
|
+
}
|
|
595
|
+
const vfPackagePath = pathHelper.join(projectDir, "node_modules", "veryfront");
|
|
596
|
+
const exportsMap = await loadVeryfrontExportsMap(projectDir, fs);
|
|
597
|
+
transformed = transformed.replace(/from\s+["'](veryfront\/[^"']+)["']/g, (match, fullSpecifier) => {
|
|
598
|
+
const subpath = "./" + fullSpecifier.replace("veryfront/", "");
|
|
599
|
+
const exportEntry = exportsMap[subpath];
|
|
600
|
+
if (!exportEntry?.import) {
|
|
601
|
+
logger.warn(`No export found for ${subpath}`);
|
|
602
|
+
return match;
|
|
603
|
+
}
|
|
604
|
+
const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
|
|
605
|
+
logger.debug(`Resolved ${fullSpecifier} -> ${resolvedPath}`);
|
|
606
|
+
return `from "${pathToFileURL(resolvedPath).href}"`;
|
|
607
|
+
});
|
|
608
|
+
transformed = transformed.replace(/from\s+["']veryfront["']/g, () => {
|
|
609
|
+
const exportEntry = exportsMap["."];
|
|
610
|
+
if (!exportEntry?.import)
|
|
611
|
+
return 'from "veryfront"';
|
|
612
|
+
const resolvedPath = pathHelper.join(vfPackagePath, exportEntry.import);
|
|
613
|
+
logger.debug(`Resolved veryfront -> ${resolvedPath}`);
|
|
614
|
+
return `from "${pathToFileURL(resolvedPath).href}"`;
|
|
615
|
+
});
|
|
616
|
+
return transformed;
|
|
617
|
+
}
|
|
618
|
+
async function rewriteExternalImports(code, projectDir, fs, userDeps = new Map()) {
|
|
619
|
+
let transformed = code;
|
|
620
|
+
if (isNode) {
|
|
621
|
+
try {
|
|
622
|
+
transformed = await rewriteNodeExternalImports(transformed, projectDir, fs, userDeps);
|
|
623
|
+
}
|
|
614
624
|
catch (e) {
|
|
615
625
|
logger.warn(`Failed to import node:module: ${e}`);
|
|
616
626
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.161";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
|
@@ -87,6 +87,15 @@ function getBranchParam(branch?: string): string {
|
|
|
87
87
|
return branch ? `?branch_id=${branch}` : "";
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
function buildProjectApiPath(project: string, resource: string, branch?: string): string {
|
|
91
|
+
const normalizedResource = resource.startsWith("/") ? resource.slice(1) : resource;
|
|
92
|
+
return `/${project}${getBranchPath(branch)}/${normalizedResource}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function buildProjectFilePath(project: string, filePath: string, branch?: string): string {
|
|
96
|
+
return buildProjectApiPath(project, `files/${encodeFilePath(filePath)}`, branch);
|
|
97
|
+
}
|
|
98
|
+
|
|
90
99
|
interface RemoteFile {
|
|
91
100
|
id?: string;
|
|
92
101
|
path: string;
|
|
@@ -214,9 +223,9 @@ export const vfRemoteListFiles: MCPTool<RemoteListFilesInput, RemoteListFilesOut
|
|
|
214
223
|
params.set("limit", String(input.limit));
|
|
215
224
|
params.set("fields", "(path,type,size)");
|
|
216
225
|
|
|
217
|
-
const apiPath =
|
|
218
|
-
|
|
219
|
-
}
|
|
226
|
+
const apiPath = `${
|
|
227
|
+
buildProjectApiPath(input.project, "files", input.branch)
|
|
228
|
+
}?${params.toString()}`;
|
|
220
229
|
const result = await apiRequest<FileListResponse>("GET", apiPath);
|
|
221
230
|
if (!result.ok) return { success: false, error: result.error };
|
|
222
231
|
|
|
@@ -260,9 +269,7 @@ export const vfRemoteGetFile: MCPTool<RemoteGetFileInput, RemoteGetFileOutput> =
|
|
|
260
269
|
withSpan(
|
|
261
270
|
"cli.mcp.tool.vf_remote_get_file",
|
|
262
271
|
async () => {
|
|
263
|
-
const apiPath =
|
|
264
|
-
encodeFilePath(input.path)
|
|
265
|
-
}`;
|
|
272
|
+
const apiPath = buildProjectFilePath(input.project, input.path, input.branch);
|
|
266
273
|
const result = await apiRequest<RemoteFile>("GET", apiPath);
|
|
267
274
|
if (!result.ok) return { success: false, error: result.error };
|
|
268
275
|
|
|
@@ -314,7 +321,7 @@ export const vfRemoteUpdateFile: MCPTool<RemoteUpdateFileInput, RemoteUpdateFile
|
|
|
314
321
|
withSpan(
|
|
315
322
|
"cli.mcp.tool.vf_remote_update_file",
|
|
316
323
|
async () => {
|
|
317
|
-
const apiPath =
|
|
324
|
+
const apiPath = `${buildProjectFilePath(input.project, input.path)}${
|
|
318
325
|
getBranchParam(input.branch)
|
|
319
326
|
}`;
|
|
320
327
|
const result = await apiRequest<{ id: string; path: string }>("PUT", apiPath, {
|
|
@@ -362,7 +369,7 @@ export const vfRemoteDeleteFile: MCPTool<RemoteDeleteFileInput, RemoteDeleteFile
|
|
|
362
369
|
description: "Delete a file from a remote Veryfront project.",
|
|
363
370
|
inputSchema: remoteDeleteFileInput,
|
|
364
371
|
execute: async (input) => {
|
|
365
|
-
const apiPath =
|
|
372
|
+
const apiPath = `${buildProjectFilePath(input.project, input.path)}${
|
|
366
373
|
getBranchParam(input.branch)
|
|
367
374
|
}`;
|
|
368
375
|
const result = await apiRequest<void>("DELETE", apiPath);
|
|
@@ -405,7 +412,7 @@ export const vfRemoteSearchFiles: MCPTool<RemoteSearchFilesInput, RemoteSearchFi
|
|
|
405
412
|
withSpan(
|
|
406
413
|
"cli.mcp.tool.vf_remote_search_files",
|
|
407
414
|
async () => {
|
|
408
|
-
const apiPath =
|
|
415
|
+
const apiPath = buildProjectApiPath(input.project, "files/search", input.branch);
|
|
409
416
|
const result = await apiRequest<SearchResponse>("POST", apiPath, {
|
|
410
417
|
body: {
|
|
411
418
|
query: input.query,
|
|
@@ -455,7 +462,11 @@ export const vfRemoteMoveFile: MCPTool<RemoteMoveFileInput, RemoteMoveFileOutput
|
|
|
455
462
|
description: "Move or rename a file in a remote Veryfront project.",
|
|
456
463
|
inputSchema: remoteMoveFileInput,
|
|
457
464
|
execute: async (input) => {
|
|
458
|
-
const apiPath =
|
|
465
|
+
const apiPath = `${buildProjectApiPath(input.project, "files/move")}${
|
|
466
|
+
getBranchParam(
|
|
467
|
+
input.branch,
|
|
468
|
+
)
|
|
469
|
+
}`;
|
|
459
470
|
const result = await apiRequest<{ source_path: string; destination_path: string }>(
|
|
460
471
|
"POST",
|
|
461
472
|
apiPath,
|
|
@@ -732,7 +743,7 @@ export const vfRemoteCloneProject: MCPTool<RemoteCloneProjectInput, RemoteCloneP
|
|
|
732
743
|
|
|
733
744
|
const listResult = await apiRequest<FileListResponse>(
|
|
734
745
|
"GET",
|
|
735
|
-
|
|
746
|
+
`${buildProjectApiPath(input.source_project, "files")}?${params.toString()}`,
|
|
736
747
|
);
|
|
737
748
|
|
|
738
749
|
if (!listResult.ok) {
|
|
@@ -750,7 +761,7 @@ export const vfRemoteCloneProject: MCPTool<RemoteCloneProjectInput, RemoteCloneP
|
|
|
750
761
|
for (const file of sourceFiles) {
|
|
751
762
|
const getResult = await apiRequest<RemoteFile>(
|
|
752
763
|
"GET",
|
|
753
|
-
|
|
764
|
+
buildProjectFilePath(input.source_project, file.path),
|
|
754
765
|
);
|
|
755
766
|
|
|
756
767
|
if (!getResult.ok || !getResult.data) {
|
|
@@ -760,7 +771,7 @@ export const vfRemoteCloneProject: MCPTool<RemoteCloneProjectInput, RemoteCloneP
|
|
|
760
771
|
|
|
761
772
|
const createFileResult = await apiRequest<{ id: string; path: string }>(
|
|
762
773
|
"PUT",
|
|
763
|
-
|
|
774
|
+
buildProjectFilePath(createResult.slug, file.path),
|
|
764
775
|
{ body: { content: getResult.data.content } },
|
|
765
776
|
);
|
|
766
777
|
|
package/src/deno.js
CHANGED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AgUiRuntimeRunIdSchema } from "./runtime-ag-ui-contract.js";
|
|
3
|
+
import { RunResumeSessionManager } from "./runtime/index.js";
|
|
4
|
+
|
|
5
|
+
const TOOL_CALL_ID_SCHEMA = z.string().min(1).max(128);
|
|
6
|
+
|
|
7
|
+
export const HumanInputOptionSchema = z.object({
|
|
8
|
+
value: z.string(),
|
|
9
|
+
label: z.string(),
|
|
10
|
+
description: z.string().optional(),
|
|
11
|
+
recommended: z.boolean().optional(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const BaseHumanInputFieldSchema = z.object({
|
|
15
|
+
name: z.string().min(1).max(128),
|
|
16
|
+
label: z.string().min(1).max(256),
|
|
17
|
+
description: z.string().max(1024).optional(),
|
|
18
|
+
required: z.boolean().optional().default(false),
|
|
19
|
+
secret: z.boolean().optional().default(false),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const HumanInputFieldSchema = z.discriminatedUnion("type", [
|
|
23
|
+
BaseHumanInputFieldSchema.extend({
|
|
24
|
+
type: z.enum(["text", "email", "url", "password", "number"]),
|
|
25
|
+
placeholder: z.string().max(512).optional(),
|
|
26
|
+
defaultValue: z.string().optional(),
|
|
27
|
+
pattern: z.string().max(512).optional(),
|
|
28
|
+
minLength: z.number().int().nonnegative().optional(),
|
|
29
|
+
maxLength: z.number().int().positive().optional(),
|
|
30
|
+
min: z.number().optional(),
|
|
31
|
+
max: z.number().optional(),
|
|
32
|
+
}),
|
|
33
|
+
BaseHumanInputFieldSchema.extend({
|
|
34
|
+
type: z.literal("textarea"),
|
|
35
|
+
placeholder: z.string().max(512).optional(),
|
|
36
|
+
defaultValue: z.string().optional(),
|
|
37
|
+
minLength: z.number().int().nonnegative().optional(),
|
|
38
|
+
maxLength: z.number().int().positive().optional(),
|
|
39
|
+
rows: z.number().int().positive().optional().default(3),
|
|
40
|
+
}),
|
|
41
|
+
BaseHumanInputFieldSchema.extend({
|
|
42
|
+
type: z.literal("select"),
|
|
43
|
+
options: z.array(HumanInputOptionSchema).min(1),
|
|
44
|
+
defaultValue: z.string().optional(),
|
|
45
|
+
placeholder: z.string().max(512).optional(),
|
|
46
|
+
}),
|
|
47
|
+
BaseHumanInputFieldSchema.extend({
|
|
48
|
+
type: z.literal("checkbox"),
|
|
49
|
+
defaultValue: z.boolean().optional().default(false),
|
|
50
|
+
}),
|
|
51
|
+
BaseHumanInputFieldSchema.extend({
|
|
52
|
+
type: z.literal("radio"),
|
|
53
|
+
options: z.array(HumanInputOptionSchema).min(1),
|
|
54
|
+
defaultValue: z.string().optional(),
|
|
55
|
+
}),
|
|
56
|
+
BaseHumanInputFieldSchema.extend({
|
|
57
|
+
type: z.literal("confirm"),
|
|
58
|
+
confirmLabel: z.string().max(64).optional().default("Yes"),
|
|
59
|
+
denyLabel: z.string().max(64).optional().default("No"),
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
export const HumanInputRequestSchema = z.object({
|
|
64
|
+
title: z.string().min(1).max(256),
|
|
65
|
+
description: z.string().max(2048).optional(),
|
|
66
|
+
fields: z.array(HumanInputFieldSchema).min(1),
|
|
67
|
+
submitLabel: z.string().max(64).optional().default("Submit"),
|
|
68
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const HumanInputResponseValuesSchema = z.record(
|
|
72
|
+
z.string(),
|
|
73
|
+
z.union([z.string(), z.boolean(), z.number(), z.null()]),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
export const HumanInputResultSchema = z.discriminatedUnion("submitted", [
|
|
77
|
+
z.object({
|
|
78
|
+
submitted: z.literal(true),
|
|
79
|
+
values: HumanInputResponseValuesSchema,
|
|
80
|
+
}),
|
|
81
|
+
z.object({
|
|
82
|
+
submitted: z.literal(false),
|
|
83
|
+
values: HumanInputResponseValuesSchema.default({}),
|
|
84
|
+
}),
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
export const HumanInputPendingRequestSchema = z.object({
|
|
88
|
+
runId: AgUiRuntimeRunIdSchema,
|
|
89
|
+
toolCallId: TOOL_CALL_ID_SCHEMA,
|
|
90
|
+
request: HumanInputRequestSchema,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export type HumanInputOption = z.infer<typeof HumanInputOptionSchema>;
|
|
94
|
+
export type HumanInputField = z.infer<typeof HumanInputFieldSchema>;
|
|
95
|
+
export type HumanInputFieldInput = z.input<typeof HumanInputFieldSchema>;
|
|
96
|
+
export type HumanInputRequest = z.infer<typeof HumanInputRequestSchema>;
|
|
97
|
+
export type HumanInputRequestInput = z.input<typeof HumanInputRequestSchema>;
|
|
98
|
+
export type HumanInputResult = z.infer<typeof HumanInputResultSchema>;
|
|
99
|
+
export type HumanInputPendingRequest = z.infer<typeof HumanInputPendingRequestSchema>;
|
|
100
|
+
|
|
101
|
+
type HumanInputResumeValue = {
|
|
102
|
+
result: unknown;
|
|
103
|
+
isError: boolean;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export interface WaitForHumanInputOptions {
|
|
107
|
+
sessionManager: RunResumeSessionManager<HumanInputResumeValue>;
|
|
108
|
+
runId: string;
|
|
109
|
+
toolCallId: string;
|
|
110
|
+
request: HumanInputRequestInput;
|
|
111
|
+
onRequest?: ((request: HumanInputPendingRequest) => void | Promise<void>) | undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export class HumanInputResumeError extends Error {
|
|
115
|
+
constructor(readonly detail: unknown) {
|
|
116
|
+
super(
|
|
117
|
+
typeof detail === "string" ? detail : "Human input resume failed",
|
|
118
|
+
);
|
|
119
|
+
this.name = "HumanInputResumeError";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export class InvalidHumanInputResultError extends Error {
|
|
124
|
+
constructor(readonly detail: z.ZodIssue[]) {
|
|
125
|
+
super("Invalid human input resume payload");
|
|
126
|
+
this.name = "InvalidHumanInputResultError";
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export async function waitForHumanInput(
|
|
131
|
+
options: WaitForHumanInputOptions,
|
|
132
|
+
): Promise<HumanInputResult> {
|
|
133
|
+
const pendingRequest = HumanInputPendingRequestSchema.parse({
|
|
134
|
+
runId: options.runId,
|
|
135
|
+
toolCallId: options.toolCallId,
|
|
136
|
+
request: options.request,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
await options.onRequest?.(pendingRequest);
|
|
140
|
+
|
|
141
|
+
const resumed = await options.sessionManager.waitForSignal(options.runId, options.toolCallId);
|
|
142
|
+
if (resumed.isError) {
|
|
143
|
+
throw new HumanInputResumeError(resumed.result);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const parsed = HumanInputResultSchema.safeParse(resumed.result);
|
|
147
|
+
if (!parsed.success) {
|
|
148
|
+
throw new InvalidHumanInputResultError(parsed.error.issues);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return parsed.data;
|
|
152
|
+
}
|
package/src/src/agent/index.ts
CHANGED
|
@@ -97,7 +97,13 @@ export type {
|
|
|
97
97
|
MessagePart,
|
|
98
98
|
ModelProvider,
|
|
99
99
|
ModelString,
|
|
100
|
+
ModelTransportRequest,
|
|
101
|
+
ModelTransportResolver,
|
|
100
102
|
ResolvedAgentConfig,
|
|
103
|
+
ResolvedModelTransport,
|
|
104
|
+
ResolvedRuntimeState,
|
|
105
|
+
RuntimeStateRequest,
|
|
106
|
+
RuntimeStateResolver,
|
|
101
107
|
StreamToolCall,
|
|
102
108
|
ToolCall,
|
|
103
109
|
ToolCallPart,
|
|
@@ -162,6 +168,24 @@ export {
|
|
|
162
168
|
AgUiRequestSchema,
|
|
163
169
|
createAgUiHandler,
|
|
164
170
|
} from "./ag-ui-handler.js";
|
|
171
|
+
export {
|
|
172
|
+
type HumanInputField,
|
|
173
|
+
type HumanInputFieldInput,
|
|
174
|
+
HumanInputFieldSchema,
|
|
175
|
+
type HumanInputOption,
|
|
176
|
+
HumanInputOptionSchema,
|
|
177
|
+
type HumanInputPendingRequest,
|
|
178
|
+
HumanInputPendingRequestSchema,
|
|
179
|
+
type HumanInputRequest,
|
|
180
|
+
type HumanInputRequestInput,
|
|
181
|
+
HumanInputRequestSchema,
|
|
182
|
+
type HumanInputResult,
|
|
183
|
+
HumanInputResultSchema,
|
|
184
|
+
HumanInputResumeError,
|
|
185
|
+
InvalidHumanInputResultError,
|
|
186
|
+
waitForHumanInput,
|
|
187
|
+
type WaitForHumanInputOptions,
|
|
188
|
+
} from "./human-input.js";
|
|
165
189
|
export {
|
|
166
190
|
type ChatHandlerBeforeStream,
|
|
167
191
|
type ChatHandlerBeforeStreamContext,
|