@byok-sdk/client 0.11.0 → 0.13.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.
Files changed (34) hide show
  1. package/README.md +28 -3
  2. package/dist/adapters/index.js +74 -5
  3. package/dist/adapters/index.js.map +1 -1
  4. package/dist/adapters/pi/pi-adapter.d.ts +3 -0
  5. package/dist/adapters/pi/subagents-policy-extension.js +1 -1
  6. package/dist/adapters/pi/subagents-policy-extension.js.map +1 -1
  7. package/dist/agent-home.d.ts +107 -0
  8. package/dist/agent-memory/index.d.ts +1 -1
  9. package/dist/agent-memory/index.js +8 -5
  10. package/dist/agent-memory/index.js.map +1 -1
  11. package/dist/bin/byok-agent-memory-mcp.js.map +1 -1
  12. package/dist/bin/byok-agent-message-mcp.js.map +1 -1
  13. package/dist/bin/byok-agent-team-mcp.js.map +1 -1
  14. package/dist/bin/byok-agent.js +1279 -642
  15. package/dist/bin/byok-agent.js.map +1 -1
  16. package/dist/bin/byok-approval-mcp.js.map +1 -1
  17. package/dist/daemon/agent-egress-controller.d.ts +4 -0
  18. package/dist/daemon/auth-manager.d.ts +20 -0
  19. package/dist/daemon/blob-client.d.ts +24 -6
  20. package/dist/daemon/connection-manager.d.ts +69 -126
  21. package/dist/daemon/control-protocol.d.ts +8 -1
  22. package/dist/daemon/create-daemon.d.ts +28 -13
  23. package/dist/daemon/device-credential-store.d.ts +16 -0
  24. package/dist/daemon/long-poll-transport.d.ts +32 -23
  25. package/dist/daemon/observer.d.ts +1 -1
  26. package/dist/daemon/replay-cursor.d.ts +9 -0
  27. package/dist/daemon/task-runner.d.ts +22 -0
  28. package/dist/daemon/url.d.ts +17 -13
  29. package/dist/diagnostics/support-bundle.d.ts +1 -1
  30. package/dist/index.d.ts +5 -4
  31. package/dist/index.js +1278 -641
  32. package/dist/index.js.map +1 -1
  33. package/package.json +5 -7
  34. package/dist/daemon/ws-transport.d.ts +0 -139
package/README.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @byok-sdk/client
2
2
 
3
+ ## Exact provider-profile admission
4
+
5
+ When `DaemonConfig.piByokLauncher` is configured, the daemon advertises the
6
+ additive `provider-profile-binding` capability. A `byok-profile` dispatch
7
+ selection carries only an opaque local `profileRef`, exact revision/hash,
8
+ model, and bounded required capabilities. `PiAdapter.prepare()` asks the keys
9
+ launcher to validate that binding before claim. Missing or stale local state,
10
+ model mismatch, and unsupported capabilities decline without workspace or
11
+ runtime side effects. The immutable operation manifest seals the nested
12
+ binding, and the launcher revalidates it before credential access and spawn.
13
+
14
+ The task offer and manifest never contain the provider Base URL or secret.
15
+
3
16
  The local BYOK daemon. It pairs a device, durably journals tasks, connects over
4
17
  WebSocket or long poll, dispatches to local Claude Code, Codex, or pi adapters,
5
18
  and exposes authenticated local diagnostics/control commands.
@@ -175,9 +188,21 @@ strict Agent execution has one workspace authority and never falls back to a
175
188
  task-scoped Git workspace.
176
189
 
177
190
  Successful startup with this configuration advertises `agent-home-contract`. Agent offers are distinct
