(modelsDir: string)
| 398 | } |
| 399 | |
| 400 | async function readExisting(modelsDir: string) { |
| 401 | const existing = new Map<string, { |
| 402 | authored: ExistingModel; |
| 403 | toml: ExistingModel; |
| 404 | header: string; |
| 405 | symlink: boolean; |
| 406 | }>(); |
| 407 | const brokenSymlinks = new Set<string>(); |
| 408 | let modelMetadata: Record<string, Record<string, unknown>> | undefined; |
| 409 | |
| 410 | for (const { file, symlink } of await tomlFiles(modelsDir)) { |
| 411 | const filePath = path.join(modelsDir, file); |
| 412 | let text: string; |
| 413 | try { |
| 414 | text = await Bun.file(filePath).text(); |
| 415 | } catch (error) { |
| 416 | if (symlink && error instanceof Error && "code" in error && error.code === "ENOENT") { |
| 417 | brokenSymlinks.add(file); |
| 418 | continue; |
| 419 | } |
| 420 | throw error; |
| 421 | } |
| 422 | const parsed = ExistingModel.safeParse(Bun.TOML.parse(text)); |
| 423 | if (!parsed.success) { |
| 424 | parsed.error.cause = { path: filePath }; |
| 425 | throw parsed.error; |
| 426 | } |
| 427 | |
| 428 | const authored = parsed.data as ExistingModel; |
| 429 | if (authored.base_model !== undefined && modelMetadata === undefined) { |
| 430 | modelMetadata = await readModelMetadata(modelsDir); |
| 431 | } |
| 432 | const toml = authored.base_model === undefined |
| 433 | ? authored |
| 434 | : resolveBaseModel(authored, modelMetadata ?? {}, filePath); |
| 435 | |
| 436 | existing.set(file, { authored, toml, header: leadingComments(text), symlink }); |
| 437 | } |
| 438 | |
| 439 | return { models: existing, brokenSymlinks, modelMetadata }; |
| 440 | } |
| 441 | |
| 442 | async function isSymlink(filePath: string) { |
| 443 | try { |
no test coverage detected