@stackbone/sdk 0.1.0-alpha.6 → 0.1.0-alpha.7

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/index.js CHANGED
@@ -3,7 +3,7 @@ export { z } from 'zod';
3
3
  import { drizzle } from 'drizzle-orm/postgres-js';
4
4
  import postgres from 'postgres';
5
5
  import { extractText } from 'unpdf';
6
- import { createHash } from 'crypto';
6
+ import { createHash, createHmac } from 'crypto';
7
7
  import OpenAI from 'openai';
8
8
  import { PutObjectCommand, GetObjectCommand, ListObjectsV2Command, DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3';
9
9
  import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
@@ -2366,7 +2366,7 @@ var require_luxon = __commonJS({
2366
2366
  return new Formatter2(locale, opts);
2367
2367
  }
2368
2368
  static parseFormat(fmt) {
2369
- let current = null, currentFull = "", bracketed = false;
2369
+ let current3 = null, currentFull = "", bracketed = false;
2370
2370
  const splits = [];
2371
2371
  for (let i2 = 0; i2 < fmt.length; i2++) {
2372
2372
  const c2 = fmt.charAt(i2);
@@ -2377,12 +2377,12 @@ var require_luxon = __commonJS({
2377
2377
  val: currentFull === "" ? "'" : currentFull
2378
2378
  });
2379
2379
  }
2380
- current = null;
2380
+ current3 = null;
2381
2381
  currentFull = "";
2382
2382
  bracketed = !bracketed;
2383
2383
  } else if (bracketed) {
2384
2384
  currentFull += c2;
2385
- } else if (c2 === current) {
2385
+ } else if (c2 === current3) {
2386
2386
  currentFull += c2;
2387
2387
  } else {
2388
2388
  if (currentFull.length > 0) {
@@ -2392,7 +2392,7 @@ var require_luxon = __commonJS({
2392
2392
  });
2393
2393
  }
2394
2394
  currentFull = c2;
2395
- current = c2;
2395
+ current3 = c2;
2396
2396
  }
2397
2397
  }
2398
2398
  if (currentFull.length > 0) {
@@ -3122,28 +3122,28 @@ var require_luxon = __commonJS({
3122
3122
  __name(durationToMillis, "durationToMillis");
3123
3123
  function normalizeValues(matrix, vals) {
3124
3124
  const factor = durationToMillis(matrix, vals) < 0 ? -1 : 1;
3125
- orderedUnits$1.reduceRight((previous, current) => {
3126
- if (!isUndefined(vals[current])) {
3125
+ orderedUnits$1.reduceRight((previous, current3) => {
3126
+ if (!isUndefined(vals[current3])) {
3127
3127
  if (previous) {
3128
3128
  const previousVal = vals[previous] * factor;
3129
- const conv = matrix[current][previous];
3129
+ const conv = matrix[current3][previous];
3130
3130
  const rollUp = Math.floor(previousVal / conv);
3131
- vals[current] += rollUp * factor;
3131
+ vals[current3] += rollUp * factor;
3132
3132
  vals[previous] -= rollUp * conv * factor;
3133
3133
  }
3134
- return current;
3134
+ return current3;
3135
3135
  } else {
3136
3136
  return previous;
3137
3137
  }
3138
3138
  }, null);
3139
- orderedUnits$1.reduce((previous, current) => {
3140
- if (!isUndefined(vals[current])) {
3139
+ orderedUnits$1.reduce((previous, current3) => {
3140
+ if (!isUndefined(vals[current3])) {
3141
3141
  if (previous) {
3142
3142
  const fraction = vals[previous] % 1;
3143
3143
  vals[previous] -= fraction;
3144
- vals[current] += fraction * matrix[previous][current];
3144
+ vals[current3] += fraction * matrix[previous][current3];
3145
3145
  }
3146
- return current;
3146
+ return current3;
3147
3147
  } else {
3148
3148
  return previous;
3149
3149
  }
@@ -4256,21 +4256,21 @@ var require_luxon = __commonJS({
4256
4256
  * @return {Array}
4257
4257
  */
4258
4258
  static merge(intervals) {
4259
- const [found, final] = intervals.sort((a2, b2) => a2.s - b2.s).reduce(([sofar, current], item) => {
4260
- if (!current) {
4259
+ const [found, final] = intervals.sort((a2, b2) => a2.s - b2.s).reduce(([sofar, current3], item) => {
4260
+ if (!current3) {
4261
4261
  return [
4262
4262
  sofar,
4263
4263
  item
4264
4264
  ];
4265
- } else if (current.overlaps(item) || current.abutsStart(item)) {
4265
+ } else if (current3.overlaps(item) || current3.abutsStart(item)) {
4266
4266
  return [
4267
4267
  sofar,
4268
- current.union(item)
4268
+ current3.union(item)
4269
4269
  ];
4270
4270
  } else {
4271
4271
  return [
4272
4272
  sofar.concat([
4273
- current
4273
+ current3
4274
4274
  ]),
4275
4275
  item
4276
4276
  ];
@@ -5202,7 +5202,7 @@ var require_luxon = __commonJS({
5202
5202
  }
5203
5203
  __name(possiblyCachedLocalWeekData, "possiblyCachedLocalWeekData");
5204
5204
  function clone(inst, alts) {
5205
- const current = {
5205
+ const current3 = {
5206
5206
  ts: inst.ts,
5207
5207
  zone: inst.zone,
5208
5208
  c: inst.c,
@@ -5211,9 +5211,9 @@ var require_luxon = __commonJS({
5211
5211
  invalid: inst.invalid
5212
5212
  };
5213
5213
  return new DateTime({
5214
- ...current,
5214
+ ...current3,
5215
5215
  ...alts,
5216
- old: current
5216
+ old: current3
5217
5217
  });
5218
5218
  }
5219
5219
  __name(clone, "clone");
@@ -8218,7 +8218,7 @@ var require_expression = __commonJS({
8218
8218
  return schedule;
8219
8219
  }, "prev");
8220
8220
  CronExpression.prototype.hasNext = function() {
8221
- var current = this._currentDate;
8221
+ var current3 = this._currentDate;
8222
8222
  var hasIterated = this._hasIterated;
8223
8223
  try {
8224
8224
  this._findSchedule();
@@ -8226,12 +8226,12 @@ var require_expression = __commonJS({
8226
8226
  } catch (err3) {
8227
8227
  return false;
8228
8228
  } finally {
8229
- this._currentDate = current;
8229
+ this._currentDate = current3;
8230
8230
  this._hasIterated = hasIterated;
8231
8231
  }
8232
8232
  };
8233
8233
  CronExpression.prototype.hasPrev = function() {
8234
- var current = this._currentDate;
8234
+ var current3 = this._currentDate;
8235
8235
  var hasIterated = this._hasIterated;
8236
8236
  try {
8237
8237
  this._findSchedule(true);
@@ -8239,7 +8239,7 @@ var require_expression = __commonJS({
8239
8239
  } catch (err3) {
8240
8240
  return false;
8241
8241
  } finally {
8242
- this._currentDate = current;
8242
+ this._currentDate = current3;
8243
8243
  this._hasIterated = hasIterated;
8244
8244
  }
8245
8245
  };
@@ -8746,9 +8746,11 @@ var CAPABILITIES = [
8746
8746
  "prompts.basic",
8747
8747
  // `connections.actions`: the agent → control-plane connectors proxy
8748
8748
  // (feature connectors-connections-automations). Role-based naming per repo
8749
- // convention. `client.connections.list()` / `.invoke(connector, action, args)`
8749
+ // convention. `client.legacyConnections.list()` / `.invoke(connector, action, args)`
8750
8750
  // run against the proxy; the agent container never sees a credential. The
8751
- // v13 bump reintroduces this capability after v12 removed it.
8751
+ // v13 bump reintroduces this capability after v12 removed it. The capability
8752
+ // string stays `connections.actions` (it names the wire domain, not the
8753
+ // renamed SDK accessor).
8752
8754
  "connections.actions"
8753
8755
  ];
8754
8756
  var MODULE_CAPABILITIES = {
@@ -8765,10 +8767,11 @@ var MODULE_CAPABILITIES = {
8765
8767
  // row is still declared here because the table is shared with the cloud
8766
8768
  // contract / Studio capability advertisement.
8767
8769
  prompts: "prompts.basic",
8768
- // `client.connections` is a control-plane PROXY surface (like queues): the
8769
- // agent POSTs to `/api/v1/agent/connections/*` with its agent JWT and the
8770
+ // `client.legacyConnections` is a control-plane PROXY surface (like queues):
8771
+ // the agent POSTs to `/api/v1/agent/connections/*` with its agent JWT and the
8770
8772
  // control plane runs the connector action with credentials resolved in
8771
- // memory. Gated against `connections.actions`.
8773
+ // memory. Gated against `connections.actions`. The map key stays `connections`
8774
+ // (it is the module id shared with the cloud contract, not the SDK accessor).
8772
8775
  connections: "connections.actions"
8773
8776
  };
8774
8777
  var contractBuildNameSchema = z.enum([
@@ -9187,9 +9190,9 @@ function createContractStore(resolved = resolveConfig({})) {
9187
9190
  function peek(baseUrl) {
9188
9191
  if (!baseUrl || baseUrl.trim() === "") return null;
9189
9192
  const key = normaliseBaseUrl(baseUrl);
9190
- const cached = lastResolved.get(key);
9191
- if (!cached || cached.error) return null;
9192
- return cached.data;
9193
+ const cached2 = lastResolved.get(key);
9194
+ if (!cached2 || cached2.error) return null;
9195
+ return cached2.data;
9193
9196
  }
9194
9197
  __name(peek, "peek");
9195
9198
  function gatingEnabled() {
@@ -9455,9 +9458,9 @@ var HttpClient = class {
9455
9458
  if (jwt && !requestHeaders.has("Authorization")) {
9456
9459
  requestHeaders.set("Authorization", `Bearer ${jwt}`);
9457
9460
  }
9458
- const installationId = resolveInstallationId(this.resolved);
9459
- if (installationId && !requestHeaders.has("X-Stackbone-Installation-Id")) {
9460
- requestHeaders.set("X-Stackbone-Installation-Id", installationId);
9461
+ const installationId2 = resolveInstallationId(this.resolved);
9462
+ if (installationId2 && !requestHeaders.has("X-Stackbone-Installation-Id")) {
9463
+ requestHeaders.set("X-Stackbone-Installation-Id", installationId2);
9461
9464
  }
9462
9465
  const body = serializeBody(method, options.body, requestHeaders);
9463
9466
  let lastError = null;
@@ -9955,7 +9958,7 @@ var ApprovalFacade = class {
9955
9958
  const rows = await this._getDatabase().runShared((db) => db`
9956
9959
  INSERT INTO stackbone_platform.approvals (
9957
9960
  topic, payload, callback_url, idempotency_key,
9958
- fallback, metadata, timeout_at
9961
+ fallback, metadata, run_id, requested_by_step_id, timeout_at
9959
9962
  ) VALUES (
9960
9963
  ${options.topic},
9961
9964
  ${JSON.stringify(options.payload ?? {})}::jsonb,
@@ -9963,6 +9966,8 @@ var ApprovalFacade = class {
9963
9966
  ${options.idempotencyKey ?? null},
9964
9967
  ${fallback},
9965
9968
  ${JSON.stringify(options.metadata ?? {})}::jsonb,
9969
+ ${options.runId ?? null}::uuid,
9970
+ ${options.requestedByStepId ?? null}::uuid,
9966
9971
  now() + (${timeoutMs}::int * interval '1 millisecond')
9967
9972
  )
9968
9973
  ON CONFLICT (workspace_id, topic, idempotency_key)
@@ -10195,7 +10200,7 @@ var ConfigFacade = class {
10195
10200
  void this._resolved;
10196
10201
  }
10197
10202
  async get(key) {
10198
- if (!key.trim()) {
10203
+ if (!String(key).trim()) {
10199
10204
  return err({
10200
10205
  code: "config_invalid_request",
10201
10206
  message: "`key` is required."
@@ -10206,7 +10211,7 @@ var ConfigFacade = class {
10206
10211
  if (!payload.data || !(key in payload.data)) {
10207
10212
  return err({
10208
10213
  code: "config_not_found",
10209
- message: `Config key \`${key}\` is not set for this agent.`,
10214
+ message: `Config key \`${String(key)}\` is not set for this agent.`,
10210
10215
  meta: {
10211
10216
  key
10212
10217
  }
@@ -10235,6 +10240,17 @@ var ConfigFacade = class {
10235
10240
  }
10236
10241
  return ok(out);
10237
10242
  }
10243
+ /**
10244
+ * Returns the agent's entire config payload as one typed object. An
10245
+ * absent/null `agent_config` row resolves to `ok({})` — an empty config is
10246
+ * "no config set", consistent with the facade reading the singleton row.
10247
+ * Reads stay an unvalidated SELECT (no AJV on the read path).
10248
+ */
10249
+ async getAll() {
10250
+ const payload = await this.loadPayload();
10251
+ if (payload.error) return err(payload.error);
10252
+ return ok(payload.data ?? {});
10253
+ }
10238
10254
  async loadPayload() {
10239
10255
  const sql = this.sql();
10240
10256
  if (sql.error) return err(sql.error);
@@ -10420,21 +10436,21 @@ function buildProxy(steps, seed, rootCall, gate) {
10420
10436
  }
10421
10437
  __name(buildProxy, "buildProxy");
10422
10438
  function replayChain(seed, steps) {
10423
- let current = seed;
10439
+ let current3 = seed;
10424
10440
  for (const step of steps) {
10425
- if (current === null || current === void 0) return current;
10441
+ if (current3 === null || current3 === void 0) return current3;
10426
10442
  if (step.kind === "get") {
10427
- current = current[step.key];
10443
+ current3 = current3[step.key];
10428
10444
  continue;
10429
10445
  }
10430
- const parent = current;
10446
+ const parent = current3;
10431
10447
  const fn = parent[step.key];
10432
10448
  if (typeof fn !== "function") {
10433
10449
  throw new TypeError(`[stackbone/sdk] cold-start retry could not replay "${step.key}": not a function on the rebuilt handle`);
10434
10450
  }
10435
- current = fn.apply(parent, step.args);
10451
+ current3 = fn.apply(parent, step.args);
10436
10452
  }
10437
- return current;
10453
+ return current3;
10438
10454
  }
10439
10455
  __name(replayChain, "replayChain");
10440
10456
 
@@ -10794,11 +10810,11 @@ var PromptsFacade = class {
10794
10810
  WHERE p.key = ${key} AND p.deleted_at IS NULL
10795
10811
  LIMIT 1
10796
10812
  `;
10797
- const current = existing[0];
10798
- if (!current) return null;
10799
- let nextVersion = current.current_version;
10813
+ const current3 = existing[0];
10814
+ if (!current3) return null;
10815
+ let nextVersion = current3.current_version;
10800
10816
  if (options.template !== void 0) {
10801
- nextVersion = current.current_version + 1;
10817
+ nextVersion = current3.current_version + 1;
10802
10818
  const variables = extractVars(options.template);
10803
10819
  await tx`
10804
10820
  INSERT INTO stackbone_platform.prompt_versions
@@ -10812,8 +10828,8 @@ var PromptsFacade = class {
10812
10828
  await tx`
10813
10829
  UPDATE stackbone_platform.prompts
10814
10830
  SET current_version = ${nextVersion},
10815
- name = ${options.name ?? current.name},
10816
- description = ${options.description !== void 0 ? options.description : current.description},
10831
+ name = ${options.name ?? current3.name},
10832
+ description = ${options.description !== void 0 ? options.description : current3.description},
10817
10833
  metadata = COALESCE(${options.metadata !== void 0 ? JSON.stringify(options.metadata) : null}::jsonb, metadata),
10818
10834
  updated_at = now()
10819
10835
  WHERE key = ${key}
@@ -11235,7 +11251,7 @@ async function createDocument(sql, args) {
11235
11251
  `;
11236
11252
  const insertedDoc = await tx`
11237
11253
  INSERT INTO stackbone_platform.rag_documents (collection_id, source, content_hash, metadata)
11238
- VALUES (${collectionId}, ${args.source}, ${args.contentHash}, ${tx.json(args.metadata)})
11254
+ VALUES (${collectionId}, ${args.source}, ${args.contentHash}, ${JSON.stringify(args.metadata)}::jsonb)
11239
11255
  RETURNING id
11240
11256
  `;
11241
11257
  const documentId = insertedDoc[0]?.id;
@@ -15994,6 +16010,99 @@ var SecretsFacade = class {
15994
16010
  }
15995
16011
  }
15996
16012
  };
16013
+ function agentRegistry() {
16014
+ const raw = process.env["AGENT_URLS"];
16015
+ if (!raw) {
16016
+ throw new Error("AGENT_URLS is not set. The emulator injects it; run this workflow through `stackbone dev`.");
16017
+ }
16018
+ return JSON.parse(raw);
16019
+ }
16020
+ __name(agentRegistry, "agentRegistry");
16021
+ function resolveAgentHost(name) {
16022
+ const registry = agentRegistry();
16023
+ const host = registry[name];
16024
+ if (!host) {
16025
+ throw new Error(`Unknown agent "${name}". Known agents: ${Object.keys(registry).join(", ")}`);
16026
+ }
16027
+ return host;
16028
+ }
16029
+ __name(resolveAgentHost, "resolveAgentHost");
16030
+ function signWorkflowHeaders() {
16031
+ const secret = process.env["HMAC_SECRET"] ?? "";
16032
+ const timestamp = String(Date.now());
16033
+ const signature = createHmac("sha256", secret).update(timestamp).digest("hex");
16034
+ return {
16035
+ "x-stackbone-timestamp": timestamp,
16036
+ "x-stackbone-workflow-signature": signature
16037
+ };
16038
+ }
16039
+ __name(signWorkflowHeaders, "signWorkflowHeaders");
16040
+
16041
+ // src/surfaces/external/agents/lazy-agent.ts
16042
+ var EVE_CLIENT_MODULE = "eve/client";
16043
+ async function buildEveClient(name) {
16044
+ const host = resolveAgentHost(name);
16045
+ const { Client } = await import(EVE_CLIENT_MODULE);
16046
+ return new Client({
16047
+ host,
16048
+ headers: /* @__PURE__ */ __name(() => signWorkflowHeaders(), "headers")
16049
+ });
16050
+ }
16051
+ __name(buildEveClient, "buildEveClient");
16052
+ function seedSessionState(seed) {
16053
+ if (typeof seed === "string") return {
16054
+ continuationToken: seed,
16055
+ streamIndex: 0
16056
+ };
16057
+ return seed ?? {
16058
+ streamIndex: 0
16059
+ };
16060
+ }
16061
+ __name(seedSessionState, "seedSessionState");
16062
+ function lazyAgentSession(getClient, seed) {
16063
+ const seededState = seedSessionState(seed);
16064
+ let real;
16065
+ let opened;
16066
+ const session = /* @__PURE__ */ __name(() => {
16067
+ real ??= getClient().then((client) => client.session(seed)).then((s2) => {
16068
+ opened = s2;
16069
+ return s2;
16070
+ }).catch((error) => {
16071
+ real = void 0;
16072
+ throw error;
16073
+ });
16074
+ return real;
16075
+ }, "session");
16076
+ return {
16077
+ get state() {
16078
+ return opened ? opened.state : seededState;
16079
+ },
16080
+ async send(input) {
16081
+ return (await session()).send(input);
16082
+ },
16083
+ async *stream(options) {
16084
+ yield* (await session()).stream(options);
16085
+ }
16086
+ };
16087
+ }
16088
+ __name(lazyAgentSession, "lazyAgentSession");
16089
+ function lazyAgent(name) {
16090
+ let client;
16091
+ const getClient = /* @__PURE__ */ __name(() => {
16092
+ client ??= buildEveClient(name).catch((error) => {
16093
+ client = void 0;
16094
+ throw error;
16095
+ });
16096
+ return client;
16097
+ }, "getClient");
16098
+ return {
16099
+ session(state) {
16100
+ return lazyAgentSession(getClient, state);
16101
+ }
16102
+ };
16103
+ }
16104
+ __name(lazyAgent, "lazyAgent");
16105
+ var agent = /* @__PURE__ */ __name((name) => lazyAgent(name), "agent");
15997
16106
  var AiModule = class {
15998
16107
  static {
15999
16108
  __name(this, "AiModule");
@@ -16324,6 +16433,95 @@ function mapApiError(raw, model) {
16324
16433
  };
16325
16434
  }
16326
16435
  __name(mapApiError, "mapApiError");
16436
+ var TIMESTAMP_HEADER = "x-stackbone-timestamp";
16437
+ var SIGNATURE_HEADER2 = "x-stackbone-workflow-signature";
16438
+ function signBrokerHeaders() {
16439
+ const secret = process.env["HMAC_SECRET"] ?? "";
16440
+ const timestamp = String(Date.now());
16441
+ const signature = createHmac("sha256", secret).update(timestamp).digest("hex");
16442
+ return {
16443
+ [TIMESTAMP_HEADER]: timestamp,
16444
+ [SIGNATURE_HEADER2]: signature
16445
+ };
16446
+ }
16447
+ __name(signBrokerHeaders, "signBrokerHeaders");
16448
+ function brokerBaseUrl() {
16449
+ const url = process.env["STACKBONE_API_URL"];
16450
+ if (!url) {
16451
+ throw new Error("STACKBONE_API_URL is not set. The Stackbone runtime injects the broker base URL; run this agent through `stackbone dev`.");
16452
+ }
16453
+ return url.replace(/\/+$/, "");
16454
+ }
16455
+ __name(brokerBaseUrl, "brokerBaseUrl");
16456
+ function installationId() {
16457
+ const id = process.env["STACKBONE_INSTALLATION_ID"];
16458
+ if (!id) {
16459
+ throw new Error("STACKBONE_INSTALLATION_ID is not set. The Stackbone runtime injects it; run this agent through `stackbone dev`.");
16460
+ }
16461
+ return id;
16462
+ }
16463
+ __name(installationId, "installationId");
16464
+
16465
+ // src/surfaces/external/connect/call-connector.ts
16466
+ var EXECUTE_PATH = "/api/connect/execute";
16467
+ function connectorCallError(code, message) {
16468
+ const error = new Error(message);
16469
+ error.code = code;
16470
+ return error;
16471
+ }
16472
+ __name(connectorCallError, "connectorCallError");
16473
+ function errorFromBody(status, body) {
16474
+ if (body && body.ok === false && body.error && typeof body.error.code === "string") {
16475
+ return connectorCallError(body.error.code, body.error.message ?? `Stackbone Connect broker rejected the call (code "${body.error.code}").`);
16476
+ }
16477
+ return connectorCallError("credential_error", `Stackbone Connect broker responded ${status}.`);
16478
+ }
16479
+ __name(errorFromBody, "errorFromBody");
16480
+ async function callConnector(connector, operation, args, opts) {
16481
+ const principal = opts?.principal ?? {
16482
+ type: "app"
16483
+ };
16484
+ const url = `${brokerBaseUrl()}${EXECUTE_PATH}`;
16485
+ const body = JSON.stringify({
16486
+ connector,
16487
+ operation,
16488
+ args: args ?? {},
16489
+ principal,
16490
+ installationId: installationId()
16491
+ });
16492
+ let response;
16493
+ try {
16494
+ response = await fetch(url, {
16495
+ method: "POST",
16496
+ headers: {
16497
+ "content-type": "application/json",
16498
+ ...signBrokerHeaders()
16499
+ },
16500
+ body
16501
+ });
16502
+ } catch (cause) {
16503
+ throw connectorCallError("execute_failed", `Stackbone Connect broker is unreachable: ${cause instanceof Error ? cause.message : String(cause)}`);
16504
+ }
16505
+ const parsed = await response.json().catch(() => null);
16506
+ if (!response.ok || parsed && parsed.ok === false) {
16507
+ throw errorFromBody(response.status, parsed ?? null);
16508
+ }
16509
+ if (!parsed || parsed.ok !== true) {
16510
+ throw connectorCallError("invalid_output", "Stackbone Connect broker returned a malformed execute response.");
16511
+ }
16512
+ return parsed.output;
16513
+ }
16514
+ __name(callConnector, "callConnector");
16515
+ var connectorHandle = /* @__PURE__ */ __name((id) => new Proxy(/* @__PURE__ */ Object.create(null), {
16516
+ get(_target, prop) {
16517
+ if (typeof prop !== "string" || prop === "then") return void 0;
16518
+ if (prop === "call") {
16519
+ return (operation, args, opts) => callConnector(id, operation, args, opts);
16520
+ }
16521
+ return (args, opts) => callConnector(id, prop, args, opts);
16522
+ }
16523
+ }), "connectorHandle");
16524
+ var connection = /* @__PURE__ */ __name((id) => connectorHandle(id), "connection");
16327
16525
  var R2_ENDPOINT_HOST_SUFFIX = ".r2.cloudflarestorage.com";
16328
16526
  function createS3CompatClient(options) {
16329
16527
  return new S3Client({
@@ -16753,6 +16951,8 @@ var QueuesModule = class {
16753
16951
  this._http = _http;
16754
16952
  this._gate = gate ?? createModuleGate("queues", resolved);
16755
16953
  }
16954
+ /** @deprecated Classic v2 only. Prefer `startWorkflow(name, input)` from
16955
+ * `@stackbone/sdk/workflow` (a job → a workflow run on the World). */
16756
16956
  async publish(request) {
16757
16957
  return withGate(this._gate, async () => {
16758
16958
  const body = {
@@ -16771,6 +16971,8 @@ var QueuesModule = class {
16771
16971
  });
16772
16972
  });
16773
16973
  }
16974
+ /** @deprecated Classic v2 only. Prefer `scheduleWorkflow(name, input, cron)`
16975
+ * from `@stackbone/sdk/workflow` (a cron → a workflow run on the World). */
16774
16976
  async schedule(request) {
16775
16977
  return withGate(this._gate, async () => {
16776
16978
  const body = {
@@ -16789,6 +16991,8 @@ var QueuesModule = class {
16789
16991
  });
16790
16992
  });
16791
16993
  }
16994
+ /** @deprecated Classic v2 only. Prefer `unschedule(name)` from
16995
+ * `@stackbone/sdk/workflow`. */
16792
16996
  async unschedule(request) {
16793
16997
  return withGate(this._gate, async () => this._http.request({
16794
16998
  method: "POST",
@@ -16800,6 +17004,8 @@ var QueuesModule = class {
16800
17004
  errorMapping: ERROR_MAPPING2
16801
17005
  }));
16802
17006
  }
17007
+ /** @deprecated Classic v2 only. Prefer `listSchedules()` from
17008
+ * `@stackbone/sdk/workflow`. */
16803
17009
  async listSchedules() {
16804
17010
  return withGate(this._gate, async () => this._http.request({
16805
17011
  method: "GET",
@@ -16824,7 +17030,7 @@ var StackboneClient = class {
16824
17030
  _secrets;
16825
17031
  _config;
16826
17032
  _queues;
16827
- _connections;
17033
+ _legacyConnections;
16828
17034
  _memory;
16829
17035
  _prompts;
16830
17036
  _httpClient;
@@ -16878,16 +17084,59 @@ var StackboneClient = class {
16878
17084
  return this._queues;
16879
17085
  }
16880
17086
  /**
16881
- * Live surface — the agent's handle on the workspace's connector connections.
16882
- * `list` / `invoke` make authenticated calls to the control-plane connectors
16883
- * proxy (`/api/v1/agent/connections/*`); the credentials never enter the agent
17087
+ * Legacy surface — the agent's handle on the workspace's connector connections
17088
+ * under the OLD connector model. `list` / `invoke(connector, action, args)` make
17089
+ * authenticated calls to the control-plane connectors proxy
17090
+ * (`/api/v1/agent/connections/*`); the credentials never enter the agent
16884
17091
  * container. Gated against `connections.actions` so the handshake-blocked /
16885
17092
  * capability-missing paths are exercised the same way as the other gated
16886
17093
  * surfaces.
17094
+ *
17095
+ * Named `legacyConnections` (not `connections`) so it no longer sits one letter
17096
+ * from the new peer-free `connection(id)` entrypoint above — the two connector
17097
+ * entrypoints are now unambiguous. Behaviour is unchanged from the old
17098
+ * `connections` member.
17099
+ */
17100
+ get legacyConnections() {
17101
+ this._legacyConnections ??= new ConnectionsModule(this.resolved, this.http(), createModuleGate("connections", this.resolved, this._contractStore));
17102
+ return this._legacyConnections;
17103
+ }
17104
+ /**
17105
+ * Peer-free connector entrypoint — `stackbone.connection(id)` selects a Stackbone
17106
+ * Connect connector by its verbatim id and returns a typed handle whose generated
17107
+ * operations (`.sendMail({ ... })`, typed via the `StackboneConnections` registry)
17108
+ * and dynamic `.call(operation, args)` escape hatch both resolve to the same broker
17109
+ * call (`POST /api/connect/execute`, HMAC scheme A). It is a plain HMAC fetch — it
17110
+ * imports NO `eve` peer — so it is wired directly onto the client with no lazy
17111
+ * loading and pulls no new peer into the main barrel.
17112
+ *
17113
+ * This is the namespaced form of the top-level `connection(...)` export (now
17114
+ * `@deprecated`); both delegate to the same implementation. Distinct from the
17115
+ * plural `connections` surface above, which is the control-plane connectors proxy
17116
+ * (`list` / `invoke`).
17117
+ */
17118
+ get connection() {
17119
+ return connection;
17120
+ }
17121
+ /**
17122
+ * Namespaced sibling-agent entrypoint — `stackbone.agent(id)` selects a sibling
17123
+ * eve agent by its verbatim name and returns a lazy eve `Client`, so a workflow
17124
+ * step delegates with `stackbone.agent('support').session().send({ ... })`. The
17125
+ * name is typed against the augmentable `AgentRegistry` (declared names
17126
+ * autocomplete, a typo is a compile error).
17127
+ *
17128
+ * Peer isolation is load-bearing: selecting the agent and opening a session are
17129
+ * synchronous and import NO `eve` peer — only the session's already-async leaves
17130
+ * (`send` / `stream`) resolve `eve/client` via dynamic import on first use. So a
17131
+ * tool-only agent that imports `@stackbone/sdk` and never calls `agent(...)` never
17132
+ * eager-loads the optional `eve` peer and cannot crash-loop on a missing dep.
17133
+ *
17134
+ * This is the namespaced form of the top-level `eveAgent(...)` export (now
17135
+ * `@deprecated`) on the `@stackbone/sdk/workflow` subpath; both produce the same
17136
+ * signed workflow→agent call and the same eve `Client` API.
16887
17137
  */
16888
- get connections() {
16889
- this._connections ??= new ConnectionsModule(this.resolved, this.http(), createModuleGate("connections", this.resolved, this._contractStore));
16890
- return this._connections;
17138
+ get agent() {
17139
+ return agent;
16891
17140
  }
16892
17141
  /**
16893
17142
  * Pending surface — runtime not built. Every method returns
@@ -17056,7 +17305,9 @@ var SDK_ERROR_CODE_PREFIXES = {
17056
17305
  "unavailable"
17057
17306
  ],
17058
17307
  /**
17059
- * `client.connections` — the agent → control plane connectors proxy. Both
17308
+ * `client.legacyConnections` — the agent → control plane connectors proxy
17309
+ * (legacy connector model). The `connections_*` code prefix stays stable (it
17310
+ * names the wire domain, not the client accessor). Both
17060
17311
  * methods (`list`, `invoke`) hit the `/api/v1/agent/connections/*` endpoints
17061
17312
  * over `HttpClient`, so the full status→domain remap (`connections_unauthorized`,
17062
17313
  * `connections_not_found`, `connections_unavailable`, …) is in play. The agent
@@ -17237,6 +17488,9 @@ function assertCapabilityShape(name, capability) {
17237
17488
  }
17238
17489
  __name(assertCapabilityShape, "assertCapabilityShape");
17239
17490
 
17491
+ // src/runtime/define-workspace.ts
17492
+ var defineWorkspace = /* @__PURE__ */ __name((workspace) => workspace, "defineWorkspace");
17493
+
17240
17494
  // src/runtime/logger.ts
17241
17495
  var writeLine = /* @__PURE__ */ __name((stream, level, msg, bindings, meta, now) => {
17242
17496
  const record = {
@@ -17274,6 +17528,65 @@ function getInvocationContext() {
17274
17528
  return storage.getStore();
17275
17529
  }
17276
17530
  __name(getInvocationContext, "getInvocationContext");
17531
+ function runWithCallerId(id, fn, options) {
17532
+ const context = {
17533
+ runId: id,
17534
+ invocationId: options?.invocationId ?? id,
17535
+ // Only attach `handler` when supplied: `exactOptionalPropertyTypes` forbids
17536
+ // an explicit `undefined` on an optional property.
17537
+ ...options?.handler !== void 0 ? {
17538
+ handler: options.handler
17539
+ } : {}
17540
+ };
17541
+ return runWithInvocationContext(context, fn);
17542
+ }
17543
+ __name(runWithCallerId, "runWithCallerId");
17544
+
17545
+ // src/runtime/workflow-starter.ts
17546
+ var current;
17547
+ function setWorkflowStarter(starter) {
17548
+ current = starter;
17549
+ }
17550
+ __name(setWorkflowStarter, "setWorkflowStarter");
17551
+ function getWorkflowStarter() {
17552
+ if (!current) {
17553
+ throw new Error("No workflow starter is bound. `startWorkflow` / `startWorkflowAndWait` can only be called from inside a running workflow \u2014 the runtime binds the starter on its first dispatch.");
17554
+ }
17555
+ return current;
17556
+ }
17557
+ __name(getWorkflowStarter, "getWorkflowStarter");
17558
+
17559
+ // src/runtime/workflow-scheduler.ts
17560
+ var current2;
17561
+ function setWorkflowScheduler(scheduler) {
17562
+ current2 = scheduler;
17563
+ }
17564
+ __name(setWorkflowScheduler, "setWorkflowScheduler");
17565
+ function getWorkflowScheduler() {
17566
+ if (!current2) {
17567
+ throw new Error("No workflow scheduler is bound. `scheduleWorkflow` / `unschedule` / `listSchedules` can only be called inside a running workflow runtime \u2014 the runtime binds the scheduler on its first dispatch.");
17568
+ }
17569
+ return current2;
17570
+ }
17571
+ __name(getWorkflowScheduler, "getWorkflowScheduler");
17572
+
17573
+ // src/runtime/ambient-client.ts
17574
+ var cached;
17575
+ function resolveAmbientClient() {
17576
+ cached ??= createClient();
17577
+ return cached;
17578
+ }
17579
+ __name(resolveAmbientClient, "resolveAmbientClient");
17580
+ var stackbone = new Proxy({}, {
17581
+ get(_target, prop) {
17582
+ const client = resolveAmbientClient();
17583
+ const value = Reflect.get(client, prop, client);
17584
+ return typeof value === "function" ? value.bind(client) : value;
17585
+ },
17586
+ has(_target, prop) {
17587
+ return Reflect.has(resolveAmbientClient(), prop);
17588
+ }
17589
+ });
17277
17590
  var patched = /* @__PURE__ */ new WeakSet();
17278
17591
  function installInvocationConsoleCapture(options = {}) {
17279
17592
  const target = options.console ?? console;
@@ -17568,6 +17881,6 @@ var analyzeAgentSchemas = /* @__PURE__ */ __name((pair) => {
17568
17881
  };
17569
17882
  }, "analyzeAgentSchemas");
17570
17883
 
17571
- export { INVOCATION_ID_HEADER, INVOKE_TIMEOUT_HARD_CAP_MS, RESERVED_ERROR_CODES, RESERVED_HANDLER_NAMES, RUN_ID_HEADER, STORED_TO_SDK_ENV, StackboneClient, analyzeAgentSchemas, createClient, createStructuredLogger, defineAgent, getInvocationContext, installInvocationConsoleCapture, invokeRequestSchema, isReservedErrorCode, isSdkErrorCode, loadSystemSecretsIntoEnv, rehydrateSystemSecretsRows, runWithInvocationContext };
17884
+ export { INVOCATION_ID_HEADER, INVOKE_TIMEOUT_HARD_CAP_MS, RESERVED_ERROR_CODES, RESERVED_HANDLER_NAMES, RUN_ID_HEADER, STORED_TO_SDK_ENV, StackboneClient, analyzeAgentSchemas, createClient, createStructuredLogger, defineAgent, defineWorkspace, getInvocationContext, getWorkflowScheduler, getWorkflowStarter, installInvocationConsoleCapture, invokeRequestSchema, isReservedErrorCode, isSdkErrorCode, loadSystemSecretsIntoEnv, rehydrateSystemSecretsRows, runWithCallerId, runWithInvocationContext, setWorkflowScheduler, setWorkflowStarter, stackbone };
17572
17885
  //# sourceMappingURL=index.js.map
17573
17886
  //# sourceMappingURL=index.js.map