import type { AgentBrowserDetailsV1, CapabilityBillingReceiptV1, CapabilityResultV1, ChangedFileDetailsV1, GameAssetsDetailsV1, KnownToolDetails, RuntimeContextDetailsV1, TaskStateDetailsV1, } from './coding-conversation-contracts'; import type { ModelToolDetailsV1, ModelWebSearchErrorCode } from './model-tools'; import { DEVICE_PACKAGE_TOOL_NAMES, type DevicePackageIndexV1, type DevicePackageRecordV1, type DevicePackageToolDetailsV1, type InstallPreviewV1, } from './device-packages'; import { DATA_SERVICE_PI_TOOL_NAMES } from './data-service'; const PRODUCT_TOOL_NAMES = new Set([ 'agent_browser', 'game_asset_browser', 'game_asset_review', 'task_state', 'changed_file', 'runtime_context', 'web_search', ...DEVICE_PACKAGE_TOOL_NAMES, ...DATA_SERVICE_PI_TOOL_NAMES, ]); const CAPABILITY_CONTEXT_KEYS = new Set([ 'resource', 'limit', 'current', 'attempted', 'actual', 'current_revision', ]); const CAPABILITY_CONTEXT_RESOURCES = new Set(['instances', 'collections', 'documents', 'bytes']); const CAPABILITY_ID_PATTERN = /^[a-z][a-z0-9.-]{0,63}$/u; const CAPABILITY_OPERATION_PATTERN = /^[a-z][a-z0-9._-]{0,63}$/u; const CAPABILITY_PLUGIN_ID_PATTERN = /^[a-z][a-z0-9.-]{0,47}$/u; const CAPABILITY_DECIMAL_PATTERN = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u; const MAX_CAPABILITY_DATA_BYTES = 1_310_720; function record(value: unknown): Record | null { return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record : null; } function text(value: unknown, max = 4096): string | null { return typeof value === 'string' && value.trim() && value.length <= max ? value : null; } function strings(value: unknown, maxItems = 200): string[] | null { if (!Array.isArray(value) || value.length > maxItems) return null; const result: string[] = []; for (const item of value) { const normalized = text(item); if (!normalized) return null; result.push(normalized); } return result; } function relativePaths(value: unknown): string[] | null { const paths = strings(value); if (!paths) return null; const result: string[] = []; for (const candidate of paths) { const normalized = candidate.replaceAll('\\', '/').replace(/^\.\//, ''); if (!normalized || normalized.startsWith('/') || /^[A-Za-z]:\//.test(normalized) || normalized.split('/').some((segment) => segment === '..')) return null; result.push(normalized); } return result; } function browserDetails(value: Record): AgentBrowserDetailsV1 | null { const actions = new Set([ 'open', 'status', 'close', 'reset_profile', 'navigate', 'send_cdp', 'read_events', 'read_payload', ]); if (!actions.has(String(value.action))) return null; const attachmentId = value.attachmentId === undefined ? undefined : text(value.attachmentId, 128); const mime = value.mime === undefined ? undefined : text(value.mime, 128); if ((value.attachmentId !== undefined && !attachmentId) || (value.mime !== undefined && !mime)) return null; if (Boolean(attachmentId) !== Boolean(mime) || (attachmentId && value.action !== 'send_cdp')) return null; return { schema: 'agent-browser.v1', action: value.action as AgentBrowserDetailsV1['action'], ...(attachmentId ? { attachmentId } : {}), ...(mime ? { mime } : {}), }; } function gameAssetDetails(value: Record): GameAssetsDetailsV1 | null { const invocationId = text(value.invocationId, 200); const candidateIds = strings(value.candidateIds); const pendingAssetIds = strings(value.pendingAssetIds); const approvedAssetIds = strings(value.approvedAssetIds); const discardedAssetIds = strings(value.discardedAssetIds); if (!invocationId || !candidateIds || !pendingAssetIds || !approvedAssetIds || !discardedAssetIds) return null; if (value.status !== 'pending' && value.status !== 'resolved') return null; return { schema: 'game-assets.v1', invocationId, candidateIds, status: value.status, pendingAssetIds, approvedAssetIds, discardedAssetIds, }; } function taskDetails(value: Record): TaskStateDetailsV1 | null { if (!Array.isArray(value.tasks) || value.tasks.length === 0 || value.tasks.length > 100) return null; const tasks: TaskStateDetailsV1['tasks'] = []; for (const candidate of value.tasks) { const item = record(candidate); const id = text(item?.id, 128); const title = text(item?.title, 500); if (!item || !id || !title || !['pending', 'running', 'complete', 'error'].includes(String(item.status))) { return null; } tasks.push({ id, title, status: item.status as TaskStateDetailsV1['tasks'][number]['status'] }); } return { schema: 'task-state.v1', tasks }; } function runtimeContextDetails(value: Record): RuntimeContextDetailsV1 | null { if (!Array.isArray(value.skills) || value.skills.length > 100 || !Array.isArray(value.commands) || value.commands.length > 200) return null; const skills: RuntimeContextDetailsV1['skills'] = []; const commands: RuntimeContextDetailsV1['commands'] = []; for (const candidate of value.skills) { const item = record(candidate); const id = text(item?.id, 128); const name = text(item?.name, 200); if (!item || !id || !name || typeof item.description !== 'string' || item.description.length > 2000 || typeof item.selected !== 'boolean') return null; skills.push({ id, name, description: item.description, selected: item.selected }); } for (const candidate of value.commands) { const item = record(candidate); const name = text(item?.name, 128); const title = text(item?.title, 200); if (!item || !name || !title || typeof item.description !== 'string' || item.description.length > 2000 || !['makelore', 'pi', 'skill'].includes(String(item.source))) return null; const skillId = item.skillId === undefined ? undefined : text(item.skillId, 128); if (item.skillId !== undefined && !skillId) return null; commands.push({ name, title, description: item.description, source: item.source as RuntimeContextDetailsV1['commands'][number]['source'], ...(skillId ? { skillId } : {}), }); } return { schema: 'runtime-context.v1', skills, commands }; } function capabilityContext(value: unknown): Readonly> | undefined | null { if (value === undefined) return undefined; const source = record(value); if (!source || Object.keys(source).length > 6) return null; const context: Record = {}; for (const [key, item] of Object.entries(source)) { if (!CAPABILITY_CONTEXT_KEYS.has(key)) return null; if (key === 'resource') { if (typeof item !== 'string' || item.length === 0 || item.length > 32 || !CAPABILITY_CONTEXT_RESOURCES.has(item)) return null; context[key] = item; } else if (Number.isSafeInteger(item) && (item as number) >= 0) { context[key] = item as number; } else { return null; } } return Object.keys(context).length > 0 ? context : undefined; } function exactKeys(value: Record, required: readonly string[], optional: readonly string[] = []): boolean { const allowed = new Set([...required, ...optional]); return required.every((key) => Object.prototype.hasOwnProperty.call(value, key)) && Object.keys(value).every((key) => allowed.has(key)); } function capabilityBilling(value: unknown): CapabilityBillingReceiptV1 | null { const billing = record(value); if (!billing || typeof billing.mode !== 'string' || typeof billing.status !== 'string') return null; if (billing.status === 'not_started') { if (!exactKeys(billing, ['mode', 'status']) || !['unknown', 'included', 'platform_metered', 'external_account'].includes(billing.mode)) return null; return { mode: billing.mode as CapabilityBillingReceiptV1['mode'], status: 'not_started', }; } if (billing.mode === 'included' && billing.status === 'included') { return exactKeys(billing, ['mode', 'status']) ? { mode: 'included', status: 'included' } : null; } if (billing.mode === 'external_account' && billing.status === 'external') { return exactKeys(billing, ['mode', 'status']) ? { mode: 'external_account', status: 'external' } : null; } if (billing.mode === 'platform_metered' && billing.status === 'receipt_unavailable') { return exactKeys(billing, ['mode', 'status']) ? { mode: 'platform_metered', status: 'receipt_unavailable' } : null; } if (billing.mode !== 'platform_metered' || typeof billing.reserved_points !== 'string' || !CAPABILITY_DECIMAL_PATTERN.test(billing.reserved_points) || billing.reserved_points.length > 32) return null; if (!exactKeys(billing, ['mode', 'status', 'reserved_points'], ['actual_points', 'usage_amount', 'unit'])) return null; if (billing.actual_points !== undefined && (typeof billing.actual_points !== 'string' || billing.actual_points.length > 32 || !CAPABILITY_DECIMAL_PATTERN.test(billing.actual_points))) return null; if (billing.usage_amount !== undefined && (typeof billing.usage_amount !== 'number' || !Number.isFinite(billing.usage_amount) || billing.usage_amount < 0 || billing.usage_amount > Number.MAX_SAFE_INTEGER)) return null; if (billing.unit !== undefined && (typeof billing.unit !== 'string' || billing.unit.length === 0 || billing.unit.length > 80)) return null; if (['settled', 'refunded'].includes(billing.status)) { return billing.actual_points === undefined ? null : { mode: 'platform_metered', status: billing.status as 'settled' | 'refunded', reserved_points: billing.reserved_points, actual_points: billing.actual_points, ...(billing.usage_amount === undefined ? {} : { usage_amount: billing.usage_amount as number }), ...(billing.unit === undefined ? {} : { unit: billing.unit as string }), }; } if (!['reserved', 'dispatched', 'released', 'pending_review', 'expired'].includes(billing.status)) return null; return { mode: 'platform_metered', status: billing.status as 'reserved' | 'dispatched' | 'released' | 'pending_review' | 'expired', reserved_points: billing.reserved_points, ...(billing.actual_points === undefined ? {} : { actual_points: billing.actual_points as string }), ...(billing.usage_amount === undefined ? {} : { usage_amount: billing.usage_amount as number }), ...(billing.unit === undefined ? {} : { unit: billing.unit as string }), }; } function capabilityDetails(value: Record): CapabilityResultV1 | null { const required = [ 'schema', 'plugin_id', 'plugin_version', 'capability_id', 'operation', 'request_id', 'success', 'status', 'code', 'error', 'retryable', 'billing', 'payload_schema', 'data', ]; if (!exactKeys(value, required, ['retry_after_seconds', 'context']) || value.schema !== 'makelore-capability.v1') return null; if (typeof value.plugin_id !== 'string' || value.plugin_id.length > 48 || !CAPABILITY_PLUGIN_ID_PATTERN.test(value.plugin_id) || value.plugin_id === 'makelore.web-search' || !text(value.plugin_version, 64) || typeof value.capability_id !== 'string' || !CAPABILITY_ID_PATTERN.test(value.capability_id) || typeof value.operation !== 'string' || !CAPABILITY_OPERATION_PATTERN.test(value.operation) || typeof value.request_id !== 'string' || value.request_id.length === 0 || value.request_id.length > 128 || typeof value.payload_schema !== 'string' || value.payload_schema.length === 0 || value.payload_schema.length > 128) return null; if (typeof value.success !== 'boolean' || !Number.isSafeInteger(value.status) || (value.status as number) < 100 || (value.status as number) > 599 || (value.code !== null && text(value.code, 128) === null) || (value.error !== null && text(value.error, 2_000) === null) || typeof value.retryable !== 'boolean' || !Object.prototype.hasOwnProperty.call(value, 'data')) return null; if (value.success) { if ((value.status as number) < 200 || (value.status as number) > 299 || value.code !== null || value.error !== null || value.retryable !== false) return null; } else if ((value.status as number) < 400 || value.code === null || value.error === null) { return null; } const retryAfter = value.retry_after_seconds; if (retryAfter !== undefined && (!Number.isSafeInteger(retryAfter) || (retryAfter as number) < 0 || (retryAfter as number) > 86_400)) { return null; } const context = capabilityContext(value.context); if (context === null) return null; const billing = capabilityBilling(value.billing); if (!billing) return null; const data = value.data === null ? null : record(value.data); if (value.data !== null && !data) return null; if (data !== null) { try { const encoded = JSON.stringify(data); if (typeof encoded !== 'string' || new TextEncoder().encode(encoded).byteLength > MAX_CAPABILITY_DATA_BYTES) { return null; } } catch { return null; } } return { schema: 'makelore-capability.v1', plugin_id: value.plugin_id as string, plugin_version: value.plugin_version as string, capability_id: value.capability_id as string, operation: value.operation as string, request_id: value.request_id as string, success: value.success, status: value.status as number, code: value.code as string | null, error: value.error as string | null, retryable: value.retryable, ...(retryAfter === undefined ? {} : { retry_after_seconds: retryAfter as number }), ...(context === undefined ? {} : { context }), billing, payload_schema: value.payload_schema as string, data, }; } const MODEL_WEB_SEARCH_ERROR_CONTRACT = Object.freeze({ model_web_search_unsupported: { httpStatus: 400, retryable: false }, model_context_changed: { httpStatus: 409, retryable: false }, model_web_search_rate_limited: { httpStatus: 429, retryable: false }, model_web_search_unavailable: { httpStatus: 503, retryable: true }, model_web_search_invalid_result: { httpStatus: 502, retryable: false }, } satisfies Record); function modelToolSource(value: unknown): { title: string; url: string } | null { const source = record(value); const title = text(source?.title, 240); const rawUrl = text(source?.url, 2_048); if (!source || !exactKeys(source, ['title', 'url']) || !title || !rawUrl) return null; try { const url = new URL(rawUrl); if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password) return null; return { title, url: url.toString() }; } catch { return null; } } function modelToolDetails(value: Record): ModelToolDetailsV1 | null { if (value.schema !== 'makelore-model-tool.v1' || value.tool !== 'web_search') return null; const modelId = text(value.modelId, 256); if (!modelId) return null; if (value.status === 'succeeded') { if (!exactKeys(value, [ 'schema', 'tool', 'status', 'modelId', 'answer', 'sources', 'sourceMode', ])) return null; const answer = text(value.answer, 20_000); if (!answer || !Array.isArray(value.sources) || value.sources.length > 20 || (value.sourceMode !== 'structured' && value.sourceMode !== 'inline-or-structured')) return null; const sources = value.sources.map(modelToolSource); if (sources.some((source) => source === null) || (value.sourceMode === 'structured' && sources.length === 0)) return null; return { schema: 'makelore-model-tool.v1', tool: 'web_search', status: 'succeeded', modelId, answer, sources: sources as Array<{ title: string; url: string }>, sourceMode: value.sourceMode, }; } if (value.status !== 'failed' || !exactKeys(value, ['schema', 'tool', 'status', 'modelId', 'error'])) return null; const error = record(value.error); const code = error?.code; const contract = typeof code === 'string' ? MODEL_WEB_SEARCH_ERROR_CONTRACT[code as ModelWebSearchErrorCode] : undefined; const message = text(error?.message, 2_000); if (!error || !contract || !message || !exactKeys(error, ['code', 'message', 'httpStatus', 'retryable']) || error.httpStatus !== contract.httpStatus || error.retryable !== contract.retryable) return null; return { schema: 'makelore-model-tool.v1', tool: 'web_search', status: 'failed', modelId, error: { code: code as ModelWebSearchErrorCode, message, httpStatus: contract.httpStatus as 400 | 409 | 429 | 502 | 503, retryable: contract.retryable, }, }; } function deviceSkillEntries(value: unknown): DevicePackageRecordV1['skillEntries'] | null { if (!Array.isArray(value) || value.length > 100) return null; const entries: Array<{ id: string; entryPath: string }> = []; for (const candidate of value) { const item = record(candidate); const id = text(item?.id, 128); const entryPath = text(item?.entryPath, 1_024); if (!item || !exactKeys(item, ['id', 'entryPath']) || !id || !entryPath) return null; entries.push({ id, entryPath }); } return entries; } function devicePackageKind(value: unknown): DevicePackageRecordV1['kind'] | null { return value === 'skill-only' || value === 'pi-extension' || value === 'mixed' ? value : null; } function devicePackagePreview(value: unknown): InstallPreviewV1 | null { const preview = record(value); if (!preview || !exactKeys(preview, [ 'schemaVersion', 'planId', 'expiresAt', 'requestedSource', 'resolvedSource', 'packageId', 'displayName', 'resolvedVersion', 'kind', 'skillEntries', 'extensionEntries', 'includesExecutableCode', 'ignoredLifecycleScripts', 'warnings', 'scope', ]) || preview.schemaVersion !== 1 || preview.scope !== 'device-parent-workers' || typeof preview.includesExecutableCode !== 'boolean') return null; const planId = text(preview.planId, 128); const expiresAt = text(preview.expiresAt, 64); const requestedSource = text(preview.requestedSource, 2_048); const resolvedSource = text(preview.resolvedSource, 4_096); const packageId = text(preview.packageId, 128); const displayName = text(preview.displayName, 240); const resolvedVersion = text(preview.resolvedVersion, 128); const kind = devicePackageKind(preview.kind); const skillEntries = deviceSkillEntries(preview.skillEntries); const extensionEntries = strings(preview.extensionEntries, 100); const ignoredLifecycleScripts = strings(preview.ignoredLifecycleScripts, 20); const warnings = strings(preview.warnings, 20); if (!planId || !expiresAt || !requestedSource || !resolvedSource || !packageId || !displayName || !resolvedVersion || !kind || !skillEntries || !extensionEntries || !ignoredLifecycleScripts || !warnings) return null; return { schemaVersion: 1, planId, expiresAt, requestedSource, resolvedSource, packageId, displayName, resolvedVersion, kind, skillEntries, extensionEntries, includesExecutableCode: preview.includesExecutableCode, ignoredLifecycleScripts, warnings, scope: 'device-parent-workers', }; } function devicePackageRecord(value: unknown): DevicePackageRecordV1 | null { const item = record(value); if (!item || !exactKeys(item, [ 'schemaVersion', 'packageId', 'displayName', 'resolvedVersion', 'source', 'kind', 'skillEntries', 'extensionEntries', 'enabled', 'confirmedExecutableCode', 'installedAt', ]) || item.schemaVersion !== 1 || typeof item.enabled !== 'boolean' || typeof item.confirmedExecutableCode !== 'boolean') return null; const source = record(item.source); const packageId = text(item.packageId, 128); const displayName = text(item.displayName, 240); const resolvedVersion = text(item.resolvedVersion, 128); const kind = devicePackageKind(item.kind); const installedAt = text(item.installedAt, 64); const skillEntries = deviceSkillEntries(item.skillEntries); const extensionEntries = strings(item.extensionEntries, 100); if (!source || !exactKeys(source, ['kind', 'requested', 'resolved']) || !['npm', 'git', 'file'].includes(String(source.kind)) || !packageId || !displayName || !resolvedVersion || !kind || !installedAt || !skillEntries || !extensionEntries) return null; const requested = text(source.requested, 2_048); const resolved = text(source.resolved, 4_096); if (!requested || !resolved) return null; return { schemaVersion: 1, packageId, displayName, resolvedVersion, source: { kind: source.kind as DevicePackageRecordV1['source']['kind'], requested, resolved }, kind, skillEntries, extensionEntries, enabled: item.enabled, confirmedExecutableCode: item.confirmedExecutableCode, installedAt, }; } function devicePackageIndex(value: unknown): DevicePackageIndexV1 | null { const index = record(value); if (!index || !exactKeys(index, ['schemaVersion', 'generation', 'packages']) || index.schemaVersion !== 1 || !Number.isSafeInteger(index.generation) || (index.generation as number) < 0 || !Array.isArray(index.packages) || index.packages.length > 200) return null; const packages = index.packages.map(devicePackageRecord); if (packages.some((item) => item === null)) return null; return { schemaVersion: 1, generation: index.generation as number, packages: packages as DevicePackageRecordV1[] }; } function devicePackageDetails(value: Record): DevicePackageToolDetailsV1 | null { if (value.schema !== 'makelore-device-package.v1' || value.success !== true || !['prepare', 'commit', 'list', 'set_enabled', 'uninstall'].includes(String(value.operation))) return null; if (value.operation === 'prepare') { if (!exactKeys(value, ['schema', 'operation', 'success', 'preview'])) return null; const preview = devicePackagePreview(value.preview); return preview ? { schema: 'makelore-device-package.v1', operation: 'prepare', success: true, preview } : null; } if (!exactKeys(value, ['schema', 'operation', 'success', 'index'])) return null; const index = devicePackageIndex(value.index); return index ? { schema: 'makelore-device-package.v1', operation: value.operation as Exclude, success: true, index, } : null; } export function productToolDetails(value: unknown): Exclude | null { const details = record(value); if (!details) return null; if (details.schema === 'changed-file.v1') { const paths = relativePaths(details.paths); return paths ? { schema: 'changed-file.v1', paths } satisfies ChangedFileDetailsV1 : null; } if (details.schema === 'task-state.v1') return taskDetails(details); if (details.schema === 'agent-browser.v1') return browserDetails(details); if (details.schema === 'game-assets.v1') return gameAssetDetails(details); if (details.schema === 'runtime-context.v1') return runtimeContextDetails(details); if (details.schema === 'makelore-capability.v1') return capabilityDetails(details); if (details.schema === 'makelore-model-tool.v1') return modelToolDetails(details); if (details.schema === 'makelore-device-package.v1') return devicePackageDetails(details); return null; } export function productToolDetailsOfResult(value: unknown) { return productToolDetails(record(value)?.details); } export function isProductToolName(value: string): boolean { return PRODUCT_TOOL_NAMES.has(value); }