@byok-sdk/client 0.7.0 → 0.8.0-beta.0

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.
@@ -372,8 +372,11 @@ export interface AgentContentReadConfig {
372
372
  export interface AgentReliableEgressInput {
373
373
  agentRef: AgentRef;
374
374
  sessionRef: string;
375
+ /** Exact runtime identity from the durable Agent-home handoff. */
376
+ runtimeId: string;
377
+ /** Exact task identity from the same durable Agent-home handoff. */
378
+ taskId: string;
375
379
  payload: unknown;
376
- taskId?: string;
377
380
  eventId?: string;
378
381
  }
379
382
  /**
@@ -1,4 +1,4 @@
1
- import { type AgentEgressPolicy, type Envelope, type PermissionPolicy, type RuntimeId, type TaskOfferPayload, type TaskOfferForAgentPayload, type TaskOfferForAgentWithEgressPayload, type TaskOfferWithToolsetsPayload } from '@byok-sdk/protocol';
1
+ import { type AgentEgressPolicy, type Envelope, type PermissionPolicy, type RuntimeId, type TaskOfferPayload, type TaskOfferForAgentPayload, type TaskOfferForAgentWithEgressPayload, type TaskOfferForAgentWithEgressFreshPayload, type TaskOfferWithToolsetsPayload } from '@byok-sdk/protocol';
2
2
  import { type McpToolsetConfig, type RuntimeAdapter } from '../types';
3
3
  import { AgentHomeManager, type AgentRef } from '../agent-home';
4
4
  import { AgentSessionHandoffStore, type AgentTerminalCause } from './agent-session-handoff-store';
@@ -366,7 +366,7 @@ export type AdmissionGuardDecision = {
366
366
  readonly reason: string;
367
367
  readonly retryable: boolean;
368
368
  };
369
- type AcceptedOfferPayload = TaskOfferPayload | TaskOfferWithToolsetsPayload | TaskOfferForAgentPayload | TaskOfferForAgentWithEgressPayload;
369
+ type AcceptedOfferPayload = TaskOfferPayload | TaskOfferWithToolsetsPayload | TaskOfferForAgentPayload | TaskOfferForAgentWithEgressPayload | TaskOfferForAgentWithEgressFreshPayload;
370
370
  /**
371
371
  * Per-connection task orchestration: offer -> (decline | prepare -> seal ->
372
372
  * claim -> prepared operation -> started) -> seq-ordered progress batches -> complete/fail/
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomUUID, createHash, sign, createPrivateKey, generateKeyPairSync, randomBytes, timingSafeEqual, createHmac } from 'crypto';
2
2
  import { promises, mkdirSync, existsSync, renameSync, writeFileSync, chmodSync, statSync, readdirSync, linkSync, fstatSync, lstatSync, unlinkSync, constants, readFileSync, realpathSync } from 'fs';
3
3
  import path, { join, isAbsolute } from 'path';
4
- import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AgentRefSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, partitionAgentEvents, BYOK_SKILL_PACKS_PATH, byokSkillPackFilePath, BYOK_RECORDS_PATH, byokRecordPath, TASK_TRANSITIONS, AgentEgressPolicySchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentContentReceiptPayloadSchema, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AGENT_EGRESS_POLICY_CAPABILITY, parseMessage, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS, TERMINAL_INFERENCE_USAGE_MAX_TOKENS, RESULT_DOCUMENT_MAX_BYTES, decodeEnvelope, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendResponseSchema, UnknownMessageTypeError, BYOK_WS_PATH } from '@byok-sdk/protocol';
4
+ import { AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, AgentRefSchema, BYOK_PAIR_PATH, PairResponseSchema, BYOK_CHALLENGE_PATH, BYOK_TOKEN_PATH, byokBlobUrlPath, BYOK_BLOBS_PATH, byokBlobFinalizePath, partitionAgentEvents, BYOK_SKILL_PACKS_PATH, byokSkillPackFilePath, BYOK_RECORDS_PATH, byokRecordPath, TASK_TRANSITIONS, AgentEgressPolicySchema, CONFIGURED_TOOLSETS_MAX_ITEMS, ToolsetIdSchema, AgentContentReceiptPayloadSchema, encodeEnvelope, PROTOCOL_VERSION, createEnvelope, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_FRESH_SESSION_CAPABILITY, parseMessage, checkResultDocument, MAX_MESSAGES_PER_BATCH, BYOK_CAPABILITIES_PATH, BYOK_PRESENCE_PATH, RuntimeIdSchema, TERMINAL_INFERENCE_USAGE_MAX_DURATION_MS, TERMINAL_INFERENCE_USAGE_MAX_TOKENS, RESULT_DOCUMENT_MAX_BYTES, decodeEnvelope, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendResponseSchema, UnknownMessageTypeError, BYOK_WS_PATH } from '@byok-sdk/protocol';
5
5
  import { execFile, spawn } from 'child_process';
6
6
  import os6 from 'os';
7
7
  import { parseDeviceAssertionEnvelope, tenantId, DeviceProofProtectedClaimsSchema, deviceProofSigningInput, DEVICE_PROOF_SCHEMA_ID, SKILL_PACK_MAX_BYTES, hasCapability, parseSkillPackManifest, checkSkillPackManifest, skillPackContentHashInput, checkSkillPackFileContent, SKILL_PACK_ENTRY_PATH, checkSkillPackEntry, isSkillPackPathSafe, DEVICE_PROOF_HEADER, contentHash as contentHash$1, TRUTH_RECORD_KINDS, nonceSigningBytes, DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, DEVICE_ASSERTION_DEFAULT_TTL_MS, DEVICE_ASSERTION_MAX_TTL_MS, CONTENT_HASH_PATTERN, isTenantId, CapabilityDeclarationSchema, DeviceAssertionClaimsSchema, deviceAssertionSigningInput, DEVICE_ASSERTION_SCHEMA_ID } from '@byok-sdk/core';
@@ -9827,6 +9827,11 @@ function offeredAgentRef(payload) {
9827
9827
  if (!Object.prototype.hasOwnProperty.call(payload, "agentRef")) return void 0;
9828
9828
  return validateAgentRef(payload.agentRef);
9829
9829
  }
9830
+ function offeredSessionRef(payload) {
9831
+ if (!Object.prototype.hasOwnProperty.call(payload, "sessionRef")) return void 0;
9832
+ const value = payload.sessionRef;
9833
+ return typeof value === "string" ? value : void 0;
9834
+ }
9830
9835
  function errorMessage4(err) {
9831
9836
  return err instanceof Error ? err.message : String(err);
9832
9837
  }
@@ -10195,6 +10200,9 @@ var TaskRunner = class {
10195
10200
  case "task.offer_for_agent_with_egress":
10196
10201
  await this.handleOffer(envelope.task_id, envelope.payload, true);
10197
10202
  return;
10203
+ case "task.offer_for_agent_with_egress_fresh":
10204
+ await this.handleOffer(envelope.task_id, envelope.payload, true);
10205
+ return;
10198
10206
  case "task.cancel":
10199
10207
  await this.handleCancel(envelope.task_id, envelope.payload.reason);
10200
10208
  return;
@@ -10236,6 +10244,7 @@ var TaskRunner = class {
10236
10244
  const decline = (reason, retryable) => {
10237
10245
  this.decline(taskId, reason, retryable, agentRef);
10238
10246
  };
10247
+ const sessionRef = offeredSessionRef(payload);
10239
10248
  if ("egressPolicy" in payload) {
10240
10249
  if (this.deps.agentEgressPolicy === void 0 || !sameEgressPolicy(this.deps.agentEgressPolicy, payload.egressPolicy)) {
10241
10250
  decline("Agent egress offer policy is not exactly enabled by this daemon", false);
@@ -10337,11 +10346,11 @@ var TaskRunner = class {
10337
10346
  let plainWorkspaceNeedsResolve = false;
10338
10347
  if (agentBinding !== void 0) {
10339
10348
  workspaceDir = agentBinding.lease.cwd;
10340
- if (payload.sessionRef !== void 0) {
10349
+ if (sessionRef !== void 0) {
10341
10350
  try {
10342
10351
  await this.deps.agentSessionHandoffs.requireMatch({
10343
10352
  agentRef: agentBinding.resolution.agentRef,
10344
- sessionRef: payload.sessionRef,
10353
+ sessionRef,
10345
10354
  runtimeId: pick.descriptor.id,
10346
10355
  cwd: workspaceDir
10347
10356
  });
@@ -10363,15 +10372,15 @@ var TaskRunner = class {
10363
10372
  return;
10364
10373
  }
10365
10374
  } else if (this.deps.gitWorkspaceManager && this.deps.gitWorkspaceStore) {
10366
- known = payload.sessionRef ? await this.deps.sessionWorkspaces.get(payload.sessionRef) : void 0;
10375
+ known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
10367
10376
  const gitManager = this.deps.gitWorkspaceManager;
10368
10377
  const gitStore = this.deps.gitWorkspaceStore;
10369
- if (payload.sessionRef) {
10370
- const ledger = await gitStore.findBySessionAnyPhase(payload.sessionRef).catch(() => void 0);
10378
+ if (sessionRef) {
10379
+ const ledger = await gitStore.findBySessionAnyPhase(sessionRef).catch(() => void 0);
10371
10380
  const sameProtocolTask = ledger?.taskId === taskId;
10372
10381
  const interruptedOldTask = ledger?.phase === "interrupted" && sameProtocolTask;
10373
10382
  const activeDifferentTask = ledger !== void 0 && ledger.taskId !== taskId && (ledger.phase === "preparing" || ledger.phase === "active");
10374
- if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== payload.sessionRef || path.resolve(ledger.workspaceDir) !== path.resolve(known.workspaceDir) || interruptedOldTask || activeDifferentTask) {
10383
+ if (!known || known.workspaceKind !== "git" || !known.gitWorkspaceId || !ledger || ledger.workspaceId !== known.gitWorkspaceId || ledger.sessionRef !== sessionRef || path.resolve(ledger.workspaceDir) !== path.resolve(known.workspaceDir) || interruptedOldTask || activeDifferentTask) {
10375
10384
  decline("session is incompatible with Git workspace mode", true);
10376
10385
  return;
10377
10386
  }
@@ -10390,13 +10399,13 @@ var TaskRunner = class {
10390
10399
  gitWorkspaceId = randomUUID();
10391
10400
  }
10392
10401
  try {
10393
- gitLease = await gitManager.acquireLease(workspaceDir, payload.sessionRef);
10402
+ gitLease = await gitManager.acquireLease(workspaceDir, sessionRef);
10394
10403
  } catch {
10395
10404
  decline("workspace is busy or unavailable", true);
10396
10405
  return;
10397
10406
  }
10398
10407
  } else if (!this.deps.gitWorkspaceManager && !this.deps.gitWorkspaceStore) {
10399
- known = payload.sessionRef ? await this.deps.sessionWorkspaces.get(payload.sessionRef) : void 0;
10408
+ known = sessionRef ? await this.deps.sessionWorkspaces.get(sessionRef) : void 0;
10400
10409
  workspaceDir = known?.workspaceDir ?? path.join(this.deps.workspaceRoot, taskId);
10401
10410
  plainWorkspaceNeedsResolve = true;
10402
10411
  } else {
@@ -10415,7 +10424,7 @@ var TaskRunner = class {
10415
10424
  policy: decision.policy,
10416
10425
  requiredToolsetIds: requiredToolsets ?? [],
10417
10426
  ...offered.dispatchSelection === void 0 ? {} : { dispatchSelection: offered.dispatchSelection },
10418
- ...payload.sessionRef === void 0 || known === void 0 && agentBinding === void 0 ? {} : { sessionRef: payload.sessionRef },
10427
+ ...sessionRef === void 0 || known === void 0 && agentBinding === void 0 ? {} : { sessionRef },
10419
10428
  ...agentBinding === void 0 ? {} : {
10420
10429
  agentRef: agentBinding.resolution.agentRef,
10421
10430
  cwd: agentBinding.lease.cwd,
@@ -10518,7 +10527,7 @@ var TaskRunner = class {
10518
10527
  workspaceId,
10519
10528
  taskId,
10520
10529
  workspaceDir,
10521
- sessionRef: payload.sessionRef,
10530
+ sessionRef,
10522
10531
  phase,
10523
10532
  baseline: gitBaseline ?? observation.head,
10524
10533
  current: observation.head,
@@ -13485,7 +13494,13 @@ function computeCapabilities(adapters, agentHomeConfigured = false, agentEgressC
13485
13494
  flags.push("toolset-selection");
13486
13495
  }
13487
13496
  if (agentHomeConfigured) flags.push("agent-home-contract");
13488
- if (agentEgressConfigured) flags.push(AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY);
13497
+ if (agentEgressConfigured) {
13498
+ flags.push(
13499
+ AGENT_EGRESS_POLICY_CAPABILITY,
13500
+ AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
13501
+ AGENT_EGRESS_FRESH_SESSION_CAPABILITY
13502
+ );
13503
+ }
13489
13504
  if (contentReadPolicies !== void 0) {
13490
13505
  for (const surface of Object.keys(AGENT_CONTENT_READ_CAPABILITIES)) {
13491
13506
  const policy = contentReadPolicies[surface];
@@ -14690,7 +14705,7 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14690
14705
  connection.send(sanitized.envelope);
14691
14706
  }
14692
14707
  async function publishReliableAgentEgress(input) {
14693
- if (config.agentEgress === void 0 || agentHomeManager === void 0) {
14708
+ if (config.agentEgress === void 0 || agentHomeManager === void 0 || agentSessionHandoffs === void 0) {
14694
14709
  throw new Error("Agent reliable egress is not configured");
14695
14710
  }
14696
14711
  if (tenantRebinding) {
@@ -14699,12 +14714,21 @@ function buildDaemonWithAdapters(config, adapters, overrides = {}, assertionProb
14699
14714
  const binding = await agentHomeManager.acquire(input.agentRef);
14700
14715
  try {
14701
14716
  await agentHomeManager.initialize(binding);
14717
+ const handoff = await agentSessionHandoffs.requireMatch({
14718
+ agentRef: binding.resolution.agentRef,
14719
+ sessionRef: input.sessionRef,
14720
+ runtimeId: input.runtimeId,
14721
+ cwd: binding.resolution.canonicalHome
14722
+ });
14723
+ if (handoff.taskId !== input.taskId) {
14724
+ throw new Error("Agent reliable egress taskId does not match the durable session handoff");
14725
+ }
14702
14726
  const appended = await agentEgress.appendReliable({
14703
14727
  homeDir: binding.resolution.canonicalHome,
14704
14728
  agentRef: binding.resolution.agentRef,
14705
14729
  sessionRef: input.sessionRef,
14706
14730
  payload: input.payload,
14707
- ...input.taskId === void 0 ? {} : { taskId: input.taskId },
14731
+ taskId: input.taskId,
14708
14732
  ...input.eventId === void 0 ? {} : { eventId: input.eventId }
14709
14733
  });
14710
14734
  if (appended.ok) dispatchReliableRecord(appended.record);