Files
deepseek-harness/packages/host/plugin-inventory/src/index.ts
T
creatixchu 06ebda4385 Revert "refactor(plugin-inventory): collect startup diagnostics concurrently"
This reverts commit c3d4f4bb70f685acdd289acb5d72472087e8377a.
2026-10-25 18:36:55 +08:00

122 lines
4.6 KiB
TypeScript

/** Read-only projection of the current Cordis Loader plugin entries. */
import type { Context, FiberState } from '@deepseek-ai/cordis'
import type {} from '@deepseek-ai/cordis-plugin-loader'
// Type-only: the optional agent-preset roster resolved through `ctx.get`.
import type {} from '@deepseek-ai/dsh-agent-preset-registry'
import type {} from '@deepseek-ai/dsh-app-boot'
import { TypertRemoteService, Remote } from '@deepseek-ai/dsh-typert-protocol'
// Typert-generated ./typert and ./remote artifacts import Zod at runtime.
import type {} from 'zod'
import type {
AgentPresetPluginGroup,
PluginEntryId,
PluginFiberPhase,
PluginInventoryEntry,
PluginInventorySnapshot,
} from './types.ts'
export type * from './types.ts'
/**
* Brand an existing Loader-tree entry id at the owning boundary.
* @param value - the entry id as the Loader tree spells it.
* @returns the same id as the inventory's branded entry id.
*/
export function pluginEntryId(value: string): PluginEntryId {
return value as PluginEntryId
}
/** Runtime mirror: FiberState is a cross-package const enum. */
const FIBER_STATE = {
PENDING: 0 as FiberState.PENDING,
LOADING: 1 as FiberState.LOADING,
ACTIVE: 2 as FiberState.ACTIVE,
FAILED: 3 as FiberState.FAILED,
DISPOSED: 4 as FiberState.DISPOSED,
UNLOADING: 5 as FiberState.UNLOADING,
} as const
/** Complete public projection of Cordis Fiber states. */
const FIBER_PHASE = {
[FIBER_STATE.PENDING]: 'pending',
[FIBER_STATE.LOADING]: 'loading',
[FIBER_STATE.ACTIVE]: 'active',
[FIBER_STATE.FAILED]: 'failed',
[FIBER_STATE.DISPOSED]: null,
[FIBER_STATE.UNLOADING]: 'unloading',
} as const satisfies Record<FiberState, PluginFiberPhase>
/** Remote-only service exposing the Loader's current non-group entry state. */
export class PluginInventoryGateway extends TypertRemoteService {
static inject = ['loader']
constructor(ctx: Context) {
super(ctx, 'pluginInventory')
}
/**
* Read the Loader directly on every call. Cordis's internal plugin/status
* events already maintain Entry.fiber and Fiber.state, so a second cache
* would only add another lifecycle truth to keep synchronized.
*
* When an agent-preset roster is composed, the snapshot also carries each
* preset's composition rows, because those rows — not the Loader's own
* entries — are where a deployment that mounts the roster runs its
* model-facing plugins.
* @returns Current non-group Loader entries in Loader order, with optional display metadata
* and per-preset compositions when a roster is composed.
*/
@Remote('list')
async list(): Promise<PluginInventorySnapshot> {
return readPluginInventory(this.ctx)
}
}
export default PluginInventoryGateway
/** Read current Loader entries and optional preset compositions.
* @param ctx Context with the Loader service.
* @returns Current inventory with optional display metadata and no separate runtime cache.
*/
export async function readPluginInventory(ctx: Context): Promise<PluginInventorySnapshot> {
const entries: PluginInventoryEntry[] = []
const packages = ctx.get('pluginPackages')
for (const entry of ctx.loader.entries()) {
if (entry.options.group) continue
const base = entry.parent.tree.ctx.baseUrl
const meta = base === undefined ? undefined : packages?.metaOf(entry.options.name, base)
const fiber = entry.fiber
const fiberPhase = fiber === undefined ? null : FIBER_PHASE[fiber.state]
let diagnostic: string | undefined
if (fiber !== undefined && fiberPhase === 'failed') {
try { await fiber.await() } catch (error) { diagnostic = error instanceof Error ? error.message : String(error) }
}
entries.push({
entryId: pluginEntryId(entry.id),
moduleName: entry.options.name,
enabled: !entry.disabled,
fiberPhase,
...diagnostic === undefined ? {} : { diagnostic },
...meta === undefined ? {} : { meta },
})
}
const presets = ctx.get('agentPresets')
const management = ctx.get('pluginManager') === undefined ? {} : { managementAvailable: true }
if (presets === undefined) return { entries, ...management }
const agentPresets: AgentPresetPluginGroup[] = (await presets.compositionInventory()).map(
composition => ({
...composition,
rows: composition.rows.map(({ fiberState, ...row }) => {
const meta = ctx.baseUrl === undefined ? undefined : packages?.metaOf(row.moduleName, ctx.baseUrl)
return {
...row,
fiberPhase: fiberState === undefined ? null : FIBER_PHASE[fiberState],
...meta === undefined ? {} : { meta },
}
}),
}),
)
return { entries, agentPresets, ...management }
}