fix(coding): remediate ML-07 plugin authority
This commit is contained in:
@@ -20,7 +20,6 @@ import type { PiProductTools } from '../coding-runtime/pi/product-tools';
|
||||
import type { DataServiceOperations } from '../services/data-service-client';
|
||||
import type { PreviewDataSessionManager } from '../services/preview-data-session';
|
||||
import {
|
||||
BUNDLED_CODING_PLUGIN_DEFINITIONS,
|
||||
type CodingPluginDefinition,
|
||||
type PluginBillingMode,
|
||||
} from '../../shared/coding-plugins';
|
||||
@@ -97,6 +96,8 @@ export interface CodingPluginProjectProjection {
|
||||
items: Array<{
|
||||
id: string;
|
||||
version: string;
|
||||
contractVersion: number;
|
||||
requiresBackend: boolean;
|
||||
displayName: string;
|
||||
description: string;
|
||||
enabled: boolean;
|
||||
@@ -105,7 +106,17 @@ export interface CodingPluginProjectProjection {
|
||||
skills: Array<{ id: string; assignedAgentIds: string[] }>;
|
||||
capabilities: Array<{
|
||||
id: string;
|
||||
operations: Array<{ id: string; billing: PublicPluginBilling }>;
|
||||
operations: Array<{
|
||||
id: string;
|
||||
billing: PublicPluginBilling;
|
||||
tool: {
|
||||
name: string;
|
||||
label: string;
|
||||
description: string;
|
||||
mutation: 'read' | 'write' | 'destructive';
|
||||
permissions: string[];
|
||||
} | null;
|
||||
}>;
|
||||
}>;
|
||||
settingsSurface: string | null;
|
||||
}>;
|
||||
@@ -137,7 +148,7 @@ export interface CreateCodingProjectPluginServiceOptions {
|
||||
projectPlugins: Pick<ProjectPluginService, 'getEnabledPluginIds' | 'setEnabled'>;
|
||||
policyClient: Pick<PluginPolicyClient, 'refresh' | 'getState'>;
|
||||
adapters: readonly CodingPluginAdapter[];
|
||||
definitions?: readonly CodingPluginDefinition[];
|
||||
definitions: readonly CodingPluginDefinition[];
|
||||
}
|
||||
|
||||
function policyOperation(
|
||||
@@ -245,7 +256,7 @@ function effectiveState(input: {
|
||||
export function createCodingProjectPluginService(
|
||||
options: CreateCodingProjectPluginServiceOptions,
|
||||
): CodingProjectPluginService {
|
||||
const definitions = options.definitions ?? BUNDLED_CODING_PLUGIN_DEFINITIONS;
|
||||
const definitions = options.definitions;
|
||||
const adapters = new Map(options.adapters.map((adapter) => [adapter.pluginId, adapter]));
|
||||
|
||||
async function project(localProjectId: string) {
|
||||
@@ -278,13 +289,27 @@ export function createCodingProjectPluginService(
|
||||
const policyAvailable = Boolean(
|
||||
pluginPolicy?.supported_contract_versions.includes(definition.contractVersion),
|
||||
);
|
||||
const capabilityIds = [...new Set(definition.tools.map(({ capabilityId }) => capabilityId))];
|
||||
const capabilityIds = [...new Set(definition.operations.map(({ capabilityId }) => capabilityId))];
|
||||
const capabilities = capabilityIds.flatMap((capabilityId) => {
|
||||
const operations = definition.tools
|
||||
.filter((tool) => tool.capabilityId === capabilityId)
|
||||
.flatMap((tool) => {
|
||||
const joined = policyOperation(policy, definition, capabilityId, tool.operation);
|
||||
return joined ? [{ id: tool.operation, billing: publicBilling(joined.billing, policy) }] : [];
|
||||
const operations = definition.operations
|
||||
.filter((candidate) => candidate.capabilityId === capabilityId)
|
||||
.flatMap((candidate) => {
|
||||
const joined = policyOperation(policy, definition, capabilityId, candidate.operation);
|
||||
if (!joined) return [];
|
||||
const tool = candidate.toolName
|
||||
? definition.tools.find(({ name }) => name === candidate.toolName)
|
||||
: undefined;
|
||||
return [{
|
||||
id: candidate.operation,
|
||||
billing: publicBilling(joined.billing, policy),
|
||||
tool: tool ? {
|
||||
name: tool.name,
|
||||
label: tool.label,
|
||||
description: tool.description,
|
||||
mutation: tool.mutation,
|
||||
permissions: [...tool.permissions],
|
||||
} : null,
|
||||
}];
|
||||
});
|
||||
return operations.length > 0 ? [{ id: capabilityId, operations }] : [];
|
||||
});
|
||||
@@ -292,6 +317,8 @@ export function createCodingProjectPluginService(
|
||||
return {
|
||||
id: definition.id,
|
||||
version: definition.version,
|
||||
contractVersion: definition.contractVersion,
|
||||
requiresBackend: definition.requiresBackend,
|
||||
displayName: definition.displayName,
|
||||
description: definition.description,
|
||||
enabled,
|
||||
@@ -349,6 +376,7 @@ export interface CodingProductHostOptions {
|
||||
projects: Pick<CodingProjectService, 'getActiveProject' | 'findActiveConversation'>;
|
||||
productTools: PiProductTools;
|
||||
files?: CodingProjectFileService;
|
||||
getEnabledPluginIds?(projectPath: string): Promise<readonly string[]>;
|
||||
listPiCommands?(conversationId: string): Promise<unknown>;
|
||||
}
|
||||
|
||||
@@ -455,16 +483,23 @@ export function createCodingProductHost(options: CodingProductHostOptions): Codi
|
||||
},
|
||||
async listSkills(agentId) {
|
||||
const project = await activeProject();
|
||||
const enabledPluginIds = options.getEnabledPluginIds
|
||||
? await options.getEnabledPluginIds(project.path)
|
||||
: [];
|
||||
return await options.productTools.listSkills(
|
||||
await selectedSkillIds(project.path, agentId),
|
||||
enabledPluginIds,
|
||||
);
|
||||
},
|
||||
async listCommands(conversationId) {
|
||||
const context = await conversationContext(conversationId);
|
||||
const enabledPluginIds = options.getEnabledPluginIds
|
||||
? await options.getEnabledPluginIds(context.project.path)
|
||||
: [];
|
||||
const piCommands = options.listPiCommands
|
||||
? normalizePiCommands(await options.listPiCommands(conversationId))
|
||||
: [];
|
||||
return await options.productTools.listCommands(context.skillIds, piCommands);
|
||||
return await options.productTools.listCommands(context.skillIds, piCommands, enabledPluginIds);
|
||||
},
|
||||
async getChanges(conversationId) {
|
||||
await conversationContext(conversationId);
|
||||
|
||||
Reference in New Issue
Block a user