178
- from legacy task offers and fail closed when identity, profile revision,
179
- session/runtime/cwd evidence, or the one-writer lease does not match. Agent
180
- files other than the SDK-reserved `.byok` namespace are opaque; there is no
191
+ from legacy task offers and fail closed when identity, profile revision, or
192
+ session/runtime/cwd evidence does not match. Within one daemon process,
193
+ execution leases are scoped to `(agentId, sessionRef)`: different sessions of
194
+ one Agent may run concurrently in the same canonical home, while the same
195
+ session remains serialized. Fresh
196
+ tasks bind their task-scoped admission lease to the runtime-created session
197
+ before the SDK exposes that session. Shared `.byok` metadata mutations use a
198
+ short per-home gate. Agent-memory hosted projection serializes the complete
199
+ close-time outbox transaction per home because its durable outbox is one CAS
200
+ authority; the publish wait remains timeout-bounded and does not serialize the
201
+ sessions' runtime execution. The process-owned home activity marker remains
202
+ held until the final active session exits so relocation stays fail-closed. A
203
+ second daemon process remains excluded by that marker; cross-process session
204
+ multiplexing is not provided. Agent files
205
+ other than the SDK-reserved `.byok` namespace are opaque; there is no
181
206
  required `artifacts/` directory and the client does not parse or index their
182
207
  contents.
183
208
 
@@ -958,7 +958,11 @@ function validatePiByokLauncherConfig(launcher) {
958
958
  "--macos-keychain-path",
959
959
  "--secret-service-prefix",
960
960
  "--provider",
961
- "--model"
961
+ "--model",
962
+ "--profile-revision",
963
+ "--profile-hash",
964
+ "--required-capabilities",
965
+ "--validate-only"
962
966
  ]);
963
967
  const conflicting = launcher.args?.find((arg) => reserved.has(arg));
