evOo-local/packages/contracts/src/media-library.ts
Claude 044669edfc
Add a media library: owner folders that bots can search and import from
The deployment owner adds folders of photos and videos in the media settings. A per-folder
background job indexes them (relative path, kind, size, capture date, dimensions, duration),
re-indexes every six hours, and drops files that are gone. The owner's own runs get two tools:
search_media (words in folder and file names, kind, capture date range, newest first) and
import_media (copies one file into the conversation as an artifact). Files are never changed;
hidden entries and symlinks are skipped, and an import must resolve inside its folder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wy1md9QE1ayJbDCwJ4vAQs
2026-10-05 08:45:30 +00:00

40 lines
1.6 KiB
TypeScript

import { z } from "zod";
/** Kinds a library folder indexes; everything else in the folder is ignored. */
export const MediaLibraryKindSchema = z.enum(["photo", "video"]);
export type MediaLibraryKind = z.infer<typeof MediaLibraryKindSchema>;
export const MediaLibrarySourceStatusSchema = z.enum(["idle", "syncing", "failed"]);
export type MediaLibrarySourceStatus = z.infer<typeof MediaLibrarySourceStatusSchema>;
export const MediaLibrarySourceSchema = z.object({
id: z.string(),
path: z.string(),
status: MediaLibrarySourceStatusSchema,
error: z.string().nullable(),
assetCount: z.number().int().nonnegative(),
lastSyncedAt: z.string().nullable(),
});
export type MediaLibrarySource = z.infer<typeof MediaLibrarySourceSchema>;
export const MediaLibrarySourceAddInputSchema = z.object({
path: z.string().trim().min(1).max(4096),
});
export type MediaLibrarySourceAddInput = z.infer<typeof MediaLibrarySourceAddInputSchema>;
/** Arguments of the `search_media` agent tool. */
export const MediaLibrarySearchInputSchema = z.object({
query: z.string().trim().max(200).optional(),
kind: MediaLibraryKindSchema.optional(),
taken_after: z.string().datetime({ offset: true }).optional(),
taken_before: z.string().datetime({ offset: true }).optional(),
limit: z.number().int().min(1).max(50).optional(),
});
export type MediaLibrarySearchInput = z.infer<typeof MediaLibrarySearchInputSchema>;
/** Arguments of the `import_media` agent tool. */
export const MediaLibraryImportInputSchema = z.object({
asset_id: z.string().min(1).max(64),
});
export type MediaLibraryImportInput = z.infer<typeof MediaLibraryImportInputSchema>;