import { type CodingPluginDefinition, type CodingPluginToolDefinition, type PluginBillingMode, } from '../../shared/coding-plugins'; import { CORE_CODING_SKILL_IDS } from '../../shared/coding-skills'; import type { CapabilityBillingReceiptV1, CapabilityResultV1, } from '../../shared/data-service'; import type { PiProductToolContext, PiProductToolResult } from '../coding-runtime/pi/product-tools'; import type { PluginCatalog, PluginCatalogOperation, PluginPolicyClientState, } from '../services/plugin-policy-client'; import type { EffectivePluginResolver, EffectivePluginSnapshot, EffectivePluginSkillSource, } from './effective-resolver'; const MAX_REQUEST_ID = 128; const PLUGIN_ID_PATTERN = /^[a-z][a-z0-9.-]{0,47}$/u; const CAPABILITY_ID_PATTERN = /^[a-z][a-z0-9.-]{0,63}$/u; const OPERATION_PATTERN = /^[a-z][a-z0-9._-]{0,63}$/u; const VERSION_PATTERN = /^[A-Za-z0-9][A-Za-z0-9.+-]{0,63}$/u; const DECIMAL_PATTERN = /^(?:0|[1-9]\d*)(?:\.\d+)?$/u; const CONTEXT_KEYS = new Set([ 'resource', 'limit', 'current', 'attempted', 'actual', 'current_revision', ]); const CONTEXT_RESOURCES = new Set(['instances', 'collections', 'documents', 'bytes']); export interface TrustedCodingCapabilityContext { conversationId: string; runId: string; resourceId: string; requestId: string; localProjectId: string; projectPath: string; durableProjectId: string; workerRole: 'parent' | 'child'; effectiveSkillIds: readonly string[]; pluginReleaseId?: string; } export type PluginBackendProjection = | { status: 'not_required' } | { status: 'identity_required' } | { status: 'authentication_required' } | { status: 'unconfigured' } | { status: 'ready' } | { status: 'degraded'; code: string; message: string; retryable: boolean; retry_after_seconds?: number; }; export type AdapterInvocationResult = | { success: true; status: number; code: null; error: null; retryable: false; payload_schema: string; data: T | null; billing?: CapabilityBillingReceiptV1; } | { success: false; status: number; code: string; error: string; retryable: boolean; retry_after_seconds?: number; context?: Readonly>; payload_schema: string; data: null; billing?: CapabilityBillingReceiptV1; }; export interface CodingPluginAdapter { readonly pluginId: string; inspect(projectPath: string): Promise; invoke( context: TrustedCodingCapabilityContext, tool: CodingPluginToolDefinition, input: unknown, ): Promise; deactivate?(projectPath: string): Promise; } export interface ResolvedWorkerResources { catalogRevision: number; pluginIds: readonly string[]; effectiveSkillIds: readonly string[]; skillEntries: readonly { id: string; entryPath: string; packageRoot?: string }[]; tools: readonly CodingPluginToolDefinition[]; /** The exact Main-owned snapshot used to produce these legacy fields. */ effectiveSnapshot?: EffectivePluginSnapshot; /** Trusted package roots paired with the same effective snapshot. */ skillRoots?: readonly string[]; } export interface CodingCapabilityRegistryPort { resolveWorkerResources(input: { projectPath: string; assignedSkillIds: readonly string[]; role: 'parent' | 'child'; projectId?: string; }): Promise; resolveEffectivePluginSnapshot?(input: { projectId: string; projectPath: string; assignedSkillIds: readonly string[]; role: 'parent' | 'child'; }): Promise; invoke(input: { toolName: string; context: PiProductToolContext; workerRole: 'parent' | 'child'; effectiveSkillIds: readonly string[]; value: unknown; }): Promise; } export type CodingCapabilityRegistry = CodingCapabilityRegistryPort; export interface CodingCapabilityRegistryOptions { policyClient: { getState(): PluginPolicyClientState; refresh(): Promise; }; getEnabledPluginIds?: (projectPath: string) => Promise; projectPlugins?: { getEnabledPluginIds(projectPath: string): Promise; }; adapters: readonly CodingPluginAdapter[]; definitions: readonly CodingPluginDefinition[]; getDurableProjectId?: (projectPath: string, localProjectId: string) => Promise | string; effectiveResolver?: EffectivePluginResolver; } function isRecord(value: unknown): value is Record { return value !== null && typeof value === 'object' && !Array.isArray(value); } function boundedText(value: unknown, maximum: number, fallback: string): string { return typeof value === 'string' && value.trim().length > 0 && value.length <= maximum ? value : fallback; } function validRequestPart(value: unknown): value is string { return typeof value === 'string' && value.length > 0 && value.length <= MAX_REQUEST_ID; } function requestId(context: PiProductToolContext): string { const runId = context.runId; const resourceId = context.resourceId; const result = `pi:${runId}:${resourceId}`; return validRequestPart(runId) && validRequestPart(resourceId) && result.length <= MAX_REQUEST_ID ? result : 'invalid-request-id'; } function boundedStatus(value: unknown, fallback: number): number { return Number.isSafeInteger(value) && (value as number) >= 100 && (value as number) <= 599 ? value as number : fallback; } function boundedRetry(value: unknown): number | undefined { return Number.isSafeInteger(value) && (value as number) >= 0 && (value as number) <= 86_400 ? value as number : undefined; } function boundedContext(value: unknown): Readonly> | undefined { if (!isRecord(value)) return undefined; const result: Record = {}; for (const [key, item] of Object.entries(value)) { if (!CONTEXT_KEYS.has(key)) continue; if (key === 'resource') { if (typeof item !== 'string' || item.length === 0 || item.length > 32 || !CONTEXT_RESOURCES.has(item)) continue; result[key] = item; } else if (Number.isSafeInteger(item) && (item as number) >= 0) { result[key] = item as number; } } return Object.keys(result).length > 0 ? result : undefined; } function validDecimal(value: unknown): value is string { return typeof value === 'string' && value.length > 0 && value.length <= 32 && DECIMAL_PATTERN.test(value); } function validBillingReceipt(value: unknown): value is CapabilityBillingReceiptV1 { if (!isRecord(value) || typeof value.mode !== 'string' || typeof value.status !== 'string') return false; const keys = new Set(Object.keys(value)); if (value.status === 'not_started') { return keys.size === 2 && ['unknown', 'included', 'platform_metered', 'external_account'].includes(value.mode); } if (value.mode === 'included' && value.status === 'included') return keys.size === 2; if (value.mode === 'external_account' && value.status === 'external') return keys.size === 2; if (value.mode === 'platform_metered' && value.status === 'receipt_unavailable') { return keys.size === 2; } if (value.mode !== 'platform_metered' || !validDecimal(value.reserved_points)) return false; const common = new Set(['mode', 'status', 'reserved_points', 'actual_points', 'usage_amount', 'unit']); if (keys.size !== [...keys].filter((key) => common.has(key)).length) return false; if (value.actual_points !== undefined && !validDecimal(value.actual_points)) return false; if (value.usage_amount !== undefined && (typeof value.usage_amount !== 'number' || !Number.isFinite(value.usage_amount) || value.usage_amount < 0 || value.usage_amount > Number.MAX_SAFE_INTEGER)) return false; if (value.unit !== undefined && (typeof value.unit !== 'string' || value.unit.length === 0 || value.unit.length > 80)) return false; const status = value.status; if (['settled', 'refunded'].includes(status)) return value.actual_points !== undefined; return ['reserved', 'dispatched', 'released', 'pending_review', 'expired'].includes(status); } function schemaValid(value: unknown, schema: Readonly>): boolean { if (schema.type === 'object') { if (!isRecord(value)) return false; const properties = isRecord(schema.properties) ? schema.properties : {}; if (schema.additionalProperties === false && Object.keys(value).some((key) => !Object.prototype.hasOwnProperty.call(properties, key))) return false; const required = Array.isArray(schema.required) ? schema.required : []; if (required.some((key) => typeof key !== 'string' || !Object.prototype.hasOwnProperty.call(value, key))) return false; return Object.entries(value).every(([key, item]) => { const child = properties[key]; return !child || (isRecord(child) && schemaValid(item, child)); }); } if (schema.type === 'array') { if (!Array.isArray(value)) return false; if (typeof schema.maxItems === 'number' && value.length > schema.maxItems) return false; const items = isRecord(schema.items) ? schema.items : undefined; return !items || value.every((item) => schemaValid(item, items)); } if (schema.type === 'string') { if (typeof value !== 'string') return false; if (typeof schema.minLength === 'number' && value.length < schema.minLength) return false; if (typeof schema.maxLength === 'number' && value.length > schema.maxLength) return false; if (typeof schema.pattern === 'string' && !(new RegExp(schema.pattern, 'u')).test(value)) return false; return true; } if (schema.type === 'integer') { if (!Number.isSafeInteger(value)) return false; if (typeof schema.minimum === 'number' && (value as number) < schema.minimum) return false; if (typeof schema.maximum === 'number' && (value as number) > schema.maximum) return false; return true; } if (schema.type === 'boolean') { return typeof value === 'boolean' && (schema.const === undefined || value === schema.const); } return true; } function policyOperation( catalog: PluginCatalog, definition: CodingPluginDefinition, tool: CodingPluginToolDefinition, ): PluginCatalogOperation | null { const plugin = catalog.plugins.find(({ plugin_id }) => plugin_id === definition.id); if (!plugin || plugin.status !== 'active' || !plugin.supported_contract_versions.includes(definition.contractVersion)) return null; const capability = plugin.capabilities.find(({ capability_id }) => capability_id === tool.capabilityId); return capability?.operations.find(({ operation }) => operation === tool.operation) ?? null; } function definitionValid(definition: CodingPluginDefinition): boolean { if (!PLUGIN_ID_PATTERN.test(definition.id) || !VERSION_PATTERN.test(definition.version) || !Number.isSafeInteger(definition.contractVersion) || definition.contractVersion < 1 || definition.scope !== 'project' || typeof definition.requiresBackend !== 'boolean') return false; if (!definition.skills.length || (definition.runtimeKind !== 'skill_only' && !definition.tools.length) || (definition.runtimeKind === 'skill_only' && (definition.requiresBackend || definition.tools.length > 0))) return false; const skillIds = new Set(); for (const skill of definition.skills) { if (!skill.id || skillIds.has(skill.id) || !skill.entryPath || (definition.runtimeKind !== 'skill_only' && skill.grants.length === 0) || (definition.runtimeKind === 'skill_only' && skill.grants.length > 0)) return false; skillIds.add(skill.id); } const toolNames = new Set(); for (const tool of definition.tools) { if (!tool.name || toolNames.has(tool.name) || tool.roles.length !== 1 || tool.roles[0] !== 'parent' || !CAPABILITY_ID_PATTERN.test(tool.capabilityId) || !OPERATION_PATTERN.test(tool.operation) || !isRecord(tool.inputSchema) || tool.inputSchema.type !== 'object' || tool.inputSchema.additionalProperties !== false) return false; toolNames.add(tool.name); } return true; } function policyNotStarted(mode: PluginBillingMode | 'unknown'): CapabilityBillingReceiptV1 { return { mode, status: 'not_started' }; } function policyEntered(mode: PluginBillingMode): CapabilityBillingReceiptV1 { if (mode === 'included') return { mode, status: 'included' }; if (mode === 'external_account') return { mode, status: 'external' }; return { mode, status: 'not_started' }; } function resultDetails( definition: CodingPluginDefinition, tool: CodingPluginToolDefinition, context: PiProductToolContext, result: AdapterInvocationResult, billing: CapabilityBillingReceiptV1, ): CapabilityResultV1 { const id = requestId(context); const rawStatus = boundedStatus(result.status, 502); const success = result.success && rawStatus >= 200 && rawStatus <= 299; const status = success ? rawStatus : rawStatus >= 400 ? rawStatus : 502; const payloadSchema = boundedText(result.payload_schema, 128, 'unknown'); const code = success ? null : result.success ? 'plugin_backend_unavailable' : boundedText(result.code, 128, 'plugin_backend_unavailable'); const details: CapabilityResultV1 = { schema: 'makelore-capability.v1', plugin_id: definition.id, plugin_version: definition.version, capability_id: tool.capabilityId, operation: tool.operation, request_id: id, success, status, code, error: success ? null : boundedText(result.success ? null : result.error, 2_000, 'Plugin capability failed'), retryable: success ? false : result.success ? true : result.retryable, ...(success || result.success ? {} : (boundedRetry(result.retry_after_seconds) === undefined ? {} : { retry_after_seconds: boundedRetry(result.retry_after_seconds) })), ...(success || result.success ? {} : (boundedContext(result.context) === undefined ? {} : { context: boundedContext(result.context) })), billing, payload_schema: payloadSchema, data: success ? (result.data ?? null) : null, }; return details; } export function buildCapabilityToolResult( definition: CodingPluginDefinition, tool: CodingPluginToolDefinition, context: PiProductToolContext, result: AdapterInvocationResult, billing: CapabilityBillingReceiptV1 = { mode: 'included', status: 'included' }, ): PiProductToolResult { const details = resultDetails(definition, tool, context, result, billing); return { content: [{ type: 'text', text: JSON.stringify(details) }], details, }; } export class CodingCapabilityRegistryImpl implements CodingCapabilityRegistryPort { private readonly definitions: readonly CodingPluginDefinition[]; private readonly toolsByName: ReadonlyMap; private readonly adaptersByPluginId: ReadonlyMap; constructor(private readonly options: CodingCapabilityRegistryOptions) { const definitions = options.definitions.filter(definitionValid); this.definitions = Object.freeze([...definitions]); const tools = new Map(); for (const definition of this.definitions) { for (const tool of definition.tools) { if (!tools.has(tool.name)) tools.set(tool.name, { definition, tool }); } } this.toolsByName = tools; this.adaptersByPluginId = new Map(options.adapters.map((adapter) => [adapter.pluginId, adapter])); } async resolveWorkerResources(input: { projectPath: string; assignedSkillIds: readonly string[]; role: 'parent' | 'child'; projectId?: string; }): Promise { if (this.options.effectiveResolver) { const snapshot = await this.options.effectiveResolver.resolve({ projectId: input.projectId ?? input.projectPath, projectPath: input.projectPath, assignedSkillIds: input.assignedSkillIds, role: input.role, }); const sources = await this.options.effectiveResolver.getSkillSources(); const effectiveSkills = new Set(snapshot.effectiveSkillIds); const pluginIds = new Set(snapshot.runtimePolicies.map(({ pluginId }) => pluginId)); const skillRoots = new Set(); const sourcesBySkillId = new Map(); for (const source of sources) { if (effectiveSkills.has(source.id) && !sourcesBySkillId.has(source.id)) { sourcesBySkillId.set(source.id, source); } } const skillEntries = snapshot.skillEntries.map(({ id, entryPath, packageRoot }) => { const source = sourcesBySkillId.get(id); const pairedRoot = packageRoot ?? source?.packageRoot; if (source && pairedRoot) { pluginIds.add(source.pluginId); skillRoots.add(pairedRoot); } return { id, entryPath, ...(pairedRoot ? { packageRoot: pairedRoot } : {}), }; }); return { catalogRevision: this.options.effectiveResolver.getPolicyState().revision, pluginIds: [...pluginIds], effectiveSkillIds: [...snapshot.effectiveSkillIds], skillEntries, tools: snapshot.toolDefinitions.map((tool) => structuredClone(tool)), effectiveSnapshot: snapshot, skillRoots: [...skillRoots], }; } const assigned = [...new Set(input.assignedSkillIds)]; const coreIds = new Set(CORE_CODING_SKILL_IDS); const pluginSkillOwners = new Map(); for (const definition of this.definitions) { for (const skill of definition.skills) pluginSkillOwners.set(skill.id, definition); } for (const id of assigned) { if (!coreIds.has(id) && !pluginSkillOwners.has(id)) throw new Error(`Unknown bundled coding skill: ${id}`); } const effectiveCoreSkills = assigned.filter((id) => coreIds.has(id)); if (input.role === 'child') { return { catalogRevision: this.options.policyClient.getState().revision, pluginIds: [], effectiveSkillIds: effectiveCoreSkills, skillEntries: effectiveCoreSkills.map((id) => ({ id, entryPath: `${id}/SKILL.md` })), tools: [], }; } const hasAssignedServerPlugin = this.definitions.some((definition) => ( definition.requiresBackend && this.adaptersByPluginId.has(definition.id) && definition.skills.some(({ id }) => assigned.includes(id)) )); if (!hasAssignedServerPlugin) { return { catalogRevision: this.options.policyClient.getState().revision, pluginIds: [], effectiveSkillIds: effectiveCoreSkills, skillEntries: effectiveCoreSkills.map((id) => ({ id, entryPath: `${id}/SKILL.md` })), tools: [], }; } await this.options.policyClient.refresh(); const enabled = await this.enabledPluginIds(input.projectPath); const state = this.options.policyClient.getState(); const pluginIds: string[] = []; const effectiveSkillIds = [...effectiveCoreSkills]; const skillEntries = effectiveCoreSkills.map((id) => ({ id, entryPath: `${id}/SKILL.md` })); const tools: CodingPluginToolDefinition[] = []; for (const definition of this.definitions) { if (!definition.requiresBackend || !enabled.includes(definition.id) || !this.adaptersByPluginId.has(definition.id)) continue; const pluginPolicy = state.catalog ? state.catalog.plugins.find(({ plugin_id }) => plugin_id === definition.id) : undefined; if (!pluginPolicy || pluginPolicy.status !== 'active' || !pluginPolicy.supported_contract_versions.includes(definition.contractVersion)) continue; pluginIds.push(definition.id); const selectedSkills = definition.skills.filter(({ id }) => assigned.includes(id)); if (selectedSkills.length === 0) continue; for (const skill of selectedSkills) { effectiveSkillIds.push(skill.id); skillEntries.push({ id: skill.id, entryPath: skill.entryPath, ...(definition.provenance.source === 'marketplace' ? { packageRoot: definition.provenance.packageRoot } : {}), }); } for (const tool of definition.tools) { const granted = selectedSkills.some(({ grants }) => grants.includes(tool.capabilityId)); const policy = state.catalog ? policyOperation(state.catalog, definition, tool) : null; const available = policy !== null && ( policy.billing.mode !== 'platform_metered' || !('status' in policy.billing && policy.billing.status === 'billing_unavailable') ); if (granted && available) { tools.push(tool); } } } return { catalogRevision: state.revision, pluginIds, effectiveSkillIds: [...new Set(effectiveSkillIds)], skillEntries, tools, }; } async resolveEffectivePluginSnapshot(input: { projectId: string; projectPath: string; assignedSkillIds: readonly string[]; role: 'parent' | 'child'; }): Promise { if (this.options.effectiveResolver) return await this.options.effectiveResolver.resolve(input); const resources = await this.resolveWorkerResources(input); return Object.freeze({ accountSessionId: 'anonymous', projectId: input.projectId, pluginReleaseIds: Object.freeze([]), effectiveSkillIds: Object.freeze([...resources.effectiveSkillIds]), skillEntries: Object.freeze(resources.skillEntries.map((entry) => Object.freeze({ ...entry }))), toolDefinitions: Object.freeze(resources.tools.map((tool) => structuredClone(tool))), runtimePolicies: Object.freeze([]), unavailableReasons: Object.freeze([]), }); } async invoke(input: { toolName: string; context: PiProductToolContext; workerRole: 'parent' | 'child'; effectiveSkillIds: readonly string[]; value: unknown; }): Promise { let indexed = this.toolsByName.get(input.toolName); const validId = requestId(input.context) !== 'invalid-request-id'; if (!indexed && this.options.effectiveResolver && input.context.effectiveSnapshot) { const snapshotTool = input.context.effectiveSnapshot.toolDefinitions .find(({ name }) => name === input.toolName); const policy = snapshotTool ? input.context.effectiveSnapshot.runtimePolicies.find((candidate) => ( candidate.capabilityId === snapshotTool.capabilityId && candidate.operation === snapshotTool.operation )) : undefined; const definition = policy ? await this.options.effectiveResolver.getInstalledDefinition(policy.pluginId, policy.releaseId) : null; const tool = definition?.tools.find((candidate) => ( candidate.name === input.toolName && candidate.capabilityId === snapshotTool?.capabilityId && candidate.operation === snapshotTool.operation )); if (definition && tool) indexed = { definition, tool }; } if (!indexed) return this.unknownResult(input.context, 'plugin_backend_unavailable', 'Plugin capability is unavailable'); const { definition, tool } = indexed; if (this.options.effectiveResolver && input.context.effectiveSnapshot) { const frozenPolicy = input.context.effectiveSnapshot.runtimePolicies.find((candidate) => ( candidate.pluginId === definition.id && candidate.capabilityId === tool.capabilityId && candidate.operation === tool.operation )); const currentSnapshot = await this.options.effectiveResolver.resolveForInvocation({ projectId: input.context.projectId, projectPath: input.context.projectPath, assignedSkillIds: input.context.effectiveSnapshot.effectiveSkillIds, role: input.workerRole, }); const currentPolicy = currentSnapshot.runtimePolicies.find((candidate) => ( candidate.pluginId === definition.id && candidate.capabilityId === tool.capabilityId && candidate.operation === tool.operation )); if (currentSnapshot.accountSessionId !== input.context.effectiveSnapshot.accountSessionId || !currentSnapshot.toolDefinitions.some(({ name }) => name === input.toolName) || frozenPolicy?.releaseId !== currentPolicy?.releaseId || frozenPolicy?.pluginVersion !== currentPolicy?.pluginVersion) { const disabled = currentSnapshot.unavailableReasons.some((reason) => ( reason.pluginId === definition.id && reason.code === 'project_disabled' )); return this.resultFailure( definition, tool, input.context, disabled ? 'plugin_not_enabled' : 'plugin_runtime_stale', disabled ? 'Plugin is not enabled for this project' : 'Plugin worker resources are stale', disabled ? 403 : 409, false, policyNotStarted('unknown'), ); } } // The effective resolver may refresh a stale policy while checking the // worker snapshot. Read the post-resolution state for invocation checks. const state = this.options.policyClient.getState(); const currentEnabled = await this.enabledPluginIds(input.context.projectPath); const catalogPolicy = state.catalog ? policyOperation(state.catalog, definition, tool) : null; const baseBilling = catalogPolicy ? policyNotStarted(catalogPolicy.billing.mode) : policyNotStarted('unknown'); if (!validId) return this.resultFailure(definition, tool, input.context, 'plugin_input_invalid', 'Pi request identity is invalid', 422, false, baseBilling); if (input.workerRole !== 'parent' || !tool.roles.includes(input.workerRole)) { return this.resultFailure(definition, tool, input.context, 'plugin_permission_denied', 'Plugin capability is not permitted for this worker', 403, false, baseBilling); } if (state.status === 'unavailable' || !state.catalog) { return this.unknownResult(input.context, 'plugin_backend_unavailable', 'Plugin policy is unavailable'); } if (!currentEnabled.includes(definition.id)) { return this.resultFailure(definition, tool, input.context, 'plugin_not_enabled', 'Plugin is not enabled for this project', 403, false, baseBilling); } if (!catalogPolicy) { return this.resultFailure(definition, tool, input.context, 'plugin_contract_unsupported', 'Plugin capability is not supported by the server policy', 503, true, policyNotStarted('unknown')); } const selectedSkill = definition.skills.find(({ id }) => input.effectiveSkillIds.includes(id)); if (!selectedSkill || !selectedSkill.grants.includes(tool.capabilityId)) { return this.resultFailure(definition, tool, input.context, 'plugin_permission_denied', 'Plugin Skill grant is required', 403, false, baseBilling); } if (catalogPolicy.billing.mode === 'platform_metered' && 'status' in catalogPolicy.billing && catalogPolicy.billing.status === 'billing_unavailable') { return this.resultFailure(definition, tool, input.context, 'plugin_billing_unavailable', 'Plugin billing is unavailable', 503, true, baseBilling); } if (!schemaValid(input.value, tool.inputSchema)) { return this.resultFailure(definition, tool, input.context, 'plugin_input_invalid', 'Plugin tool input is invalid', 422, false, baseBilling); } const adapter = this.adaptersByPluginId.get(definition.id); if (!adapter) return this.resultFailure(definition, tool, input.context, 'plugin_backend_unavailable', 'Plugin adapter is unavailable', 503, true, baseBilling); const durableProjectId = await this.options.getDurableProjectId?.(input.context.projectPath, input.context.projectId) ?? input.context.projectId; const trustedContext: TrustedCodingCapabilityContext = { conversationId: input.context.conversationId, runId: input.context.runId, resourceId: input.context.resourceId, requestId: requestId(input.context), localProjectId: input.context.projectId, projectPath: input.context.projectPath, durableProjectId, workerRole: input.workerRole, effectiveSkillIds: [...input.effectiveSkillIds], ...(definition.releaseId ? { pluginReleaseId: definition.releaseId } : {}), }; let result: AdapterInvocationResult; try { result = await adapter.invoke(trustedContext, tool, input.value); } catch { return this.resultFailure(definition, tool, input.context, 'plugin_backend_unavailable', 'Plugin adapter is temporarily unavailable', 503, true, baseBilling); } let billing: CapabilityBillingReceiptV1; if (catalogPolicy.billing.mode === 'platform_metered') { if (!result.billing || !validBillingReceipt(result.billing) || result.billing.mode !== 'platform_metered') { return this.resultFailure(definition, tool, input.context, 'plugin_billing_unavailable', 'Plugin billing receipt is unavailable', 503, true, policyNotStarted('platform_metered')); } billing = result.billing; } else { billing = policyEntered(catalogPolicy.billing.mode); } return buildCapabilityToolResult(definition, tool, input.context, result, billing); } private async enabledPluginIds(projectPath: string): Promise { if (this.options.getEnabledPluginIds) return await this.options.getEnabledPluginIds(projectPath); if (this.options.projectPlugins) return await this.options.projectPlugins.getEnabledPluginIds(projectPath); return []; } private resultFailure( definition: CodingPluginDefinition, tool: CodingPluginToolDefinition, context: PiProductToolContext, code: string, error: string, status: number, retryable: boolean, billing: CapabilityBillingReceiptV1, ): PiProductToolResult { return buildCapabilityToolResult(definition, tool, context, { success: false, status, code, error, retryable, payload_schema: 'unknown', data: null, }, billing); } private unknownResult( context: PiProductToolContext, code: string, error: string, ): PiProductToolResult { const details: CapabilityResultV1 = { schema: 'makelore-capability.v1', plugin_id: 'unknown', plugin_version: 'unknown', capability_id: 'unknown', operation: 'unknown', request_id: requestId(context), success: false, status: 503, code, error, retryable: true, billing: { mode: 'unknown', status: 'not_started' }, payload_schema: 'unknown', data: null, }; return { content: [{ type: 'text', text: JSON.stringify(details) }], details, }; } } export const CodingCapabilityRegistry = CodingCapabilityRegistryImpl; export const createCodingCapabilityRegistry = ( options: CodingCapabilityRegistryOptions, ): CodingCapabilityRegistry => new CodingCapabilityRegistryImpl(options);