964
968
  if (conflicting !== void 0) {
@@ -1020,11 +1024,17 @@ var PiAdapter = class {
1020
1024
  const bin = this.resolveBin();
1021
1025
  const extensions = (this.options.resolveExtensions ?? resolvePiExtensions)();
1022
1026
  const selection = input.offer.dispatchSelection;
1023
- const pinnedSelection = selection === void 0 ? void 0 : Object.freeze({ ...selection });
1027
+ const pinnedSelection = selection === void 0 ? void 0 : selection.lane === "byok-profile" ? Object.freeze({
1028
+ ...selection,
1029
+ providerProfile: Object.freeze({
1030
+ ...selection.providerProfile,
1031
+ requiredCapabilities: Object.freeze([...selection.providerProfile.requiredCapabilities])
1032
+ })
1033
+ }) : Object.freeze({ ...selection });
1024
1034
  let command = bin.command;
1025
1035
  let launcherArgs;
1026
1036
  if (pinnedSelection !== void 0) {
1027
- if (pinnedSelection.lane !== "byok" || pinnedSelection.runtimeId !== "pi") {
1037
+ if (pinnedSelection.lane !== "byok" && pinnedSelection.lane !== "byok-profile" || pinnedSelection.runtimeId !== "pi") {
1028
1038
  return { kind: "reject", reason: `pi adapter cannot execute ${pinnedSelection.lane} selection for runtime ${pinnedSelection.runtimeId}`, retryable: false };
1029
1039
  }
1030
1040
  const launcher = this.options.byokLauncher;
@@ -1032,6 +1042,21 @@ var PiAdapter = class {
1032
1042
  return { kind: "reject", reason: "pi BYOK selection requires a configured credential-custody launcher", retryable: false };
1033
1043
  }
1034
1044
  command = launcher.command;
1045
+ const providerProfile = pinnedSelection.lane === "byok-profile" ? pinnedSelection.providerProfile : void 0;
1046
+ if (providerProfile !== void 0) {
1047
+ try {
1048
+ await (this.options.validateProviderProfileBinding ?? validateProviderProfileBindingWithLauncher)(
1049
+ providerProfile,
1050
+ launcher
1051
+ );
1052
+ } catch (error) {
1053
+ return {
1054
+ kind: "reject",
1055
+ reason: `provider profile admission failed: ${errorMessage(error)}`,
1056
+ retryable: false
1057
+ };
1058
+ }
1059
+ }
1035
1060
  launcherArgs = [
1036
1061
  ...launcher.args ?? [],
1037
1062
  "--pi-bin",
@@ -1043,9 +1068,19 @@ var PiAdapter = class {
1043
1068
  ...launcher.macosKeychainPath !== void 0 ? ["--macos-keychain-path", launcher.macosKeychainPath] : [],
1044
1069
  ...launcher.secretServicePrefix ? ["--secret-service-prefix", launcher.secretServicePrefix] : [],
1045
1070
  "--provider",
1046
- pinnedSelection.providerId,
1071
+ providerProfile?.profileRef ?? (pinnedSelection.lane === "byok" ? pinnedSelection.providerId : ""),
1047
1072
  "--model",
1048
- pinnedSelection.modelId
1073
+ providerProfile?.modelId ?? (pinnedSelection.lane === "byok" ? pinnedSelection.modelId : ""),
1074
+ ...providerProfile === void 0 ? [] : [
1075
+ "--profile-revision",
1076
+ providerProfile.profileRevision,
1077
+ "--profile-hash",
1078
+ providerProfile.profileHash,
1079
+ "--required-capabilities",
1080
+ JSON.stringify(providerProfile.requiredCapabilities),
1081
+ "--validate-only",
1082
+ "false"
1083
+ ]
1049
1084
  ];
1050
1085
  }
1051
1086
  return {
@@ -1188,8 +1223,42 @@ var PiAdapter = class {
1188
1223
  return (this.options.resolveBin ?? resolvePiBin)();
1189
1224
  }
1190
1225
  };
1226
+ async function validateProviderProfileBindingWithLauncher(binding, launcher) {
1227
+ await execFileAsync(launcher.command, [
1228
+ ...launcher.args ?? [],
1229
+ "--pi-bin",
1230
+ process.execPath,
1231
+ "--profile-db",
1232
+ launcher.profileDbPath,
1233
+ "--session-dir",
1234
+ launcher.sessionDir,
1235
+ "--provider",
1236
+ binding.profileRef,
1237
+ "--model",
1238
+ binding.modelId,
1239
+ "--profile-revision",
1240
+ binding.profileRevision,
1241
+ "--profile-hash",
1242
+ binding.profileHash,
1243
+ "--required-capabilities",
1244
+ JSON.stringify(binding.requiredCapabilities),
1245
+ "--validate-only",
1246
+ "true",
1247
+ ...launcher.macosKeychainPath !== void 0 ? ["--macos-keychain-path", launcher.macosKeychainPath] : [],
1248
+ ...launcher.secretServicePrefix ? ["--secret-service-prefix", launcher.secretServicePrefix] : []
1249
+ ], { timeout: DETECT_TIMEOUT_MS });
1250
+ }
1191
1251
  function sameDispatchSelection(left, right) {
1192
1252
  if (left === void 0 || right === void 0) return left === right;
1253
+ if (left.lane === "byok-profile" || right.lane === "byok-profile") {
1254
+ if (left.lane !== "byok-profile" || right.lane !== "byok-profile") return false;
1255
+ if (left.runtimeId !== right.runtimeId) return false;
1256
+ const leftProfile = left.providerProfile;
1257
+ const rightProfile = right.providerProfile;
1258
+ return leftProfile.profileRef === rightProfile.profileRef && leftProfile.profileRevision === rightProfile.profileRevision && leftProfile.profileHash === rightProfile.profileHash && leftProfile.modelId === rightProfile.modelId && leftProfile.requiredCapabilities.length === rightProfile.requiredCapabilities.length && leftProfile.requiredCapabilities.every(
1259
+ (capability, index) => capability === rightProfile.requiredCapabilities[index]
1260
+ );
1261
+ }
1193
1262
  return left.lane === right.lane && left.runtimeId === right.runtimeId && left.providerId === right.providerId && left.modelId === right.modelId;
1194
1263
  }
1195
1264
  async function resolveAuthoritativeSessionId(rpc) {