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

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,164 @@ var SecretsFacade = class {
15994
16010
  }
15995
16011
  }
15996
16012
  };
16013
+
16014
+ // src/runtime/workflow-scheduler.ts
16015
+ var current;
16016
+ function setWorkflowScheduler(scheduler) {
16017
+ current = scheduler;
16018
+ }
16019
+ __name(setWorkflowScheduler, "setWorkflowScheduler");
16020
+ function getWorkflowScheduler() {
16021
+ if (!current) {
16022
+ 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.");
16023
+ }
16024
+ return current;
16025
+ }
16026
+ __name(getWorkflowScheduler, "getWorkflowScheduler");
16027
+
16028
+ // src/surfaces/agent-local/workflows/schedule-workflow.ts
16029
+ async function scheduleWorkflow(name, input, cron) {
16030
+ return getWorkflowScheduler().schedule(name, input, cron);
16031
+ }
16032
+ __name(scheduleWorkflow, "scheduleWorkflow");
16033
+ async function unschedule(name) {
16034
+ return getWorkflowScheduler().unschedule(name);
16035
+ }
16036
+ __name(unschedule, "unschedule");
16037
+ async function listSchedules() {
16038
+ return getWorkflowScheduler().listSchedules();
16039
+ }
16040
+ __name(listSchedules, "listSchedules");
16041
+
16042
+ // src/runtime/workflow-starter.ts
16043
+ var current2;
16044
+ function setWorkflowStarter(starter) {
16045
+ current2 = starter;
16046
+ }
16047
+ __name(setWorkflowStarter, "setWorkflowStarter");
16048
+ function getWorkflowStarter() {
16049
+ if (!current2) {
16050
+ 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.");
16051
+ }
16052
+ return current2;
16053
+ }
16054
+ __name(getWorkflowStarter, "getWorkflowStarter");
16055
+
16056
+ // src/surfaces/agent-local/workflows/start-workflow.ts
16057
+ async function startWorkflow(name, input, opts) {
16058
+ "use step";
16059
+ return getWorkflowStarter().start(name, input, opts);
16060
+ }
16061
+ __name(startWorkflow, "startWorkflow");
16062
+
16063
+ // src/surfaces/agent-local/workflows/start-workflow-and-wait.ts
16064
+ async function startWorkflowAndWait(name, input, opts) {
16065
+ "use step";
16066
+ return await getWorkflowStarter().startAndWait(name, input, opts);
16067
+ }
16068
+ __name(startWorkflowAndWait, "startWorkflowAndWait");
16069
+
16070
+ // src/surfaces/agent-local/workflows/workflows-accessor.ts
16071
+ var workflows = {
16072
+ start: startWorkflow,
16073
+ startAndWait: startWorkflowAndWait,
16074
+ schedule: scheduleWorkflow,
16075
+ unschedule,
16076
+ listSchedules
16077
+ };
16078
+ function agentRegistry() {
16079
+ const raw = process.env["AGENT_URLS"];
16080
+ if (!raw) {
16081
+ throw new Error("AGENT_URLS is not set. The emulator injects it; run this workflow through `stackbone dev`.");
16082
+ }
16083
+ return JSON.parse(raw);
16084
+ }
16085
+ __name(agentRegistry, "agentRegistry");
16086
+ function resolveAgentHost(name) {
16087
+ const registry = agentRegistry();
16088
+ const host = registry[name];
16089
+ if (!host) {
16090
+ throw new Error(`Unknown agent "${name}". Known agents: ${Object.keys(registry).join(", ")}`);
16091
+ }
16092
+ return host;
16093
+ }
16094
+ __name(resolveAgentHost, "resolveAgentHost");
16095
+ function signWorkflowHeaders() {
16096
+ const secret = process.env["HMAC_SECRET"] ?? "";
16097
+ const timestamp = String(Date.now());
16098
+ const signature = createHmac("sha256", secret).update(timestamp).digest("hex");
16099
+ return {
16100
+ "x-stackbone-timestamp": timestamp,
16101
+ "x-stackbone-workflow-signature": signature
16102
+ };
16103
+ }
16104
+ __name(signWorkflowHeaders, "signWorkflowHeaders");
16105
+
16106
+ // src/surfaces/external/agents/lazy-agent.ts
16107
+ var EVE_CLIENT_MODULE = "eve/client";
16108
+ async function buildEveClient(name) {
16109
+ const host = resolveAgentHost(name);
16110
+ const { Client } = await import(EVE_CLIENT_MODULE);
16111
+ return new Client({
16112
+ host,
16113
+ headers: /* @__PURE__ */ __name(() => signWorkflowHeaders(), "headers")
16114
+ });
16115
+ }
16116
+ __name(buildEveClient, "buildEveClient");
16117
+ function seedSessionState(seed) {
16118
+ if (typeof seed === "string") return {
16119
+ continuationToken: seed,
16120
+ streamIndex: 0
16121
+ };
16122
+ return seed ?? {
16123
+ streamIndex: 0
16124
+ };
16125
+ }
16126
+ __name(seedSessionState, "seedSessionState");
16127
+ function lazyAgentSession(getClient, seed) {
16128
+ const seededState = seedSessionState(seed);
16129
+ let real;
16130
+ let opened;
16131
+ const session = /* @__PURE__ */ __name(() => {
16132
+ real ??= getClient().then((client) => client.session(seed)).then((s2) => {
16133
+ opened = s2;
16134
+ return s2;
16135
+ }).catch((error) => {
16136
+ real = void 0;
16137
+ throw error;
16138
+ });
16139
+ return real;
16140
+ }, "session");
16141
+ return {
16142
+ get state() {
16143
+ return opened ? opened.state : seededState;
16144
+ },
16145
+ async send(input) {
16146
+ return (await session()).send(input);
16147
+ },
16148
+ async *stream(options) {
16149
+ yield* (await session()).stream(options);
16150
+ }
16151
+ };
16152
+ }
16153
+ __name(lazyAgentSession, "lazyAgentSession");
16154
+ function lazyAgent(name) {
16155
+ let client;
16156
+ const getClient = /* @__PURE__ */ __name(() => {
16157
+ client ??= buildEveClient(name).catch((error) => {
16158
+ client = void 0;
16159
+ throw error;
16160
+ });
16161
+ return client;
16162
+ }, "getClient");
16163
+ return {
16164
+ session(state) {
16165
+ return lazyAgentSession(getClient, state);
16166
+ }
16167
+ };
16168
+ }
16169
+ __name(lazyAgent, "lazyAgent");
16170
+ var agent = /* @__PURE__ */ __name((name) => lazyAgent(name), "agent");
15997
16171
  var AiModule = class {
15998
16172
  static {
15999
16173
  __name(this, "AiModule");
@@ -16324,6 +16498,95 @@ function mapApiError(raw, model) {
16324
16498
  };
16325
16499
  }
16326
16500
  __name(mapApiError, "mapApiError");
16501
+ var TIMESTAMP_HEADER = "x-stackbone-timestamp";
16502
+ var SIGNATURE_HEADER2 = "x-stackbone-workflow-signature";
16503
+ function signBrokerHeaders() {
16504
+ const secret = process.env["HMAC_SECRET"] ?? "";
16505
+ const timestamp = String(Date.now());
16506
+ const signature = createHmac("sha256", secret).update(timestamp).digest("hex");
16507
+ return {
16508
+ [TIMESTAMP_HEADER]: timestamp,
16509
+ [SIGNATURE_HEADER2]: signature
16510
+ };
16511
+ }
16512
+ __name(signBrokerHeaders, "signBrokerHeaders");
16513
+ function brokerBaseUrl() {
16514
+ const url = process.env["STACKBONE_API_URL"];
16515
+ if (!url) {
16516
+ throw new Error("STACKBONE_API_URL is not set. The Stackbone runtime injects the broker base URL; run this agent through `stackbone dev`.");
16517
+ }
16518
+ return url.replace(/\/+$/, "");
16519
+ }
16520
+ __name(brokerBaseUrl, "brokerBaseUrl");
16521
+ function installationId() {
16522
+ const id = process.env["STACKBONE_INSTALLATION_ID"];
16523
+ if (!id) {
16524
+ throw new Error("STACKBONE_INSTALLATION_ID is not set. The Stackbone runtime injects it; run this agent through `stackbone dev`.");
16525
+ }
16526
+ return id;
16527
+ }
16528
+ __name(installationId, "installationId");
16529
+
16530
+ // src/surfaces/external/connect/call-connector.ts
16531
+ var EXECUTE_PATH = "/api/connect/execute";
16532
+ function connectorCallError(code, message) {
16533
+ const error = new Error(message);
16534
+ error.code = code;
16535
+ return error;
16536
+ }
16537
+ __name(connectorCallError, "connectorCallError");
16538
+ function errorFromBody(status, body) {
16539
+ if (body && body.ok === false && body.error && typeof body.error.code === "string") {
16540
+ return connectorCallError(body.error.code, body.error.message ?? `Stackbone Connect broker rejected the call (code "${body.error.code}").`);
16541
+ }
16542
+ return connectorCallError("credential_error", `Stackbone Connect broker responded ${status}.`);
16543
+ }
16544
+ __name(errorFromBody, "errorFromBody");
16545
+ async function callConnector(connector, operation, args, opts) {
16546
+ const principal = opts?.principal ?? {
16547
+ type: "app"
16548
+ };
16549
+ const url = `${brokerBaseUrl()}${EXECUTE_PATH}`;
16550
+ const body = JSON.stringify({
16551
+ connector,
16552
+ operation,
16553
+ args: args ?? {},
16554
+ principal,
16555
+ installationId: installationId()
16556
+ });
16557
+ let response;
16558
+ try {
16559
+ response = await fetch(url, {
16560
+ method: "POST",
16561
+ headers: {
16562
+ "content-type": "application/json",
16563
+ ...signBrokerHeaders()
16564
+ },
16565
+ body
16566
+ });
16567
+ } catch (cause) {
16568
+ throw connectorCallError("execute_failed", `Stackbone Connect broker is unreachable: ${cause instanceof Error ? cause.message : String(cause)}`);
16569
+ }
16570
+ const parsed = await response.json().catch(() => null);
16571
+ if (!response.ok || parsed && parsed.ok === false) {
16572
+ throw errorFromBody(response.status, parsed ?? null);
16573
+ }
16574
+ if (!parsed || parsed.ok !== true) {
16575
+ throw connectorCallError("invalid_output", "Stackbone Connect broker returned a malformed execute response.");
16576
+ }
16577
+ return parsed.output;
16578
+ }
16579
+ __name(callConnector, "callConnector");
16580
+ var connectorHandle = /* @__PURE__ */ __name((id) => new Proxy(/* @__PURE__ */ Object.create(null), {
16581
+ get(_target, prop) {
16582
+ if (typeof prop !== "string" || prop === "then") return void 0;
16583
+ if (prop === "call") {
16584
+ return (operation, args, opts) => callConnector(id, operation, args, opts);
16585
+ }
16586
+ return (args, opts) => callConnector(id, prop, args, opts);
16587
+ }
16588
+ }), "connectorHandle");
16589
+ var connection = /* @__PURE__ */ __name((id) => connectorHandle(id), "connection");
16327
16590
  var R2_ENDPOINT_HOST_SUFFIX = ".r2.cloudflarestorage.com";
16328
16591
  function createS3CompatClient(options) {
16329
16592
  return new S3Client({
@@ -16753,6 +17016,8 @@ var QueuesModule = class {
16753
17016
  this._http = _http;
16754
17017
  this._gate = gate ?? createModuleGate("queues", resolved);
16755
17018
  }
17019
+ /** @deprecated Classic v2 only. Prefer `startWorkflow(name, input)` from
17020
+ * `@stackbone/sdk/workflow` (a job → a workflow run on the World). */
16756
17021
  async publish(request) {
16757
17022
  return withGate(this._gate, async () => {
16758
17023
  const body = {
@@ -16771,6 +17036,8 @@ var QueuesModule = class {
16771
17036
  });
16772
17037
  });
16773
17038
  }
17039
+ /** @deprecated Classic v2 only. Prefer `scheduleWorkflow(name, input, cron)`
17040
+ * from `@stackbone/sdk/workflow` (a cron → a workflow run on the World). */
16774
17041
  async schedule(request) {
16775
17042
  return withGate(this._gate, async () => {
16776
17043
  const body = {
@@ -16789,6 +17056,8 @@ var QueuesModule = class {
16789
17056
  });
16790
17057
  });
16791
17058
  }
17059
+ /** @deprecated Classic v2 only. Prefer `unschedule(name)` from
17060
+ * `@stackbone/sdk/workflow`. */
16792
17061
  async unschedule(request) {
16793
17062
  return withGate(this._gate, async () => this._http.request({
16794
17063
  method: "POST",
@@ -16800,6 +17069,8 @@ var QueuesModule = class {
16800
17069
  errorMapping: ERROR_MAPPING2
16801
17070
  }));
16802
17071
  }
17072
+ /** @deprecated Classic v2 only. Prefer `listSchedules()` from
17073
+ * `@stackbone/sdk/workflow`. */
16803
17074
  async listSchedules() {
16804
17075
  return withGate(this._gate, async () => this._http.request({
16805
17076
  method: "GET",
@@ -16824,7 +17095,7 @@ var StackboneClient = class {
16824
17095
  _secrets;
16825
17096
  _config;
16826
17097
  _queues;
16827
- _connections;
17098
+ _legacyConnections;
16828
17099
  _memory;
16829
17100
  _prompts;
16830
17101
  _httpClient;
@@ -16878,16 +17149,77 @@ var StackboneClient = class {
16878
17149
  return this._queues;
16879
17150
  }
16880
17151
  /**
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
17152
+ * Legacy surface — the agent's handle on the workspace's connector connections
17153
+ * under the OLD connector model. `list` / `invoke(connector, action, args)` make
17154
+ * authenticated calls to the control-plane connectors proxy
17155
+ * (`/api/v1/agent/connections/*`); the credentials never enter the agent
16884
17156
  * container. Gated against `connections.actions` so the handshake-blocked /
16885
17157
  * capability-missing paths are exercised the same way as the other gated
16886
17158
  * surfaces.
17159
+ *
17160
+ * Named `legacyConnections` (not `connections`) so it no longer sits one letter
17161
+ * from the new peer-free `connection(id)` entrypoint above — the two connector
17162
+ * entrypoints are now unambiguous. Behaviour is unchanged from the old
17163
+ * `connections` member.
17164
+ */
17165
+ get legacyConnections() {
17166
+ this._legacyConnections ??= new ConnectionsModule(this.resolved, this.http(), createModuleGate("connections", this.resolved, this._contractStore));
17167
+ return this._legacyConnections;
17168
+ }
17169
+ /**
17170
+ * Peer-free connector entrypoint — `stackbone.connection(id)` selects a Stackbone
17171
+ * Connect connector by its verbatim id and returns a typed handle whose generated
17172
+ * operations (`.sendMail({ ... })`, typed via the `StackboneConnections` registry)
17173
+ * and dynamic `.call(operation, args)` escape hatch both resolve to the same broker
17174
+ * call (`POST /api/connect/execute`, HMAC scheme A). It is a plain HMAC fetch — it
17175
+ * imports NO `eve` peer — so it is wired directly onto the client with no lazy
17176
+ * loading and pulls no new peer into the main barrel.
17177
+ *
17178
+ * This is the namespaced form of the top-level `connection(...)` export (now
17179
+ * `@deprecated`); both delegate to the same implementation. Distinct from the
17180
+ * plural `connections` surface above, which is the control-plane connectors proxy
17181
+ * (`list` / `invoke`).
17182
+ */
17183
+ get connection() {
17184
+ return connection;
17185
+ }
17186
+ /**
17187
+ * Namespaced sibling-agent entrypoint — `stackbone.agent(id)` selects a sibling
17188
+ * eve agent by its verbatim name and returns a lazy eve `Client`, so a workflow
17189
+ * step delegates with `stackbone.agent('support').session().send({ ... })`. The
17190
+ * name is typed against the augmentable `AgentRegistry` (declared names
17191
+ * autocomplete, a typo is a compile error).
17192
+ *
17193
+ * Peer isolation is load-bearing: selecting the agent and opening a session are
17194
+ * synchronous and import NO `eve` peer — only the session's already-async leaves
17195
+ * (`send` / `stream`) resolve `eve/client` via dynamic import on first use. So a
17196
+ * tool-only agent that imports `@stackbone/sdk` and never calls `agent(...)` never
17197
+ * eager-loads the optional `eve` peer and cannot crash-loop on a missing dep.
17198
+ *
17199
+ * This is the namespaced form of the top-level `eveAgent(...)` export (now
17200
+ * `@deprecated`) on the `@stackbone/sdk/workflow` subpath; both produce the same
17201
+ * signed workflow→agent call and the same eve `Client` API.
17202
+ */
17203
+ get agent() {
17204
+ return agent;
17205
+ }
17206
+ /**
17207
+ * Namespaced workflow trigger + schedule surface — `stackbone.workflows.start(...)`
17208
+ * / `.startAndWait(...)` / `.schedule(...)` / `.unschedule(...)` / `.listSchedules()`.
17209
+ * Start another workflow by name (fire-and-forget or durable sub-routine) and
17210
+ * manage dynamic cron triggers, all from inside a running workflow.
17211
+ *
17212
+ * These are peer-free shims over the ambient `WorkflowStarter` / `WorkflowScheduler`
17213
+ * the runtime injects on first dispatch — they import NO `workflow` / `eve` peer,
17214
+ * so (like `connection` / `agent`) they are wired directly onto the client and
17215
+ * pull nothing new into the main barrel. This is the namespaced form of the loose
17216
+ * `startWorkflow(...)` / `scheduleWorkflow(...)` exports (now `@deprecated`) on the
17217
+ * `@stackbone/sdk/workflow` subpath; both delegate to the same implementation, so
17218
+ * `start` / `startAndWait` keep their `"use step"` durability. The peer-bound
17219
+ * authoring API (`requestApproval` / `defineHook` / `sleep`) stays on that subpath.
16887
17220
  */
16888
- get connections() {
16889
- this._connections ??= new ConnectionsModule(this.resolved, this.http(), createModuleGate("connections", this.resolved, this._contractStore));
16890
- return this._connections;
17221
+ get workflows() {
17222
+ return workflows;
16891
17223
  }
16892
17224
  /**
16893
17225
  * Pending surface — runtime not built. Every method returns
@@ -17056,7 +17388,9 @@ var SDK_ERROR_CODE_PREFIXES = {
17056
17388
  "unavailable"
17057
17389
  ],
17058
17390
  /**
17059
- * `client.connections` — the agent → control plane connectors proxy. Both
17391
+ * `client.legacyConnections` — the agent → control plane connectors proxy
17392
+ * (legacy connector model). The `connections_*` code prefix stays stable (it
17393
+ * names the wire domain, not the client accessor). Both
17060
17394
  * methods (`list`, `invoke`) hit the `/api/v1/agent/connections/*` endpoints
17061
17395
  * over `HttpClient`, so the full status→domain remap (`connections_unauthorized`,
17062
17396
  * `connections_not_found`, `connections_unavailable`, …) is in play. The agent
@@ -17237,6 +17571,9 @@ function assertCapabilityShape(name, capability) {
17237
17571
  }
17238
17572
  __name(assertCapabilityShape, "assertCapabilityShape");
17239
17573
 
17574
+ // src/runtime/define-workspace.ts
17575
+ var defineWorkspace = /* @__PURE__ */ __name((workspace) => workspace, "defineWorkspace");
17576
+
17240
17577
  // src/runtime/logger.ts
17241
17578
  var writeLine = /* @__PURE__ */ __name((stream, level, msg, bindings, meta, now) => {
17242
17579
  const record = {
@@ -17274,6 +17611,37 @@ function getInvocationContext() {
17274
17611
  return storage.getStore();
17275
17612
  }
17276
17613
  __name(getInvocationContext, "getInvocationContext");
17614
+ function runWithCallerId(id, fn, options) {
17615
+ const context = {
17616
+ runId: id,
17617
+ invocationId: options?.invocationId ?? id,
17618
+ // Only attach `handler` when supplied: `exactOptionalPropertyTypes` forbids
17619
+ // an explicit `undefined` on an optional property.
17620
+ ...options?.handler !== void 0 ? {
17621
+ handler: options.handler
17622
+ } : {}
17623
+ };
17624
+ return runWithInvocationContext(context, fn);
17625
+ }
17626
+ __name(runWithCallerId, "runWithCallerId");
17627
+
17628
+ // src/runtime/ambient-client.ts
17629
+ var cached;
17630
+ function resolveAmbientClient() {
17631
+ cached ??= createClient();
17632
+ return cached;
17633
+ }
17634
+ __name(resolveAmbientClient, "resolveAmbientClient");
17635
+ var stackbone = new Proxy({}, {
17636
+ get(_target, prop) {
17637
+ const client = resolveAmbientClient();
17638
+ const value = Reflect.get(client, prop, client);
17639
+ return typeof value === "function" ? value.bind(client) : value;
17640
+ },
17641
+ has(_target, prop) {
17642
+ return Reflect.has(resolveAmbientClient(), prop);
17643
+ }
17644
+ });
17277
17645
  var patched = /* @__PURE__ */ new WeakSet();
17278
17646
  function installInvocationConsoleCapture(options = {}) {
17279
17647
  const target = options.console ?? console;
@@ -17568,6 +17936,6 @@ var analyzeAgentSchemas = /* @__PURE__ */ __name((pair) => {
17568
17936
  };
17569
17937
  }, "analyzeAgentSchemas");
17570
17938
 
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 };
17939
+ 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
17940
  //# sourceMappingURL=index.js.map
17573
17941
  //# sourceMappingURL=index.js.map