# Conflicts:
#	electron/coding-runtime/pi/extensions/makelore-runtime.ts
This commit is contained in:
2026-08-31 15:06:37 +08:00
128 changed files with 8282 additions and 3026 deletions

View File

@@ -1,3 +1,4 @@
import { accessSync, constants } from 'node:fs';
import path from 'node:path';
import type { AgentBrowserModule } from '../agent-browser';
import { CodingAttachmentStore } from '../coding-projects/attachment-store';
@@ -10,6 +11,7 @@ import {
} from '../coding-projects/project-store';
import { CodingConversationService } from '../coding-runtime/conversation-service';
import { PiManagedExtensionHost } from '../coding-runtime/pi/extension-host';
import { PiAgentServerProcess } from '../coding-runtime/pi/agent-server-process';
import { PiManagedInputRevisionCoordinator } from '../coding-runtime/pi/managed-input-revision';
import { PiProductTools } from '../coding-runtime/pi/product-tools';
import {
@@ -33,8 +35,10 @@ import {
import { createCodingProductHost, type CodingProductComposition } from './coding-product-services';
import { createDataServiceOperations } from '../services/data-service-client';
import { createPreviewDataSessionManager, type PreviewDataSessionManager } from '../services/preview-data-session';
import { archivePiConversationSession } from '../coding-runtime/pi/resource-loader';
import { resolveLegacyProjectModel } from '../coding-projects/legacy-v1';
import {
archivePiConversationSession,
getPiManagedPaths,
} from '../coding-runtime/pi/resource-loader';
import { createProjectPluginService } from '../coding-plugins/project-service';
import {
createCodingCapabilityRegistry,
@@ -71,6 +75,7 @@ import {
export interface CodingCompositionPaths {
executablePath: string;
cliPath: string;
serverPath: string;
userDataDir: string;
bundledSkillsDir: string;
}
@@ -89,14 +94,51 @@ export interface CreateCodingCompositionOptions {
policyClient?: PluginPolicyClient;
}
type PiWorkerExecutableProbe = (candidate: string) => boolean;
function canExecute(candidate: string): boolean {
try {
accessSync(candidate, constants.X_OK);
return true;
} catch {
return false;
}
}
export function resolvePiWorkerExecutablePath(
executablePath: string,
options: {
platform?: NodeJS.Platform;
canExecute?: PiWorkerExecutableProbe;
} = {},
): string {
if ((options.platform ?? process.platform) !== 'darwin') return executablePath;
// The product binary remains a Foreground LaunchServices app even in Node mode.
// Electron's generic Helper is LSUIElement=true, so workers stay out of the Dock.
const executableName = path.basename(executablePath);
const helperExecutablePath = path.resolve(
path.dirname(executablePath),
'..',
'Frameworks',
`${executableName} Helper.app`,
'Contents',
'MacOS',
`${executableName} Helper`,
);
return (options.canExecute ?? canExecute)(helperExecutablePath)
? helperExecutablePath
: executablePath;
}
export function resolveCodingPiRuntimePaths(input: {
isPackaged: boolean;
resourcesPath: string;
appPath: string;
executablePath: string;
}): Pick<CodingCompositionPaths, 'executablePath' | 'cliPath'> {
}): Pick<CodingCompositionPaths, 'executablePath' | 'cliPath' | 'serverPath'> {
return {
executablePath: input.executablePath,
executablePath: resolvePiWorkerExecutablePath(input.executablePath),
cliPath: input.isPackaged
? path.join(input.resourcesPath, 'pi-runtime', 'dist', 'cli.js')
: path.join(
@@ -107,6 +149,9 @@ export function resolveCodingPiRuntimePaths(input: {
'dist',
'cli.js',
),
serverPath: input.isPackaged
? path.join(input.resourcesPath, 'resources', 'pi-agent-server.mjs')
: path.join(input.appPath, 'resources', 'pi-agent-server.mjs'),
};
}
@@ -196,6 +241,12 @@ export function createCodingComposition(
});
const revisions = new PiManagedInputRevisionCoordinator();
const processBudget = new PiProcessBudget();
const agentServer = new PiAgentServerProcess({
executablePath: options.paths.executablePath,
serverPath: options.paths.serverPath,
runtimeRoot: path.dirname(path.dirname(options.paths.cliPath)),
configDir: getPiManagedPaths(options.paths.userDataDir).configDir,
});
const loadProviderInput = async () => ({
accounts: await getProviderService().listAccounts(),
modelSummaries: [],
@@ -204,12 +255,6 @@ export function createCodingComposition(
let plugins: CodingProjectPluginService | undefined;
let previewDataSession: PreviewDataSessionManager | undefined;
const projects = new CodingProjectService(projectStore, {
migration: {
resolveLegacyModel: async ({ legacyModel }) => resolveLegacyProjectModel(
legacyModel,
await getProviderService().listAccounts(),
),
},
createConversationStore: conversationStoreForProject,
onResourcesChanged: async (project) => {
runtime?.markResourcesStale();
@@ -308,6 +353,8 @@ export function createCodingComposition(
});
const workerPool = new PiWorkerPool({
processBudget,
processMode: 'shared',
maxIdle: 8,
revisionCoordinator: revisions,
openWorker: createPiManagedWorkerOpener({
registry,
@@ -321,6 +368,7 @@ export function createCodingComposition(
registerActivePluginReleases,
loadProviderInput,
resolveCredential: resolvePiProviderCredentialFromSecretStore,
createProcess: (processOptions) => agentServer.createWorker(processOptions),
...(getLocalProxyCredential
? { getLocalProxyCredential: async () => getLocalProxyCredential() }
: {}),
@@ -349,7 +397,6 @@ export function createCodingComposition(
const subagents = new PiSubagentScheduler({
openChild: childOpener,
processBudget,
reclaimProcessCapacity: (signal) => workerPool.reclaimIdleWorker(signal),
});
runtime = new PiConversationRuntime({
pool: workerPool,
@@ -443,6 +490,7 @@ export function createCodingComposition(
await Promise.allSettled(conversationIds.map((conversationId) => (
runtime.dispose(conversationId, reason)
)));
await agentServer.stop();
},
async shutdown() {
previewDataSession?.dispose();
@@ -456,9 +504,13 @@ export function createCodingComposition(
await subagents.close();
await runtime.shutdown();
} finally {
unsubscribeMarketplaceSession();
packageStore.dispose();
marketplaceClient.dispose();
try {
await agentServer.stop();
} finally {
unsubscribeMarketplaceSession();
packageStore.dispose();
marketplaceClient.dispose();
}
}
},
};