1135 lines · 40.7 KB · TypeScript
RawDownload
import { z } from 'zod' import {  defineApplicationCommandContract,  validationCodec,  type RuntimeCodec} from './application-command-contract'import type { ArtifactFile } from './artifacts'import type { ExecutionFileEvidenceSummary } from './execution-file-evidence'import type { NotebookRuntimeBindings } from './notebook-runtime'import type { OptionalProjectIdScope, ProjectIdScope } from './project-scope' export const NOTEBOOKS_DIR = 'notebooks'export const NOTEBOOK_RUN_FILE = 'run.json'// Execution authorization canonicalizes omitted control/shell deadlines to the same defaults used// by the MCP schema and process owner. These are runtime constants, not persisted schema fields.export const NOTEBOOK_REPL_DEFAULT_TIMEOUT_MS = 30 * 60 * 1_000 + 15_000export const NOTEBOOK_SHELL_DEFAULT_TIMEOUT_MS = 120_000 export type ShellRuntimeBinding =  | Readonly<{      kind: 'powershell'      version: '5.1'    }>  | Readonly<{      kind: 'native-posix'      shell: string    }>  | Readonly<{      kind: 'wsl2-bash'      profileId: string      distro: string      user: string    }> // Identifies whether a run was initiated by the agent or by the user terminal.export type NotebookRunSource = 'agent' | 'user' // Exact app-local dispatch methods corresponding to the three approval-gated Notebook MCP tools.export type NotebookExecutionRpcMethod = 'execute' | 'executeControl' | 'executeShell' export type RequestNotebookNetworkAccessRequest = NotebookSessionRequest & {  hostname: string  reason: string  runtime?: 'python' | 'r' | 'repl' | 'bash'  command?: string} export type RequestNotebookNetworkAccessResult = Readonly<{  hostname: string  status: 'alreadyAllowed' | 'allowedOnce' | 'alwaysAllowed' | 'denied' | 'blocked' | 'unavailable'  decisionSource?:    'missing-command-context' | 'aborted' | 'user-decision' | 'approval-surface-unavailable'  message?: string}> // Distinguishes regular notebook cells from terminal submissions in the same history.export type NotebookRunInputKind = 'cell' | 'terminal' // Mirrors the lifecycle of one persisted execution record in run.json. 'interrupted' = the process// died (crash / force-quit) while the run was in flight — reconciled from a stale 'running' on the// next startup. 'cancelled' = the run was deliberately aborted (e.g. a force-stop disable).export type NotebookRunStatus =  'queued' | 'running' | 'completed' | 'failed' | 'timeout' | 'interrupted' | 'cancelled' export type NotebookBackgroundRunReceipt = Readonly<{  runId: string  executionType: 'python-notebook-run' | 'r-notebook-run' | 'javascript-repl' | 'shell-command'  projectId: string  sessionId: string  status: NotebookRunStatus  acceptedAt: number  lifecycleScope: 'app-process'  submissionIdentity: string  shellConcurrency?: Readonly<{ limit: number; slot?: number }>}> export type NotebookBackgroundRunResult = Readonly<{  receipt: NotebookBackgroundRunReceipt  run: NotebookRunSummary  // Present on Agent queries. Terminal results report whether this query suppressed the fallback  // or automatic delivery was already committed; non-terminal snapshots remain `pending`.  followUpDelivery?: 'pending' | 'suppressed' | 'committed'}> export type NotebookBackgroundRunErrorDetail = Readonly<{  code: string  stage: 'pre-admission' | 'query' | 'cancel'  retryable: boolean  hint: string  runId?: string  submissionIdentity?: string}> export class NotebookBackgroundRunError extends Error {  readonly name = 'NotebookBackgroundRunError'   constructor(    readonly detail: NotebookBackgroundRunErrorDetail,    message: string  ) {    super(message)  }} export type NotebookBackgroundRunLookupRequest = NotebookSessionRequest & {  runId?: string  submissionIdentity?: string  // The authenticated local RPC bridge overwrites this with its capability-bound Agent Frame.  // Renderer Session management supplies the frame recorded on the selected Run.  agentFrameId?: string} export type NotebookRunProvenanceContext = {  rootFrameId: string  agentFrameId: string  messageBranchId: string  runtimeSegmentId: string  promptMessageId: string  originMessageId?: string} // Languages a notebook kernel can run in this phase; each runs as a persistent exec-loop process// (no ipykernel/IRkernel involved). Renderer IPC must parse this at runtime — TypeScript unions// do not reject a compromised or stale client.export const NOTEBOOK_LANGUAGES = ['python', 'r'] as constexport type NotebookLanguage = (typeof NOTEBOOK_LANGUAGES)[number]export const notebookLanguageSchema = z.enum(NOTEBOOK_LANGUAGES) export const parseNotebookLanguage = (value: unknown): NotebookLanguage => {  const parsed = notebookLanguageSchema.safeParse(value)  if (!parsed.success) {    throw new Error('Notebook language must be python or r.')  }  return parsed.data} export const parseOptionalNotebookLanguage = (value: unknown): NotebookLanguage | undefined => {  if (value == null) return undefined  return parseNotebookLanguage(value)} // JSON RPC encodes omitted optional slots as null. Drop trailing nulls so cancel() and// provision/repair without an operation id stay valid, while a null required language still fails.const omitTrailingNull = (value: unknown): unknown => {  if (!Array.isArray(value)) return value  const args = [...value]  while (args.length > 0 && args[args.length - 1] === null) args.pop()  return args} const parsedArgs = <Args extends readonly unknown[]>(schema: z.ZodType<Args>): RuntimeCodec<Args> =>  Object.freeze({    parse: (value: unknown): Args => schema.parse(omitTrailingNull(value))  }) const languageAndOptionalOperationId = parsedArgs(  z.union([z.tuple([notebookLanguageSchema]), z.tuple([notebookLanguageSchema, z.string()])])) const repairArgs = parsedArgs(  z.union([    z.tuple([notebookLanguageSchema, z.string().min(1)]),    z.tuple([notebookLanguageSchema, z.string().min(1), z.string()])  ])) export const notebookEnvironmentApplicationCommandContracts = Object.freeze({  provision: defineApplicationCommandContract(    languageAndOptionalOperationId,    validationCodec(z.undefined())  ),  repair: defineApplicationCommandContract(repairArgs, validationCodec(z.undefined())),  cancel: defineApplicationCommandContract(    parsedArgs(z.union([z.tuple([]), z.tuple([notebookLanguageSchema])])),    validationCodec(z.undefined())  )}) // Identifies which kernel produced a run: python/r are analysis cells, repl/bash are// control-plane/shell.export type NotebookKernelKind = 'python' | 'r' | 'repl' | 'bash'export type NotebookPersistentKernelKind = Exclude<NotebookKernelKind, 'bash'> export type NotebookPackageSource =  | {      type: 'github'      repository: string      ref?: string      commit?: string      subdirectory?: string    }  | {      type: 'bioconductor'      version?: string    } export type NotebookEnvironmentPackage = {  name: string  version?: string  versionStatus: 'known' | 'unavailable'  ecosystem: 'python' | 'r' | 'native' | 'unknown'  evidenceSources: Array<    | 'python-importlib-metadata'    | 'python-kernel-modules'    | 'r-installed-packages'    | 'r-session-info'  >  loadedState?: 'attached' | 'loaded' | 'installed-only' | 'unknown'  libraryRank?: number  libraryScope?: 'environment' | 'user' | 'system' | 'unknown'  builtForRuntime?: string  priority?: 'base' | 'recommended' | 'other'  source?: NotebookPackageSource} export type NotebookPackageInstaller =  | 'conda'  | 'pip'  | 'uv'  | 'poetry'  | 'r-install-packages'  | 'renv'  | 'pak'  | 'biocmanager'  | 'github'  | 'unknown' export type NotebookPackageInstallerAttempt = {  groupOrdinal: number  installer: NotebookPackageInstaller  packages: string[]  status: 'succeeded' | 'failed' | 'skipped'  mutationRisk: 'none' | 'possible' | 'confirmed' | 'unknown'  reason?:    | 'package-not-found'    | 'solver-failed'    | 'installer-unavailable'    | 'permission'    | 'network'    | 'authentication'    | 'tls-policy'    | 'validation'    | 'cancelled'    | 'process-unconfirmed'    | 'recovery-blocked'    | 'unknown'} export type NotebookInventoryRefreshAttempt = {  attempt: number  trigger: 'terminal' | 'recovery'  timestamp: string  result: 'published' | 'unchanged' | 'failed'  error?: string} export type NotebookEnvironmentPackageChange = {  name: string  ecosystem: NotebookEnvironmentPackage['ecosystem']  relationship: 'requested' | 'dependency' | 'unattributed'  change: 'installed' | 'updated' | 'removed' | 'unchanged' | 'observed'  beforeVersion?: string  afterVersion?: string  libraryRank?: number  libraryScope?: NotebookEnvironmentPackage['libraryScope']  source?: NotebookPackageSource} export type NotebookEnvironmentOperation = {  operationId: string  timestamp: string  operation: 'create' | 'install' | 'uninstall' | 'update'  packages: string[]  result: 'success' | 'failure'  attempts: NotebookPackageInstallerAttempt[]  fallbackUsed: boolean  inventoryRefresh: 'published' | 'unchanged' | 'failed'  inventoryRefreshAttempts: NotebookInventoryRefreshAttempt[]  packageChanges?: NotebookEnvironmentPackageChange[]} export type NotebookEnvironmentOperationLogTruncation = {  omittedCount: number  earliestRetainedAt?: string} export const isNotebookEnvironmentOperationLogTruncation = (  value: unknown): value is NotebookEnvironmentOperationLogTruncation => {  if (typeof value !== 'object' || value === null || Array.isArray(value)) return false  const candidate = value as Record<string, unknown>  return (    Number.isInteger(candidate.omittedCount) &&    Number(candidate.omittedCount) > 0 &&    (candidate.earliestRetainedAt === undefined || typeof candidate.earliestRetainedAt === 'string')  )} export type NotebookEnvironmentManifest = {  executionContext?: import('./notebook-execution-context').NotebookExecutionContext  schemaVersion: 1  captureKind: 'completed-run'  capturedAt: string  installedInventory: {    capturedAt: string    source: 'full-scan' | 'cache-reused'    validation: 'full-scan' | 'best-effort'  }  kernelKind: NotebookLanguage  environmentName: string  runtimeSource: 'managed' | 'external'  runtimeVersion?: string  platform?: string  architecture?: string  inventorySources: Array<'kernel-native' | 'interpreter-native' | 'operation-log'>  packages: NotebookEnvironmentPackage[]  operationLog?: NotebookEnvironmentOperation[]  operationLogTruncation?: NotebookEnvironmentOperationLogTruncation  complete: boolean  captureStatus: 'complete' | 'partial'  warnings?: string[]} export type NotebookRunEnvironmentCapture =  | {      state: 'available' | 'partial'      manifestChecksum: string      warnings?: string[]    }  | {      state: 'unavailable'      reason:        | 'environment-not-supported'        | 'environment-capture-failed'        | 'environment-manifest-publication-failed'        | 'legacy-environment-reference-unavailable'    } export type NotebookEnvironmentLockPartialReason =  | 'external-interpreter-required'  | 'environment-manifest-partial'  | 'non-conda-package-detected'  | 'non-conda-installer-detected'  | 'native-lock-file-best-effort'  | 'native-lock-file-rejected' export type NotebookEnvironmentLockDiagnostic = {  reason:    | 'package-lock-missing'    | 'package-version-unresolved'    | 'package-version-mismatch'    | 'package-not-captured'    | 'source-unpinned'    | 'source-mismatch'    | 'project-selection-unresolved'  packageName?: string  observedVersion?: string  lockedVersion?: string} export type NotebookEnvironmentLockFile = {  path: string  checksum: string  content: string} export type NotebookEnvironmentLockComponent =  | {      ecosystem: 'conda'      format: 'conda-explicit-md5'      resolution: 'locked'      explicitLock: string      packages: string[]    }  | {      ecosystem: 'python'      format: 'uv-lock' | 'poetry-lock' | 'pip-requirements'      resolution: 'locked' | 'best-effort'      files: NotebookEnvironmentLockFile[]    }  | {      ecosystem: 'r'      format: 'renv-lock' | 'pak-lock'      resolution: 'locked'      files: NotebookEnvironmentLockFile[]    } export type NotebookEnvironmentLock = {  schemaVersion: 1 | 2  // v2 native-only locks restore packages conditionally; they do not provision this runtime.  externalRuntime?: { version: string; installerVersion: string }  format: 'environment-lock-bundle'  kernelKind: NotebookLanguage  environmentName: string  platform?: string  architecture?: string  components: NotebookEnvironmentLockComponent[]  untrackedPackages?: string[]  // Native distributions observed as unused by this run; retained in the full inventory.  omittedPackages?: string[]  nonCondaInstallers?: NotebookPackageInstaller[]} export type NotebookRunEnvironmentLockCapture =  | {      state: 'available' | 'partial'      format: NotebookEnvironmentLock['format']      lockChecksum: string      partialReasons?: NotebookEnvironmentLockPartialReason[]      diagnostics?: NotebookEnvironmentLockDiagnostic[]    }  | {      state: 'unavailable'      reason:        | 'environment-not-managed'        | 'conda-prefix-unavailable'        | 'micromamba-unavailable'        | 'environment-lock-capture-failed'        | 'environment-lock-invalid'        | 'environment-lock-publication-failed'    } export type NotebookLiveEnvironmentOverlay = {  executionContext?: import('./notebook-execution-context').NotebookExecutionContext  runtimeVersion?: string  packages: NotebookEnvironmentPackage[]  warnings?: string[]} export type NotebookInputAssociation = 'turn-attached' | 'resolver-accessed'export type NotebookInputAccessEvidence = 'resolver' | 'file-evidence' // Path-independent immutable input identity captured from the trusted main-process registry. The// storage key is persisted only in run.json/evidence; summaries returned to agents and renderers omit// it and resolve previews through main-process IPC.export type NotebookRunInputFile = {  inputFileVersionId: string  sourceKind: 'upload-version' | 'artifact-version'  sourceFileId: string  sourceVersionNumber?: number  sourceCreatedAt?: string  sourceProjectId: string  sourceSessionId: string  filename: string  contentType?: string  sizeBytes: number  checksum: string  storageKey: string  association: NotebookInputAssociation  accessEvidence?: NotebookInputAccessEvidence} export type NotebookInputFileSummary = Omit<NotebookRunInputFile, 'storageKey'> // Transient model-facing projection of one exact Notebook input Version. The relative path is// materialized under the current Notebook data directory and is never persisted in run history.export type NotebookPromptInput = Pick<  NotebookRunInputFile,  'sourceKind' | 'inputFileVersionId' | 'filename'> & {  notebookPath: string} export type NotebookInputPreviewIdentity = {  projectId: string  sourceKind: NotebookRunInputFile['sourceKind']  sourceFileId: string  inputFileVersionId: string} const NOTEBOOK_INPUT_PREVIEW_PREFIX = 'notebook-input:' export const createNotebookInputPreviewKey = (identity: NotebookInputPreviewIdentity): string =>  `${NOTEBOOK_INPUT_PREVIEW_PREFIX}${encodeURIComponent(    JSON.stringify([      identity.projectId,      identity.sourceKind,      identity.sourceFileId,      identity.inputFileVersionId    ])  )}` export const parseNotebookInputPreviewKey = (key: string): NotebookInputPreviewIdentity => {  if (!key.startsWith(NOTEBOOK_INPUT_PREVIEW_PREFIX)) {    throw new Error('Invalid Notebook input preview key.')  }  const parsed = JSON.parse(    decodeURIComponent(key.slice(NOTEBOOK_INPUT_PREVIEW_PREFIX.length))  ) as unknown  if (    !Array.isArray(parsed) ||    parsed.length !== 4 ||    parsed.some((value) => typeof value !== 'string') ||    (parsed[1] !== 'upload-version' && parsed[1] !== 'artifact-version')  ) {    throw new Error('Invalid Notebook input preview key.')  }  return {    projectId: parsed[0] as string,

Lines 1–500 of 1135.