@byok-sdk/server 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.
package/dist/hub.d.ts CHANGED
@@ -3,7 +3,7 @@ import { type Envelope, type RuntimeId, type RuntimeInfo, type TaskState, type T
3
3
  import type { DeviceRegistry } from './auth';
4
4
  import { RateLimiter } from './rate-limiter';
5
5
  import type { TaskStore } from './task-store';
6
- import type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, DispatchInput, HubStats, MachineInfo, TaskHandle, TaskSnapshot } from './types';
6
+ import type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, DispatchInput, FreshAgentEgressDispatchInput, HubStats, MachineInfo, TaskHandle, TaskSnapshot } from './types';
7
7
  /**
8
8
  * The connection hub: tracks each device's live transport (WS or long-poll —
9
9
  * never both at once, see {@link takeOverAsLongPoll}), routes `dispatch()`'d
@@ -749,6 +749,8 @@ export declare class ConnectionHub {
749
749
  /** Reap one lease-expired task through the exact same TaskStore/canTransition path — and terminal-event emission — as any other `task.fail` (see {@link applyOrFail}). */
750
750
  private reapTask;
751
751
  dispatch(input: DispatchInput): Promise<TaskHandle>;
752
+ dispatchFreshAgentEgress(input: FreshAgentEgressDispatchInput): Promise<TaskHandle>;
753
+ private dispatchInternal;
752
754
  /** Capability-gated control-plane read request; no request enters the outbox on omission. */
753
755
  requestAgentContentRead(input: AgentContentReadRequest): Promise<void>;
754
756
  private buildTaskHandle;
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import type { Server as HttpServer } from 'node:http';
2
2
  import type { Hono } from 'hono';
3
3
  import { type TenantId } from './auth';
4
4
  import { type PairingCodeClaims, type PairingCodeInfo } from './pairing';
5
- import type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, CreateByokServerOptions, DispatchInput, HubStats, MachineInfo, TaskHandle, TaskSnapshot } from './types';
6
- export type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, CreateByokServerOptions, DispatchInput, HubStats, MachineInfo, ServerTaskEvent, TaskHandle, TaskResult, TaskSnapshot, } from './types';
5
+ import type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, CreateByokServerOptions, DispatchInput, FreshAgentEgressDispatchInput, HubStats, MachineInfo, TaskHandle, TaskSnapshot } from './types';
6
+ export type { ByokServerEvent, AgentContentReadRequest, AgentEgressReceipt, CreateByokServerOptions, DispatchInput, FreshAgentEgressDispatchInput, HubStats, MachineInfo, ServerTaskEvent, TaskHandle, TaskResult, TaskSnapshot, } from './types';
7
7
  export type { CreateTaskInput, TaskRecord, TaskStore } from './task-store';
8
8
  export { IllegalTaskTransitionError, InMemoryTaskStore } from './task-store';
9
9
  /**
@@ -60,6 +60,8 @@ export interface ByokServer {
60
60
  createPairingCode(claims: PairingCodeClaims): PairingCodeInfo;
61
61
  };
62
62
  dispatch(input: DispatchInput): Promise<TaskHandle>;
63
+ /** Dispatch a fresh Agent execution whose runtime will mint its session after start. */
64
+ dispatchFreshAgentEgress(input: FreshAgentEgressDispatchInput): Promise<TaskHandle>;
63
65
  /** Enqueue one capability-gated, exact-identity content-read request. */
64
66
  requestAgentContentRead(input: AgentContentReadRequest): Promise<void>;
