@agimon-ai/po-core 0.0.0-alpha.29 → 0.0.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.cjs +1 -0
- package/dist/main.d.mts +2 -2
- package/dist/main.mjs +2 -2
- package/dist/packageApiServer.cjs.map +1 -1
- package/dist/packageApiServer.mjs.map +1 -1
- package/dist/runtimeLogSinkTelemetry.cjs +2 -2
- package/dist/runtimeLogSinkTelemetry.cjs.map +1 -1
- package/dist/runtimeLogSinkTelemetry.d.mts +2 -1
- package/dist/runtimeLogSinkTelemetry.d.mts.map +1 -1
- package/dist/runtimeLogSinkTelemetry.mjs +2 -2
- package/dist/runtimeLogSinkTelemetry.mjs.map +1 -1
- package/dist/serverTelemetry.cjs +2 -2
- package/dist/serverTelemetry.cjs.map +1 -1
- package/dist/serverTelemetry.d.mts +2 -1
- package/dist/serverTelemetry.d.mts.map +1 -1
- package/dist/serverTelemetry.mjs +1 -1
- package/dist/serverTelemetry.mjs.map +1 -1
- package/dist/src/schemas/delegation.cjs +2 -1
- package/dist/src/schemas/delegation.cjs.map +1 -1
- package/dist/src/schemas/delegation.d.mts +1 -0
- package/dist/src/schemas/delegation.d.mts.map +1 -1
- package/dist/src/schemas/delegation.mjs +2 -1
- package/dist/src/schemas/delegation.mjs.map +1 -1
- package/dist/src/schemas/headless.cjs.map +1 -1
- package/dist/src/schemas/headless.d.mts +6 -1
- package/dist/src/schemas/headless.d.mts.map +1 -1
- package/dist/src/schemas/headless.mjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.cjs +7 -1
- package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.mjs +7 -1
- package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
- package/dist/src/services/poTelemetry/index.cjs +21 -0
- package/dist/src/services/poTelemetry/index.cjs.map +1 -0
- package/dist/src/services/poTelemetry/index.d.mts +7 -0
- package/dist/src/services/poTelemetry/index.d.mts.map +1 -0
- package/dist/src/services/poTelemetry/index.mjs +18 -0
- package/dist/src/services/poTelemetry/index.mjs.map +1 -0
- package/dist/src/services/telemetry/index.cjs +547 -0
- package/dist/src/services/telemetry/index.cjs.map +1 -0
- package/dist/src/services/telemetry/index.d.mts +7 -0
- package/dist/src/services/telemetry/index.d.mts.map +1 -0
- package/dist/src/services/telemetry/index.mjs +544 -0
- package/dist/src/services/telemetry/index.mjs.map +1 -0
- package/dist/src/services/traceContext/index.cjs.map +1 -1
- package/dist/src/services/traceContext/index.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.cjs +12 -2
- package/dist/src/systems/main/adapters/headlessHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.d.mts +2 -0
- package/dist/src/systems/main/adapters/headlessHost.d.mts.map +1 -1
- package/dist/src/systems/main/adapters/headlessHost.mjs +12 -3
- package/dist/src/systems/main/adapters/headlessHost.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs +2 -5
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.d.mts.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs +4 -7
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
- package/dist/src/systems/main/types/headlessHost.d.mts +1 -1
- package/dist/src/types/telemetry.d.mts +64 -0
- package/dist/src/types/telemetry.d.mts.map +1 -0
- package/dist/telemetry.cjs +7 -0
- package/dist/telemetry.d.mts +4 -0
- package/dist/telemetry.mjs +3 -0
- package/package.json +10 -4
package/dist/main.cjs
CHANGED
|
@@ -9,5 +9,6 @@ exports.createHeadlessSessionManager = require_headlessSessionManager.createHead
|
|
|
9
9
|
exports.describeSkillTool = require_headlessHost.describeSkillTool;
|
|
10
10
|
exports.headlessHarnessSkill = require_headlessHost.headlessHarnessSkill;
|
|
11
11
|
exports.restoreHeadlessSelection = require_headlessSessionHost.restoreHeadlessSelection;
|
|
12
|
+
exports.systemPromptSkills = require_headlessHost.systemPromptSkills;
|
|
12
13
|
exports.toolAdapter = require_headlessSessionHost.toolAdapter;
|
|
13
14
|
exports.validateDirectHeadlessArgs = require_index.validateDirectHeadlessArgs;
|
package/dist/main.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HeadlessContextInventory, HeadlessHostOptions, HeadlessSelectionStatus, ResolvedHeadlessResource } from "./src/systems/main/types/headlessHost.mjs";
|
|
2
|
-
import { HeadlessHost, describeSkillTool, headlessHarnessSkill } from "./src/systems/main/adapters/headlessHost.mjs";
|
|
2
|
+
import { HeadlessHost, describeSkillTool, headlessHarnessSkill, systemPromptSkills } from "./src/systems/main/adapters/headlessHost.mjs";
|
|
3
3
|
import { validateDirectHeadlessArgs } from "./src/services/piArgs/index.mjs";
|
|
4
4
|
import { createHeadlessSessionHost, restoreHeadlessSelection, toolAdapter } from "./src/systems/main/adapters/headlessSessionHost.mjs";
|
|
5
5
|
import { createHeadlessSessionManager } from "./headlessSessionManager.mjs";
|
|
6
|
-
export { type HeadlessContextInventory, HeadlessHost, type HeadlessHostOptions, type HeadlessSelectionStatus, type ResolvedHeadlessResource, createHeadlessSessionHost, createHeadlessSessionManager, describeSkillTool, headlessHarnessSkill, restoreHeadlessSelection, toolAdapter, validateDirectHeadlessArgs };
|
|
6
|
+
export { type HeadlessContextInventory, HeadlessHost, type HeadlessHostOptions, type HeadlessSelectionStatus, type ResolvedHeadlessResource, createHeadlessSessionHost, createHeadlessSessionManager, describeSkillTool, headlessHarnessSkill, restoreHeadlessSelection, systemPromptSkills, toolAdapter, validateDirectHeadlessArgs };
|
package/dist/main.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { HeadlessHost, describeSkillTool, headlessHarnessSkill } from "./src/systems/main/adapters/headlessHost.mjs";
|
|
1
|
+
import { HeadlessHost, describeSkillTool, headlessHarnessSkill, systemPromptSkills } from "./src/systems/main/adapters/headlessHost.mjs";
|
|
2
2
|
import { validateDirectHeadlessArgs } from "./src/services/piArgs/index.mjs";
|
|
3
3
|
import { createHeadlessSessionHost, restoreHeadlessSelection, toolAdapter } from "./src/systems/main/adapters/headlessSessionHost.mjs";
|
|
4
4
|
import { createHeadlessSessionManager } from "./headlessSessionManager.mjs";
|
|
5
|
-
export { HeadlessHost, createHeadlessSessionHost, createHeadlessSessionManager, describeSkillTool, headlessHarnessSkill, restoreHeadlessSelection, toolAdapter, validateDirectHeadlessArgs };
|
|
5
|
+
export { HeadlessHost, createHeadlessSessionHost, createHeadlessSessionManager, describeSkillTool, headlessHarnessSkill, restoreHeadlessSelection, systemPromptSkills, toolAdapter, validateDirectHeadlessArgs };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageApiServer.cjs","names":["SESSION_FILES_API","readAccessibleFile","prepareSessionEnvironment","createPoServerHost","createFileAccess","PO_SESSION_TEMP_DIR","path","PoServerScope","PO_FILE_ACCESS_SERVICE","PO_API_ROUTE_PREFIX","validatedTraceContext"],"sources":["../src/server/packageApiServer.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { PoTraceContext } from '@agimon-ai/po-telemetry';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { SESSION_FILES_API } from '../constants/sessionFiles';\nimport type { PoDirectEventBus, PoHubSessionPromptOptions, PoHubSessionService } from '../exports/hubChannel';\nimport { PO_API_ROUTE_PREFIX, type PoApi, type PoApiContext } from '../exports/packageApi';\nimport type { PoPlatform } from '../exports/platform';\nimport type { PoPluginRegistry } from '../exports/pluginProtocol';\nimport {\n createPoServerHost,\n type CreatePoServerHostOptions,\n type LoadedServerPackage,\n type PoServerPlugin,\n PoServerScope,\n} from '../exports/serverPlugin';\nimport {\n createFileAccess,\n PO_FILE_ACCESS_SERVICE,\n type PoFileAccess,\n readAccessibleFile,\n} from '../services/fileAccess';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { PO_SESSION_TEMP_DIR, prepareSessionEnvironment } from '../services/sessionFiles';\nimport { validatedTraceContext } from '../services/traceContext';\n\n/**\n * A body that keeps streaming well after its headers went out is worth its own span. A fast\n * one is not: the request span already carries the duration and outcome, so emitting a second\n * span per call made package API traffic 99.65% of all spans recorded in a two hour sample.\n */\nexport const COMPLETION_SPAN_MIN_DURATION_MS = 1000;\n\nexport interface PackageApiServerOptions {\n sessionId: string;\n workspaceId?: string;\n workspaceRoot?: string;\n sessionContext?: PoApiContext['sessionContext'];\n homeDirectory?: string;\n mountChannel?: CreatePoServerHostOptions['mountChannel'];\n cwd: string;\n /** Admitted environment for APIs serving this session. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n /** Lifecycle-owned direct events shared with the hub. */\n readonly directEvents: PoDirectEventBus;\n readonly computerUse?: PoApiContext['computerUse'];\n /** Bound to this session's id and cwd by the host. */\n readonly shareFile?: PoApiContext['shareFile'];\n readonly mediaArbitration?: PoApiContext['mediaArbitration'];\n readonly executionBudget?: PoApiContext['executionBudget'];\n readonly editPresence?: PoApiContext['editPresence'];\n readonly peerAgents?: PoApiContext['peerAgents'];\n readonly requestApi?: PoApiContext['requestApi'];\n /** Publishes this session's activity line through the hub; bound to this session only. */\n readonly publishActivity?: PoApiContext['publishActivity'];\n internalToken?: string;\n hubToken?: string;\n /** Shared exact-scope dispatch table, so session packages can mount plugin methods. */\n pluginRegistry?: PoPluginRegistry;\n sessionService?: PoHubSessionService;\n apis: readonly PoApi[];\n /** Server packages to install; each registers its own APIs through the host. */\n packages?: readonly (PoServerPlugin | LoadedServerPackage)[];\n /** Publishes the session's own services into its scope root before any package installs. */\n preparePackages?: (root: Context) => void | Promise<void>;\n /** The hub's workspace or global scope; the session's own scope opens below it and closes with it. */\n parentScope?: PoServerScope;\n /** Host capabilities for the session scope root, injected by the composition root. */\n platform: PoPlatform;\n activatePackages?: (installedPackages: readonly string[]) => Promise<void>;\n canDispatch?: () => boolean;\n telemetry?: ServerTelemetry;\n onNotice: (message: string) => void;\n}\n\nexport interface PackageApiServer {\n /** Dispatches an already-authenticated request without crossing a transport boundary. */\n readonly request: (request: Request) => Promise<Response>;\n close(): Promise<void>;\n}\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction responseWithCompletion(response: Response, complete: () => void): Response {\n if (response.body === null) {\n complete();\n return response;\n }\n const reader = response.body.getReader();\n let completed = false;\n const finish = (): void => {\n if (completed) return;\n completed = true;\n complete();\n };\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const result = await reader.read();\n if (result.done) {\n finish();\n controller.close();\n } else controller.enqueue(result.value);\n } catch (error) {\n finish();\n controller.error(error);\n }\n },\n async cancel(reason) {\n finish();\n await reader.cancel(reason);\n },\n });\n return new Response(body, response);\n}\n\n/** Reads files under the session's open folders; the hub's session `/file` route forwards here. */\nfunction sessionFilesApi(fileAccess: PoFileAccess, cwd: string): PoApi {\n return {\n basePath: SESSION_FILES_API,\n start: () => ({\n fetch: (request) => {\n if (request.method !== 'GET') return Response.json({ error: 'Method not allowed.' }, { status: 405 });\n return readAccessibleFile({\n roots: fileAccess.roots(),\n cwd,\n path: new URL(request.url).searchParams.get('path'),\n ...(request.headers.get('range') === null ? {} : { range: request.headers.get('range')! }),\n ...(request.headers.get('if-match') === null ? {} : { expectedVersion: request.headers.get('if-match')! }),\n });\n },\n close: () => undefined,\n }),\n };\n}\n/** Installs session packages and dispatches authenticated package API calls in-process. */\nexport async function serveSessionApis(options: PackageApiServerOptions): Promise<PackageApiServer> {\n if (options.environment === undefined)\n throw new Error('Session package API server requires an admitted environment.');\n if (options.directEvents === undefined) throw new Error('Session package API server requires direct events.');\n options = { ...options, environment: await prepareSessionEnvironment(options) };\n const packages = options.packages ?? [];\n // Without a level above it, a session that mounts nothing has nothing to route.\n const routesNothing = (): boolean => !options.preparePackages && options.parentScope === undefined;\n if (options.apis.length === 0 && packages.length === 0 && routesNothing()) {\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n\n const owningSessionService = options.sessionService;\n const communication = owningSessionService?.bindCommunication?.(options.sessionId);\n const ownedReadExecutionState = owningSessionService?.readExecutionState?.bind(owningSessionService);\n const ownedPrompt = owningSessionService?.prompt?.bind(owningSessionService);\n const ownedAbort = owningSessionService?.abort?.bind(owningSessionService);\n const ownedSteer = owningSessionService?.steer?.bind(owningSessionService);\n const ownedRelease = owningSessionService?.release?.bind(owningSessionService);\n const exposedSessionService: PoHubSessionService | undefined =\n owningSessionService === undefined\n ? undefined\n : {\n create: (request) => owningSessionService.create(request),\n close: (sessionId) => owningSessionService.close(sessionId),\n isLive: (sessionId) => owningSessionService.isLive(sessionId),\n ...(ownedReadExecutionState === undefined\n ? {}\n : {\n readExecutionState: (sessionId: string) =>\n ownedReadExecutionState(sessionId, { parentSessionId: options.sessionId }),\n }),\n // A session may drive only the children it started, never its parent or a sibling.\n ...(ownedPrompt === undefined\n ? {}\n : {\n prompt: (sessionId: string, text: string, promptOptions?: PoHubSessionPromptOptions) =>\n ownedPrompt(sessionId, text, {\n ...(promptOptions?.signal === undefined ? {} : { signal: promptOptions.signal }),\n parentSessionId: options.sessionId,\n }),\n }),\n ...(ownedAbort === undefined\n ? {}\n : {\n abort: (sessionId: string) => ownedAbort(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(ownedSteer === undefined\n ? {}\n : {\n steer: (sessionId: string, message: string) =>\n ownedSteer(sessionId, message, { parentSessionId: options.sessionId }),\n }),\n ...(ownedRelease === undefined\n ? {}\n : {\n release: (sessionId: string) => ownedRelease(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(owningSessionService.canCommunicate === undefined\n ? {}\n : {\n canCommunicate: (sourceSessionId: string, targetSessionId: string) =>\n owningSessionService.canCommunicate?.(sourceSessionId, targetSessionId) === true,\n }),\n };\n const context: PoApiContext = {\n scope: 'session',\n sessionId: options.sessionId,\n workspaceId: options.workspaceId,\n workspaceRoot: options.workspaceRoot,\n ...(options.sessionContext === undefined ? {} : { sessionContext: options.sessionContext }),\n homeDirectory: options.homeDirectory ?? options.platform.homeDirectory,\n sessionStorage: options.platform.sessions,\n cwd: options.cwd,\n environment: options.environment,\n directEvents: options.directEvents,\n ...(options.computerUse === undefined ? {} : { computerUse: options.computerUse }),\n ...(options.shareFile === undefined ? {} : { shareFile: options.shareFile }),\n ...(options.mediaArbitration === undefined ? {} : { mediaArbitration: options.mediaArbitration }),\n ...(options.executionBudget === undefined ? {} : { executionBudget: options.executionBudget }),\n ...(options.editPresence === undefined ? {} : { editPresence: options.editPresence }),\n ...(options.peerAgents === undefined ? {} : { peerAgents: options.peerAgents }),\n ...(options.requestApi === undefined ? {} : { requestApi: options.requestApi }),\n ...(options.publishActivity === undefined ? {} : { publishActivity: options.publishActivity }),\n ...(options.internalToken === undefined ? {} : { internalToken: options.internalToken }),\n ...(options.hubToken === undefined ? {} : { hubToken: options.hubToken }),\n ...(exposedSessionService === undefined ? {} : { sessionService: exposedSessionService }),\n ...(communication === undefined ? {} : { sessionCommunication: communication }),\n onNotice: options.onNotice,\n };\n const host = createPoServerHost({\n scope: 'session',\n context,\n mountChannel: options.mountChannel,\n ...(options.pluginRegistry === undefined ? {} : { pluginRegistry: options.pluginRegistry }),\n });\n // The session's own folder, its workspace and its temp folder; extensions open their own beside these.\n const fileAccess = createFileAccess();\n for (const directory of [options.cwd, options.workspaceRoot, options.environment[PO_SESSION_TEMP_DIR]])\n if (directory !== undefined && path.isAbsolute(directory)) fileAccess.register(directory);\n let scope: PoServerScope | undefined;\n try {\n // Registered first, so no package can claim the host's own base path.\n host.registerApi(sessionFilesApi(fileAccess, options.cwd));\n for (const api of options.apis) host.registerApi(api);\n // The session's own level of the server IoC tree; it closes with the hub level it opens below.\n scope = await PoServerScope.open('session', options.parentScope);\n await scope.serve({ host, platform: options.platform });\n await scope.root.plugin((root) => {\n root.provide(PO_FILE_ACCESS_SERVICE, fileAccess);\n });\n await options.preparePackages?.(scope.root);\n const installed = await scope.install(packages, {\n onNotice: options.onNotice,\n onPackageSettled: (report) => {\n if (!options.telemetry) return;\n observe(\n options.telemetry.recordEvent('po_server.package_install', {\n 'package.name': report.packageName,\n 'package.outcome': report.outcome,\n duration_ms: report.durationMs,\n scope: 'session',\n }),\n options.onNotice,\n );\n },\n });\n await options.activatePackages?.(installed);\n } catch (error) {\n await scope?.dispose();\n communication?.close();\n host.dispose();\n throw error;\n }\n if (host.mounted().length === 0 && routesNothing()) {\n await scope.dispose();\n communication?.close();\n host.dispose();\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n const sessionScope = scope;\n\n const dispatch = async (request: Request): Promise<Response> => {\n if (options.canDispatch?.() === false)\n return Response.json({ error: 'Session selection is not ready.' }, { status: 503 });\n const url = new URL(request.url);\n if (!url.pathname.startsWith(`${PO_API_ROUTE_PREFIX}/`))\n return Response.json({ error: 'Not found.' }, { status: 404 });\n const rest = url.pathname.slice(PO_API_ROUTE_PREFIX.length + 1);\n const slash = rest.indexOf('/');\n const basePath = slash === -1 ? rest : rest.slice(0, slash);\n // The session's own API, else the nearest level above it that serves one.\n const handler = sessionScope.apiHandler(basePath);\n if (handler === undefined)\n return Response.json({ error: `No API '${basePath}' in this session.` }, { status: 404 });\n url.pathname = slash === -1 ? '/' : rest.slice(slash);\n const startedAt = performance.now();\n const parent = validatedTraceContext(request.headers.get('traceparent'));\n let childContext: PoTraceContext | undefined;\n let response: Response;\n try {\n const invoke = async (context?: PoTraceContext): Promise<Response> => {\n if (options.canDispatch?.() === false || sessionScope.apiHandler(basePath) !== handler) {\n return Response.json({ error: 'Session selection changed before dispatch.' }, { status: 503 });\n }\n childContext = context;\n return handler.fetch(new Request(url, request));\n };\n response = options.telemetry\n ? await options.telemetry.runInSpan(\n 'po_server.package_api.request',\n { api: basePath, method: request.method },\n invoke,\n parent,\n )\n : await invoke();\n } catch (error) {\n if (request.signal.aborted) return new Response(null, { status: 499 });\n options.onNotice(`package API '${basePath}' failed on ${url.pathname} (${describeError(error)})`);\n response = Response.json({ error: `The '${basePath}' API failed.` }, { status: 500 });\n }\n return responseWithCompletion(response, () => {\n if (!options.telemetry) return;\n const durationMs = Math.round(performance.now() - startedAt);\n // Keep this span only where it says something the request span cannot: a failing status,\n // or a body that took real time to flush after the headers were sent.\n if (response.status < 400 && durationMs < COMPLETION_SPAN_MIN_DURATION_MS) return;\n observe(\n options.telemetry.runInSpan(\n 'po_server.package_api.complete',\n {\n api: basePath,\n method: request.method,\n status_code: response.status,\n duration_ms: durationMs,\n },\n async () => undefined,\n childContext ?? parent,\n ),\n options.onNotice,\n );\n });\n };\n let closePromise: Promise<void> | undefined;\n\n return {\n request: dispatch,\n close: () => {\n closePromise ??= (async () => {\n await scope.dispose();\n communication?.close();\n host.dispose();\n })();\n return closePromise;\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"packageApiServer.cjs","names":["SESSION_FILES_API","readAccessibleFile","prepareSessionEnvironment","createPoServerHost","createFileAccess","PO_SESSION_TEMP_DIR","path","PoServerScope","PO_FILE_ACCESS_SERVICE","PO_API_ROUTE_PREFIX","validatedTraceContext"],"sources":["../src/server/packageApiServer.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { SESSION_FILES_API } from '../constants/sessionFiles';\nimport type { PoDirectEventBus, PoHubSessionPromptOptions, PoHubSessionService } from '../exports/hubChannel';\nimport { PO_API_ROUTE_PREFIX, type PoApi, type PoApiContext } from '../exports/packageApi';\nimport type { PoPlatform } from '../exports/platform';\nimport type { PoPluginRegistry } from '../exports/pluginProtocol';\nimport {\n createPoServerHost,\n type CreatePoServerHostOptions,\n type LoadedServerPackage,\n type PoServerPlugin,\n PoServerScope,\n} from '../exports/serverPlugin';\nimport {\n createFileAccess,\n PO_FILE_ACCESS_SERVICE,\n type PoFileAccess,\n readAccessibleFile,\n} from '../services/fileAccess';\nimport type { PoTraceContext } from '../services/poTelemetry';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { PO_SESSION_TEMP_DIR, prepareSessionEnvironment } from '../services/sessionFiles';\nimport { validatedTraceContext } from '../services/traceContext';\n\n/**\n * A body that keeps streaming well after its headers went out is worth its own span. A fast\n * one is not: the request span already carries the duration and outcome, so emitting a second\n * span per call made package API traffic 99.65% of all spans recorded in a two hour sample.\n */\nexport const COMPLETION_SPAN_MIN_DURATION_MS = 1000;\n\nexport interface PackageApiServerOptions {\n sessionId: string;\n workspaceId?: string;\n workspaceRoot?: string;\n sessionContext?: PoApiContext['sessionContext'];\n homeDirectory?: string;\n mountChannel?: CreatePoServerHostOptions['mountChannel'];\n cwd: string;\n /** Admitted environment for APIs serving this session. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n /** Lifecycle-owned direct events shared with the hub. */\n readonly directEvents: PoDirectEventBus;\n readonly computerUse?: PoApiContext['computerUse'];\n /** Bound to this session's id and cwd by the host. */\n readonly shareFile?: PoApiContext['shareFile'];\n readonly mediaArbitration?: PoApiContext['mediaArbitration'];\n readonly executionBudget?: PoApiContext['executionBudget'];\n readonly editPresence?: PoApiContext['editPresence'];\n readonly peerAgents?: PoApiContext['peerAgents'];\n readonly requestApi?: PoApiContext['requestApi'];\n /** Publishes this session's activity line through the hub; bound to this session only. */\n readonly publishActivity?: PoApiContext['publishActivity'];\n internalToken?: string;\n hubToken?: string;\n /** Shared exact-scope dispatch table, so session packages can mount plugin methods. */\n pluginRegistry?: PoPluginRegistry;\n sessionService?: PoHubSessionService;\n apis: readonly PoApi[];\n /** Server packages to install; each registers its own APIs through the host. */\n packages?: readonly (PoServerPlugin | LoadedServerPackage)[];\n /** Publishes the session's own services into its scope root before any package installs. */\n preparePackages?: (root: Context) => void | Promise<void>;\n /** The hub's workspace or global scope; the session's own scope opens below it and closes with it. */\n parentScope?: PoServerScope;\n /** Host capabilities for the session scope root, injected by the composition root. */\n platform: PoPlatform;\n activatePackages?: (installedPackages: readonly string[]) => Promise<void>;\n canDispatch?: () => boolean;\n telemetry?: ServerTelemetry;\n onNotice: (message: string) => void;\n}\n\nexport interface PackageApiServer {\n /** Dispatches an already-authenticated request without crossing a transport boundary. */\n readonly request: (request: Request) => Promise<Response>;\n close(): Promise<void>;\n}\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction responseWithCompletion(response: Response, complete: () => void): Response {\n if (response.body === null) {\n complete();\n return response;\n }\n const reader = response.body.getReader();\n let completed = false;\n const finish = (): void => {\n if (completed) return;\n completed = true;\n complete();\n };\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const result = await reader.read();\n if (result.done) {\n finish();\n controller.close();\n } else controller.enqueue(result.value);\n } catch (error) {\n finish();\n controller.error(error);\n }\n },\n async cancel(reason) {\n finish();\n await reader.cancel(reason);\n },\n });\n return new Response(body, response);\n}\n\n/** Reads files under the session's open folders; the hub's session `/file` route forwards here. */\nfunction sessionFilesApi(fileAccess: PoFileAccess, cwd: string): PoApi {\n return {\n basePath: SESSION_FILES_API,\n start: () => ({\n fetch: (request) => {\n if (request.method !== 'GET') return Response.json({ error: 'Method not allowed.' }, { status: 405 });\n return readAccessibleFile({\n roots: fileAccess.roots(),\n cwd,\n path: new URL(request.url).searchParams.get('path'),\n ...(request.headers.get('range') === null ? {} : { range: request.headers.get('range')! }),\n ...(request.headers.get('if-match') === null ? {} : { expectedVersion: request.headers.get('if-match')! }),\n });\n },\n close: () => undefined,\n }),\n };\n}\n/** Installs session packages and dispatches authenticated package API calls in-process. */\nexport async function serveSessionApis(options: PackageApiServerOptions): Promise<PackageApiServer> {\n if (options.environment === undefined)\n throw new Error('Session package API server requires an admitted environment.');\n if (options.directEvents === undefined) throw new Error('Session package API server requires direct events.');\n options = { ...options, environment: await prepareSessionEnvironment(options) };\n const packages = options.packages ?? [];\n // Without a level above it, a session that mounts nothing has nothing to route.\n const routesNothing = (): boolean => !options.preparePackages && options.parentScope === undefined;\n if (options.apis.length === 0 && packages.length === 0 && routesNothing()) {\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n\n const owningSessionService = options.sessionService;\n const communication = owningSessionService?.bindCommunication?.(options.sessionId);\n const ownedReadExecutionState = owningSessionService?.readExecutionState?.bind(owningSessionService);\n const ownedPrompt = owningSessionService?.prompt?.bind(owningSessionService);\n const ownedAbort = owningSessionService?.abort?.bind(owningSessionService);\n const ownedSteer = owningSessionService?.steer?.bind(owningSessionService);\n const ownedRelease = owningSessionService?.release?.bind(owningSessionService);\n const exposedSessionService: PoHubSessionService | undefined =\n owningSessionService === undefined\n ? undefined\n : {\n create: (request) => owningSessionService.create(request),\n close: (sessionId) => owningSessionService.close(sessionId),\n isLive: (sessionId) => owningSessionService.isLive(sessionId),\n ...(ownedReadExecutionState === undefined\n ? {}\n : {\n readExecutionState: (sessionId: string) =>\n ownedReadExecutionState(sessionId, { parentSessionId: options.sessionId }),\n }),\n // A session may drive only the children it started, never its parent or a sibling.\n ...(ownedPrompt === undefined\n ? {}\n : {\n prompt: (sessionId: string, text: string, promptOptions?: PoHubSessionPromptOptions) =>\n ownedPrompt(sessionId, text, {\n ...(promptOptions?.signal === undefined ? {} : { signal: promptOptions.signal }),\n parentSessionId: options.sessionId,\n }),\n }),\n ...(ownedAbort === undefined\n ? {}\n : {\n abort: (sessionId: string) => ownedAbort(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(ownedSteer === undefined\n ? {}\n : {\n steer: (sessionId: string, message: string) =>\n ownedSteer(sessionId, message, { parentSessionId: options.sessionId }),\n }),\n ...(ownedRelease === undefined\n ? {}\n : {\n release: (sessionId: string) => ownedRelease(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(owningSessionService.canCommunicate === undefined\n ? {}\n : {\n canCommunicate: (sourceSessionId: string, targetSessionId: string) =>\n owningSessionService.canCommunicate?.(sourceSessionId, targetSessionId) === true,\n }),\n };\n const context: PoApiContext = {\n scope: 'session',\n sessionId: options.sessionId,\n workspaceId: options.workspaceId,\n workspaceRoot: options.workspaceRoot,\n ...(options.sessionContext === undefined ? {} : { sessionContext: options.sessionContext }),\n homeDirectory: options.homeDirectory ?? options.platform.homeDirectory,\n sessionStorage: options.platform.sessions,\n cwd: options.cwd,\n environment: options.environment,\n directEvents: options.directEvents,\n ...(options.computerUse === undefined ? {} : { computerUse: options.computerUse }),\n ...(options.shareFile === undefined ? {} : { shareFile: options.shareFile }),\n ...(options.mediaArbitration === undefined ? {} : { mediaArbitration: options.mediaArbitration }),\n ...(options.executionBudget === undefined ? {} : { executionBudget: options.executionBudget }),\n ...(options.editPresence === undefined ? {} : { editPresence: options.editPresence }),\n ...(options.peerAgents === undefined ? {} : { peerAgents: options.peerAgents }),\n ...(options.requestApi === undefined ? {} : { requestApi: options.requestApi }),\n ...(options.publishActivity === undefined ? {} : { publishActivity: options.publishActivity }),\n ...(options.internalToken === undefined ? {} : { internalToken: options.internalToken }),\n ...(options.hubToken === undefined ? {} : { hubToken: options.hubToken }),\n ...(exposedSessionService === undefined ? {} : { sessionService: exposedSessionService }),\n ...(communication === undefined ? {} : { sessionCommunication: communication }),\n onNotice: options.onNotice,\n };\n const host = createPoServerHost({\n scope: 'session',\n context,\n mountChannel: options.mountChannel,\n ...(options.pluginRegistry === undefined ? {} : { pluginRegistry: options.pluginRegistry }),\n });\n // The session's own folder, its workspace and its temp folder; extensions open their own beside these.\n const fileAccess = createFileAccess();\n for (const directory of [options.cwd, options.workspaceRoot, options.environment[PO_SESSION_TEMP_DIR]])\n if (directory !== undefined && path.isAbsolute(directory)) fileAccess.register(directory);\n let scope: PoServerScope | undefined;\n try {\n // Registered first, so no package can claim the host's own base path.\n host.registerApi(sessionFilesApi(fileAccess, options.cwd));\n for (const api of options.apis) host.registerApi(api);\n // The session's own level of the server IoC tree; it closes with the hub level it opens below.\n scope = await PoServerScope.open('session', options.parentScope);\n await scope.serve({ host, platform: options.platform });\n await scope.root.plugin((root) => {\n root.provide(PO_FILE_ACCESS_SERVICE, fileAccess);\n });\n await options.preparePackages?.(scope.root);\n const installed = await scope.install(packages, {\n onNotice: options.onNotice,\n onPackageSettled: (report) => {\n if (!options.telemetry) return;\n observe(\n options.telemetry.recordEvent('po_server.package_install', {\n 'package.name': report.packageName,\n 'package.outcome': report.outcome,\n duration_ms: report.durationMs,\n scope: 'session',\n }),\n options.onNotice,\n );\n },\n });\n await options.activatePackages?.(installed);\n } catch (error) {\n await scope?.dispose();\n communication?.close();\n host.dispose();\n throw error;\n }\n if (host.mounted().length === 0 && routesNothing()) {\n await scope.dispose();\n communication?.close();\n host.dispose();\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n const sessionScope = scope;\n\n const dispatch = async (request: Request): Promise<Response> => {\n if (options.canDispatch?.() === false)\n return Response.json({ error: 'Session selection is not ready.' }, { status: 503 });\n const url = new URL(request.url);\n if (!url.pathname.startsWith(`${PO_API_ROUTE_PREFIX}/`))\n return Response.json({ error: 'Not found.' }, { status: 404 });\n const rest = url.pathname.slice(PO_API_ROUTE_PREFIX.length + 1);\n const slash = rest.indexOf('/');\n const basePath = slash === -1 ? rest : rest.slice(0, slash);\n // The session's own API, else the nearest level above it that serves one.\n const handler = sessionScope.apiHandler(basePath);\n if (handler === undefined)\n return Response.json({ error: `No API '${basePath}' in this session.` }, { status: 404 });\n url.pathname = slash === -1 ? '/' : rest.slice(slash);\n const startedAt = performance.now();\n const parent = validatedTraceContext(request.headers.get('traceparent'));\n let childContext: PoTraceContext | undefined;\n let response: Response;\n try {\n const invoke = async (context?: PoTraceContext): Promise<Response> => {\n if (options.canDispatch?.() === false || sessionScope.apiHandler(basePath) !== handler) {\n return Response.json({ error: 'Session selection changed before dispatch.' }, { status: 503 });\n }\n childContext = context;\n return handler.fetch(new Request(url, request));\n };\n response = options.telemetry\n ? await options.telemetry.runInSpan(\n 'po_server.package_api.request',\n { api: basePath, method: request.method },\n invoke,\n parent,\n )\n : await invoke();\n } catch (error) {\n if (request.signal.aborted) return new Response(null, { status: 499 });\n options.onNotice(`package API '${basePath}' failed on ${url.pathname} (${describeError(error)})`);\n response = Response.json({ error: `The '${basePath}' API failed.` }, { status: 500 });\n }\n return responseWithCompletion(response, () => {\n if (!options.telemetry) return;\n const durationMs = Math.round(performance.now() - startedAt);\n // Keep this span only where it says something the request span cannot: a failing status,\n // or a body that took real time to flush after the headers were sent.\n if (response.status < 400 && durationMs < COMPLETION_SPAN_MIN_DURATION_MS) return;\n observe(\n options.telemetry.runInSpan(\n 'po_server.package_api.complete',\n {\n api: basePath,\n method: request.method,\n status_code: response.status,\n duration_ms: durationMs,\n },\n async () => undefined,\n childContext ?? parent,\n ),\n options.onNotice,\n );\n });\n };\n let closePromise: Promise<void> | undefined;\n\n return {\n request: dispatch,\n close: () => {\n closePromise ??= (async () => {\n await scope.dispose();\n communication?.close();\n host.dispose();\n })();\n return closePromise;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageApiServer.mjs","names":[],"sources":["../src/server/packageApiServer.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { PoTraceContext } from '@agimon-ai/po-telemetry';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { SESSION_FILES_API } from '../constants/sessionFiles';\nimport type { PoDirectEventBus, PoHubSessionPromptOptions, PoHubSessionService } from '../exports/hubChannel';\nimport { PO_API_ROUTE_PREFIX, type PoApi, type PoApiContext } from '../exports/packageApi';\nimport type { PoPlatform } from '../exports/platform';\nimport type { PoPluginRegistry } from '../exports/pluginProtocol';\nimport {\n createPoServerHost,\n type CreatePoServerHostOptions,\n type LoadedServerPackage,\n type PoServerPlugin,\n PoServerScope,\n} from '../exports/serverPlugin';\nimport {\n createFileAccess,\n PO_FILE_ACCESS_SERVICE,\n type PoFileAccess,\n readAccessibleFile,\n} from '../services/fileAccess';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { PO_SESSION_TEMP_DIR, prepareSessionEnvironment } from '../services/sessionFiles';\nimport { validatedTraceContext } from '../services/traceContext';\n\n/**\n * A body that keeps streaming well after its headers went out is worth its own span. A fast\n * one is not: the request span already carries the duration and outcome, so emitting a second\n * span per call made package API traffic 99.65% of all spans recorded in a two hour sample.\n */\nexport const COMPLETION_SPAN_MIN_DURATION_MS = 1000;\n\nexport interface PackageApiServerOptions {\n sessionId: string;\n workspaceId?: string;\n workspaceRoot?: string;\n sessionContext?: PoApiContext['sessionContext'];\n homeDirectory?: string;\n mountChannel?: CreatePoServerHostOptions['mountChannel'];\n cwd: string;\n /** Admitted environment for APIs serving this session. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n /** Lifecycle-owned direct events shared with the hub. */\n readonly directEvents: PoDirectEventBus;\n readonly computerUse?: PoApiContext['computerUse'];\n /** Bound to this session's id and cwd by the host. */\n readonly shareFile?: PoApiContext['shareFile'];\n readonly mediaArbitration?: PoApiContext['mediaArbitration'];\n readonly executionBudget?: PoApiContext['executionBudget'];\n readonly editPresence?: PoApiContext['editPresence'];\n readonly peerAgents?: PoApiContext['peerAgents'];\n readonly requestApi?: PoApiContext['requestApi'];\n /** Publishes this session's activity line through the hub; bound to this session only. */\n readonly publishActivity?: PoApiContext['publishActivity'];\n internalToken?: string;\n hubToken?: string;\n /** Shared exact-scope dispatch table, so session packages can mount plugin methods. */\n pluginRegistry?: PoPluginRegistry;\n sessionService?: PoHubSessionService;\n apis: readonly PoApi[];\n /** Server packages to install; each registers its own APIs through the host. */\n packages?: readonly (PoServerPlugin | LoadedServerPackage)[];\n /** Publishes the session's own services into its scope root before any package installs. */\n preparePackages?: (root: Context) => void | Promise<void>;\n /** The hub's workspace or global scope; the session's own scope opens below it and closes with it. */\n parentScope?: PoServerScope;\n /** Host capabilities for the session scope root, injected by the composition root. */\n platform: PoPlatform;\n activatePackages?: (installedPackages: readonly string[]) => Promise<void>;\n canDispatch?: () => boolean;\n telemetry?: ServerTelemetry;\n onNotice: (message: string) => void;\n}\n\nexport interface PackageApiServer {\n /** Dispatches an already-authenticated request without crossing a transport boundary. */\n readonly request: (request: Request) => Promise<Response>;\n close(): Promise<void>;\n}\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction responseWithCompletion(response: Response, complete: () => void): Response {\n if (response.body === null) {\n complete();\n return response;\n }\n const reader = response.body.getReader();\n let completed = false;\n const finish = (): void => {\n if (completed) return;\n completed = true;\n complete();\n };\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const result = await reader.read();\n if (result.done) {\n finish();\n controller.close();\n } else controller.enqueue(result.value);\n } catch (error) {\n finish();\n controller.error(error);\n }\n },\n async cancel(reason) {\n finish();\n await reader.cancel(reason);\n },\n });\n return new Response(body, response);\n}\n\n/** Reads files under the session's open folders; the hub's session `/file` route forwards here. */\nfunction sessionFilesApi(fileAccess: PoFileAccess, cwd: string): PoApi {\n return {\n basePath: SESSION_FILES_API,\n start: () => ({\n fetch: (request) => {\n if (request.method !== 'GET') return Response.json({ error: 'Method not allowed.' }, { status: 405 });\n return readAccessibleFile({\n roots: fileAccess.roots(),\n cwd,\n path: new URL(request.url).searchParams.get('path'),\n ...(request.headers.get('range') === null ? {} : { range: request.headers.get('range')! }),\n ...(request.headers.get('if-match') === null ? {} : { expectedVersion: request.headers.get('if-match')! }),\n });\n },\n close: () => undefined,\n }),\n };\n}\n/** Installs session packages and dispatches authenticated package API calls in-process. */\nexport async function serveSessionApis(options: PackageApiServerOptions): Promise<PackageApiServer> {\n if (options.environment === undefined)\n throw new Error('Session package API server requires an admitted environment.');\n if (options.directEvents === undefined) throw new Error('Session package API server requires direct events.');\n options = { ...options, environment: await prepareSessionEnvironment(options) };\n const packages = options.packages ?? [];\n // Without a level above it, a session that mounts nothing has nothing to route.\n const routesNothing = (): boolean => !options.preparePackages && options.parentScope === undefined;\n if (options.apis.length === 0 && packages.length === 0 && routesNothing()) {\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n\n const owningSessionService = options.sessionService;\n const communication = owningSessionService?.bindCommunication?.(options.sessionId);\n const ownedReadExecutionState = owningSessionService?.readExecutionState?.bind(owningSessionService);\n const ownedPrompt = owningSessionService?.prompt?.bind(owningSessionService);\n const ownedAbort = owningSessionService?.abort?.bind(owningSessionService);\n const ownedSteer = owningSessionService?.steer?.bind(owningSessionService);\n const ownedRelease = owningSessionService?.release?.bind(owningSessionService);\n const exposedSessionService: PoHubSessionService | undefined =\n owningSessionService === undefined\n ? undefined\n : {\n create: (request) => owningSessionService.create(request),\n close: (sessionId) => owningSessionService.close(sessionId),\n isLive: (sessionId) => owningSessionService.isLive(sessionId),\n ...(ownedReadExecutionState === undefined\n ? {}\n : {\n readExecutionState: (sessionId: string) =>\n ownedReadExecutionState(sessionId, { parentSessionId: options.sessionId }),\n }),\n // A session may drive only the children it started, never its parent or a sibling.\n ...(ownedPrompt === undefined\n ? {}\n : {\n prompt: (sessionId: string, text: string, promptOptions?: PoHubSessionPromptOptions) =>\n ownedPrompt(sessionId, text, {\n ...(promptOptions?.signal === undefined ? {} : { signal: promptOptions.signal }),\n parentSessionId: options.sessionId,\n }),\n }),\n ...(ownedAbort === undefined\n ? {}\n : {\n abort: (sessionId: string) => ownedAbort(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(ownedSteer === undefined\n ? {}\n : {\n steer: (sessionId: string, message: string) =>\n ownedSteer(sessionId, message, { parentSessionId: options.sessionId }),\n }),\n ...(ownedRelease === undefined\n ? {}\n : {\n release: (sessionId: string) => ownedRelease(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(owningSessionService.canCommunicate === undefined\n ? {}\n : {\n canCommunicate: (sourceSessionId: string, targetSessionId: string) =>\n owningSessionService.canCommunicate?.(sourceSessionId, targetSessionId) === true,\n }),\n };\n const context: PoApiContext = {\n scope: 'session',\n sessionId: options.sessionId,\n workspaceId: options.workspaceId,\n workspaceRoot: options.workspaceRoot,\n ...(options.sessionContext === undefined ? {} : { sessionContext: options.sessionContext }),\n homeDirectory: options.homeDirectory ?? options.platform.homeDirectory,\n sessionStorage: options.platform.sessions,\n cwd: options.cwd,\n environment: options.environment,\n directEvents: options.directEvents,\n ...(options.computerUse === undefined ? {} : { computerUse: options.computerUse }),\n ...(options.shareFile === undefined ? {} : { shareFile: options.shareFile }),\n ...(options.mediaArbitration === undefined ? {} : { mediaArbitration: options.mediaArbitration }),\n ...(options.executionBudget === undefined ? {} : { executionBudget: options.executionBudget }),\n ...(options.editPresence === undefined ? {} : { editPresence: options.editPresence }),\n ...(options.peerAgents === undefined ? {} : { peerAgents: options.peerAgents }),\n ...(options.requestApi === undefined ? {} : { requestApi: options.requestApi }),\n ...(options.publishActivity === undefined ? {} : { publishActivity: options.publishActivity }),\n ...(options.internalToken === undefined ? {} : { internalToken: options.internalToken }),\n ...(options.hubToken === undefined ? {} : { hubToken: options.hubToken }),\n ...(exposedSessionService === undefined ? {} : { sessionService: exposedSessionService }),\n ...(communication === undefined ? {} : { sessionCommunication: communication }),\n onNotice: options.onNotice,\n };\n const host = createPoServerHost({\n scope: 'session',\n context,\n mountChannel: options.mountChannel,\n ...(options.pluginRegistry === undefined ? {} : { pluginRegistry: options.pluginRegistry }),\n });\n // The session's own folder, its workspace and its temp folder; extensions open their own beside these.\n const fileAccess = createFileAccess();\n for (const directory of [options.cwd, options.workspaceRoot, options.environment[PO_SESSION_TEMP_DIR]])\n if (directory !== undefined && path.isAbsolute(directory)) fileAccess.register(directory);\n let scope: PoServerScope | undefined;\n try {\n // Registered first, so no package can claim the host's own base path.\n host.registerApi(sessionFilesApi(fileAccess, options.cwd));\n for (const api of options.apis) host.registerApi(api);\n // The session's own level of the server IoC tree; it closes with the hub level it opens below.\n scope = await PoServerScope.open('session', options.parentScope);\n await scope.serve({ host, platform: options.platform });\n await scope.root.plugin((root) => {\n root.provide(PO_FILE_ACCESS_SERVICE, fileAccess);\n });\n await options.preparePackages?.(scope.root);\n const installed = await scope.install(packages, {\n onNotice: options.onNotice,\n onPackageSettled: (report) => {\n if (!options.telemetry) return;\n observe(\n options.telemetry.recordEvent('po_server.package_install', {\n 'package.name': report.packageName,\n 'package.outcome': report.outcome,\n duration_ms: report.durationMs,\n scope: 'session',\n }),\n options.onNotice,\n );\n },\n });\n await options.activatePackages?.(installed);\n } catch (error) {\n await scope?.dispose();\n communication?.close();\n host.dispose();\n throw error;\n }\n if (host.mounted().length === 0 && routesNothing()) {\n await scope.dispose();\n communication?.close();\n host.dispose();\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n const sessionScope = scope;\n\n const dispatch = async (request: Request): Promise<Response> => {\n if (options.canDispatch?.() === false)\n return Response.json({ error: 'Session selection is not ready.' }, { status: 503 });\n const url = new URL(request.url);\n if (!url.pathname.startsWith(`${PO_API_ROUTE_PREFIX}/`))\n return Response.json({ error: 'Not found.' }, { status: 404 });\n const rest = url.pathname.slice(PO_API_ROUTE_PREFIX.length + 1);\n const slash = rest.indexOf('/');\n const basePath = slash === -1 ? rest : rest.slice(0, slash);\n // The session's own API, else the nearest level above it that serves one.\n const handler = sessionScope.apiHandler(basePath);\n if (handler === undefined)\n return Response.json({ error: `No API '${basePath}' in this session.` }, { status: 404 });\n url.pathname = slash === -1 ? '/' : rest.slice(slash);\n const startedAt = performance.now();\n const parent = validatedTraceContext(request.headers.get('traceparent'));\n let childContext: PoTraceContext | undefined;\n let response: Response;\n try {\n const invoke = async (context?: PoTraceContext): Promise<Response> => {\n if (options.canDispatch?.() === false || sessionScope.apiHandler(basePath) !== handler) {\n return Response.json({ error: 'Session selection changed before dispatch.' }, { status: 503 });\n }\n childContext = context;\n return handler.fetch(new Request(url, request));\n };\n response = options.telemetry\n ? await options.telemetry.runInSpan(\n 'po_server.package_api.request',\n { api: basePath, method: request.method },\n invoke,\n parent,\n )\n : await invoke();\n } catch (error) {\n if (request.signal.aborted) return new Response(null, { status: 499 });\n options.onNotice(`package API '${basePath}' failed on ${url.pathname} (${describeError(error)})`);\n response = Response.json({ error: `The '${basePath}' API failed.` }, { status: 500 });\n }\n return responseWithCompletion(response, () => {\n if (!options.telemetry) return;\n const durationMs = Math.round(performance.now() - startedAt);\n // Keep this span only where it says something the request span cannot: a failing status,\n // or a body that took real time to flush after the headers were sent.\n if (response.status < 400 && durationMs < COMPLETION_SPAN_MIN_DURATION_MS) return;\n observe(\n options.telemetry.runInSpan(\n 'po_server.package_api.complete',\n {\n api: basePath,\n method: request.method,\n status_code: response.status,\n duration_ms: durationMs,\n },\n async () => undefined,\n childContext ?? parent,\n ),\n options.onNotice,\n );\n });\n };\n let closePromise: Promise<void> | undefined;\n\n return {\n request: dispatch,\n close: () => {\n closePromise ??= (async () => {\n await scope.dispose();\n communication?.close();\n host.dispose();\n })();\n return closePromise;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,MAAa,kCAAkC;AAkD/C,SAAS,cAAc,OAAwB;CAC7C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,uBAAuB,UAAoB,UAAgC;CAClF,IAAI,SAAS,SAAS,MAAM;EAC1B,SAAS;EACT,OAAO;CACT;CACA,MAAM,SAAS,SAAS,KAAK,UAAU;CACvC,IAAI,YAAY;CAChB,MAAM,eAAqB;EACzB,IAAI,WAAW;EACf,YAAY;EACZ,SAAS;CACX;CACA,MAAM,OAAO,IAAI,eAA2B;EAC1C,MAAM,KAAK,YAAY;GACrB,IAAI;IACF,MAAM,SAAS,MAAM,OAAO,KAAK;IACjC,IAAI,OAAO,MAAM;KACf,OAAO;KACP,WAAW,MAAM;IACnB,OAAO,WAAW,QAAQ,OAAO,KAAK;GACxC,SAAS,OAAO;IACd,OAAO;IACP,WAAW,MAAM,KAAK;GACxB;EACF;EACA,MAAM,OAAO,QAAQ;GACnB,OAAO;GACP,MAAM,OAAO,OAAO,MAAM;EAC5B;CACF,CAAC;CACD,OAAO,IAAI,SAAS,MAAM,QAAQ;AACpC;;AAGA,SAAS,gBAAgB,YAA0B,KAAoB;CACrE,OAAO;EACL,UAAU;EACV,cAAc;GACZ,QAAQ,YAAY;IAClB,IAAI,QAAQ,WAAW,OAAO,OAAO,SAAS,KAAK,EAAE,OAAO,sBAAsB,GAAG,EAAE,QAAQ,IAAI,CAAC;IACpG,OAAO,mBAAmB;KACxB,OAAO,WAAW,MAAM;KACxB;KACA,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,aAAa,IAAI,MAAM;KAClD,GAAI,QAAQ,QAAQ,IAAI,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,IAAI,OAAO,EAAG;KACxF,GAAI,QAAQ,QAAQ,IAAI,UAAU,MAAM,OAAO,CAAC,IAAI,EAAE,iBAAiB,QAAQ,QAAQ,IAAI,UAAU,EAAG;IAC1G,CAAC;GACH;GACA,aAAa,KAAA;EACf;CACF;AACF;;AAEA,eAAsB,iBAAiB,SAA6D;CAClG,IAAI,QAAQ,gBAAgB,KAAA,GAC1B,MAAM,IAAI,MAAM,8DAA8D;CAChF,IAAI,QAAQ,iBAAiB,KAAA,GAAW,MAAM,IAAI,MAAM,oDAAoD;CAC5G,UAAU;EAAE,GAAG;EAAS,aAAa,MAAM,0BAA0B,OAAO;CAAE;CAC9E,MAAM,WAAW,QAAQ,YAAY,CAAC;CAEtC,MAAM,sBAA+B,CAAC,QAAQ,mBAAmB,QAAQ,gBAAgB,KAAA;CACzF,IAAI,QAAQ,KAAK,WAAW,KAAK,SAAS,WAAW,KAAK,cAAc,GACtE,OAAO;EACL,SAAS,YAAY,SAAS,KAAK,EAAE,OAAO,+BAA+B,GAAG,EAAE,QAAQ,IAAI,CAAC;EAC7F,aAAa,QAAQ,QAAQ;CAC/B;CAGF,MAAM,uBAAuB,QAAQ;CACrC,MAAM,gBAAgB,sBAAsB,oBAAoB,QAAQ,SAAS;CACjF,MAAM,0BAA0B,sBAAsB,oBAAoB,KAAK,oBAAoB;CACnG,MAAM,cAAc,sBAAsB,QAAQ,KAAK,oBAAoB;CAC3E,MAAM,aAAa,sBAAsB,OAAO,KAAK,oBAAoB;CACzE,MAAM,aAAa,sBAAsB,OAAO,KAAK,oBAAoB;CACzE,MAAM,eAAe,sBAAsB,SAAS,KAAK,oBAAoB;CAC7E,MAAM,wBACJ,yBAAyB,KAAA,IACrB,KAAA,IACA;EACE,SAAS,YAAY,qBAAqB,OAAO,OAAO;EACxD,QAAQ,cAAc,qBAAqB,MAAM,SAAS;EAC1D,SAAS,cAAc,qBAAqB,OAAO,SAAS;EAC5D,GAAI,4BAA4B,KAAA,IAC5B,CAAC,IACD,EACE,qBAAqB,cACnB,wBAAwB,WAAW,EAAE,iBAAiB,QAAQ,UAAU,CAAC,EAC7E;EAEJ,GAAI,gBAAgB,KAAA,IAChB,CAAC,IACD,EACE,SAAS,WAAmB,MAAc,kBACxC,YAAY,WAAW,MAAM;GAC3B,GAAI,eAAe,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,cAAc,OAAO;GAC9E,iBAAiB,QAAQ;EAC3B,CAAC,EACL;EACJ,GAAI,eAAe,KAAA,IACf,CAAC,IACD,EACE,QAAQ,cAAsB,WAAW,WAAW,EAAE,iBAAiB,QAAQ,UAAU,CAAC,EAC5F;EACJ,GAAI,eAAe,KAAA,IACf,CAAC,IACD,EACE,QAAQ,WAAmB,YACzB,WAAW,WAAW,SAAS,EAAE,iBAAiB,QAAQ,UAAU,CAAC,EACzE;EACJ,GAAI,iBAAiB,KAAA,IACjB,CAAC,IACD,EACE,UAAU,cAAsB,aAAa,WAAW,EAAE,iBAAiB,QAAQ,UAAU,CAAC,EAChG;EACJ,GAAI,qBAAqB,mBAAmB,KAAA,IACxC,CAAC,IACD,EACE,iBAAiB,iBAAyB,oBACxC,qBAAqB,iBAAiB,iBAAiB,eAAe,MAAM,KAChF;CACN;CACN,MAAM,UAAwB;EAC5B,OAAO;EACP,WAAW,QAAQ;EACnB,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACvB,GAAI,QAAQ,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,QAAQ,eAAe;EACzF,eAAe,QAAQ,iBAAiB,QAAQ,SAAS;EACzD,gBAAgB,QAAQ,SAAS;EACjC,KAAK,QAAQ;EACb,aAAa,QAAQ;EACrB,cAAc,QAAQ;EACtB,GAAI,QAAQ,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,QAAQ,YAAY;EAChF,GAAI,QAAQ,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,QAAQ,UAAU;EAC1E,GAAI,QAAQ,qBAAqB,KAAA,IAAY,CAAC,IAAI,EAAE,kBAAkB,QAAQ,iBAAiB;EAC/F,GAAI,QAAQ,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,QAAQ,gBAAgB;EAC5F,GAAI,QAAQ,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,QAAQ,aAAa;EACnF,GAAI,QAAQ,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;EAC7E,GAAI,QAAQ,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;EAC7E,GAAI,QAAQ,oBAAoB,KAAA,IAAY,CAAC,IAAI,EAAE,iBAAiB,QAAQ,gBAAgB;EAC5F,GAAI,QAAQ,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;EACtF,GAAI,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;EACvE,GAAI,0BAA0B,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,sBAAsB;EACvF,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,sBAAsB,cAAc;EAC7E,UAAU,QAAQ;CACpB;CACA,MAAM,OAAO,mBAAmB;EAC9B,OAAO;EACP;EACA,cAAc,QAAQ;EACtB,GAAI,QAAQ,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,QAAQ,eAAe;CAC3F,CAAC;CAED,MAAM,aAAa,iBAAiB;CACpC,KAAK,MAAM,aAAa;EAAC,QAAQ;EAAK,QAAQ;EAAe,QAAQ,YAAY;CAAoB,GACnG,IAAI,cAAc,KAAA,KAAa,KAAK,WAAW,SAAS,GAAG,WAAW,SAAS,SAAS;CAC1F,IAAI;CACJ,IAAI;EAEF,KAAK,YAAY,gBAAgB,YAAY,QAAQ,GAAG,CAAC;EACzD,KAAK,MAAM,OAAO,QAAQ,MAAM,KAAK,YAAY,GAAG;EAEpD,QAAQ,MAAM,cAAc,KAAK,WAAW,QAAQ,WAAW;EAC/D,MAAM,MAAM,MAAM;GAAE;GAAM,UAAU,QAAQ;EAAS,CAAC;EACtD,MAAM,MAAM,KAAK,QAAQ,SAAS;GAChC,KAAK,QAAQ,wBAAwB,UAAU;EACjD,CAAC;EACD,MAAM,QAAQ,kBAAkB,MAAM,IAAI;EAC1C,MAAM,YAAY,MAAM,MAAM,QAAQ,UAAU;GAC9C,UAAU,QAAQ;GAClB,mBAAmB,WAAW;IAC5B,IAAI,CAAC,QAAQ,WAAW;IACxB,QACE,QAAQ,UAAU,YAAY,6BAA6B;KACzD,gBAAgB,OAAO;KACvB,mBAAmB,OAAO;KAC1B,aAAa,OAAO;KACpB,OAAO;IACT,CAAC,GACD,QAAQ,QACV;GACF;EACF,CAAC;EACD,MAAM,QAAQ,mBAAmB,SAAS;CAC5C,SAAS,OAAO;EACd,MAAM,OAAO,QAAQ;EACrB,eAAe,MAAM;EACrB,KAAK,QAAQ;EACb,MAAM;CACR;CACA,IAAI,KAAK,QAAQ,CAAC,CAAC,WAAW,KAAK,cAAc,GAAG;EAClD,MAAM,MAAM,QAAQ;EACpB,eAAe,MAAM;EACrB,KAAK,QAAQ;EACb,OAAO;GACL,SAAS,YAAY,SAAS,KAAK,EAAE,OAAO,+BAA+B,GAAG,EAAE,QAAQ,IAAI,CAAC;GAC7F,aAAa,QAAQ,QAAQ;EAC/B;CACF;CACA,MAAM,eAAe;CAErB,MAAM,WAAW,OAAO,YAAwC;EAC9D,IAAI,QAAQ,cAAc,MAAM,OAC9B,OAAO,SAAS,KAAK,EAAE,OAAO,kCAAkC,GAAG,EAAE,QAAQ,IAAI,CAAC;EACpF,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;EAC/B,IAAI,CAAC,IAAI,SAAS,WAAW,eAAyB,GACpD,OAAO,SAAS,KAAK,EAAE,OAAO,aAAa,GAAG,EAAE,QAAQ,IAAI,CAAC;EAC/D,MAAM,OAAO,IAAI,SAAS,MAAM,oBAAoB,SAAS,CAAC;EAC9D,MAAM,QAAQ,KAAK,QAAQ,GAAG;EAC9B,MAAM,WAAW,UAAU,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK;EAE1D,MAAM,UAAU,aAAa,WAAW,QAAQ;EAChD,IAAI,YAAY,KAAA,GACd,OAAO,SAAS,KAAK,EAAE,OAAO,WAAW,SAAS,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;EAC1F,IAAI,WAAW,UAAU,KAAK,MAAM,KAAK,MAAM,KAAK;EACpD,MAAM,YAAY,YAAY,IAAI;EAClC,MAAM,SAAS,sBAAsB,QAAQ,QAAQ,IAAI,aAAa,CAAC;EACvE,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,MAAM,SAAS,OAAO,YAAgD;IACpE,IAAI,QAAQ,cAAc,MAAM,SAAS,aAAa,WAAW,QAAQ,MAAM,SAC7E,OAAO,SAAS,KAAK,EAAE,OAAO,6CAA6C,GAAG,EAAE,QAAQ,IAAI,CAAC;IAE/F,eAAe;IACf,OAAO,QAAQ,MAAM,IAAI,QAAQ,KAAK,OAAO,CAAC;GAChD;GACA,WAAW,QAAQ,YACf,MAAM,QAAQ,UAAU,UACtB,iCACA;IAAE,KAAK;IAAU,QAAQ,QAAQ;GAAO,GACxC,QACA,MACF,IACA,MAAM,OAAO;EACnB,SAAS,OAAO;GACd,IAAI,QAAQ,OAAO,SAAS,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;GACrE,QAAQ,SAAS,gBAAgB,SAAS,cAAc,IAAI,SAAS,IAAI,cAAc,KAAK,EAAE,EAAE;GAChG,WAAW,SAAS,KAAK,EAAE,OAAO,QAAQ,SAAS,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;EACtF;EACA,OAAO,uBAAuB,gBAAgB;GAC5C,IAAI,CAAC,QAAQ,WAAW;GACxB,MAAM,aAAa,KAAK,MAAM,YAAY,IAAI,IAAI,SAAS;GAG3D,IAAI,SAAS,SAAS,OAAO,aAAA,KAA8C;GAC3E,QACE,QAAQ,UAAU,UAChB,kCACA;IACE,KAAK;IACL,QAAQ,QAAQ;IAChB,aAAa,SAAS;IACtB,aAAa;GACf,GACA,YAAY,KAAA,GACZ,gBAAgB,MAClB,GACA,QAAQ,QACV;EACF,CAAC;CACH;CACA,IAAI;CAEJ,OAAO;EACL,SAAS;EACT,aAAa;GACX,kBAAkB,YAAY;IAC5B,MAAM,MAAM,QAAQ;IACpB,eAAe,MAAM;IACrB,KAAK,QAAQ;GACf,EAAA,CAAG;GACH,OAAO;EACT;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"packageApiServer.mjs","names":[],"sources":["../src/server/packageApiServer.ts"],"sourcesContent":["import path from 'node:path';\n\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport { SESSION_FILES_API } from '../constants/sessionFiles';\nimport type { PoDirectEventBus, PoHubSessionPromptOptions, PoHubSessionService } from '../exports/hubChannel';\nimport { PO_API_ROUTE_PREFIX, type PoApi, type PoApiContext } from '../exports/packageApi';\nimport type { PoPlatform } from '../exports/platform';\nimport type { PoPluginRegistry } from '../exports/pluginProtocol';\nimport {\n createPoServerHost,\n type CreatePoServerHostOptions,\n type LoadedServerPackage,\n type PoServerPlugin,\n PoServerScope,\n} from '../exports/serverPlugin';\nimport {\n createFileAccess,\n PO_FILE_ACCESS_SERVICE,\n type PoFileAccess,\n readAccessibleFile,\n} from '../services/fileAccess';\nimport type { PoTraceContext } from '../services/poTelemetry';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { PO_SESSION_TEMP_DIR, prepareSessionEnvironment } from '../services/sessionFiles';\nimport { validatedTraceContext } from '../services/traceContext';\n\n/**\n * A body that keeps streaming well after its headers went out is worth its own span. A fast\n * one is not: the request span already carries the duration and outcome, so emitting a second\n * span per call made package API traffic 99.65% of all spans recorded in a two hour sample.\n */\nexport const COMPLETION_SPAN_MIN_DURATION_MS = 1000;\n\nexport interface PackageApiServerOptions {\n sessionId: string;\n workspaceId?: string;\n workspaceRoot?: string;\n sessionContext?: PoApiContext['sessionContext'];\n homeDirectory?: string;\n mountChannel?: CreatePoServerHostOptions['mountChannel'];\n cwd: string;\n /** Admitted environment for APIs serving this session. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n /** Lifecycle-owned direct events shared with the hub. */\n readonly directEvents: PoDirectEventBus;\n readonly computerUse?: PoApiContext['computerUse'];\n /** Bound to this session's id and cwd by the host. */\n readonly shareFile?: PoApiContext['shareFile'];\n readonly mediaArbitration?: PoApiContext['mediaArbitration'];\n readonly executionBudget?: PoApiContext['executionBudget'];\n readonly editPresence?: PoApiContext['editPresence'];\n readonly peerAgents?: PoApiContext['peerAgents'];\n readonly requestApi?: PoApiContext['requestApi'];\n /** Publishes this session's activity line through the hub; bound to this session only. */\n readonly publishActivity?: PoApiContext['publishActivity'];\n internalToken?: string;\n hubToken?: string;\n /** Shared exact-scope dispatch table, so session packages can mount plugin methods. */\n pluginRegistry?: PoPluginRegistry;\n sessionService?: PoHubSessionService;\n apis: readonly PoApi[];\n /** Server packages to install; each registers its own APIs through the host. */\n packages?: readonly (PoServerPlugin | LoadedServerPackage)[];\n /** Publishes the session's own services into its scope root before any package installs. */\n preparePackages?: (root: Context) => void | Promise<void>;\n /** The hub's workspace or global scope; the session's own scope opens below it and closes with it. */\n parentScope?: PoServerScope;\n /** Host capabilities for the session scope root, injected by the composition root. */\n platform: PoPlatform;\n activatePackages?: (installedPackages: readonly string[]) => Promise<void>;\n canDispatch?: () => boolean;\n telemetry?: ServerTelemetry;\n onNotice: (message: string) => void;\n}\n\nexport interface PackageApiServer {\n /** Dispatches an already-authenticated request without crossing a transport boundary. */\n readonly request: (request: Request) => Promise<Response>;\n close(): Promise<void>;\n}\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction responseWithCompletion(response: Response, complete: () => void): Response {\n if (response.body === null) {\n complete();\n return response;\n }\n const reader = response.body.getReader();\n let completed = false;\n const finish = (): void => {\n if (completed) return;\n completed = true;\n complete();\n };\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const result = await reader.read();\n if (result.done) {\n finish();\n controller.close();\n } else controller.enqueue(result.value);\n } catch (error) {\n finish();\n controller.error(error);\n }\n },\n async cancel(reason) {\n finish();\n await reader.cancel(reason);\n },\n });\n return new Response(body, response);\n}\n\n/** Reads files under the session's open folders; the hub's session `/file` route forwards here. */\nfunction sessionFilesApi(fileAccess: PoFileAccess, cwd: string): PoApi {\n return {\n basePath: SESSION_FILES_API,\n start: () => ({\n fetch: (request) => {\n if (request.method !== 'GET') return Response.json({ error: 'Method not allowed.' }, { status: 405 });\n return readAccessibleFile({\n roots: fileAccess.roots(),\n cwd,\n path: new URL(request.url).searchParams.get('path'),\n ...(request.headers.get('range') === null ? {} : { range: request.headers.get('range')! }),\n ...(request.headers.get('if-match') === null ? {} : { expectedVersion: request.headers.get('if-match')! }),\n });\n },\n close: () => undefined,\n }),\n };\n}\n/** Installs session packages and dispatches authenticated package API calls in-process. */\nexport async function serveSessionApis(options: PackageApiServerOptions): Promise<PackageApiServer> {\n if (options.environment === undefined)\n throw new Error('Session package API server requires an admitted environment.');\n if (options.directEvents === undefined) throw new Error('Session package API server requires direct events.');\n options = { ...options, environment: await prepareSessionEnvironment(options) };\n const packages = options.packages ?? [];\n // Without a level above it, a session that mounts nothing has nothing to route.\n const routesNothing = (): boolean => !options.preparePackages && options.parentScope === undefined;\n if (options.apis.length === 0 && packages.length === 0 && routesNothing()) {\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n\n const owningSessionService = options.sessionService;\n const communication = owningSessionService?.bindCommunication?.(options.sessionId);\n const ownedReadExecutionState = owningSessionService?.readExecutionState?.bind(owningSessionService);\n const ownedPrompt = owningSessionService?.prompt?.bind(owningSessionService);\n const ownedAbort = owningSessionService?.abort?.bind(owningSessionService);\n const ownedSteer = owningSessionService?.steer?.bind(owningSessionService);\n const ownedRelease = owningSessionService?.release?.bind(owningSessionService);\n const exposedSessionService: PoHubSessionService | undefined =\n owningSessionService === undefined\n ? undefined\n : {\n create: (request) => owningSessionService.create(request),\n close: (sessionId) => owningSessionService.close(sessionId),\n isLive: (sessionId) => owningSessionService.isLive(sessionId),\n ...(ownedReadExecutionState === undefined\n ? {}\n : {\n readExecutionState: (sessionId: string) =>\n ownedReadExecutionState(sessionId, { parentSessionId: options.sessionId }),\n }),\n // A session may drive only the children it started, never its parent or a sibling.\n ...(ownedPrompt === undefined\n ? {}\n : {\n prompt: (sessionId: string, text: string, promptOptions?: PoHubSessionPromptOptions) =>\n ownedPrompt(sessionId, text, {\n ...(promptOptions?.signal === undefined ? {} : { signal: promptOptions.signal }),\n parentSessionId: options.sessionId,\n }),\n }),\n ...(ownedAbort === undefined\n ? {}\n : {\n abort: (sessionId: string) => ownedAbort(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(ownedSteer === undefined\n ? {}\n : {\n steer: (sessionId: string, message: string) =>\n ownedSteer(sessionId, message, { parentSessionId: options.sessionId }),\n }),\n ...(ownedRelease === undefined\n ? {}\n : {\n release: (sessionId: string) => ownedRelease(sessionId, { parentSessionId: options.sessionId }),\n }),\n ...(owningSessionService.canCommunicate === undefined\n ? {}\n : {\n canCommunicate: (sourceSessionId: string, targetSessionId: string) =>\n owningSessionService.canCommunicate?.(sourceSessionId, targetSessionId) === true,\n }),\n };\n const context: PoApiContext = {\n scope: 'session',\n sessionId: options.sessionId,\n workspaceId: options.workspaceId,\n workspaceRoot: options.workspaceRoot,\n ...(options.sessionContext === undefined ? {} : { sessionContext: options.sessionContext }),\n homeDirectory: options.homeDirectory ?? options.platform.homeDirectory,\n sessionStorage: options.platform.sessions,\n cwd: options.cwd,\n environment: options.environment,\n directEvents: options.directEvents,\n ...(options.computerUse === undefined ? {} : { computerUse: options.computerUse }),\n ...(options.shareFile === undefined ? {} : { shareFile: options.shareFile }),\n ...(options.mediaArbitration === undefined ? {} : { mediaArbitration: options.mediaArbitration }),\n ...(options.executionBudget === undefined ? {} : { executionBudget: options.executionBudget }),\n ...(options.editPresence === undefined ? {} : { editPresence: options.editPresence }),\n ...(options.peerAgents === undefined ? {} : { peerAgents: options.peerAgents }),\n ...(options.requestApi === undefined ? {} : { requestApi: options.requestApi }),\n ...(options.publishActivity === undefined ? {} : { publishActivity: options.publishActivity }),\n ...(options.internalToken === undefined ? {} : { internalToken: options.internalToken }),\n ...(options.hubToken === undefined ? {} : { hubToken: options.hubToken }),\n ...(exposedSessionService === undefined ? {} : { sessionService: exposedSessionService }),\n ...(communication === undefined ? {} : { sessionCommunication: communication }),\n onNotice: options.onNotice,\n };\n const host = createPoServerHost({\n scope: 'session',\n context,\n mountChannel: options.mountChannel,\n ...(options.pluginRegistry === undefined ? {} : { pluginRegistry: options.pluginRegistry }),\n });\n // The session's own folder, its workspace and its temp folder; extensions open their own beside these.\n const fileAccess = createFileAccess();\n for (const directory of [options.cwd, options.workspaceRoot, options.environment[PO_SESSION_TEMP_DIR]])\n if (directory !== undefined && path.isAbsolute(directory)) fileAccess.register(directory);\n let scope: PoServerScope | undefined;\n try {\n // Registered first, so no package can claim the host's own base path.\n host.registerApi(sessionFilesApi(fileAccess, options.cwd));\n for (const api of options.apis) host.registerApi(api);\n // The session's own level of the server IoC tree; it closes with the hub level it opens below.\n scope = await PoServerScope.open('session', options.parentScope);\n await scope.serve({ host, platform: options.platform });\n await scope.root.plugin((root) => {\n root.provide(PO_FILE_ACCESS_SERVICE, fileAccess);\n });\n await options.preparePackages?.(scope.root);\n const installed = await scope.install(packages, {\n onNotice: options.onNotice,\n onPackageSettled: (report) => {\n if (!options.telemetry) return;\n observe(\n options.telemetry.recordEvent('po_server.package_install', {\n 'package.name': report.packageName,\n 'package.outcome': report.outcome,\n duration_ms: report.durationMs,\n scope: 'session',\n }),\n options.onNotice,\n );\n },\n });\n await options.activatePackages?.(installed);\n } catch (error) {\n await scope?.dispose();\n communication?.close();\n host.dispose();\n throw error;\n }\n if (host.mounted().length === 0 && routesNothing()) {\n await scope.dispose();\n communication?.close();\n host.dispose();\n return {\n request: async () => Response.json({ error: 'No package APIs are mounted.' }, { status: 404 }),\n close: () => Promise.resolve(),\n };\n }\n const sessionScope = scope;\n\n const dispatch = async (request: Request): Promise<Response> => {\n if (options.canDispatch?.() === false)\n return Response.json({ error: 'Session selection is not ready.' }, { status: 503 });\n const url = new URL(request.url);\n if (!url.pathname.startsWith(`${PO_API_ROUTE_PREFIX}/`))\n return Response.json({ error: 'Not found.' }, { status: 404 });\n const rest = url.pathname.slice(PO_API_ROUTE_PREFIX.length + 1);\n const slash = rest.indexOf('/');\n const basePath = slash === -1 ? rest : rest.slice(0, slash);\n // The session's own API, else the nearest level above it that serves one.\n const handler = sessionScope.apiHandler(basePath);\n if (handler === undefined)\n return Response.json({ error: `No API '${basePath}' in this session.` }, { status: 404 });\n url.pathname = slash === -1 ? '/' : rest.slice(slash);\n const startedAt = performance.now();\n const parent = validatedTraceContext(request.headers.get('traceparent'));\n let childContext: PoTraceContext | undefined;\n let response: Response;\n try {\n const invoke = async (context?: PoTraceContext): Promise<Response> => {\n if (options.canDispatch?.() === false || sessionScope.apiHandler(basePath) !== handler) {\n return Response.json({ error: 'Session selection changed before dispatch.' }, { status: 503 });\n }\n childContext = context;\n return handler.fetch(new Request(url, request));\n };\n response = options.telemetry\n ? await options.telemetry.runInSpan(\n 'po_server.package_api.request',\n { api: basePath, method: request.method },\n invoke,\n parent,\n )\n : await invoke();\n } catch (error) {\n if (request.signal.aborted) return new Response(null, { status: 499 });\n options.onNotice(`package API '${basePath}' failed on ${url.pathname} (${describeError(error)})`);\n response = Response.json({ error: `The '${basePath}' API failed.` }, { status: 500 });\n }\n return responseWithCompletion(response, () => {\n if (!options.telemetry) return;\n const durationMs = Math.round(performance.now() - startedAt);\n // Keep this span only where it says something the request span cannot: a failing status,\n // or a body that took real time to flush after the headers were sent.\n if (response.status < 400 && durationMs < COMPLETION_SPAN_MIN_DURATION_MS) return;\n observe(\n options.telemetry.runInSpan(\n 'po_server.package_api.complete',\n {\n api: basePath,\n method: request.method,\n status_code: response.status,\n duration_ms: durationMs,\n },\n async () => undefined,\n childContext ?? parent,\n ),\n options.onNotice,\n );\n });\n };\n let closePromise: Promise<void> | undefined;\n\n return {\n request: dispatch,\n close: () => {\n closePromise ??= (async () => {\n await scope.dispose();\n communication?.close();\n host.dispose();\n })();\n return closePromise;\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ function createHarnessTelemetry(options = {}) {
|
|
|
27
27
|
const pendingEvents = [];
|
|
28
28
|
let pendingEventDropReported = false;
|
|
29
29
|
const telemetry = () => {
|
|
30
|
-
telemetryPromise ??=
|
|
30
|
+
telemetryPromise ??= Promise.resolve().then(() => require("./src/services/poTelemetry/index.cjs")).then(({ createPoTelemetry }) => createPoTelemetry({
|
|
31
31
|
serviceName: SERVICE_NAME,
|
|
32
32
|
packageName: PACKAGE_NAME,
|
|
33
33
|
cwd: options.cwd,
|
|
@@ -63,7 +63,7 @@ function createHarnessTelemetry(options = {}) {
|
|
|
63
63
|
else if (!pendingEventDropReported) {
|
|
64
64
|
pendingEventDropReported = true;
|
|
65
65
|
try {
|
|
66
|
-
(options.warn ?? ((message) =>
|
|
66
|
+
(options.warn ?? ((message) => console.warn(message)))("Po telemetry deferred event limit reached; later events were dropped.");
|
|
67
67
|
} catch {}
|
|
68
68
|
}
|
|
69
69
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeLogSinkTelemetry.cjs","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"sourcesContent":["import type { PoTelemetry, PoTelemetryOptions } from '
|
|
1
|
+
{"version":3,"file":"runtimeLogSinkTelemetry.cjs","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"sourcesContent":["import type { PoTelemetry, PoTelemetryOptions } from '../poTelemetry';\n\nconst MAX_PENDING_EVENTS = 64;\nconst SERVICE_NAME = 'po';\nconst PACKAGE_NAME = '@agimon-ai/po';\n\nexport const HARNESS_EVENT = {\n cliFailed: 'po_pi.cli_failed',\n contextBuildFailed: 'po_pi.context_build_failed',\n resourceCollectionFailed: 'po_pi.resource_collection_failed',\n configLoadFailed: 'po_pi.config_load_failed',\n launchFailed: 'po_pi.launch_failed',\n compatibilityLaunchFailed: 'po_pi.compatibility_launch_failed',\n harnessStateParseFailed: 'po_pi.harness_state_parse_failed',\n hookFailed: 'po_pi.hook_failed',\n hookRegistryReadFailed: 'po_pi.hook_registry_read_failed',\n personaReadFailed: 'po_pi.persona_read_failed',\n styleSystemRenderFailed: 'po_pi.style_system_render_failed',\n majorModeUnavailable: 'po_pi.major_mode_unavailable',\n profileLoadFailed: 'po_pi.profile_load_failed',\n launchCompleted: 'po_pi.launch_completed',\n projectTrustResolved: 'po_pi.project_trust_resolved',\n majorModeSwitched: 'po_pi.major_mode_switched',\n profileApplied: 'po_pi.profile_applied',\n} as const;\n\nexport type HarnessEventName = (typeof HARNESS_EVENT)[keyof typeof HARNESS_EVENT];\nexport type HarnessEventAttributes = Record<string, string | number | boolean>;\nexport type HarnessErrorSink = (event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes) => void;\n\nexport interface HarnessFailureReporter {\n error: HarnessErrorSink;\n warn: HarnessErrorSink;\n}\n\nexport interface HarnessTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<PoTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n /** Run startup callbacks before loading the telemetry backend. */\n deferSpans?: boolean;\n}\n\nexport interface HarnessTelemetry {\n recordError(event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes): Promise<void>;\n recordWarning(event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes): Promise<void>;\n recordEvent(event: HarnessEventName, attributes?: HarnessEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: HarnessEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createHarnessTelemetry(options: HarnessTelemetryOptions = {}): HarnessTelemetry {\n let telemetryPromise: Promise<PoTelemetry> | undefined;\n const pendingEvents: Array<{ event: HarnessEventName; attributes?: HarnessEventAttributes }> = [];\n let pendingEventDropReported = false;\n const telemetry = (): Promise<PoTelemetry> => {\n telemetryPromise ??= import('../poTelemetry').then(({ createPoTelemetry }) =>\n createPoTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n }),\n );\n return telemetryPromise;\n };\n const drainEvents = async (loaded: PoTelemetry): Promise<void> => {\n for (const pending of pendingEvents.splice(0)) {\n await loaded.recordEvent(pending.event, pending.attributes);\n }\n };\n return {\n recordError: async (event, error, attributes) => {\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.recordError(event, error, attributes);\n },\n recordWarning: async (event, error, attributes) => {\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.recordWarning(event, error, attributes);\n },\n recordEvent: async (event, attributes) => {\n if (options.deferSpans && !telemetryPromise) {\n if (pendingEvents.length < MAX_PENDING_EVENTS) pendingEvents.push({ event, attributes });\n else if (!pendingEventDropReported) {\n pendingEventDropReported = true;\n try {\n const reportWarning = options.warn ?? ((message: string) => console.warn(message));\n reportWarning('Po telemetry deferred event limit reached; later events were dropped.');\n } catch {\n // Telemetry warnings must not interrupt launcher startup.\n }\n }\n return;\n }\n await (await telemetry()).recordEvent(event, attributes);\n },\n runInSpan: (name, attributes, callback) => {\n // The launcher opts into this path for pre-spawn preparation. Lifecycle\n // events remain buffered until flush; failures still initialize the real\n // sink immediately so diagnostics are not lost.\n if (options.deferSpans && !telemetryPromise) return callback();\n return telemetry().then((loaded) => loaded.runInSpan(name, attributes, callback));\n },\n flush: async () => {\n if (!telemetryPromise && pendingEvents.length === 0) return;\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.flush();\n },\n shutdown: async () => {\n if (!telemetryPromise && pendingEvents.length === 0) return;\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.shutdown();\n },\n };\n}\n\nexport function toFailureReporter(telemetry: HarnessTelemetry): HarnessFailureReporter {\n return {\n error: (event, error, attributes) => void telemetry.recordError(event, error, attributes),\n warn: (event, error, attributes) => void telemetry.recordWarning(event, error, attributes),\n };\n}\n"],"mappings":";;AAEA,MAAM,qBAAqB;AAC3B,MAAM,eAAe;AACrB,MAAM,eAAe;AAErB,MAAa,gBAAgB;CAC3B,WAAW;CACX,oBAAoB;CACpB,0BAA0B;CAC1B,kBAAkB;CAClB,cAAc;CACd,2BAA2B;CAC3B,yBAAyB;CACzB,YAAY;CACZ,wBAAwB;CACxB,mBAAmB;CACnB,yBAAyB;CACzB,sBAAsB;CACtB,mBAAmB;CACnB,iBAAiB;CACjB,sBAAsB;CACtB,mBAAmB;CACnB,gBAAgB;AAClB;AA8BA,SAAgB,uBAAuB,UAAmC,CAAC,GAAqB;CAC9F,IAAI;CACJ,MAAM,gBAAyF,CAAC;CAChG,IAAI,2BAA2B;CAC/B,MAAM,kBAAwC;EAC5C,qBAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAqB,sCAAA,CAAA,CAAA,CAAyB,MAAM,EAAE,wBACpD,kBAAkB;GAChB,aAAa;GACb,aAAa;GACb,KAAK,QAAQ;GACb,eAAe,QAAQ;GACvB,KAAK,QAAQ;GACb,kBAAkB,QAAQ;GAC1B,MAAM,QAAQ;GACd,YAAY;GACZ,cAAc;EAChB,CAAC,CACH;EACA,OAAO;CACT;CACA,MAAM,cAAc,OAAO,WAAuC;EAChE,KAAK,MAAM,WAAW,cAAc,OAAO,CAAC,GAC1C,MAAM,OAAO,YAAY,QAAQ,OAAO,QAAQ,UAAU;CAE9D;CACA,OAAO;EACL,aAAa,OAAO,OAAO,OAAO,eAAe;GAC/C,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,YAAY,OAAO,OAAO,UAAU;EACnD;EACA,eAAe,OAAO,OAAO,OAAO,eAAe;GACjD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,cAAc,OAAO,OAAO,UAAU;EACrD;EACA,aAAa,OAAO,OAAO,eAAe;GACxC,IAAI,QAAQ,cAAc,CAAC,kBAAkB;IAC3C,IAAI,cAAc,SAAS,oBAAoB,cAAc,KAAK;KAAE;KAAO;IAAW,CAAC;SAClF,IAAI,CAAC,0BAA0B;KAClC,2BAA2B;KAC3B,IAAI;MAEF,CADsB,QAAQ,UAAU,YAAoB,QAAQ,KAAK,OAAO,GAAA,CAClE,uEAAuE;KACvF,QAAQ,CAER;IACF;IACA;GACF;GACA,OAAO,MAAM,UAAU,EAAA,CAAG,YAAY,OAAO,UAAU;EACzD;EACA,YAAY,MAAM,YAAY,aAAa;GAIzC,IAAI,QAAQ,cAAc,CAAC,kBAAkB,OAAO,SAAS;GAC7D,OAAO,UAAU,CAAC,CAAC,MAAM,WAAW,OAAO,UAAU,MAAM,YAAY,QAAQ,CAAC;EAClF;EACA,OAAO,YAAY;GACjB,IAAI,CAAC,oBAAoB,cAAc,WAAW,GAAG;GACrD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,MAAM;EACrB;EACA,UAAU,YAAY;GACpB,IAAI,CAAC,oBAAoB,cAAc,WAAW,GAAG;GACrD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,SAAS;EACxB;CACF;AACF;AAEA,SAAgB,kBAAkB,WAAqD;CACrF,OAAO;EACL,QAAQ,OAAO,OAAO,eAAe,KAAK,UAAU,YAAY,OAAO,OAAO,UAAU;EACxF,OAAO,OAAO,OAAO,eAAe,KAAK,UAAU,cAAc,OAAO,OAAO,UAAU;CAC3F;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { PoTelemetryOptions } from "
|
|
1
|
+
import { PoTelemetryOptions } from "./src/types/telemetry.mjs";
|
|
2
|
+
import "./src/services/poTelemetry/index.mjs";
|
|
2
3
|
//#region src/services/logSinkTelemetry/index.d.ts
|
|
3
4
|
export declare const HARNESS_EVENT: {
|
|
4
5
|
readonly cliFailed: 'po_pi.cli_failed';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeLogSinkTelemetry.d.mts","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtimeLogSinkTelemetry.d.mts","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"mappings":";;;qBAMa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;YAGU,2BAA2B,4BAA4B;YACvD,yBAAyB;YACzB,oBAAoB,OAAO,kBAAkB,gBAAgB,aAAa;iBAErE;EACf,OAAO;EACP,MAAM;;iBAGS;EACf;EACA;EACA,MAAM,OAAO;EACb,mBAAmB,YAAY;EAC/B,QAAQ;;EAER;;iBAGe;EACf,YAAY,OAAO,kBAAkB,gBAAgB,aAAa,yBAAyB;EAC3F,cAAc,OAAO,kBAAkB,gBAAgB,aAAa,yBAAyB;EAC7F,YAAY,OAAO,kBAAkB,aAAa,yBAAyB;EAC3E,UAAU,GAAG,cAAc,YAAY,wBAAwB,gBAAgB,QAAQ,KAAK,QAAQ;EACpG,SAAS;EACT,YAAY;;wBAGE,uBAAuB,UAAS,0BAA+B;wBA0E/D,kBAAkB,WAAW,mBAAmB"}
|
|
@@ -26,7 +26,7 @@ function createHarnessTelemetry(options = {}) {
|
|
|
26
26
|
const pendingEvents = [];
|
|
27
27
|
let pendingEventDropReported = false;
|
|
28
28
|
const telemetry = () => {
|
|
29
|
-
telemetryPromise ??= import("
|
|
29
|
+
telemetryPromise ??= import("./src/services/poTelemetry/index.mjs").then(({ createPoTelemetry }) => createPoTelemetry({
|
|
30
30
|
serviceName: SERVICE_NAME,
|
|
31
31
|
packageName: PACKAGE_NAME,
|
|
32
32
|
cwd: options.cwd,
|
|
@@ -62,7 +62,7 @@ function createHarnessTelemetry(options = {}) {
|
|
|
62
62
|
else if (!pendingEventDropReported) {
|
|
63
63
|
pendingEventDropReported = true;
|
|
64
64
|
try {
|
|
65
|
-
(options.warn ?? ((message) =>
|
|
65
|
+
(options.warn ?? ((message) => console.warn(message)))("Po telemetry deferred event limit reached; later events were dropped.");
|
|
66
66
|
} catch {}
|
|
67
67
|
}
|
|
68
68
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeLogSinkTelemetry.mjs","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"sourcesContent":["import type { PoTelemetry, PoTelemetryOptions } from '
|
|
1
|
+
{"version":3,"file":"runtimeLogSinkTelemetry.mjs","names":[],"sources":["../src/services/logSinkTelemetry/index.ts"],"sourcesContent":["import type { PoTelemetry, PoTelemetryOptions } from '../poTelemetry';\n\nconst MAX_PENDING_EVENTS = 64;\nconst SERVICE_NAME = 'po';\nconst PACKAGE_NAME = '@agimon-ai/po';\n\nexport const HARNESS_EVENT = {\n cliFailed: 'po_pi.cli_failed',\n contextBuildFailed: 'po_pi.context_build_failed',\n resourceCollectionFailed: 'po_pi.resource_collection_failed',\n configLoadFailed: 'po_pi.config_load_failed',\n launchFailed: 'po_pi.launch_failed',\n compatibilityLaunchFailed: 'po_pi.compatibility_launch_failed',\n harnessStateParseFailed: 'po_pi.harness_state_parse_failed',\n hookFailed: 'po_pi.hook_failed',\n hookRegistryReadFailed: 'po_pi.hook_registry_read_failed',\n personaReadFailed: 'po_pi.persona_read_failed',\n styleSystemRenderFailed: 'po_pi.style_system_render_failed',\n majorModeUnavailable: 'po_pi.major_mode_unavailable',\n profileLoadFailed: 'po_pi.profile_load_failed',\n launchCompleted: 'po_pi.launch_completed',\n projectTrustResolved: 'po_pi.project_trust_resolved',\n majorModeSwitched: 'po_pi.major_mode_switched',\n profileApplied: 'po_pi.profile_applied',\n} as const;\n\nexport type HarnessEventName = (typeof HARNESS_EVENT)[keyof typeof HARNESS_EVENT];\nexport type HarnessEventAttributes = Record<string, string | number | boolean>;\nexport type HarnessErrorSink = (event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes) => void;\n\nexport interface HarnessFailureReporter {\n error: HarnessErrorSink;\n warn: HarnessErrorSink;\n}\n\nexport interface HarnessTelemetryOptions {\n cwd?: string;\n workspaceRoot?: string;\n env?: NodeJS.ProcessEnv;\n telemetryFactory?: NonNullable<PoTelemetryOptions['telemetryFactory']>;\n warn?: (message: string) => void;\n /** Run startup callbacks before loading the telemetry backend. */\n deferSpans?: boolean;\n}\n\nexport interface HarnessTelemetry {\n recordError(event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes): Promise<void>;\n recordWarning(event: HarnessEventName, error: unknown, attributes?: HarnessEventAttributes): Promise<void>;\n recordEvent(event: HarnessEventName, attributes?: HarnessEventAttributes): Promise<void>;\n runInSpan<T>(name: string, attributes: HarnessEventAttributes, callback: () => Promise<T>): Promise<T>;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n}\n\nexport function createHarnessTelemetry(options: HarnessTelemetryOptions = {}): HarnessTelemetry {\n let telemetryPromise: Promise<PoTelemetry> | undefined;\n const pendingEvents: Array<{ event: HarnessEventName; attributes?: HarnessEventAttributes }> = [];\n let pendingEventDropReported = false;\n const telemetry = (): Promise<PoTelemetry> => {\n telemetryPromise ??= import('../poTelemetry').then(({ createPoTelemetry }) =>\n createPoTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n workspaceRoot: options.workspaceRoot,\n env: options.env,\n telemetryFactory: options.telemetryFactory,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n }),\n );\n return telemetryPromise;\n };\n const drainEvents = async (loaded: PoTelemetry): Promise<void> => {\n for (const pending of pendingEvents.splice(0)) {\n await loaded.recordEvent(pending.event, pending.attributes);\n }\n };\n return {\n recordError: async (event, error, attributes) => {\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.recordError(event, error, attributes);\n },\n recordWarning: async (event, error, attributes) => {\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.recordWarning(event, error, attributes);\n },\n recordEvent: async (event, attributes) => {\n if (options.deferSpans && !telemetryPromise) {\n if (pendingEvents.length < MAX_PENDING_EVENTS) pendingEvents.push({ event, attributes });\n else if (!pendingEventDropReported) {\n pendingEventDropReported = true;\n try {\n const reportWarning = options.warn ?? ((message: string) => console.warn(message));\n reportWarning('Po telemetry deferred event limit reached; later events were dropped.');\n } catch {\n // Telemetry warnings must not interrupt launcher startup.\n }\n }\n return;\n }\n await (await telemetry()).recordEvent(event, attributes);\n },\n runInSpan: (name, attributes, callback) => {\n // The launcher opts into this path for pre-spawn preparation. Lifecycle\n // events remain buffered until flush; failures still initialize the real\n // sink immediately so diagnostics are not lost.\n if (options.deferSpans && !telemetryPromise) return callback();\n return telemetry().then((loaded) => loaded.runInSpan(name, attributes, callback));\n },\n flush: async () => {\n if (!telemetryPromise && pendingEvents.length === 0) return;\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.flush();\n },\n shutdown: async () => {\n if (!telemetryPromise && pendingEvents.length === 0) return;\n const loaded = await telemetry();\n await drainEvents(loaded);\n await loaded.shutdown();\n },\n };\n}\n\nexport function toFailureReporter(telemetry: HarnessTelemetry): HarnessFailureReporter {\n return {\n error: (event, error, attributes) => void telemetry.recordError(event, error, attributes),\n warn: (event, error, attributes) => void telemetry.recordWarning(event, error, attributes),\n };\n}\n"],"mappings":";AAEA,MAAM,qBAAqB;AAC3B,MAAM,eAAe;AACrB,MAAM,eAAe;AAErB,MAAa,gBAAgB;CAC3B,WAAW;CACX,oBAAoB;CACpB,0BAA0B;CAC1B,kBAAkB;CAClB,cAAc;CACd,2BAA2B;CAC3B,yBAAyB;CACzB,YAAY;CACZ,wBAAwB;CACxB,mBAAmB;CACnB,yBAAyB;CACzB,sBAAsB;CACtB,mBAAmB;CACnB,iBAAiB;CACjB,sBAAsB;CACtB,mBAAmB;CACnB,gBAAgB;AAClB;AA8BA,SAAgB,uBAAuB,UAAmC,CAAC,GAAqB;CAC9F,IAAI;CACJ,MAAM,gBAAyF,CAAC;CAChG,IAAI,2BAA2B;CAC/B,MAAM,kBAAwC;EAC5C,qBAAqB,OAAO,uCAAiB,CAAC,MAAM,EAAE,wBACpD,kBAAkB;GAChB,aAAa;GACb,aAAa;GACb,KAAK,QAAQ;GACb,eAAe,QAAQ;GACvB,KAAK,QAAQ;GACb,kBAAkB,QAAQ;GAC1B,MAAM,QAAQ;GACd,YAAY;GACZ,cAAc;EAChB,CAAC,CACH;EACA,OAAO;CACT;CACA,MAAM,cAAc,OAAO,WAAuC;EAChE,KAAK,MAAM,WAAW,cAAc,OAAO,CAAC,GAC1C,MAAM,OAAO,YAAY,QAAQ,OAAO,QAAQ,UAAU;CAE9D;CACA,OAAO;EACL,aAAa,OAAO,OAAO,OAAO,eAAe;GAC/C,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,YAAY,OAAO,OAAO,UAAU;EACnD;EACA,eAAe,OAAO,OAAO,OAAO,eAAe;GACjD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,cAAc,OAAO,OAAO,UAAU;EACrD;EACA,aAAa,OAAO,OAAO,eAAe;GACxC,IAAI,QAAQ,cAAc,CAAC,kBAAkB;IAC3C,IAAI,cAAc,SAAS,oBAAoB,cAAc,KAAK;KAAE;KAAO;IAAW,CAAC;SAClF,IAAI,CAAC,0BAA0B;KAClC,2BAA2B;KAC3B,IAAI;MAEF,CADsB,QAAQ,UAAU,YAAoB,QAAQ,KAAK,OAAO,GAAA,CAClE,uEAAuE;KACvF,QAAQ,CAER;IACF;IACA;GACF;GACA,OAAO,MAAM,UAAU,EAAA,CAAG,YAAY,OAAO,UAAU;EACzD;EACA,YAAY,MAAM,YAAY,aAAa;GAIzC,IAAI,QAAQ,cAAc,CAAC,kBAAkB,OAAO,SAAS;GAC7D,OAAO,UAAU,CAAC,CAAC,MAAM,WAAW,OAAO,UAAU,MAAM,YAAY,QAAQ,CAAC;EAClF;EACA,OAAO,YAAY;GACjB,IAAI,CAAC,oBAAoB,cAAc,WAAW,GAAG;GACrD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,MAAM;EACrB;EACA,UAAU,YAAY;GACpB,IAAI,CAAC,oBAAoB,cAAc,WAAW,GAAG;GACrD,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,YAAY,MAAM;GACxB,MAAM,OAAO,SAAS;EACxB;CACF;AACF;AAEA,SAAgB,kBAAkB,WAAqD;CACrF,OAAO;EACL,QAAQ,OAAO,OAAO,eAAe,KAAK,UAAU,YAAY,OAAO,OAAO,UAAU;EACxF,OAAO,OAAO,OAAO,eAAe,KAAK,UAAU,cAAc,OAAO,OAAO,UAAU;CAC3F;AACF"}
|
package/dist/serverTelemetry.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
2
|
+
const require_index = require("./src/services/poTelemetry/index.cjs");
|
|
3
3
|
//#region src/services/serverTelemetry/index.ts
|
|
4
4
|
const SERVICE_NAME = "po-server";
|
|
5
5
|
const PACKAGE_NAME = "@agimon-ai/po";
|
|
6
6
|
function createServerTelemetry(options = {}) {
|
|
7
|
-
return
|
|
7
|
+
return require_index.createPoTelemetry({
|
|
8
8
|
serviceName: SERVICE_NAME,
|
|
9
9
|
packageName: PACKAGE_NAME,
|
|
10
10
|
cwd: options.cwd,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverTelemetry.cjs","names":["createPoTelemetry"],"sources":["../src/services/serverTelemetry/index.ts"],"sourcesContent":["import { createPoTelemetry, type PoTelemetry } from '
|
|
1
|
+
{"version":3,"file":"serverTelemetry.cjs","names":["createPoTelemetry"],"sources":["../src/services/serverTelemetry/index.ts"],"sourcesContent":["import { createPoTelemetry, type PoTelemetry } from '../poTelemetry';\n\nconst SERVICE_NAME = 'po-server';\nconst PACKAGE_NAME = '@agimon-ai/po';\n\nexport type ServerTelemetry = Pick<\n PoTelemetry,\n 'recordEvent' | 'recordWarning' | 'recordError' | 'runInSpan' | 'flush' | 'shutdown'\n>;\n\nexport function createServerTelemetry(\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n warn?: (message: string) => void;\n } = {},\n): ServerTelemetry {\n return createPoTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n env: options.env,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n}\n\n/** Telemetry is diagnostic and must never interrupt the server's critical path. */\nexport function observe(operation: Promise<unknown>, onNotice?: (message: string) => void): void {\n void operation.catch((error: unknown) =>\n onNotice?.(`telemetry failed: ${error instanceof Error ? error.message : String(error)}`),\n );\n}\n"],"mappings":";;;AAEA,MAAM,eAAe;AACrB,MAAM,eAAe;AAOrB,SAAgB,sBACd,UAII,CAAC,GACY;CACjB,OAAOA,cAAAA,kBAAkB;EACvB,aAAa;EACb,aAAa;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,MAAM,QAAQ;EACd,YAAY;EACZ,cAAc;CAChB,CAAC;AACH;;AAGA,SAAgB,QAAQ,WAA6B,UAA4C;CAC/F,UAAe,OAAO,UACpB,WAAW,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,CAC1F;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { PoTelemetry } from "
|
|
1
|
+
import { PoTelemetry } from "./src/types/telemetry.mjs";
|
|
2
|
+
import "./src/services/poTelemetry/index.mjs";
|
|
2
3
|
//#region src/services/serverTelemetry/index.d.ts
|
|
3
4
|
export type ServerTelemetry = Pick<PoTelemetry, 'recordEvent' | 'recordWarning' | 'recordError' | 'runInSpan' | 'flush' | 'shutdown'>;
|
|
4
5
|
export declare function createServerTelemetry(options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverTelemetry.d.mts","names":[],"sources":["../src/services/serverTelemetry/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"serverTelemetry.d.mts","names":[],"sources":["../src/services/serverTelemetry/index.ts"],"mappings":";;;YAKY,kBAAkB,KAC5B;wBAIc,sBACd;EACE;EACA,MAAM,OAAO;EACb,QAAQ;IAET;;wBAaa,QAAQ,WAAW,kBAAkB,YAAY"}
|
package/dist/serverTelemetry.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverTelemetry.mjs","names":[],"sources":["../src/services/serverTelemetry/index.ts"],"sourcesContent":["import { createPoTelemetry, type PoTelemetry } from '
|
|
1
|
+
{"version":3,"file":"serverTelemetry.mjs","names":[],"sources":["../src/services/serverTelemetry/index.ts"],"sourcesContent":["import { createPoTelemetry, type PoTelemetry } from '../poTelemetry';\n\nconst SERVICE_NAME = 'po-server';\nconst PACKAGE_NAME = '@agimon-ai/po';\n\nexport type ServerTelemetry = Pick<\n PoTelemetry,\n 'recordEvent' | 'recordWarning' | 'recordError' | 'runInSpan' | 'flush' | 'shutdown'\n>;\n\nexport function createServerTelemetry(\n options: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n warn?: (message: string) => void;\n } = {},\n): ServerTelemetry {\n return createPoTelemetry({\n serviceName: SERVICE_NAME,\n packageName: PACKAGE_NAME,\n cwd: options.cwd,\n env: options.env,\n warn: options.warn,\n enableLogs: true,\n enableTraces: true,\n });\n}\n\n/** Telemetry is diagnostic and must never interrupt the server's critical path. */\nexport function observe(operation: Promise<unknown>, onNotice?: (message: string) => void): void {\n void operation.catch((error: unknown) =>\n onNotice?.(`telemetry failed: ${error instanceof Error ? error.message : String(error)}`),\n );\n}\n"],"mappings":";;AAEA,MAAM,eAAe;AACrB,MAAM,eAAe;AAOrB,SAAgB,sBACd,UAII,CAAC,GACY;CACjB,OAAO,kBAAkB;EACvB,aAAa;EACb,aAAa;EACb,KAAK,QAAQ;EACb,KAAK,QAAQ;EACb,MAAM,QAAQ;EACd,YAAY;EACZ,cAAc;CAChB,CAAC;AACH;;AAGA,SAAgB,QAAQ,WAA6B,UAA4C;CAC/F,UAAe,OAAO,UACpB,WAAW,qBAAqB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG,CAC1F;AACF"}
|
|
@@ -29,7 +29,8 @@ const DelegationRequestSchema = typebox.Type.Object({
|
|
|
29
29
|
const DelegationAcceptedSchema = typebox.Type.Object({ requestId: typebox.Type.String({ minLength: 1 }) }, { additionalProperties: false });
|
|
30
30
|
const DelegationStartedSchema = typebox.Type.Object({
|
|
31
31
|
requestId: typebox.Type.String({ minLength: 1 }),
|
|
32
|
-
runId: typebox.Type.String({ minLength: 1 })
|
|
32
|
+
runId: typebox.Type.String({ minLength: 1 }),
|
|
33
|
+
identity: typebox.Type.Optional(typebox.Type.String({ minLength: 1 }))
|
|
33
34
|
}, { additionalProperties: false });
|
|
34
35
|
const DelegationUpdateSchema = typebox.Type.Object({
|
|
35
36
|
requestId: typebox.Type.String({ minLength: 1 }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation.cjs","names":["Type"],"sources":["../../../src/schemas/delegation.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\n\nexport const InlineAgentSchema = Type.Object(\n { systemPrompt: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type InlineAgent = Static<typeof InlineAgentSchema>;\n\n/** Shared Cordis contract for an optional delegated-run provider. */\nexport const PO_DELEGATION_SERVICE = 'po/delegation';\nexport const PO_DELEGATION_REQUESTED_EVENT = 'po/delegation/requested';\nexport const PO_DELEGATION_ACCEPTED_EVENT = 'po/delegation/accepted';\nexport const PO_DELEGATION_STARTED_EVENT = 'po/delegation/started';\nexport const PO_DELEGATION_UPDATED_EVENT = 'po/delegation/updated';\nexport const PO_DELEGATION_FINISHED_EVENT = 'po/delegation/finished';\nexport const PO_DELEGATION_CANCELLED_EVENT = 'po/delegation/cancelled';\n\nexport const DelegationRequestSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n taskId: Type.Union([Type.String(), Type.Number()]),\n agent: Type.String({ minLength: 1 }),\n inlineAgent: Type.Optional(InlineAgentSchema),\n prompt: Type.String({ minLength: 1 }),\n cwd: Type.String({ minLength: 1 }),\n model: Type.Optional(Type.String({ minLength: 1 })),\n context: Type.Optional(Type.Union([Type.Literal('fresh'), Type.Literal('fork')])),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n artifacts: Type.Optional(Type.Boolean()),\n runMode: Type.Optional(Type.Union([Type.Literal('foreground'), Type.Literal('detached')])),\n teamTask: Type.Optional(\n Type.Object(\n { id: Type.String({ minLength: 1 }), subject: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n ),\n ),\n },\n { additionalProperties: false },\n);\nexport type DelegationRequest = Static<typeof DelegationRequestSchema>;\n\nexport const DelegationAcceptedSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type DelegationAccepted = Static<typeof DelegationAcceptedSchema>;\n\nexport const DelegationStartedSchema = Type.Object(\n {
|
|
1
|
+
{"version":3,"file":"delegation.cjs","names":["Type"],"sources":["../../../src/schemas/delegation.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\n\nexport const InlineAgentSchema = Type.Object(\n { systemPrompt: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type InlineAgent = Static<typeof InlineAgentSchema>;\n\n/** Shared Cordis contract for an optional delegated-run provider. */\nexport const PO_DELEGATION_SERVICE = 'po/delegation';\nexport const PO_DELEGATION_REQUESTED_EVENT = 'po/delegation/requested';\nexport const PO_DELEGATION_ACCEPTED_EVENT = 'po/delegation/accepted';\nexport const PO_DELEGATION_STARTED_EVENT = 'po/delegation/started';\nexport const PO_DELEGATION_UPDATED_EVENT = 'po/delegation/updated';\nexport const PO_DELEGATION_FINISHED_EVENT = 'po/delegation/finished';\nexport const PO_DELEGATION_CANCELLED_EVENT = 'po/delegation/cancelled';\n\nexport const DelegationRequestSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n taskId: Type.Union([Type.String(), Type.Number()]),\n agent: Type.String({ minLength: 1 }),\n inlineAgent: Type.Optional(InlineAgentSchema),\n prompt: Type.String({ minLength: 1 }),\n cwd: Type.String({ minLength: 1 }),\n model: Type.Optional(Type.String({ minLength: 1 })),\n context: Type.Optional(Type.Union([Type.Literal('fresh'), Type.Literal('fork')])),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n artifacts: Type.Optional(Type.Boolean()),\n runMode: Type.Optional(Type.Union([Type.Literal('foreground'), Type.Literal('detached')])),\n teamTask: Type.Optional(\n Type.Object(\n { id: Type.String({ minLength: 1 }), subject: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n ),\n ),\n },\n { additionalProperties: false },\n);\nexport type DelegationRequest = Static<typeof DelegationRequestSchema>;\n\nexport const DelegationAcceptedSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type DelegationAccepted = Static<typeof DelegationAcceptedSchema>;\n\nexport const DelegationStartedSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n identity: Type.Optional(Type.String({ minLength: 1 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationStarted = Static<typeof DelegationStartedSchema>;\n\nexport const DelegationUpdateSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n status: Type.Optional(Type.String({ minLength: 1 })),\n currentTool: Type.Optional(Type.String({ minLength: 1 })),\n toolCount: Type.Optional(Type.Integer({ minimum: 0 })),\n durationMs: Type.Optional(Type.Integer({ minimum: 0 })),\n tokens: Type.Optional(Type.Integer({ minimum: 0 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationUpdate = Static<typeof DelegationUpdateSchema>;\n\nexport const DelegationStatusSchema = Type.Union([\n Type.Literal('completed'),\n Type.Literal('failed'),\n Type.Literal('timed_out'),\n Type.Literal('cancelled'),\n Type.Literal('interrupted'),\n Type.Literal('turn_budget_exhausted'),\n Type.Literal('tool_budget_exhausted'),\n Type.Literal('acceptance_failed'),\n Type.Literal('invalid_request'),\n Type.Literal('unavailable_context'),\n]);\nexport type DelegationStatus = Static<typeof DelegationStatusSchema>;\n\nexport const DelegationResultSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n status: DelegationStatusSchema,\n output: Type.Optional(Type.String()),\n error: Type.Optional(Type.String()),\n outputPath: Type.Optional(Type.String({ minLength: 1 })),\n sessionFile: Type.Optional(Type.String({ minLength: 1 })),\n durationMs: Type.Optional(Type.Integer({ minimum: 0 })),\n toolCount: Type.Optional(Type.Integer({ minimum: 0 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationResult = Static<typeof DelegationResultSchema>;\n\nexport const DelegationCancelSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }), reason: Type.Optional(Type.String({ minLength: 1 })) },\n { additionalProperties: false },\n);\nexport type DelegationCancel = Static<typeof DelegationCancelSchema>;\n\nexport interface PoDelegationService {\n readonly sessionId: string;\n readonly generation: string;\n request(request: DelegationRequest): Promise<void>;\n cancel(request: DelegationCancel): void;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/delegation': PoDelegationService;\n }\n\n interface Events {\n 'po/delegation/requested'(event: DelegationRequest): void;\n 'po/delegation/accepted'(event: DelegationAccepted): void;\n 'po/delegation/started'(event: DelegationStarted): void;\n 'po/delegation/updated'(event: DelegationUpdate): void;\n 'po/delegation/finished'(event: DelegationResult): void;\n 'po/delegation/cancelled'(event: DelegationCancel): void;\n }\n}\n\nexport function readPoDelegationService(ctx: Context): PoDelegationService | undefined {\n return ctx.get(PO_DELEGATION_SERVICE) as PoDelegationService | undefined;\n}\n"],"mappings":"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"}
|
|
@@ -40,6 +40,7 @@ export type DelegationAccepted = Static<typeof DelegationAcceptedSchema>;
|
|
|
40
40
|
export declare const DelegationStartedSchema: Type.TObject<{
|
|
41
41
|
requestId: Type.TString;
|
|
42
42
|
runId: Type.TString;
|
|
43
|
+
identity: Type.TOptional<Type.TString>;
|
|
43
44
|
}>;
|
|
44
45
|
export type DelegationStarted = Static<typeof DelegationStartedSchema>;
|
|
45
46
|
export declare const DelegationUpdateSchema: Type.TObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation.d.mts","names":[],"sources":["../../../src/schemas/delegation.ts"],"mappings":";;;qBAGa,mBAAiB,KAAA;gBAAjB,KAAA;;YAID,cAAc,cAAc;;qBAG3B;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBAEA,yBAAuB,KAAA;;;;;;;;;;;;;;;;;;;YAsBxB,oBAAoB,cAAc;qBAEjC,0BAAwB,KAAA;aAAxB,KAAA;;YAID,qBAAqB,cAAc;qBAElC,yBAAuB,KAAA
|
|
1
|
+
{"version":3,"file":"delegation.d.mts","names":[],"sources":["../../../src/schemas/delegation.ts"],"mappings":";;;qBAGa,mBAAiB,KAAA;gBAAjB,KAAA;;YAID,cAAc,cAAc;;qBAG3B;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBAEA,yBAAuB,KAAA;;;;;;;;;;;;;;;;;;;YAsBxB,oBAAoB,cAAc;qBAEjC,0BAAwB,KAAA;aAAxB,KAAA;;YAID,qBAAqB,cAAc;qBAElC,yBAAuB,KAAA;;;;;YAQxB,oBAAoB,cAAc;qBAEjC,wBAAsB,KAAA;;;;;;;;;YAYvB,mBAAmB,cAAc;qBAEhC,wBAAsB,KAAA,QAAA,KAAA,uBAAA,KAAA,oBAAA,KAAA,uBAAA,KAAA,uBAAA,KAAA,yBAAA,KAAA,mCAAA,KAAA,mCAAA,KAAA,+BAAA,KAAA,6BAAA,KAAA;YAYvB,mBAAmB,cAAc;qBAEhC,wBAAsB,KAAA;;;;;;;;;;;YAcvB,mBAAmB,cAAc;qBAEhC,wBAAsB,KAAA;;;;YAIvB,mBAAmB,cAAc;iBAE5B;WACN;WACA;EACT,QAAQ,SAAS,oBAAoB;EACrC,OAAO,SAAS;;;YAIN;IACR,iBAAiB;;YAGT;IACR,0BAA0B,OAAO;IACjC,yBAAyB,OAAO;IAChC,wBAAwB,OAAO;IAC/B,wBAAwB,OAAO;IAC/B,yBAAyB,OAAO;IAChC,0BAA0B,OAAO;;;wBAIrB,wBAAwB,KAAK,UAAU"}
|
|
@@ -29,7 +29,8 @@ const DelegationRequestSchema = Type.Object({
|
|
|
29
29
|
const DelegationAcceptedSchema = Type.Object({ requestId: Type.String({ minLength: 1 }) }, { additionalProperties: false });
|
|
30
30
|
const DelegationStartedSchema = Type.Object({
|
|
31
31
|
requestId: Type.String({ minLength: 1 }),
|
|
32
|
-
runId: Type.String({ minLength: 1 })
|
|
32
|
+
runId: Type.String({ minLength: 1 }),
|
|
33
|
+
identity: Type.Optional(Type.String({ minLength: 1 }))
|
|
33
34
|
}, { additionalProperties: false });
|
|
34
35
|
const DelegationUpdateSchema = Type.Object({
|
|
35
36
|
requestId: Type.String({ minLength: 1 }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation.mjs","names":[],"sources":["../../../src/schemas/delegation.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\n\nexport const InlineAgentSchema = Type.Object(\n { systemPrompt: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type InlineAgent = Static<typeof InlineAgentSchema>;\n\n/** Shared Cordis contract for an optional delegated-run provider. */\nexport const PO_DELEGATION_SERVICE = 'po/delegation';\nexport const PO_DELEGATION_REQUESTED_EVENT = 'po/delegation/requested';\nexport const PO_DELEGATION_ACCEPTED_EVENT = 'po/delegation/accepted';\nexport const PO_DELEGATION_STARTED_EVENT = 'po/delegation/started';\nexport const PO_DELEGATION_UPDATED_EVENT = 'po/delegation/updated';\nexport const PO_DELEGATION_FINISHED_EVENT = 'po/delegation/finished';\nexport const PO_DELEGATION_CANCELLED_EVENT = 'po/delegation/cancelled';\n\nexport const DelegationRequestSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n taskId: Type.Union([Type.String(), Type.Number()]),\n agent: Type.String({ minLength: 1 }),\n inlineAgent: Type.Optional(InlineAgentSchema),\n prompt: Type.String({ minLength: 1 }),\n cwd: Type.String({ minLength: 1 }),\n model: Type.Optional(Type.String({ minLength: 1 })),\n context: Type.Optional(Type.Union([Type.Literal('fresh'), Type.Literal('fork')])),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n artifacts: Type.Optional(Type.Boolean()),\n runMode: Type.Optional(Type.Union([Type.Literal('foreground'), Type.Literal('detached')])),\n teamTask: Type.Optional(\n Type.Object(\n { id: Type.String({ minLength: 1 }), subject: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n ),\n ),\n },\n { additionalProperties: false },\n);\nexport type DelegationRequest = Static<typeof DelegationRequestSchema>;\n\nexport const DelegationAcceptedSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type DelegationAccepted = Static<typeof DelegationAcceptedSchema>;\n\nexport const DelegationStartedSchema = Type.Object(\n {
|
|
1
|
+
{"version":3,"file":"delegation.mjs","names":[],"sources":["../../../src/schemas/delegation.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport { type Static, Type } from 'typebox';\n\nexport const InlineAgentSchema = Type.Object(\n { systemPrompt: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type InlineAgent = Static<typeof InlineAgentSchema>;\n\n/** Shared Cordis contract for an optional delegated-run provider. */\nexport const PO_DELEGATION_SERVICE = 'po/delegation';\nexport const PO_DELEGATION_REQUESTED_EVENT = 'po/delegation/requested';\nexport const PO_DELEGATION_ACCEPTED_EVENT = 'po/delegation/accepted';\nexport const PO_DELEGATION_STARTED_EVENT = 'po/delegation/started';\nexport const PO_DELEGATION_UPDATED_EVENT = 'po/delegation/updated';\nexport const PO_DELEGATION_FINISHED_EVENT = 'po/delegation/finished';\nexport const PO_DELEGATION_CANCELLED_EVENT = 'po/delegation/cancelled';\n\nexport const DelegationRequestSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n taskId: Type.Union([Type.String(), Type.Number()]),\n agent: Type.String({ minLength: 1 }),\n inlineAgent: Type.Optional(InlineAgentSchema),\n prompt: Type.String({ minLength: 1 }),\n cwd: Type.String({ minLength: 1 }),\n model: Type.Optional(Type.String({ minLength: 1 })),\n context: Type.Optional(Type.Union([Type.Literal('fresh'), Type.Literal('fork')])),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n artifacts: Type.Optional(Type.Boolean()),\n runMode: Type.Optional(Type.Union([Type.Literal('foreground'), Type.Literal('detached')])),\n teamTask: Type.Optional(\n Type.Object(\n { id: Type.String({ minLength: 1 }), subject: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n ),\n ),\n },\n { additionalProperties: false },\n);\nexport type DelegationRequest = Static<typeof DelegationRequestSchema>;\n\nexport const DelegationAcceptedSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }) },\n { additionalProperties: false },\n);\nexport type DelegationAccepted = Static<typeof DelegationAcceptedSchema>;\n\nexport const DelegationStartedSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n identity: Type.Optional(Type.String({ minLength: 1 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationStarted = Static<typeof DelegationStartedSchema>;\n\nexport const DelegationUpdateSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n status: Type.Optional(Type.String({ minLength: 1 })),\n currentTool: Type.Optional(Type.String({ minLength: 1 })),\n toolCount: Type.Optional(Type.Integer({ minimum: 0 })),\n durationMs: Type.Optional(Type.Integer({ minimum: 0 })),\n tokens: Type.Optional(Type.Integer({ minimum: 0 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationUpdate = Static<typeof DelegationUpdateSchema>;\n\nexport const DelegationStatusSchema = Type.Union([\n Type.Literal('completed'),\n Type.Literal('failed'),\n Type.Literal('timed_out'),\n Type.Literal('cancelled'),\n Type.Literal('interrupted'),\n Type.Literal('turn_budget_exhausted'),\n Type.Literal('tool_budget_exhausted'),\n Type.Literal('acceptance_failed'),\n Type.Literal('invalid_request'),\n Type.Literal('unavailable_context'),\n]);\nexport type DelegationStatus = Static<typeof DelegationStatusSchema>;\n\nexport const DelegationResultSchema = Type.Object(\n {\n requestId: Type.String({ minLength: 1 }),\n runId: Type.String({ minLength: 1 }),\n status: DelegationStatusSchema,\n output: Type.Optional(Type.String()),\n error: Type.Optional(Type.String()),\n outputPath: Type.Optional(Type.String({ minLength: 1 })),\n sessionFile: Type.Optional(Type.String({ minLength: 1 })),\n durationMs: Type.Optional(Type.Integer({ minimum: 0 })),\n toolCount: Type.Optional(Type.Integer({ minimum: 0 })),\n },\n { additionalProperties: false },\n);\nexport type DelegationResult = Static<typeof DelegationResultSchema>;\n\nexport const DelegationCancelSchema = Type.Object(\n { requestId: Type.String({ minLength: 1 }), reason: Type.Optional(Type.String({ minLength: 1 })) },\n { additionalProperties: false },\n);\nexport type DelegationCancel = Static<typeof DelegationCancelSchema>;\n\nexport interface PoDelegationService {\n readonly sessionId: string;\n readonly generation: string;\n request(request: DelegationRequest): Promise<void>;\n cancel(request: DelegationCancel): void;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'po/delegation': PoDelegationService;\n }\n\n interface Events {\n 'po/delegation/requested'(event: DelegationRequest): void;\n 'po/delegation/accepted'(event: DelegationAccepted): void;\n 'po/delegation/started'(event: DelegationStarted): void;\n 'po/delegation/updated'(event: DelegationUpdate): void;\n 'po/delegation/finished'(event: DelegationResult): void;\n 'po/delegation/cancelled'(event: DelegationCancel): void;\n }\n}\n\nexport function readPoDelegationService(ctx: Context): PoDelegationService | undefined {\n return ctx.get(PO_DELEGATION_SERVICE) as PoDelegationService | undefined;\n}\n"],"mappings":"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"}
|