{"_id":"@cadia-platforms/keyedit","_rev":"2-78f6ae700ba8d6dab3edfcd024e0215e","name":"@cadia-platforms/keyedit","dist-tags":{"latest":"0.1.4"},"versions":{"0.1.3":{"name":"@cadia-platforms/keyedit","version":"0.1.3","keywords":["cadia","keyedit","ai","observability","model-evaluation"],"author":{"name":"Cadia Platforms Inc."},"license":"UNLICENSED","_id":"@cadia-platforms/keyedit@0.1.3","maintainers":[{"name":"cadia-platforms","email":"kevinsingh1220@gmail.com"}],"dist":{"shasum":"d690514f3ec1aee02756cc4eb4c0f6eec8ead829","tarball":"https://registry.npmjs.org/@cadia-platforms/keyedit/-/keyedit-0.1.3.tgz","fileCount":14,"integrity":"sha512-4H5es/ZZFfJgDnX04fCHbmI7TMwkAtCtj3Gg1+S3ClIRQMQGRq642xV6OSNnJo8T0u/1MqUN8j6zF1541Y1VSg==","signatures":[{"sig":"MEYCIQCBtSyCGHuenHJXCuygxBEnG6lVkam51Z3NWgDQedtRGAIhALnFJ0DaWVoc400sDTEJYFkVboTJhDhQ0S4xI/o6hM3T","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67727},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"fd83fb01ea181682ffd5f17d7e6cbc9ce313bcd5","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"cadia-platforms","email":"kevinsingh1220@gmail.com"},"_npmVersion":"10.9.0","description":"Server-side SDK for Cadia KeyEdit behavior ingestion and governed customer-runner execution.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.5.4","@types/node":"^20.12.12"},"_npmOperationalInternal":{"tmp":"tmp/keyedit_0.1.3_1784862669842_0.5318306753947857","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@cadia-platforms/keyedit","version":"0.1.4","description":"Server-side SDK for KeyEdit runtime protection, behavior ingestion, and governed customer-runner execution.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"sideEffects":false,"engines":{"node":">=18"},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run","prepublishOnly":"npm run build && npm test"},"keywords":["cadia","keyedit","ai","runtime-protection","observability","model-evaluation"],"author":{"name":"Cadia Platforms Inc."},"license":"UNLICENSED","publishConfig":{"access":"public"},"devDependencies":{"@types/node":"^20.12.12","typescript":"^5.5.4","vitest":"^1.6.0"},"_id":"@cadia-platforms/keyedit@0.1.4","gitHead":"ad40ffa99b80a0da6de0eb26caace6dc97d55a10","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-s8VkuvK1n6seGF9TcK4rRkIx/8z9qEovkXkPvmuwC580JPS3bQmznQkcShi6qIwewXBY4FN89oi0ehWUpWT+MQ==","shasum":"5ae23455a5a735974cce37736b8b837ad2589c7e","tarball":"https://registry.npmjs.org/@cadia-platforms/keyedit/-/keyedit-0.1.4.tgz","fileCount":14,"unpackedSize":94247,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCOWU49s/ZdwXHYr0RZjjJJYoj8NPzx2Ag1rG92i/YMvwIhAInnREyzwJL/bzUC3YTfepU/SYoVpm5mtW66lW1BakPi"}]},"_npmUser":{"name":"cadia-platforms","email":"kevinsingh1220@gmail.com"},"directories":{},"maintainers":[{"name":"cadia-platforms","email":"kevinsingh1220@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/keyedit_0.1.4_1785380500854_0.9529458831127604"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-24T03:11:09.677Z","modified":"2026-07-30T03:01:41.204Z","0.1.3":"2026-07-24T03:11:10.019Z","0.1.4":"2026-07-30T03:01:41.051Z"},"author":{"name":"Cadia Platforms Inc."},"license":"UNLICENSED","keywords":["cadia","keyedit","ai","runtime-protection","observability","model-evaluation"],"description":"Server-side SDK for KeyEdit runtime protection, behavior ingestion, and governed customer-runner execution.","maintainers":[{"name":"cadia-platforms","email":"kevinsingh1220@gmail.com"}],"readme":"# Cadia KeyEdit\n\nServer-side SDK for connecting an AI application to Cadia KeyEdit.\n\nKeyEdit is Cadia's governed production-improvement system. It validates candidate responses and proposed actions before release, safely intervenes under the customer's policy, turns verified failures into durable improvements at the correct authorized layer, and records every intervention and edit with evidence and rollback history.\n\nKeyEdit does not require customers to hand over their model. The SDK runs beside the customer's existing AI endpoint and sends model behavior, evidence, tool outcomes, and runner-scoped training work to Cadia.\n\n## Install\n\n```bash\nnpm install @cadia-platforms/keyedit\n```\n\nRequires Node.js 18 or newer.\n\nExisting `@cadia-platforms/offedit`, `@cadia-platforms/connect-sdk`,\n`@cadia-platforms/prix-sdk`, and `@cadia-platforms/florell-sdk` integrations can\nmigrate without changing Cadia routes, key prefixes, or environment variables.\n`createOffEditClient`, `createConnectClient`, `createPrixClient`, and\n`createFlorellClient` remain available as deprecated aliases.\n\n## What the SDK sends\n\n- Model inputs and outputs that your server chooses to report.\n- Candidate responses and proposed tool calls submitted for validation before release.\n- Tool calls, tool failures, latency, confidence, and metadata.\n- Approved evidence and source-truth snippets.\n- Delivery outcomes for protected responses and proposed actions.\n- Runner-scoped, authorized production work and authenticated execution receipts.\n- Training-pack, replay, verification, and adapter status for tunable models.\n\nThe SDK is server-side only. Do not use KeyEdit keys in browser code.\n\n## Protect responses before release\n\nCall `protectText` after the model generates a candidate response and before your\napplication sends that response to the end user. KeyEdit returns a deterministic\ndecision: `pass`, `correct`, `regenerate`, `abstain`, `block`, `escalate`, or\n`observe`.\n\n```ts\nimport { createKeyEditClient } from \"@cadia-platforms/keyedit\";\n\nconst keyedit = createKeyEditClient({\n  apiBase: process.env.CADIA_API_BASE,\n  workspaceId: process.env.CADIA_WORKSPACE_ID!,\n  ingestKey: process.env.CADIA_CONNECT_INGEST_KEY!,\n});\n\nconst candidate = await callYourModel(userMessage);\nconst protectedResponse = await keyedit.protectText({\n  idempotencyKey: crypto.randomUUID(),\n  userInput: userMessage,\n  candidateResponse: candidate.text,\n  modelProvider: candidate.provider,\n  modelId: candidate.model,\n  sourceTruthIds: approvedSourceTruthIds,\n  metadata: {\n    route: \"support-chat\",\n  },\n});\n\nif (protectedResponse.requiresRegeneration) {\n  // Regenerate with the returned directive, then submit the new candidate\n  // through protectText before release.\n  const regenerated = await regenerateYourModel(\n    protectedResponse.preflight.regenerationDirective\n  );\n}\n\nif (protectedResponse.releasedContent !== null) {\n  await sendToEndUser(protectedResponse.releasedContent);\n}\n\nif (protectedResponse.preflight.interventionId) {\n  await keyedit.reportRuntimeOutcome({\n    idempotencyKey: crypto.randomUUID(),\n    interventionId: protectedResponse.preflight.interventionId,\n    deliveryStatus:\n      protectedResponse.releasedContent !== null\n        ? \"delivered\"\n        : \"not_delivered\",\n    delivered: protectedResponse.releasedContent !== null,\n    finalContent: protectedResponse.releasedContent ?? undefined,\n  });\n}\n```\n\nNever release the original candidate as a fallback after KeyEdit returns\n`correct`, `regenerate`, `abstain`, `block`, or `escalate`. `protectText` returns\nonly content that the runtime policy allows the application to release.\n\nUse `protectToolCall` before executing a model-proposed action:\n\n```ts\nconst protectedAction = await keyedit.protectToolCall({\n  idempotencyKey: crypto.randomUUID(),\n  userInput: userMessage,\n  proposedToolCall: {\n    name: \"refundOrder\",\n    operation: \"orders.refund\",\n    arguments: { orderId, amount },\n  },\n  riskHints: {\n    level: \"high\",\n    domain: \"payments\",\n    highImpactAction: true,\n  },\n});\n\nif (protectedAction.releasedToolCall) {\n  // Customer application code, not KeyEdit preflight, executes the action.\n  await executeApprovedToolCall(protectedAction.releasedToolCall);\n}\n```\n\nKeyEdit validates proposed tool calls but never executes them during preflight.\n\nFor streaming responses, send ordered chunks through\n`runtimePreflightChunk`. KeyEdit buffers content according to the workspace\npolicy and returns only content that is ready for release:\n\n```ts\nconst checked = await keyedit.runtimePreflightChunk({\n  idempotencyKey: `stream-${streamId}-${sequenceNumber}`,\n  userInput: userMessage,\n  streamId,\n  chunk,\n  sequenceNumber,\n  streamingState: isFinalChunk ? \"final\" : \"partial\",\n});\n\nif (checked.data.releaseAllowed && checked.data.finalContent) {\n  await writeStreamChunk(checked.data.finalContent);\n}\n```\n\nRuntime interventions are temporary release decisions. Verified failures can\nqueue durable remediation, but permanent changes to a customer system still\nrequire evidence, Change Authority, and a registered healthy production target.\n\n## Basic usage\n\n```ts\nimport { createKeyEditClient } from \"@cadia-platforms/keyedit\";\n\nconst keyedit = createKeyEditClient({\n  apiBase: process.env.CADIA_API_BASE,\n  workspaceId: process.env.CADIA_WORKSPACE_ID!,\n  ingestKey: process.env.CADIA_CONNECT_INGEST_KEY!,\n  runnerKey: process.env.CADIA_CONNECT_RUNNER_KEY,\n  defaultProvider: \"openai\",\n  defaultModel: \"gpt-4.1-mini\",\n});\n\nconst modelResponse = await callYourModel(userMessage);\n\nawait keyedit.signal({\n  input: userMessage,\n  output: modelResponse.text,\n  latencyMs: modelResponse.latencyMs,\n  tools: modelResponse.tools,\n  metadata: {\n    route: \"support-chat\",\n  },\n});\n```\n\n## Keys\n\n- `CADIA_CONNECT_INGEST_KEY`: validates candidates before release, reports runtime outcomes, and sends model events and evidence.\n- `CADIA_CONNECT_RUNNER_KEY`: leases authorized production work, submits receipts and measured verification, and runs customer-controlled tuning work.\n- `CADIA_CONNECT_ADMIN_KEY`: control-plane administration. Use only in trusted admin services, never in ordinary inference code.\n\n## Environment\n\n```bash\nCADIA_API_BASE=https://api.cadiaai.com\nCADIA_WORKSPACE_ID=your_workspace_id\nCADIA_CONNECT_INGEST_KEY=cdi_...\nCADIA_CONNECT_RUNNER_KEY=cdr_...\n```\n\n## Direct events\n\n```ts\nawait cadia.signal({\n  idempotencyKey: \"chat-run-123\",\n  input: \"Does Starter include SSO?\",\n  output: \"Yes, Starter includes SSO.\",\n  provider: \"groq\",\n  model: \"llama-3.3-70b-versatile\",\n  expected: \"SSO is Enterprise-only.\",\n  score: 0.4,\n});\n```\n\nKeyEdit uses reported behavior, evidence, source truth, tool results, user corrections, and evaluator results to decide the correct improvement layer: memory, retrieval/context, policy/behavior, tool workflow, evaluator logic, training pack, adapter tuning, or no change.\n\n## Batch events\n\nLarge batches are chunked automatically.\n\n```ts\nawait cadia.signalBatch({\n  idempotencyKey: \"batch-2026-06-16\",\n  events: modelRuns.map((run) => ({\n    input: run.input,\n    output: run.output,\n    latencyMs: run.latencyMs,\n    tools: run.tools,\n  })),\n});\n```\n\n## Evidence\n\n```ts\nawait cadia.evidence({\n  title: \"Billing plan source truth\",\n  content: \"SSO is only available on Enterprise plans.\",\n  source: \"approved docs\",\n  sourceUrl: \"https://docs.example.com/plans\",\n});\n```\n\n## Register production destinations\n\nKeyEdit needs an explicit destination for every layer it may change. Register targets from a trusted admin service. Do not embed the admin key in inference code or a customer-facing browser.\n\n```ts\nconst admin = createKeyEditClient({\n  workspaceId: process.env.CADIA_WORKSPACE_ID!,\n  adminKey: process.env.CADIA_CONNECT_ADMIN_KEY!,\n});\n\nconst target = await admin.createTarget({\n  name: \"Production support retrieval\",\n  improvementLayer: \"retrieval_context\",\n  connectorType: \"customer_runner\",\n  environment: \"production\",\n  capabilities: [\"upsert\", \"version_restore\"],\n  allowedOperations: [\"retrieval.upsert\", \"retrieval.restore\"],\n  configuration: {\n    provider: \"pinecone\",\n    index: \"support\",\n    namespace: \"production\",\n  },\n  currentVersion: \"retrieval-v1\",\n});\n```\n\nTarget configuration may contain identifiers and routing metadata, but never plaintext credentials. Use `secretRef: \"env:YOUR_SECRET_NAME\"` when the customer's runner needs a secret from its own environment.\n\nThen define the workspace authority policy. This is the permission boundary KeyEdit evaluates before any work can be leased:\n\n```ts\nawait admin.setExecutionAuthority({\n  autonomyMode: \"guarded\",\n  allowedTargetIds: [(target.data as { id: string }).id],\n  allowedLayers: [\"retrieval_context\"],\n  allowedOperations: [\"retrieval.upsert\", \"retrieval.restore\"],\n  riskCeiling: \"medium\",\n  minimumConfidence: 0.85,\n  requireSourceTruth: true,\n  protectedDomains: [\"billing\", \"legal\"],\n  highRiskPreauthorized: false,\n  requireReplay: true,\n  incidentRetentionDays: 30,\n  redactionFields: [\"user.email\", \"user.phone\"],\n});\n```\n\n## Customer runner\n\nThe runner lives in the customer's environment and uses only the runner key. KeyEdit authorizes and describes the work; customer code applies the versioned change to the real destination and reports what happened.\n\n```ts\nconst runner = createKeyEditClient({\n  workspaceId: process.env.CADIA_WORKSPACE_ID!,\n  runnerKey: process.env.CADIA_CONNECT_RUNNER_KEY!,\n});\n\nawait runner.heartbeatTarget({\n  id: process.env.CADIA_TARGET_ID!,\n  healthy: true,\n  currentVersion: await readCurrentRetrievalVersion(),\n});\n\nconst leased = await runner.leaseExecutions({\n  targetIds: [process.env.CADIA_TARGET_ID!],\n  maxItems: 1,\n  leaseSeconds: 60,\n});\n\nfor (const work of (leased.data as { items: Array<any> }).items) {\n  const startedAt = new Date().toISOString();\n  const applied = await applyAuthorizedChangeToCustomerAsset(work);\n\n  await runner.submitExecutionReceipt({\n    executionId: work.execution.id,\n    leaseToken: work.leaseToken,\n    receipt: {\n      receiptId: crypto.randomUUID(),\n      executionId: work.execution.id,\n      targetId: work.target.id,\n      idempotencyKey: work.changeSpec.idempotencyKey,\n      previousVersion: applied.previousVersion,\n      resultingVersion: applied.resultingVersion,\n      appliedOperation: work.changeSpec.operation,\n      appliedDiffHash: applied.diffHash,\n      startedAt,\n      finishedAt: new Date().toISOString(),\n      status: \"succeeded\",\n      externalAssetRefs: applied.assetRefs,\n      rollbackHandle: applied.rollbackHandle,\n    },\n  });\n\n  const measurement = await runCustomerCanary(work);\n  await runner.submitExecutionVerification({\n    executionId: work.execution.id,\n    submission: measurement,\n  });\n}\n```\n\nThe receipt records the actual external asset and version changed. Verification must contain measured results from replay, holdout, shadow, canary, business KPI, customer evaluator, or recurrence monitoring. Projected demo lift is not a substitute for production measurement.\n\n## Incident replay\n\nCustomer runners can reproduce captured incidents and submit baseline and candidate results:\n\n```ts\nconst replayWork = await runner.leaseReplays({\n  targetIds: [process.env.CADIA_TARGET_ID!],\n  leaseSeconds: 60,\n});\n\nfor (const replay of (replayWork.data as { work: Array<any> }).work) {\n  const result = await reproduceIncident(replay);\n  await runner.submitReplayResult({\n    replayId: replay.replay.id,\n    leaseToken: replay.leaseToken,\n    phase: \"candidate\",\n    output: result.output,\n    measuredScore: result.score,\n    sampleCount: result.sampleCount,\n    evaluatorVersion: result.evaluatorVersion,\n    exactReproduction: result.exact,\n    uncertainty: result.uncertainty,\n    reproducibilityLimitations: result.limitations,\n    regressionResults: result.regressions,\n  });\n}\n```\n\n## Training work\n\nTraining work also uses the runner key and remains separate from ordinary inference events.\n\n```ts\nawait runner.runnerPing();\n\nconst packs = await runner.listTrainingPacks({ limit: 10 });\nconst latestAdapter = await runner.latestAdapterRun();\n\nawait runner.createAdapterRun({\n  status: \"succeeded\",\n  trainingPackId: \"pack-123\",\n  baseModel: \"llama-3.1-8b\",\n  adapter: {\n    id: \"adapter-run-123\",\n  },\n  metrics: {\n    evalLift: 0.08,\n  },\n});\n```\n\nFor closed hosted models, KeyEdit cannot modify weights. It can still improve behavior through memory, retrieval, policies, tool workflows, evaluators, and monitored context updates. For tunable open or customer-controlled models, the runner can execute approved adapter/LoRA work in the customer's environment.\n\n## Retries and redaction\n\nThe SDK retries transient network, rate-limit, and server errors by default. You can tune retry behavior and redact payloads before they are sent:\n\n```ts\nconst cadia = createKeyEditClient({\n  workspaceId: process.env.CADIA_WORKSPACE_ID!,\n  ingestKey: process.env.CADIA_CONNECT_INGEST_KEY!,\n  retry: {\n    retries: 2,\n    baseDelayMs: 250,\n    maxDelayMs: 2500,\n  },\n  redact(payload) {\n    return redactCustomerSecrets(payload);\n  },\n});\n```\n\n## Error handling\n\n```ts\nimport { KeyEditApiError } from \"@cadia-platforms/keyedit\";\n\ntry {\n  await cadia.health();\n} catch (error) {\n  if (error instanceof KeyEditApiError) {\n    console.error(error.status, error.data, error.requestId);\n  }\n}\n```\n\n## Publishing checklist\n\nBefore publishing:\n\n1. Run `npm ci`.\n2. Run `npm test`.\n3. Run `npm run build`.\n4. Run `npm pack --dry-run`.\n5. Publish when ready with the Cadia npm organization.\n","readmeFilename":"README.md"}