65
67
  tasks: {
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { mkdir, writeFile, readFile } from 'fs/promises';
5
5
  import { mkdtempSync, mkdirSync, existsSync, chmodSync } from 'fs';
6
6
  import { tmpdir } from 'os';
7
7
  import path, { dirname } from 'path';
8
- import { CAPABILITY_FLAGS, byokBlobContentPath, canTransition, PROTOCOL_VERSION, encodeEnvelope, DAEMON_TO_SERVER_TYPES, AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AgentRefSchema, AgentEgressPolicySchema, DispatchSelectionSchema, RequiredToolsetsSchema, AgentContentReadPayloadSchema, createEnvelope, TASK_STATES, BYOK_PAIR_PATH, PairRequestSchema, PairResponseSchema, BYOK_CHALLENGE_PATH, ChallengeRequestSchema, BYOK_TOKEN_PATH, TokenRequestSchema, BYOK_BLOBS_PATH, CreateBlobRequestSchema, BYOK_BLOB_FINALIZE_ROUTE, BYOK_BLOB_URL_ROUTE, BYOK_BLOB_CONTENT_ROUTE, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendRequestSchema, AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, PairResponseTenantIdSchema, decodeEnvelope, BYOK_WS_PATH } from '@byok-sdk/protocol';
8
+ import { CAPABILITY_FLAGS, byokBlobContentPath, canTransition, PROTOCOL_VERSION, encodeEnvelope, DAEMON_TO_SERVER_TYPES, AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY, AgentRefSchema, AgentEgressPolicySchema, DispatchSelectionSchema, RequiredToolsetsSchema, AGENT_EGRESS_FRESH_SESSION_CAPABILITY, AgentContentReadPayloadSchema, createEnvelope, TASK_STATES, BYOK_PAIR_PATH, PairRequestSchema, PairResponseSchema, BYOK_CHALLENGE_PATH, ChallengeRequestSchema, BYOK_TOKEN_PATH, TokenRequestSchema, BYOK_BLOBS_PATH, CreateBlobRequestSchema, BYOK_BLOB_FINALIZE_ROUTE, BYOK_BLOB_URL_ROUTE, BYOK_BLOB_CONTENT_ROUTE, BYOK_EVENTS_PATH, BYOK_MESSAGES_PATH, MessagesSendRequestSchema, AGENT_CONTENT_ARTIFACT_READ_CAPABILITY, AGENT_CONTENT_TRANSCRIPT_READ_CAPABILITY, AGENT_CONTENT_WORKSPACE_READ_CAPABILITY, PairResponseTenantIdSchema, decodeEnvelope, BYOK_WS_PATH } from '@byok-sdk/protocol';
9
9
  import { Hono } from 'hono';
10
10
  import { WebSocketServer } from 'ws';
11
11
  import { createRequire } from 'module';
@@ -1857,6 +1857,25 @@ var ConnectionHub = class {
1857
1857
  // dispatch() and the TaskHandle it returns
1858
1858
  // ---------------------------------------------------------------------
1859
1859
  async dispatch(input) {
1860
+ if (input.egressPolicy !== void 0 && input.sessionRef === void 0) {
1861
+ throw new Error("Agent egress resume dispatch requires an exact sessionRef; use dispatchFreshAgentEgress for fresh execution");
1862
+ }
1863
+ return this.dispatchInternal(input, false);
1864
+ }
1865
+ async dispatchFreshAgentEgress(input) {
1866
+ if (Object.prototype.hasOwnProperty.call(input, "sessionRef")) {
1867
+ throw new Error("fresh Agent egress dispatch must not carry sessionRef");
1868
+ }
1869
+ if (typeof input.deviceId !== "string" || input.deviceId.length === 0) {
1870
+ throw new Error("fresh Agent egress dispatch requires an explicit deviceId");
1871
+ }
1872
+ if (input.agentRef === void 0 || input.egressPolicy === void 0) {
1873
+ throw new Error("fresh Agent egress dispatch requires exact AgentRef and egress policy");
1874
+ }
1875
+ return this.dispatchInternal(input, true);
1876
+ }
1877
+ async dispatchInternal(input, freshAgentEgress) {
1878
+ const sessionRef = "sessionRef" in input ? input.sessionRef : void 0;
1860
1879
  const agentRef = input.agentRef === void 0 ? void 0 : AgentRefSchema.parse(input.agentRef);
1861
1880
  const egressPolicy = input.egressPolicy === void 0 ? void 0 : AgentEgressPolicySchema.parse(input.egressPolicy);
1862
1881
  const dispatchSelection = input.dispatchSelection === void 0 ? void 0 : DispatchSelectionSchema.parse(input.dispatchSelection);
@@ -1868,9 +1887,6 @@ var ConnectionHub = class {
1868
1887
  if (egressPolicy !== void 0 && agentRef === void 0) {
1869
1888
  throw new Error("Agent egress policy requires an explicit AgentRef; legacy task dispatch cannot consume it");
1870
1889
  }
1871
- if (egressPolicy !== void 0 && input.sessionRef === void 0) {
1872
- throw new Error("Agent egress policy requires an exact sessionRef");
1873
- }
1874
1890
  if (!deviceId || !this.connections.get(deviceId)?.connected) {
1875
1891
  throw new Error(
1876
1892
  deviceId ? `device ${deviceId} is not connected` : "no connected device to dispatch to (M0 does not queue tasks until a device connects)"
@@ -1881,9 +1897,14 @@ var ConnectionHub = class {
1881
1897
  `device ${deviceId} did not advertise agent-home-contract capability; refusing Agent-bound dispatch`
1882
1898
  );
1883
1899
  }
1884
- if (egressPolicy !== void 0 && !this.hasDeviceCapabilities(deviceId, [AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY])) {
1900
+ const requiredEgressCapabilities = freshAgentEgress ? [
1901
+ AGENT_EGRESS_POLICY_CAPABILITY,
1902
+ AGENT_EGRESS_RELIABLE_ACK_CAPABILITY,
1903
+ AGENT_EGRESS_FRESH_SESSION_CAPABILITY
1904
+ ] : [AGENT_EGRESS_POLICY_CAPABILITY, AGENT_EGRESS_RELIABLE_ACK_CAPABILITY];
1905
+ if (egressPolicy !== void 0 && !this.hasDeviceCapabilities(deviceId, requiredEgressCapabilities)) {
1885
1906
  throw new Error(
1886
- `device ${deviceId} did not advertise Agent egress policy and reliable acknowledgement capabilities; refusing before enqueue`
1907
+ freshAgentEgress ? `device ${deviceId} did not advertise Agent egress policy, reliable acknowledgement, and fresh-session capabilities; refusing before enqueue` : `device ${deviceId} did not advertise Agent egress policy and reliable acknowledgement capabilities; refusing before enqueue`
1887
1908
  );
1888
1909
  }
1889
1910
  if (dispatchSelection !== void 0 && !(this.getDeviceCapabilities(deviceId)?.includes("dispatch-selection") ?? false)) {
@@ -1926,7 +1947,7 @@ var ConnectionHub = class {
1926
1947
  policy,
1927
1948
  requiredToolsets,
1928
1949
  deviceId,
1929
- sessionRef: input.sessionRef,
1950
+ sessionRef,
1930
1951
  agentRef
1931
1952
  });
1932
1953
  const queue = new AsyncEventQueue();
@@ -1942,36 +1963,52 @@ var ConnectionHub = class {
1942
1963
  policy,
1943
1964
  runtime,
1944
1965
  dispatchSelection,
1945
- sessionRef: input.sessionRef
1966
+ sessionRef
1946
1967
  };
1947
- if (agentRef !== void 0 && egressPolicy !== void 0) {
1968
+ if (agentRef !== void 0 && egressPolicy !== void 0 && freshAgentEgress) {
1969
+ const freshOffer = {
1970
+ instruction: input.instruction,
1971
+ policy,
1972
+ runtime,
1973
+ dispatchSelection,
1974
+ agentRef,
1975
+ egressPolicy,
1976
+ ...requiredToolsets === void 0 ? {} : { requiredToolsets }
1977
+ };
1978
+ this.sendToDevice(
1979
+ deviceId,
1980
+ "task.offer_for_agent_with_egress_fresh",
1981
+ freshOffer,
1982
+ { taskId }
1983
+ );
1984
+ } else if (agentRef !== void 0 && egressPolicy !== void 0) {
1948
1985
  this.sendToDevice(
1949
1986
  deviceId,
1950
1987
  "task.offer_for_agent_with_egress",
1951
1988
  {
1952
1989
  ...commonOffer,
1953
- sessionRef: input.sessionRef,
1990
+ sessionRef,
1954
1991
  agentRef,
1955
1992
  egressPolicy,
1956
1993
  ...requiredToolsets === void 0 ? {} : { requiredToolsets }
1957
1994
  },
1958
- { taskId, sessionRef: input.sessionRef }
1995
+ { taskId, sessionRef }
1959
1996
  );
1960
1997
  } else if (agentRef !== void 0) {
1961
1998
  this.sendToDevice(
1962
1999
  deviceId,
1963
2000
  "task.offer_for_agent",
1964
2001
  { ...commonOffer, agentRef, ...requiredToolsets === void 0 ? {} : { requiredToolsets } },
1965
- { taskId, sessionRef: input.sessionRef }
2002
+ { taskId, sessionRef }
1966
2003
  );
1967
2004
  } else if (requiredToolsets === void 0) {
1968
- this.sendToDevice(deviceId, "task.offer", commonOffer, { taskId, sessionRef: input.sessionRef });
2005
+ this.sendToDevice(deviceId, "task.offer", commonOffer, { taskId, sessionRef });
1969
2006
  } else {
1970
2007
  this.sendToDevice(
1971
2008
  deviceId,
1972
2009
  "task.offer_with_toolsets",
1973
2010
  { ...commonOffer, requiredToolsets },
1974
- { taskId, sessionRef: input.sessionRef }
2011
+ { taskId, sessionRef }
1975
2012
  );
1976
2013
  }
1977
2014
  return this.buildTaskHandle(taskId);
@@ -3035,6 +3072,7 @@ function createByokServer(opts) {
3035
3072
  createPairingCode: (claims) => pairing.createPairingCode(claims)
3036
3073
  },
3037
3074
  dispatch: (input) => hub.dispatch(input),
3075
+ dispatchFreshAgentEgress: (input) => hub.dispatchFreshAgentEgress(input),
3038
3076
  requestAgentContentRead: (input) => hub.requestAgentContentRead(input),
3039
3077
  tasks: {
3040
3078
  get: (taskId) => hub.getTask(taskId),