mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 05:02:11 +00:00
chore: sync workspace changes
This commit is contained in:
parent
4b5b390b7f
commit
4083baa1c1
55 changed files with 2431 additions and 840 deletions
|
|
@ -12,7 +12,8 @@
|
|||
"extract:claude-events": "tsx src/claude-event-types.ts",
|
||||
"extract:claude-events:sdk": "tsx src/claude-event-types-sdk.ts",
|
||||
"extract:claude-events:cli": "tsx src/claude-event-types-cli.ts",
|
||||
"extract:claude-events:docs": "tsx src/claude-event-types-docs.ts"
|
||||
"extract:claude-events:docs": "tsx src/claude-event-types-docs.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"ts-json-schema-generator": "^2.4.0",
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"tsx": "^4.19.0",
|
||||
"@types/node": "^22.0.0"
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/json-schema": "^7.0.15"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
resources/vercel-ai-sdk-schemas/.tmp/log.txt
Normal file
50
resources/vercel-ai-sdk-schemas/.tmp/log.txt
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
> vercel-ai-sdk-schemas@1.0.0 extract /home/nathan/sandbox-daemon/resources/vercel-ai-sdk-schemas
|
||||
> tsx src/index.ts
|
||||
|
||||
Vercel AI SDK UIMessage Schema Extractor
|
||||
========================================
|
||||
|
||||
[cache hit] https://registry.npmjs.org/ai
|
||||
Target version: ai@6.0.50
|
||||
[debug] temp dir: /tmp/vercel-ai-sdk-JnQ1yL
|
||||
[cache hit] https://registry.npmjs.org/ai
|
||||
[cache hit] https://registry.npmjs.org/@opentelemetry%2Fapi
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fgateway
|
||||
[cache hit] https://registry.npmjs.org/@vercel%2Foidc
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fprovider
|
||||
[cache hit] https://registry.npmjs.org/json-schema
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fprovider-utils
|
||||
[cache hit] https://registry.npmjs.org/@standard-schema%2Fspec
|
||||
[cache hit] https://registry.npmjs.org/eventsource-parser
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fprovider
|
||||
[cache hit] https://registry.npmjs.org/zod
|
||||
[cache hit] https://registry.npmjs.org/zod
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fprovider
|
||||
[cache hit] https://registry.npmjs.org/@ai-sdk%2Fprovider-utils
|
||||
[cache hit] https://registry.npmjs.org/zod
|
||||
[shim] Wrote type-fest ValueOf shim
|
||||
[debug] DataUIPart alias snippet: type DataUIPart<DATA_TYPES extends UIDataTypes> = ValueOf<{
|
||||
[NAME in keyof DATA_TYPES & string]: {
|
||||
type: `data-${NAME}`;
|
||||
[patch] Simplified DataUIPart to avoid indexed access
|
||||
[debug] ToolUIPart alias snippet: type ToolUIPart<TOOLS extends UITools = UITools> = ValueOf<{
|
||||
[NAME in keyof TOOLS & string]: {
|
||||
type: `tool-${NAME}`;
|
||||
[patch] Simplified ToolUIPart to avoid indexed access
|
||||
[warn] ValueOf alias declaration not found
|
||||
[warn] ValueOf alias not found in ai types
|
||||
[debug] ai types path: /tmp/vercel-ai-sdk-JnQ1yL/node_modules/ai/dist/index.d.ts
|
||||
[debug] preview: ValueOf} from 'type-fest';
|
||||
import data = require('./data.json');
|
||||
|
||||
export function getData(name: string): ValueOf<typeof data> {
|
||||
return data[name];
|
||||
}
|
||||
|
||||
export function onlyBar(name: string): ValueOf
|
||||
[debug] entry path: /tmp/vercel-ai-sdk-JnQ1yL/entry.ts
|
||||
[debug] tsconfig path: /tmp/vercel-ai-sdk-JnQ1yL/tsconfig.json
|
||||
[debug] entry size: 89
|
||||
|
||||
[wrote] /home/nathan/sandbox-daemon/resources/vercel-ai-sdk-schemas/artifacts/json-schema/ui-message.json
|
||||
23
resources/vercel-ai-sdk-schemas/README.md
Normal file
23
resources/vercel-ai-sdk-schemas/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Vercel AI SDK Schemas
|
||||
|
||||
This package extracts JSON Schema for `UIMessage` from the Vercel AI SDK v6 TypeScript types.
|
||||
|
||||
## Usage
|
||||
|
||||
- Install dependencies in this folder.
|
||||
- Run the extractor:
|
||||
|
||||
```
|
||||
pnpm install
|
||||
pnpm extract
|
||||
```
|
||||
|
||||
Optional flags:
|
||||
- `--version=6.x.y` to pin an exact version
|
||||
- `--major=6` to select the latest version for a major (default: 6)
|
||||
|
||||
Output:
|
||||
- `artifacts/json-schema/ui-message.json`
|
||||
|
||||
The registry response is cached under `.cache/` for 24 hours. The extractor downloads the AI SDK package
|
||||
and the minimal dependency tree needed for TypeScript type resolution into a temporary folder.
|
||||
File diff suppressed because it is too large
Load diff
22
resources/vercel-ai-sdk-schemas/package.json
Normal file
22
resources/vercel-ai-sdk-schemas/package.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "vercel-ai-sdk-schemas",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"extract": "tsx src/index.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"ts-json-schema-generator": "^2.4.0",
|
||||
"typescript": "^5.7.0",
|
||||
"tar": "^7.0.0",
|
||||
"semver": "^7.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsx": "^4.19.0",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@types/json-schema": "^7.0.15"
|
||||
}
|
||||
}
|
||||
93
resources/vercel-ai-sdk-schemas/src/cache.ts
Normal file
93
resources/vercel-ai-sdk-schemas/src/cache.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import { createHash } from "crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
const CACHE_DIR = join(import.meta.dirname, "..", ".cache");
|
||||
const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
||||
|
||||
interface CacheEntry<T> {
|
||||
data: T;
|
||||
timestamp: number;
|
||||
ttl: number;
|
||||
}
|
||||
|
||||
function ensureCacheDir(): void {
|
||||
if (!existsSync(CACHE_DIR)) {
|
||||
mkdirSync(CACHE_DIR, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
function hashKey(key: string): string {
|
||||
return createHash("sha256").update(key).digest("hex");
|
||||
}
|
||||
|
||||
function getCachePath(key: string): string {
|
||||
return join(CACHE_DIR, `${hashKey(key)}.json`);
|
||||
}
|
||||
|
||||
export function getCached<T>(key: string): T | null {
|
||||
const path = getCachePath(key);
|
||||
|
||||
if (!existsSync(path)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = readFileSync(path, "utf-8");
|
||||
const entry: CacheEntry<T> = JSON.parse(content);
|
||||
|
||||
const now = Date.now();
|
||||
if (now - entry.timestamp > entry.ttl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entry.data;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function setCache<T>(key: string, data: T, ttl: number = DEFAULT_TTL_MS): void {
|
||||
ensureCacheDir();
|
||||
|
||||
const entry: CacheEntry<T> = {
|
||||
data,
|
||||
timestamp: Date.now(),
|
||||
ttl,
|
||||
};
|
||||
|
||||
const path = getCachePath(key);
|
||||
writeFileSync(path, JSON.stringify(entry, null, 2));
|
||||
}
|
||||
|
||||
export async function fetchWithCache(url: string, ttl?: number): Promise<string> {
|
||||
const cached = getCached<string>(url);
|
||||
if (cached !== null) {
|
||||
console.log(` [cache hit] ${url}`);
|
||||
return cached;
|
||||
}
|
||||
|
||||
console.log(` [fetching] ${url}`);
|
||||
|
||||
let lastError: Error | null = null;
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
const text = await response.text();
|
||||
setCache(url, text, ttl);
|
||||
return text;
|
||||
} catch (error) {
|
||||
lastError = error as Error;
|
||||
if (attempt < 2) {
|
||||
const delay = Math.pow(2, attempt) * 1000;
|
||||
console.log(` [retry ${attempt + 1}] waiting ${delay}ms...`);
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError;
|
||||
}
|
||||
398
resources/vercel-ai-sdk-schemas/src/index.ts
Normal file
398
resources/vercel-ai-sdk-schemas/src/index.ts
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
import {
|
||||
mkdtempSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
writeFileSync,
|
||||
existsSync,
|
||||
appendFileSync,
|
||||
statSync,
|
||||
} from "fs";
|
||||
import { join } from "path";
|
||||
import { tmpdir } from "os";
|
||||
import { createGenerator, type Config } from "ts-json-schema-generator";
|
||||
import { maxSatisfying, rsort, valid } from "semver";
|
||||
import { x as extractTar } from "tar";
|
||||
import type { JSONSchema7 } from "json-schema";
|
||||
import { fetchWithCache } from "./cache.js";
|
||||
|
||||
const REGISTRY_URL = "https://registry.npmjs.org/ai";
|
||||
const TARGET_TYPE = "UIMessage";
|
||||
const DEFAULT_MAJOR = 6;
|
||||
const RESOURCE_DIR = join(import.meta.dirname, "..");
|
||||
const OUTPUT_DIR = join(RESOURCE_DIR, "artifacts", "json-schema");
|
||||
const OUTPUT_PATH = join(OUTPUT_DIR, "ui-message.json");
|
||||
const SCHEMA_ID = "https://sandbox-agent/schemas/vercel-ai-sdk/ui-message.json";
|
||||
|
||||
interface RegistryResponse {
|
||||
versions?: Record<
|
||||
string,
|
||||
{
|
||||
dist?: { tarball?: string };
|
||||
dependencies?: Record<string, string>;
|
||||
peerDependencies?: Record<string, string>;
|
||||
}
|
||||
>;
|
||||
"dist-tags"?: Record<string, string>;
|
||||
}
|
||||
|
||||
interface Args {
|
||||
version: string | null;
|
||||
major: number;
|
||||
}
|
||||
|
||||
function parseArgs(): Args {
|
||||
const args = process.argv.slice(2);
|
||||
const versionArg = args.find((arg) => arg.startsWith("--version="));
|
||||
const majorArg = args.find((arg) => arg.startsWith("--major="));
|
||||
|
||||
const version = versionArg ? versionArg.split("=")[1] : null;
|
||||
const major = majorArg ? Number(majorArg.split("=")[1]) : DEFAULT_MAJOR;
|
||||
|
||||
return {
|
||||
version,
|
||||
major: Number.isFinite(major) && major > 0 ? major : DEFAULT_MAJOR,
|
||||
};
|
||||
}
|
||||
|
||||
function log(message: string): void {
|
||||
console.log(message);
|
||||
}
|
||||
|
||||
function ensureOutputDir(): void {
|
||||
if (!existsSync(OUTPUT_DIR)) {
|
||||
mkdirSync(OUTPUT_DIR, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchRegistry(url: string): Promise<RegistryResponse> {
|
||||
const registry = await fetchWithCache(url);
|
||||
return JSON.parse(registry) as RegistryResponse;
|
||||
}
|
||||
|
||||
function resolveLatestVersion(registry: RegistryResponse, major: number): string {
|
||||
const versions = Object.keys(registry.versions ?? {});
|
||||
const candidates = versions.filter((version) => valid(version) && version.startsWith(`${major}.`));
|
||||
const sorted = rsort(candidates);
|
||||
if (sorted.length === 0) {
|
||||
throw new Error(`No versions found for major ${major}`);
|
||||
}
|
||||
return sorted[0];
|
||||
}
|
||||
|
||||
function resolveVersionFromRange(registry: RegistryResponse, range: string): string {
|
||||
if (registry.versions?.[range]) {
|
||||
return range;
|
||||
}
|
||||
|
||||
const versions = Object.keys(registry.versions ?? {}).filter((version) => valid(version));
|
||||
const resolved = maxSatisfying(versions, range);
|
||||
if (!resolved) {
|
||||
throw new Error(`No versions satisfy range ${range}`);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
async function downloadTarball(url: string, destination: string): Promise<void> {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download tarball: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
const buffer = Buffer.from(await response.arrayBuffer());
|
||||
writeFileSync(destination, buffer);
|
||||
}
|
||||
|
||||
async function extractPackage(tarballPath: string, targetDir: string): Promise<void> {
|
||||
mkdirSync(targetDir, { recursive: true });
|
||||
await extractTar({
|
||||
file: tarballPath,
|
||||
cwd: targetDir,
|
||||
strip: 1,
|
||||
});
|
||||
}
|
||||
|
||||
function packageDirFor(name: string, nodeModulesDir: string): string {
|
||||
const parts = name.split("/");
|
||||
return join(nodeModulesDir, ...parts);
|
||||
}
|
||||
|
||||
async function installPackage(
|
||||
name: string,
|
||||
versionRange: string,
|
||||
nodeModulesDir: string,
|
||||
installed: Set<string>
|
||||
): Promise<void> {
|
||||
const encodedName = name.startsWith("@")
|
||||
? `@${encodeURIComponent(name.slice(1))}`
|
||||
: encodeURIComponent(name);
|
||||
const registryUrl = `https://registry.npmjs.org/${encodedName}`;
|
||||
const registry = await fetchRegistry(registryUrl);
|
||||
const version = resolveVersionFromRange(registry, versionRange);
|
||||
const installKey = `${name}@${version}`;
|
||||
|
||||
if (installed.has(installKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
installed.add(installKey);
|
||||
|
||||
const tarball = registry.versions?.[version]?.dist?.tarball;
|
||||
if (!tarball) {
|
||||
throw new Error(`No tarball found for ${installKey}`);
|
||||
}
|
||||
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "vercel-ai-sdk-dep-"));
|
||||
const tarballPath = join(tempDir, `${name.replace("/", "-")}-${version}.tgz`);
|
||||
const packageDir = packageDirFor(name, nodeModulesDir);
|
||||
|
||||
try {
|
||||
await downloadTarball(tarball, tarballPath);
|
||||
await extractPackage(tarballPath, packageDir);
|
||||
|
||||
const packageJsonPath = join(packageDir, "package.json");
|
||||
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as {
|
||||
dependencies?: Record<string, string>;
|
||||
peerDependencies?: Record<string, string>;
|
||||
};
|
||||
|
||||
const dependencies = {
|
||||
...packageJson.dependencies,
|
||||
...packageJson.peerDependencies,
|
||||
};
|
||||
|
||||
for (const [depName, depRange] of Object.entries(dependencies)) {
|
||||
await installPackage(depName, depRange, nodeModulesDir, installed);
|
||||
}
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
function writeTempTsconfig(tempDir: string): string {
|
||||
const tsconfigPath = join(tempDir, "tsconfig.json");
|
||||
const tsconfig = {
|
||||
compilerOptions: {
|
||||
target: "ES2022",
|
||||
module: "NodeNext",
|
||||
moduleResolution: "NodeNext",
|
||||
strict: true,
|
||||
skipLibCheck: true,
|
||||
esModuleInterop: true,
|
||||
},
|
||||
};
|
||||
writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2));
|
||||
return tsconfigPath;
|
||||
}
|
||||
|
||||
function writeEntryFile(tempDir: string): string {
|
||||
const entryPath = join(tempDir, "entry.ts");
|
||||
const contents = `import type { ${TARGET_TYPE} as AI${TARGET_TYPE} } from "ai";\nexport type ${TARGET_TYPE} = AI${TARGET_TYPE};\n`;
|
||||
writeFileSync(entryPath, contents);
|
||||
return entryPath;
|
||||
}
|
||||
|
||||
function patchValueOfAlias(nodeModulesDir: string): void {
|
||||
const aiTypesPath = join(nodeModulesDir, "ai", "dist", "index.d.ts");
|
||||
if (!existsSync(aiTypesPath)) {
|
||||
log(" [warn] ai types not found for ValueOf patch");
|
||||
return;
|
||||
}
|
||||
|
||||
const contents = readFileSync(aiTypesPath, "utf-8");
|
||||
const valueOfMatch = contents.match(/type ValueOf[\\s\\S]*?;/);
|
||||
if (valueOfMatch) {
|
||||
const snippet = valueOfMatch[0].replace(/\\s+/g, " ").slice(0, 200);
|
||||
log(` [debug] ValueOf alias snippet: ${snippet}`);
|
||||
} else {
|
||||
log(" [warn] ValueOf alias declaration not found");
|
||||
}
|
||||
|
||||
let patched = contents.replace(
|
||||
/ObjectType\\s*\\[\\s*ValueType\\s*\\]/,
|
||||
"ObjectType[string]"
|
||||
);
|
||||
|
||||
if (patched !== contents) {
|
||||
writeFileSync(aiTypesPath, patched);
|
||||
log(" [patch] Adjusted ValueOf alias for schema generation");
|
||||
return;
|
||||
}
|
||||
|
||||
const valueOfIndex = contents.indexOf("ValueOf");
|
||||
const preview =
|
||||
valueOfIndex === -1 ? contents.slice(0, 200) : contents.slice(valueOfIndex, valueOfIndex + 200);
|
||||
log(" [warn] ValueOf alias not found in ai types");
|
||||
log(` [debug] ai types path: ${aiTypesPath}`);
|
||||
log(` [debug] preview: ${preview.replace(/\\s+/g, " ").slice(0, 200)}`);
|
||||
}
|
||||
|
||||
function ensureTypeFestShim(nodeModulesDir: string): void {
|
||||
const typeFestDir = join(nodeModulesDir, "type-fest");
|
||||
if (!existsSync(typeFestDir)) {
|
||||
mkdirSync(typeFestDir, { recursive: true });
|
||||
}
|
||||
|
||||
const packageJsonPath = join(typeFestDir, "package.json");
|
||||
const typesPath = join(typeFestDir, "index.d.ts");
|
||||
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
const pkg = {
|
||||
name: "type-fest",
|
||||
version: "0.0.0",
|
||||
types: "index.d.ts",
|
||||
};
|
||||
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2));
|
||||
}
|
||||
|
||||
const shim = `export type ValueOf<\n ObjectType,\n ValueType extends keyof ObjectType = keyof ObjectType,\n> = ObjectType[string];\n\nexport type Simplify<T> = { [KeyType in keyof T]: T[KeyType] } & {};\n`;
|
||||
writeFileSync(typesPath, shim);
|
||||
log(" [shim] Wrote type-fest ValueOf shim");
|
||||
}
|
||||
|
||||
function generateSchema(entryPath: string, tsconfigPath: string): JSONSchema7 {
|
||||
const config: Config = {
|
||||
path: entryPath,
|
||||
tsconfig: tsconfigPath,
|
||||
type: TARGET_TYPE,
|
||||
expose: "export",
|
||||
skipTypeCheck: true,
|
||||
};
|
||||
|
||||
const generator = createGenerator(config);
|
||||
return generator.createSchema(TARGET_TYPE) as JSONSchema7;
|
||||
}
|
||||
|
||||
function addSchemaMetadata(schema: JSONSchema7, version: string): JSONSchema7 {
|
||||
const withMeta: JSONSchema7 = {
|
||||
...schema,
|
||||
$schema: schema.$schema ?? "http://json-schema.org/draft-07/schema#",
|
||||
$id: SCHEMA_ID,
|
||||
title: schema.title ?? TARGET_TYPE,
|
||||
description: schema.description ?? `Vercel AI SDK v${version} ${TARGET_TYPE}`,
|
||||
};
|
||||
|
||||
return withMeta;
|
||||
}
|
||||
|
||||
function loadFallback(): JSONSchema7 | null {
|
||||
if (!existsSync(OUTPUT_PATH)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = readFileSync(OUTPUT_PATH, "utf-8");
|
||||
return JSON.parse(content) as JSONSchema7;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function patchUiMessageTypes(nodeModulesDir: string): void {
|
||||
const aiTypesPath = join(nodeModulesDir, "ai", "dist", "index.d.ts");
|
||||
if (!existsSync(aiTypesPath)) {
|
||||
log(" [warn] ai types not found for UIMessage patch");
|
||||
return;
|
||||
}
|
||||
|
||||
const contents = readFileSync(aiTypesPath, "utf-8");
|
||||
let patched = contents;
|
||||
|
||||
const replaceAlias = (typeName: string, replacement: string): boolean => {
|
||||
const start = patched.indexOf(`type ${typeName}`);
|
||||
if (start === -1) {
|
||||
log(` [warn] ${typeName} alias not found for patch`);
|
||||
return false;
|
||||
}
|
||||
const end = patched.indexOf(";", start);
|
||||
if (end === -1) {
|
||||
log(` [warn] ${typeName} alias not terminated`);
|
||||
return false;
|
||||
}
|
||||
const snippet = patched.slice(start, Math.min(end + 1, start + 400)).replace(/\\s+/g, " ");
|
||||
log(` [debug] ${typeName} alias snippet: ${snippet}`);
|
||||
|
||||
patched = patched.slice(0, start) + replacement + patched.slice(end + 1);
|
||||
return true;
|
||||
};
|
||||
|
||||
const dataReplaced = replaceAlias(
|
||||
"DataUIPart",
|
||||
"type DataUIPart<DATA_TYPES extends UIDataTypes> = {\\n type: `data-${string}`;\\n id?: string;\\n data: unknown;\\n};"
|
||||
);
|
||||
if (dataReplaced) {
|
||||
log(" [patch] Simplified DataUIPart to avoid indexed access");
|
||||
}
|
||||
|
||||
const toolReplaced = replaceAlias(
|
||||
"ToolUIPart",
|
||||
"type ToolUIPart<TOOLS extends UITools = UITools> = {\\n type: `tool-${string}`;\\n} & UIToolInvocation<UITool>;"
|
||||
);
|
||||
if (toolReplaced) {
|
||||
log(" [patch] Simplified ToolUIPart to avoid indexed access");
|
||||
}
|
||||
|
||||
if (patched !== contents) {
|
||||
writeFileSync(aiTypesPath, patched);
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
log("Vercel AI SDK UIMessage Schema Extractor");
|
||||
log("========================================\n");
|
||||
|
||||
const args = parseArgs();
|
||||
ensureOutputDir();
|
||||
|
||||
const registry = await fetchRegistry(REGISTRY_URL);
|
||||
const version = args.version ?? resolveLatestVersion(registry, args.major);
|
||||
|
||||
log(`Target version: ai@${version}`);
|
||||
|
||||
const tempDir = mkdtempSync(join(tmpdir(), "vercel-ai-sdk-"));
|
||||
const nodeModulesDir = join(tempDir, "node_modules");
|
||||
|
||||
try {
|
||||
log(` [debug] temp dir: ${tempDir}`);
|
||||
await installPackage("ai", version, nodeModulesDir, new Set());
|
||||
ensureTypeFestShim(nodeModulesDir);
|
||||
patchUiMessageTypes(nodeModulesDir);
|
||||
patchValueOfAlias(nodeModulesDir);
|
||||
|
||||
const tsconfigPath = writeTempTsconfig(tempDir);
|
||||
const entryPath = writeEntryFile(tempDir);
|
||||
log(` [debug] entry path: ${entryPath}`);
|
||||
log(` [debug] tsconfig path: ${tsconfigPath}`);
|
||||
if (existsSync(entryPath)) {
|
||||
const entryStat = statSync(entryPath);
|
||||
log(` [debug] entry size: ${entryStat.size}`);
|
||||
}
|
||||
|
||||
const schema = generateSchema(entryPath, tsconfigPath);
|
||||
const schemaWithMeta = addSchemaMetadata(schema, version);
|
||||
|
||||
writeFileSync(OUTPUT_PATH, JSON.stringify(schemaWithMeta, null, 2));
|
||||
log(`\n [wrote] ${OUTPUT_PATH}`);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
log(`\n [error] ${message}`);
|
||||
if (error instanceof Error && error.stack) {
|
||||
log(error.stack);
|
||||
}
|
||||
|
||||
const fallback = loadFallback();
|
||||
if (fallback) {
|
||||
log(" [fallback] Keeping existing schema artifact");
|
||||
return;
|
||||
}
|
||||
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
11
resources/vercel-ai-sdk-schemas/tsconfig.json
Normal file
11
resources/vercel-ai-sdk-schemas/tsconfig.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue