/** * PilotSwarmManagementClient — runtime/session fleet management. * * Provides public APIs for listing sessions, renaming, cancelling, * deleting, model listing, session dumps, and status watching. * * This is the management surface for TUI and admin tools. * It replaces direct usage of private client internals, raw duroxide * client handles, and raw CMS catalog handles. * * @module */ import type { PilotSwarmSessionStatus, SessionResponsePayload, SessionCommandResponse, SessionStatusSignal, SessionContextUsage, SessionOwnerInfo, SessionSummaryState, StopTurnResult, PromptAttachmentRef } from "./types.js"; import type { TopEventEmitterRow, AgentPackageSelector, AgentPrincipal, AgentPackageScope, AgentPackageSummary, AgentPackageDetail, AgentPackageEditorInfo, AgentWorkerStateRow, WorkerRow } from "./cms.js"; import type { CanvasKvPrincipal, CanvasKvReadResult, CanvasKvWriteOp, CanvasKvWriteResult, CanvasKvMe } from "./canvas-kv.js"; import type { ProviderRow, ProviderStatusRow, PausedSessionRow, DefaultTuple, UsageFilters, ProviderClass, UsageGridRow, ProviderDefaults, SystemAgentModelOverride } from "./provider-store.js"; import type { BudgetPeriod } from "./provider-budgets.js"; import type { FeatureViewer, FeatureMutation, FeatureView, FeatureMutationResult } from "./feature-store.js"; import type { MessageSender } from "./message-sender.js"; import type { SessionMetricSummary, TokensByModelRow, SessionTreeStats, FleetStats, UserStats, SkillUsageRow, SessionTreeSkillUsage, FleetSkillUsage, RetrievalUsageRow, SessionTreeRetrievalUsage, FleetRetrievalUsage, GraphNodeUsageKind, GraphNodeUsageRow, FleetGraphNodeUsage, GraphEdgeSearchUsageRow, UserProfile, UserPrincipal, UserRoleInfo, UserRoleValue, SessionGroupRow, PlacementViewer, SessionPlacementResult, ChildOutcomeRow, SessionVisibility, SessionShareInfo, SessionAccessSnapshot, AuthzAuditEntry, KnownUserInfo } from "./cms.js"; import type { FactsStatsRow, FactsTombstoneStats, FactRecord, StoreFactInput, StoredFactResult, ReadFactsQuery, DeleteFactInput, DeletedFactResult, DeletedFactsResult, SearchOpts, SimilarOpts, SearchResult, FactsCapabilities, ForcePurgeFactsInput } from "./facts-store.js"; import type { GraphNodeInput, GraphEdgeInput, GraphNodeQuery, GraphEdgeQuery, GraphNodeHit, GraphEdgeHit, GraphNodeRef, GraphEdgeRef, SubGraph, GraphNamespaceInfo, GraphNamespaceListQuery, GraphNamespaceInput, GraphNamespaceQuery } from "./graph-store.js"; import { type StorageConfig } from "./storage-config.js"; import { type SessionFootprint } from "./footprint.js"; import { type ReasoningEffort, type ContextTier } from "./model-providers.js"; import { type PilotSwarmWebOptions } from "./web/api-connection.js"; import { WebPilotSwarmManagementClient } from "./web/web-management-client.js"; import type { AgentConfig } from "./agent-loader.js"; import { type SystemAgentStartResult } from "./system-agents.js"; import type { ArtifactStore } from "./session-store.js"; export type SystemSessionRestartDisposition = "complete" | "terminate" | "hard_delete" | "hardDelete"; /** Status view of the SYSTEM user's GitHub Copilot key (never the key itself). */ export interface SystemGitHubCopilotKeyStatus { configured: boolean; changedBy: string | null; changedAt: string | null; } export interface RestartSystemSessionOptions { disposition: SystemSessionRestartDisposition; reason?: string; timeoutMs?: number; model?: string; reasoningEffort?: ReasoningEffort | null; contextTier?: ContextTier | null; modelResolutionSource?: string; /** Stable id for an idempotent multi-agent rollout; omitted for a new manual restart. */ operationId?: string; } export interface RestartSystemSessionResult { agentId: string; agentName: string; sessionId: string; disposition: "complete" | "terminate" | "hard_delete"; previousSessionExisted: boolean; startResults: SystemAgentStartResult[]; skippedReason?: "busy" | "complete"; } /** Merged view of a session for management UIs. */ export interface PilotSwarmSessionView { sessionId: string; title?: string; agentId?: string; splash?: string; /** Narrow-viewport splash variant, used when the main splash art is wider than the pane. */ splashMobile?: string; owner?: SessionOwnerInfo; /** Live status from orchestration customStatus (idle, running, waiting, etc.) */ status: PilotSwarmSessionStatus; /** Duroxide orchestration runtime status (Running, Completed, Failed, Terminated). */ orchestrationStatus?: string; /** Registered duroxide orchestration version for the current instance execution. */ orchestrationVersion?: string; createdAt: number; updatedAt?: number; iterations?: number; parentSessionId?: string; /** The requesting viewer's private group placement for this session's root. */ viewerGroupId?: string; isSystem?: boolean; /** Service session (tree-scoped machinery, e.g. "regen-distiller"): read-only to users. */ serviceKind?: string; /** The session this service session serves. */ serviceOf?: string; model?: string; reasoningEffort?: string; contextTier?: string; shortSummary?: string; summaryState?: SessionSummaryState; summaryUpdatedAt?: number; error?: string; waitReason?: string; cronActive?: boolean; cronInterval?: number; cronReason?: string; cronKind?: "interval" | "wall-clock"; cronNextFireAt?: number; cronTimezone?: string; cronMaxFires?: number; cronFiresCompleted?: number; pendingQuestion?: { question: string; choices?: string[]; allowFreeform?: boolean; iteration?: number; }; result?: string; contextUsage?: SessionContextUsage; /** customStatusVersion for change tracking. */ statusVersion?: number; /** Sharing level of the session's tree root (private | shared_read | shared_write). */ visibility?: SessionVisibility; /** Denormalized session-tree root id (self for top-level sessions). */ rootSessionId?: string; } /** Cursor for keyset-paginated session listing. */ export interface SessionPageCursor { updatedAt: number; sessionId: string; } /** Options for bounded management session listing. */ export interface ListSessionsPageOptions { limit?: number; cursor?: SessionPageCursor | null; includeDeleted?: boolean; /** Restrict the page to system sessions, regular sessions, or keep both. */ systemFilter?: "all" | "only" | "exclude"; /** When set, restrict rows to what this principal can read (viewer-scoped listing). */ viewer?: { provider: string; subject: string; systemVisible?: boolean; } | null; /** When set, root rows carry this principal's private group placement as viewerGroupId. */ placement?: { provider: string; subject: string; } | null; } /** One bounded page of management session views. */ export interface PilotSwarmSessionPage { sessions: PilotSwarmSessionView[]; hasMore: boolean; nextCursor?: SessionPageCursor; } /** Model summary for UI display. */ export interface ModelSummary { catalogKind?: "provider_type" | "runtime_provider"; qualifiedName: string; providerId: string; providerType: string; modelName: string; description?: string; cost?: string; supportedReasoningEfforts?: ReasoningEffort[]; defaultReasoningEffort?: ReasoningEffort; supportedContextTiers?: import("./model-providers.js").ContextTier[]; defaultContextTier?: import("./model-providers.js").ContextTier; contextWindowSizes?: Partial>; /** * Whether the provider has a process/env credential. For GitHub * providers this excludes per-user CMS keys (see * getModelCredentialStatus) — a `false` here means the model is only * usable by users who configured their own GitHub Copilot key. */ credentialAvailable?: boolean; } /** Credential availability for a configured model provider. */ export interface ModelCredentialStatus { qualifiedName?: string; providerId?: string; providerType?: string; credentialAvailable: boolean; } /** * Who is asking for a provider-budget operation. * * `principal` is the caller's identity, resolved to a numeric user id on the * way in because the `cms_provider_*` procedures take numbers; `null` is a * caller the deployment has never seen, which the procedures read as nobody. * `isAdmin` is the role the caller authenticated with. Neither field decides * anything here — every rule about who may do what is in SQL. */ export interface ProviderViewer { principal: UserPrincipal | null; isAdmin: boolean; /** Resolved by the authenticated surface, never from request parameters. */ adminScope?: "unrestricted" | "cluster"; } /** What a caller sends to make a provider — the words the surface uses, not the column names. */ export interface ProviderCreateInput { name: string; type: string; credentials?: Record | null; baseUrl?: string | null; } export interface ProviderCredentialUpdateInput { name: string; credentials?: Record | null; } export interface ModelDefaultInput { scope: "user" | "cluster"; provider: string | null; model: string | null; reasoningEffort?: ReasoningEffort | null; contextTier?: ContextTier | null; } export interface SystemModelDefaultInput { provider: string | null; model: string | null; reasoningEffort?: ReasoningEffort | null; contextTier?: ContextTier | null; restartExisting?: false | { disposition: SystemSessionRestartDisposition; }; } export interface ResolvedModelDefault { provider: string; model: string; reasoningEffort: ReasoningEffort | null; contextTier: ContextTier | null; source: "user_default" | "cluster_default" | "system_default" | "first_available"; } /** Which limit on which provider: one per (period, scope). */ export interface ProviderLimitRef { provider: string; period: BudgetPeriod; /** One model, or every model on the provider when absent. */ model?: string | null; } export interface ProviderLimitInput extends ProviderLimitRef { /** A whole number of tokens. Hard — the first turn past it waits. */ tokens: number; } export interface ProviderHoldInput { provider: string; /** When the hold lifts by itself. */ untilUtc?: string | null; /** Lift it now. */ release?: boolean; } /** What a usage breakdown groups by. */ export type ProviderUsageDimension = "session" | "user" | "provider" | "model" | "agent"; export declare const PROVIDER_USAGE_DIMENSIONS: ProviderUsageDimension[]; export interface ProviderUsageQuery extends UsageFilters { dimension?: string | null; limit?: number | null; /** * "Only my own spend", resolved HERE from the authenticated caller. * * The alternative is for the caller to send their own `ownerUserId`, which * means the client has to know its own id and the wire has to carry one — * and a wire that can carry your id can carry somebody else's. This cannot: * the flag is a boolean and the id is the actor the server already * resolved. It wins over `ownerUserId` when both are sent. */ mine?: boolean | null; } /** The whole usage view in one answer: totals, the daily chart, one breakdown. */ /** What the cluster summary is asked for. */ export interface ProviderUsageSummaryQuery { /** Days of history for the chart and the model table: 1–365, default 14. */ days?: number; /** Only these providers; empty or absent means all of them. */ providers?: string[]; } /** One window's four-way token split. */ export interface ProviderUsageSummaryWindow { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; turns: number; sessions: number; } /** The cluster summary, as `cms_provider_usage_summary` builds it. */ export interface ProviderUsageSummary { days: number; /** The UTC day the windows and series count as "today". */ today: string; /** "cluster" for an admin, "mine" for everyone else. */ scope: "cluster" | "mine"; windows: { day: ProviderUsageSummaryWindow; week: ProviderUsageSummaryWindow; month: ProviderUsageSummaryWindow; }; daily: Array<{ day: string; input: number; output: number; cacheRead: number; cacheWrite: number; total: number; turns: number; }>; /** Pivoted on the model NAME, across providers, efforts and context tiers. */ models: Array<{ model: string; providers: number; turns: number; input: number; output: number; cacheRead: number; cacheWrite: number; total: number; daily: Array<{ day: string; total: number; }>; }>; classes: Array<{ chargeClass: string; total: number; turns: number; }>; } export interface ProviderUsageReport { totals: { tokensTotal: number; turns: number; sessions: number; }; daily: Array<{ dayUtc: string; tokensTotal: number; turns: number; /** The four parts of tokensTotal. */ tokensInput: number; tokensOutput: number; tokensCacheRead: number; tokensCacheWrite: number; }>; breakdown: Array<{ key: string; label: string; tokensTotal: number; turns: number; }>; /** The dimension actually grouped by, which is the default when the request named an unknown one. */ dimension: ProviderUsageDimension; /** True when more rows exist than `limit` returned. */ truncated: boolean; } /** Status change result from watchSessionStatus. */ export interface SessionStatusChange { customStatus: SessionStatusSignal | any; customStatusVersion: number; orchestrationStatus?: string; } /** Per-orchestration runtime stats from duroxide. */ export interface SessionOrchestrationStats { orchestrationVersion?: string; historyEventCount?: number; historySizeBytes?: number; queuePendingCount?: number; kvUserKeyCount?: number; kvTotalValueBytes?: number; } /** A single duroxide execution history event. */ export interface ExecutionHistoryEvent { eventId: number; kind: string; sourceEventId?: number; timestampMs: number; data?: string; } /** Options for PilotSwarmManagementClient. */ export interface PilotSwarmManagementClientOptions { /** PostgreSQL connection string. PilotSwarm requires PostgreSQL for CMS and facts. */ store: string; /** Resolved storage config. Must match the worker when supplied. */ storageConfig?: StorageConfig; /** PostgreSQL schema for duroxide tables. Default: "ps_duroxide". */ duroxideSchema?: string; /** PostgreSQL schema for CMS tables. Default: "copilot_sessions". */ cmsSchema?: string; /** PostgreSQL schema for durable facts. Default: "pilotswarm_facts". */ factsSchema?: string; /** EnhancedFactStore URL (07 P3) — must match the worker so facts reads/ * stats target the same store. Unset ⇒ facts on cmsFactsDatabaseUrl ?? store. */ enhancedFactsDatabaseUrl?: string; /** Facts provider selector — must match the worker. */ factsProvider?: "pg" | "horizon"; /** Enhanced facts schema — must match the worker's enhancedFactsSchema. */ enhancedFactsSchema?: string; /** Path to model_providers.json. Auto-discovers if not set. */ modelProvidersPath?: string; /** App plugin dirs used to discover app-defined system agents for restart operations. */ pluginDirs?: string[]; /** Disable bundled PilotSwarm management agents when discovering restartable system agents. */ disableManagementAgents?: boolean; /** Direct system-agent definitions for restart operations. Mostly useful for tests/embedded hosts. */ systemAgents?: AgentConfig[]; /** Whether restarted system-agent orchestrations should enable blob-backed dehydration. */ blobEnabled?: boolean; /** Dehydrate threshold passed to restarted system-agent orchestrations. Defaults to 30. */ waitThreshold?: number; /** * Optional trace callback for startup diagnostics. * If not provided, trace messages are discarded. */ traceWriter?: (msg: string) => void; /** * Use AAD/Managed Identity for CMS + facts Postgres pools. Mirrors * `PilotSwarmClientOptions.useManagedIdentity`. When `true`, * `cmsFactsDatabaseUrl` (or `store`) must be a passwordless URL. */ useManagedIdentity?: boolean; /** * Optional separate URL for CMS + facts pools. When unset, `store` is * reused. Pair with `useManagedIdentity: true` for the passwordless * AAD path. */ cmsFactsDatabaseUrl?: string; /** * Override the AAD principal name used as the Postgres `user` when * minting tokens. Only consulted when `useManagedIdentity` is `true`. */ aadDbUser?: string; /** Artifact store used by direct-mode agent-package publish/read/delete operations. */ artifactStore?: ArtifactStore | null; } export declare class PilotSwarmManagementClient { private config; private _catalog; private _factStore; private _graphStore; private _duroxideClient; private _modelProviders; private _systemAgents; private _artifactStore; private _activeStatusWaitControllers; private _activeStatusWaitPromises; private _started; constructor(options: PilotSwarmManagementClientOptions | PilotSwarmWebOptions); start(): Promise; stop(): Promise; private _readJsonValue; private _waitForSession; private _forceDeleteSession; private _getSystemAgentPlans; private _resolveSystemAgentPlan; private _archiveSystemSessionForRestart; private _deleteSystemOrchestrationInstance; private _terminateSystemOrchestrationInstance; /** * List all sessions with merged CMS + orchestration state. * Returns a ready-to-render view model. * * **Optimized path**: reads entirely from CMS (single SQL query). * Live status is kept up-to-date by activity-level writeback in * the runTurn activity (session-proxy). For real-time status of a * single session, use getSession() which still hits duroxide. */ listSessions(placement?: { provider: string; subject: string; } | null): Promise; /** * List one bounded page of sessions with merged CMS state. * * Uses CMS keyset pagination. For real-time status of a single session, * use getSession() which still reads duroxide runtime state. */ listSessionsPage(opts?: ListSessionsPageOptions): Promise; /** List sessions visible to a principal (non-paged viewer-scoped listing). */ listSessionsVisible(viewer: { provider: string; subject: string; systemVisible?: boolean; }, placement?: { provider: string; subject: string; } | null): Promise; /** Member directory for share autocomplete (excludes synthetic principals). */ listKnownUsers(opts?: { limit?: number; }): Promise; /** Access snapshot for the enforcement predicate (null = missing/deleted session). */ getSessionAccess(sessionId: string, viewer: { provider: string; subject: string; }): Promise; /** Set the sharing level on the ROOT of the given session's tree. */ setSessionVisibility(sessionId: string, visibility: SessionVisibility): Promise; /** Grant (or update) a targeted share on the session's tree root. */ grantSessionShare(sessionId: string, grantee: { provider: string; subject: string; email?: string | null; displayName?: string | null; }, access: "read" | "write", grantedBy?: { provider: string; subject: string; } | null): Promise; /** Revoke a targeted share on the session's tree root. */ revokeSessionShare(sessionId: string, grantee: { provider: string; subject: string; }): Promise; /** List targeted shares on the session's tree root. */ listSessionShares(sessionId: string): Promise; /** Append one authz audit record (fire-and-forget friendly; errors surface to the caller). */ recordAuthzAudit(entry: { actor?: { provider?: string | null; subject?: string | null; display?: string | null; } | null; action: string; sessionId?: string | null; target?: string | null; decision: string; reason?: string | null; details?: Record | null; }): Promise; /** Read authz audit records, newest first (optionally scoped to one session). */ listAuthzAudit(opts?: { limit?: number; sessionId?: string | null; }): Promise; /** * Record the authorization role observed for a principal at sign-in. * * DIRECT MODE ONLY, and deliberately not a Web API route: a caller able * to write its own role would hold a privilege-escalation primitive. The * only legitimate writer is the portal process itself, which has just * validated the token the role came from. Same posture as * `recordAuthzAudit`. * * Returns the normalized role that was stored (`null` when the input was * absent or outside the known vocabulary). */ recordUserRole(principal: UserPrincipal, role: string | null): Promise; /** * Read the last-observed authorization role for a principal. `null` role * means no privilege, whether the principal is unknown or simply has no * role recorded. */ getUserRole(principal: UserPrincipal): Promise; /** * Get a single session view by ID. */ getSession(sessionId: string, placement?: { provider: string; subject: string; } | null): Promise; getChildOutcome(childSessionId: string): Promise; listChildOutcomes(parentSessionId: string): Promise; createSessionGroup(input: { groupId?: string; title: string; description?: string | null; owner?: SessionOwnerInfo | null; metadata?: Record; }): Promise; listSessionGroups(viewer?: PlacementViewer | null): Promise; listGroupSessions(groupId: string, placement?: { provider: string; subject: string; } | null): Promise; updateSessionGroup(groupId: string, patch: { title?: string; description?: string | null; metadataPatch?: Record; }): Promise; /** * Upsert (or delete, when groupId is null) the viewer's private placement * for each distinct session tree root. Requires read access per session; * the target group must be owned by the viewer. Never touches shared * session data. */ placeSessionsInGroup(viewer: PlacementViewer, sessionIds: string[], groupId: string | null): Promise; /** * Deprecated alias of placeSessionsInGroup for direct-mode callers that * carry no viewer: places for the target group's owner, or (when * ungrouping) clears each session owner's own placement. */ moveSessionsToGroup(groupId: string | null, sessionIds: string[]): Promise; assignSessionsToGroup(groupId: string, sessionIds: string[]): Promise; completeSessionGroup(groupId: string, options?: { reason?: string; }): Promise; cancelSessionGroup(groupId: string, reason?: string): Promise; deleteSessionGroup(groupId: string, reason?: string): Promise; completeSession(sessionId: string, reason?: string): Promise; /** * Rename a session. Updates the title in CMS. */ renameSession(sessionId: string, title: string): Promise; /** * Cancel a session's orchestration. * Refuses to cancel system sessions. */ cancelSession(sessionId: string, reason?: string): Promise; /** * Delete a session: cancel orchestration + soft-delete from CMS. * Refuses to delete system sessions. */ deleteSession(sessionId: string, reason?: string): Promise; /** * Switch a session's model (and optionally reasoning effort) at the next * turn boundary. Applies via the durable set_model command; never affects an * in-flight turn. Allowed for system sessions too. */ setSessionModel(sessionId: string, model: string, opts?: { reasoningEffort?: ReasoningEffort | null; contextTier?: ContextTier | null; source?: string; }): Promise; /** * Regenerate a session's Copilot transcript in place (epoch rebirth, * proposal §4): archive → distill → flip, applied by the orchestration at * a turn boundary. Enqueue-then-observe — outcomes arrive as * session.regenerate_* events; the cmd handler is the gate authority * (too_young / already_pending / cooldown refusals emit * session.regenerate_refused). */ regenerateSession(sessionId: string, opts?: { handoff?: string; instructions?: string; distillMode?: "llm" | "deterministic"; distillerModel?: string; distillerReasoningEffort?: string; distillerContextTier?: string; model?: string; source?: string; force?: boolean; }): Promise<{ attemptId: string; }>; /** * Stop the session's in-flight LLM turn without completing, cancelling, * or deleting the session (stop-turn plan, * docs/proposals-impl/stop-button-turn-abort-plan.md). * * Enqueues a stop event on the TURN-SCOPED stop queue * (stopTurn.) that the session orchestration races * against the in-flight runTurn activity, then polls the KV * command-response channel for the outcome. Valid for system sessions * too; only group/container rows are not sessions and cannot be stopped. * * Outcomes: * - stopped / stop_forced: the turn was aborted mid-flight; session idle. * - no_active_turn: nothing was running (idempotent no-op). * - timeout: no response before timeoutMs — the stop may still land; * refresh session state rather than assuming failure. */ stopSessionTurn(sessionId: string, opts?: { reason?: string; timeoutMs?: number; }): Promise; restartSystemSession(agentIdOrSessionId: string, options: RestartSystemSessionOptions): Promise; /** * Get a provider-capped page of CMS events for a session, ordered by seq. * Without afterSeq this returns the latest page; with afterSeq it returns the next forward page. * Use getSessionEventsBefore() paging to drain complete history. * eventTypes narrows the page to those event types server-side (e.g. chat * message types for transcript paging); omit for the full stream. */ getSessionEvents(sessionId: string, afterSeq?: number, limit?: number, eventTypes?: string[]): Promise; /** * The canvas data plane's last-value rows for one session (migration * 0047): current doc pointer + latest merged tick per slot. The browser's * snapshot source on subscribe and on seq gaps. Empty when the plane is * absent (older deployment) — callers fall back to canvas_data events. */ /** Public view link status for one canvas — never the token itself. */ getCanvasShareLink(sessionId: string, slot: number): Promise<{ exists: boolean; createdAt?: string; createdBy?: string; }>; /** * Mint-or-rotate the ONE public view token for a canvas. The raw token * is generated here, returned exactly once, and only its sha256 hash is * stored — a rotate makes the previous link dead the moment the row * lands. */ resetCanvasShareLink(sessionId: string, slot: number, createdBy: string): Promise<{ token: string; }>; /** * SERVER-INTERNAL: hash lookup for the token doors (WS subscribe and the * share doc/live routes). Deliberately NOT a wire operation — the raw * resolve must never be callable by clients. */ resolveCanvasShareTokenHash(tokenHash: string): Promise<{ sessionId: string; slot: number; } | null>; removeCanvasShareLink(sessionId: string, slot: number): Promise<{ removed: boolean; }>; getCanvasLive(sessionId: string): Promise; updatedBy: string; updatedAt: string; }>>; getLive(sessionId: string, topics?: string[]): Promise; updatedBy: string; updatedAt: string; }>>; private _canvasKvStore; private _mapCanvasKvErrors; readCanvasKv(sessionId: string, slot: number, principal: CanvasKvPrincipal, query?: { prefix?: string | null; limit?: number | null; after?: string | null; key?: string | null; }): Promise; writeCanvasKv(sessionId: string, slot: number, principal: CanvasKvPrincipal, ops: CanvasKvWriteOp[]): Promise<{ results: CanvasKvWriteResult[]; me: CanvasKvMe; }>; /** Door 2: a link bearer reads; the link door is read-only until phase 4. */ readCanvasKvForLink(sessionId: string, slot: number, query?: { prefix?: string | null; limit?: number | null; after?: string | null; key?: string | null; }): Promise; setCanvasKvAccess(sessionId: string, slot: number, access: "owner" | "readers" | "link"): Promise; /** * Graph-search forensics (enhancedfactstore 07 P4): the `graph.searched` * events a session emitted — what graph queries it ran and how many results * each returned. Powers the agent-tuner graph-debug skill. Reads the latest * page of session events and filters to `graph.searched`. */ getSessionGraphSearches(sessionId: string, limit?: number): Promise>; /** * Get a provider-capped older page before a sequence number, ordered by seq. * Call repeatedly with the oldest returned seq to drain complete history. */ getSessionEventsBefore(sessionId: string, beforeSeq: number, limit?: number, eventTypes?: string[]): Promise; /** * Get bounded event-emitter diagnostics for noisy worker/event buckets. */ getTopEventEmitters(opts: { since: Date; limit?: number; }): Promise; /** * Get current orchestration status for a session. * Returns parsed customStatus + orchestration status. */ getSessionStatus(sessionId: string): Promise; /** * Get per-orchestration runtime stats for a session, when supported by the provider. */ getOrchestrationStats(sessionId: string): Promise; /** * Read the duroxide execution history for a session's current (or specified) execution. * Returns the raw event list from the duroxide orchestration engine. */ getExecutionHistory(sessionId: string, executionId?: number): Promise; /** * Get the latest KV-backed response payload for a session. */ getLatestResponse(sessionId: string): Promise; getSessionMetricSummary(sessionId: string): Promise; private _footprintCache; /** * Control-plane footprint for one session (never wakes it). TTL-cached * (§11 — TTL-only staleness by design); pass bypassCache for tests. */ getSessionFootprint(sessionId: string, opts?: { bypassCache?: boolean; }): Promise; /** Per-session token totals grouped by provider:model:reasoning, with turn count. */ getSessionTokensByModel(sessionId: string): Promise; getSessionTreeStats(sessionId: string): Promise; getFleetStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; getUserStats(opts?: { includeDeleted?: boolean; since?: Date; }): Promise; /** * Read a single user's profile (settings + key-set flag). Returns * `null` when the principal has no row yet — callers should treat * that as the unconfigured state. * * The raw GitHub Copilot key is intentionally NOT returned here. * The Admin Console only needs to know whether one is set so it can * render "configured" / "not configured" affordances; the worker's * per-user token resolver reads the actual key directly from CMS. */ getUserProfile(principal: UserPrincipal): Promise; /** * Replace the user's `profile_settings` JSON document. Creates the * user row lazily so settings can be saved before the principal has * created any sessions. * Saved multi-dashboard MoA settings are retained when a legacy client * omits them or submits an older schema; clear them with a v3 layout. */ setUserProfileSettings(principal: UserPrincipal, settings: Record): Promise; /** * Set or clear the per-user GitHub Copilot key. Pass `null` (or an * all-whitespace string) to remove the override and revert the user * to the worker's env-supplied default token. * * Warm sessions belonging to this user will rebind to the new * CopilotClient on their next `runTurn` (the SessionManager * detects the token change and recycles the warm handle). */ setUserGitHubCopilotKey(principal: UserPrincipal, key: string | null): Promise; /** * Set or clear the SYSTEM user's GitHub Copilot key (admin surface). * Ownerless system sessions resolve this key through the same per-user * path as owned sessions resolve their owner's key. The system user row * is created lazily on first set. `actor` — the admin performing the * change — is recorded in the system user's profile settings for audit * (pass `null` on anonymous/no-auth deployments). */ setSystemGitHubCopilotKey(actor: UserPrincipal | null, key: string | null): Promise; /** * Whether a System GitHub Copilot key is configured, and who last * changed it. Never returns the key itself. */ getSystemGitHubCopilotKeyStatus(): Promise; /** * Get per-session skill usage. Returns one row per (kind, name, plugin) * for either static skills (`skill.invoked`) or learned-knowledge reads * (`learned_skill.read`) the session has performed. */ getSessionSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** * Get skill usage rolled up across the spawn tree rooted at the given * session. Returns per-session breakdown, a flat rolled-up summary, * and total invocation count. */ getSessionTreeSkillUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** * Get fleet-wide skill usage broken down by `agentId` and skill kind. * Pass `since` for time-windowed reads (recommended for the default UI). */ getFleetSkillUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; /** Get per-session retrieval usage for enhanced facts, learned skills, and graph reads. */ getSessionRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get retrieval usage rolled up across the spawn tree rooted at the given session. */ getSessionTreeRetrievalUsage(sessionId: string, opts?: { since?: Date; }): Promise; /** Get fleet-wide retrieval usage broken down by agent and operation. */ getFleetRetrievalUsage(opts?: { since?: Date; includeDeleted?: boolean; }): Promise; /** Get exact graph node-key search/load usage for one session. */ getSessionGraphNodeUsage(sessionId: string, opts?: { since?: Date; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; /** Get exact graph node-key search/load usage across the fleet. */ getFleetGraphNodeUsage(opts?: { since?: Date; includeDeleted?: boolean; limit?: number; nodeKeyLike?: string; kind?: GraphNodeUsageKind; }): Promise; /** Get requested graph edge-search shapes for one session. */ getSessionGraphEdgeSearchUsage(sessionId: string, opts?: { since?: Date; limit?: number; }): Promise; /** * Per-session non-shared facts, bucketed by knowledge namespace * (`skills` | `asks` | `intake` | `config` | `(other)`). Counts and * total `pg_column_size(value)` bytes only — never the values themselves. */ getSessionFactsStats(sessionId: string): Promise<{ sessionId: string; rows: FactsStatsRow[]; totalCount: number; totalBytes: number; }>; /** * Facts stats rolled up across the spawn tree rooted at `sessionId`. * Resolves descendant ids from the CMS first, then aggregates in the * facts schema. Returns per-session breakdown plus a flat roll-up. */ getSessionTreeFactsStats(sessionId: string): Promise<{ rootSessionId: string; sessionIds: string[]; rolledUp: FactsStatsRow[]; totalCount: number; totalBytes: number; }>; /** * Shared (cross-session) facts bucketed by namespace. Used for the * fleet "Facts" card to spot Facts Manager activity at a glance. */ getSharedFactsStats(): Promise<{ rows: FactsStatsRow[]; totalCount: number; totalBytes: number; }>; private _requireFactStore; private _requireEnhancedFactStore; private _requireGraphStore; /** * Access context for API-brokered facts/graph reads — server-derived, * never from the client. Admin callers (and no-auth deployments) read * unrestricted, like an operator with direct DB access. A non-admin * admitted caller is limited to SHARED facts: private/session-scoped facts * of other sessions are off-limits (see _scopeReadForRole, which also drops * a client-supplied sessionId so it cannot target another session). */ private _apiAccessContext; /** Restrict a non-admin facts read to shared visibility; admins read as requested. */ private _scopeReadForRole; /** Capabilities of this deployment's fact/graph stores — the remote form of isEnhancedFactStore/isGraphStore. */ factsCapabilities(): FactsCapabilities & { graph: boolean; }; readFacts(query: ReadFactsQuery, opts?: { admin?: boolean; sessionId?: string; }): Promise<{ count: number; facts: FactRecord[]; }>; storeFact(input: StoreFactInput | StoreFactInput[]): Promise; deleteFact(input: DeleteFactInput): Promise; searchFacts(query: string, opts?: SearchOpts, roleOpts?: { admin?: boolean; }): Promise; similarFacts(scopeKey: string, opts?: SimilarOpts, roleOpts?: { admin?: boolean; }): Promise; searchGraphNodes(q: GraphNodeQuery): Promise; searchGraphEdges(q: GraphEdgeQuery): Promise; graphNeighbourhood(nodeKey: string, depth: number, opts?: GraphNamespaceQuery): Promise; upsertGraphNode(n: GraphNodeInput): Promise; upsertGraphEdge(e: GraphEdgeInput): Promise; deleteGraphNode(nodeKey: string, opts?: GraphNamespaceQuery): Promise; deleteGraphEdge(fromKey: string, toKey: string, predicateKey: string, opts?: GraphNamespaceQuery): Promise; graphStats(opts?: GraphNamespaceQuery): Promise<{ nodeCount: number; edgeCount: number; uncrawledFacts?: number; }>; listGraphNamespaces(q?: GraphNamespaceListQuery): Promise; getGraphNamespace(namespace: string): Promise; upsertGraphNamespace(input: GraphNamespaceInput): Promise; deleteGraphNamespace(namespace: string): Promise<{ deleted: boolean; nodesDeleted: number; edgesDeleted: number; }>; startEmbedder(opts?: { intervalSeconds?: number; batch?: number; }): Promise; stopEmbedder(reason?: string): Promise; forcePurgeFacts(input: ForcePurgeFactsInput): Promise; /** * Soft-deleted facts waiting for graph reconciliation or TTL purge. * Used by operator/tuner inspect tools to spot crawler lag before the TTL * backstop strands graph evidence. */ getFactsTombstoneStats(opts?: { ttlSeconds?: number; }): Promise; /** * Durable embedder status (enhancedfactstore 07 P5): whether the in-DB * batch-embedding loop is running for the configured EnhancedFactStore. * Returns `{ supported: false }` for the base PgFactStore (no embedder) or a * store that was not provisioned for embedding. Powers the agent-tuner * `read_embedder_status` tool and operator dashboards — semantic/hybrid * search only returns semantic hits while this is running. */ getEmbedderStatus(): Promise<{ supported: boolean; running?: boolean; instanceId?: string; status?: string; }>; pruneDeletedSummaries(olderThan: Date): Promise; /** * Get the KV-backed response for a command ID. */ getCommandResponse(sessionId: string, cmdId: string): Promise; /** * Wait for a session's status to change. * Blocks until customStatusVersion advances past `afterVersion`, * or until `timeoutMs` elapses. */ waitForStatusChange(sessionId: string, afterVersion: number, pollIntervalMs?: number, timeoutMs?: number, opts?: { signal?: AbortSignal; }): Promise; /** * Send a prompt message to a session's orchestration. * * @param options.clientMessageIds Optional list of UI-generated message ids * that contributed to this (potentially merged) prompt. The orchestration * preserves these and records them on the durable user.message event so * the client can ack/cancel by exact id rather than text match. * @param options.sender Server-stamped sender identity (security model). * Trusted metadata from the API edge — never client-supplied — recorded * on the durable user.message event and used for multi-writer prompt * attribution. Optional so the payload stays byte-identical for callers * that don't pass it (frozen orchestration replay safety). */ sendMessage(sessionId: string, prompt: string, options?: { clientMessageIds?: string[]; sender?: MessageSender; attachments?: PromptAttachmentRef[]; }): Promise; /** * Defense-in-depth guard for management enqueue paths. * * The management client only enqueues onto the durable messages queue — * it never starts an orchestration. If the orchestration was never * started (or has been removed), the enqueue lands on a queue with no * live instance and duroxide-pg eventually drops it as an orphan, * silently breaking the session. Refuse to enqueue in that case so the * caller sees an actionable error and can retry through the start-aware * path (`PilotSwarmSession.send` → `_ensureOrchestrationAndSend`). */ private _assertOrchestrationLive; /** * Send an answer to a pending question from a session. */ sendAnswer(sessionId: string, answer: string, options?: { sender?: MessageSender; expectedQuestion?: { question: string; iteration?: number; } | null; }): Promise; /** * Cancel one or more queued (durable) pending messages by their * UI-generated client message ids. * * @internal Prefer `PilotSwarmSession.cancelPendingMessage` for in-process * callers and the public client transport surface for remote callers; this * method is the low-level durable enqueue both layers funnel through. */ cancelPendingMessage(sessionId: string, clientMessageIds: string[]): Promise; /** * Send a command to a session's orchestration. */ sendCommand(sessionId: string, command: { cmd: string; id: string; args?: Record; }): Promise; private _requireProviders; /** * The caller as the procedures want them: a numeric user id and a role. * The id lookup never creates a row, so an unknown caller stays `null` * rather than being minted by a read. */ private _providerActor; private _auditProviderMutation; private _providerTypeModels; private _normalizeProviderTuple; private _validatedDefaultTuple; private _firstAvailableTuple; private _resolvedDefault; /** Every shared provider plus the caller's own. Admins also see other people's, unusable. */ listProviders(viewer: ProviderViewer): Promise<{ providers: ProviderRow[]; }>; /** Limits, what has been spent against them, reset times, and the caller's own ceiling. */ getProviderStatus(viewer: ProviderViewer, names?: string[] | null): Promise<{ providers: ProviderStatusRow[]; }>; /** * Everything the provider table draws, in one read. * * Rows come back in render order — shared providers first, then the * caller's own, each immediately followed by its model-scoped limits — so * a table draws the array as it arrives and never asks a second time per * provider. * * Every period reports a used figure whether or not a limit caps it. That * is the fact `getProviderStatus` cannot carry: it lists limits, and a * period with no limit has no limit to list. */ getProviderUsageGrid(viewer: ProviderViewer): Promise<{ rows: UsageGridRow[]; }>; /** Create a shared provider: anyone in the cluster may spend from it. */ /** * Wake every session waiting on this provider. * * The durable timer a paused session sleeps on is only the BACKSTOP. What * should actually release it is the change itself — a limit raised or * removed, an allowance widened, a hold released, a missing name created * again — and without this that promise was never kept: a session paused * on a monthly limit would sleep out the backstop no matter what an * administrator did. * * The wake is a nudge, not a decision. Each woken session re-enters the * gate on its next turn and pauses again if the reason still holds, so a * raise that is still not enough wakes nobody in the end — and waking * after a change that releases no one costs one cheap re-check, because * the gate runs before the model. * * Best-effort throughout. A failed wake leaves the backstop, which is * exactly what it is for. */ private _wakeProvidersPaused; /** * Refuse a provider type this deployment does not describe. * * The database cannot check it: the types live in the model-providers * FILE, which SQL has never read. Without this, a typo created a * provider that listed as an ordinary usable row and could never run a * turn — buildRuntimeRegistry drops an instance whose type it does not * know, silently, so the failure surfaced only as a session that waited * for ever on a name that was right there in the table. */ private _assertKnownProviderType; /** * Does this type authenticate as the worker rather than with a key? * * The store knows a type only by its name, so the decision is made here, * where the type catalog is. An unknown type answers false and is refused * a moment later by `_assertKnownProviderType` — this is not the place * that reports it. */ private _typeUsesWorkloadIdentity; /** * Refuse a key update on a provider that has no key. * * Accepting it would store a real secret in a row nothing ever reads a * secret from, and tell the person their rotation worked. */ private _assertCredentialIsUpdatable; createProvider(viewer: ProviderViewer, input: ProviderCreateInput): Promise<{ name: string; typeId: string; class: ProviderClass; }>; /** Create a provider of the caller's own, on their own credentials. Nobody else sees it. */ createMyProvider(viewer: ProviderViewer, input: ProviderCreateInput): Promise<{ name: string; typeId: string; class: ProviderClass; }>; /** Replace the credential on one of the caller's own personal providers. */ updateMyProviderCredential(viewer: ProviderViewer, input: ProviderCredentialUpdateInput): Promise<{ name: string; typeId: string; class: ProviderClass; }>; /** * Replace the credential on a SHARED provider. Admin-only. * * Exists so an expired cluster key can be rotated in place. Deleting and * re-creating the name would drop the cluster-default flag, the allowance, * any hold, the system-use routing and the usage history — everything the * name carries. */ updateSharedProviderCredential(viewer: ProviderViewer, input: ProviderCredentialUpdateInput): Promise<{ name: string; typeId: string; class: ProviderClass; }>; /** * Remove a shared provider. Its sessions are not moved anywhere: they * wait on a name that no longer resolves, and the count says how many. */ deleteProvider(viewer: ProviderViewer, name: string): Promise<{ name: string; waitingSessions: number; }>; /** * Remove one of the caller's own providers. The same call as * `deleteProvider`: `cms_provider_delete` refuses a name the caller may * not touch, so the two differ only in which door offers them. */ deleteMyProvider(viewer: ProviderViewer, name: string): Promise<{ name: string; waitingSessions: number; }>; clearProviderRoutingDependencies(viewer: ProviderViewer, name: string): Promise<{ clusterDefault: number; systemDefault: number; userDefaults: number; systemOverrides: number; name: string; }>; /** * Save one limit. The same (period, scope) replaces what was there. * `seededTokens` is what this period had already spent when the limit * landed — a limit counts from the current window, it never resets it. */ setProviderLimit(viewer: ProviderViewer, input: ProviderLimitInput): Promise<{ ruleId: string; seededTokens: number; }>; /** Drop one limit. `removed` is false when that (period, scope) had none. */ removeProviderLimit(viewer: ProviderViewer, input: ProviderLimitRef): Promise<{ removed: boolean; }>; /** The share of each of a shared provider's limits that one person may use. 100 is full. */ setProviderAllowance(viewer: ProviderViewer, input: { provider: string; pct: number; }): Promise<{ name: string; allowancePct: number; }>; /** * Pause new turns against a provider, independently of any limit. With * neither an end time nor a release the hold has no end, and only * another call lifts it. */ setProviderHold(viewer: ProviderViewer, input: ProviderHoldInput): Promise<{ name: string; holdUntilUtc: string | null; holdIndefinite: boolean; }>; /** Compatibility read: configured ordinary defaults plus system routing. */ getDefaults(viewer: ProviderViewer): Promise; /** @deprecated Use setModelDefault({ scope: "cluster", ... }). */ setClusterDefault(viewer: ProviderViewer, tuple: DefaultTuple): Promise; /** @deprecated Use setModelDefault({ scope: "user", ... }). */ setMyDefault(viewer: ProviderViewer, tuple: DefaultTuple | null): Promise; setModelDefault(viewer: ProviderViewer, input: ModelDefaultInput): Promise; setProviderSystemUse(viewer: ProviderViewer, input: { provider: string; enabled: boolean; }): Promise<{ provider: string; systemUseEnabled: boolean; }>; getLegacyProviderMigrationStatus(viewer: ProviderViewer): Promise; adoptLegacySystemGitHubCopilotKey(viewer: ProviderViewer, input: { name: string; }): Promise<{ provider: { name: string; typeId: string; class: ProviderClass; ownerUserId: number | null; }; status: import("./provider-store.js").LegacyProviderMigrationStatus; }>; getModelDefaults(viewer: ProviderViewer): Promise<{ userSession: { configured: DefaultTuple; effective: ResolvedModelDefault | null; error: string | null; }; clusterSession: { configured: DefaultTuple; effective: ResolvedModelDefault | null; error: string | null; }; system: { configured: DefaultTuple; effective: ResolvedModelDefault | null; error: string | null; updatedBy: number | null; updatedAt: string | null; }; systemOverrides: SystemAgentModelOverride[]; }>; setSystemModelDefault(viewer: ProviderViewer, input: SystemModelDefaultInput): Promise<{ configured: DefaultTuple; effective: ResolvedModelDefault | null; restart: null | { requested: true; disposition: "complete" | "terminate" | "hard_delete"; affected: number; restarted: number; failures: Array<{ agentId: string; error: string; }>; }; }>; setSystemSessionModel(viewer: ProviderViewer, input: { agentId: string; provider: string; model: string; reasoningEffort?: ReasoningEffort | null; contextTier?: ContextTier | null; }): Promise; clearSystemSessionModel(viewer: ProviderViewer, agentId: string): Promise<{ agentId: string; cleared: boolean; }>; /** * Where the tokens went: totals, the daily chart, and one breakdown, over * the same filters. Three reads because they group differently, one * answer because a report that shows a total and a chart from different * filters is a report nobody can act on. * * The breakdown asks for one row more than it returns, so `truncated` * reports the cut rather than guessing at it. */ getProviderUsage(viewer: ProviderViewer, query?: ProviderUsageQuery): Promise; /** * The cluster summary: totals for today / the week / the month, a per-day * series and the per-model pivot, over every provider (or the ones named). * Read from the ledger, so system sessions are in it — unlike the meters * the Providers tab reads, which count people's turns only. */ getProviderUsageSummary(viewer: ProviderViewer, query?: ProviderUsageSummaryQuery): Promise; /** * The agent pivot from the same ledger: tokens, turns and models per * agent (with '(none)' for unbound sessions) plus a day×agent series. * Same viewer scoping as getProviderUsageSummary. */ getProviderUsageAgents(viewer: ProviderViewer, query?: ProviderUsageSummaryQuery): Promise>; /** Sessions waiting on a limit right now, with what is holding each one. */ listPausedSessions(viewer: ProviderViewer): Promise<{ sessions: PausedSessionRow[]; }>; private _agentPackagePrincipal; private _agentPackageSelector; private _mapAgentPackageErrors; private _requireAgentPackageArtifacts; listAgentPackages(owner: AgentPrincipal | null, isAdmin: boolean): Promise; getAgentPackage(name: string, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise; listAgentWorkerState(): Promise; listWorkers(): Promise; private _requireFeatures; listFeatureFlags(viewer: FeatureViewer): Promise; getClusterFeatureFlags(viewer: FeatureViewer): Promise; getMyFeatureFlags(viewer: FeatureViewer): Promise; getUserFeatureFlags(viewer: FeatureViewer, userId: number): Promise; setClusterFeatureFlag(viewer: FeatureViewer, input: FeatureMutation): Promise; resetClusterFeatureFlag(viewer: FeatureViewer, input: FeatureMutation): Promise; setMyFeatureFlag(viewer: FeatureViewer, input: FeatureMutation): Promise; unsetMyFeatureFlag(viewer: FeatureViewer, input: FeatureMutation): Promise; setUserFeatureFlag(viewer: FeatureViewer, userId: number, input: FeatureMutation): Promise; unsetUserFeatureFlag(viewer: FeatureViewer, userId: number, input: FeatureMutation): Promise; listFeatureFlagChanges(viewer: FeatureViewer, limit?: number): Promise; listFeatureFlagUsers(viewer: FeatureViewer, query?: string): Promise<(import("./feature-flags.js").FeatureOwner & { userId: number; email: string | null; displayName: string | null; })[]>; setAgentPackageScope(name: string, scope: AgentPackageScope, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ ok: true; }>; setAgentPackageEnabled(name: string, enabled: boolean, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ ok: true; }>; grantAgentPackageEditor(name: string, grantee: { provider: string; subject: string; }, owner: AgentPrincipal | null, isAdmin: boolean): Promise<{ ok: true; }>; revokeAgentPackageEditor(name: string, grantee: { provider: string; subject: string; }, owner: AgentPrincipal | null, isAdmin: boolean): Promise<{ ok: true; }>; listAgentPackageEditors(name: string): Promise; pinAgentPackageVersion(name: string, semver: string, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ ok: true; }>; deleteAgentPackage(name: string, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ ok: true; }>; publishAgentPackageDirectory(dir: string, scope: AgentPackageScope, owner: AgentPrincipal | null, isAdmin: boolean, opts?: { createdBy?: string | null; reservedAgentNames?: string[]; reservedMcpServerNames?: string[]; }): Promise; uploadAgentPackage(files: Array<{ path: string; contentBase64: string; }>, scope: AgentPackageScope, owner: AgentPrincipal | null, isAdmin: boolean, opts?: { createdBy?: string | null; reservedAgentNames?: string[]; reservedMcpServerNames?: string[]; }): Promise; private _agentPackageVersion; getAgentPackageTree(name: string, semver: string | null, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ name: string; semver: string; sha256: string; dirs: string[]; files: { path: string; size: number; }[]; }>; getAgentPackageFile(name: string, semver: string | null, filePath: string, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ name: string; semver: string; path: string; size: number; truncated: boolean; binary: boolean; encoding: string; content: string; }>; downloadAgentPackage(name: string, semver: string | null, owner: AgentPrincipal | null, isAdmin: boolean, selector?: AgentPackageSelector | null): Promise<{ name: string; semver: string; sha256: string; filename: string; contentType: string; body: Uint8Array; }>; republishAgentPackageVersion(name: string, semver: string | null, targetScope: AgentPackageScope, owner: AgentPrincipal | null, isAdmin: boolean, opts?: { createdBy?: string | null; selector?: AgentPackageSelector | null; }): Promise<{ name: string; semver: string; sha256: string; sizeBytes: number; artifactFilename: string; warnings: import("./agent-package-format.js").AgentPackageValidation["warnings"]; status: "published" | "noop"; packageId: string; versionId: string; }>; /** * List all available models across all configured providers. */ listModels(): ModelSummary[]; listRuntimeModels(viewer: ProviderViewer): Promise; /** * Get models grouped by provider for display. */ getModelsByProvider(): Array<{ catalogKind: "provider_type"; providerId: string; type: string; models: ModelSummary[]; }>; /** * Get the default model name, if configured. */ getDefaultModel(): string | undefined; /** * Normalize a model reference to qualified `provider:model` format. */ normalizeModel(ref?: string): string | undefined; /** * Return whether the model's provider has a process/env credential * available. For GitHub providers this intentionally does not include * per-user CMS keys; callers that create user-owned sessions should OR * this with the relevant profile's githubCopilotKeySet flag. */ getModelCredentialStatus(ref?: string): ModelCredentialStatus; /** * Dump a session and all its descendants to Markdown. */ dumpSession(sessionId: string): Promise; private _ensureStarted; } /** * Construct a management client with an honest return type. * * Web options yield the WebPilotSwarmManagementClient itself — including its * generated `ops` surface (one wire-shaped method per protocol-table * operation) — rather than a cast to the direct class. Direct options yield * the direct client. * * `new PilotSwarmManagementClient(options)` remains supported and behaves * identically at runtime; this factory exists so web-mode callers get the * type that tells the truth. */ export declare function createManagementClient(options: PilotSwarmWebOptions): WebPilotSwarmManagementClient; export declare function createManagementClient(options: PilotSwarmManagementClientOptions): PilotSwarmManagementClient; //# sourceMappingURL=management-client.d.ts.map