@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.d.ts CHANGED
@@ -6,6 +6,9 @@ export { ChunkOptions, ChunkStrategy, DeleteOptions, DeleteResponse, IngestChunk
6
6
  import OpenAI from 'openai';
7
7
  import { ChatCompletionCreateParamsStreaming, ChatCompletionChunk, ChatCompletionCreateParamsNonStreaming, ChatCompletion, EmbeddingCreateParams, CreateEmbeddingResponse, ChatCompletionMessageParam } from 'openai/resources';
8
8
  import { Stream } from 'openai/streaming';
9
+ import { W as WorkflowName, c as StartWorkflowOptions, e as WorkflowStartHandle, b as StartWorkflowAndWaitOptions, S as ScheduledWorkflow, A as AgentName } from './agent-registry-BNXuj88Q.js';
10
+ export { a as AgentRegistry, g as WorkflowScheduler, h as WorkflowStarter, i as WorkflowTriggerOptions, j as getWorkflowScheduler, k as getWorkflowStarter, l as setWorkflowScheduler, m as setWorkflowStarter } from './agent-registry-BNXuj88Q.js';
11
+ import { a as ConnectionAccessor } from './call-connector-CYDw_yG5.js';
9
12
  import { S3Client } from '@aws-sdk/client-s3';
10
13
  import { z } from 'zod';
11
14
  export { z } from 'zod';
@@ -268,7 +271,9 @@ declare const SDK_ERROR_CODE_PREFIXES: {
268
271
  */
269
272
  readonly queues: readonly ["forbidden", "invalid_request", "invalid_response", "not_found", "rate_limited", "timeout", "unauthorized", "unavailable"];
270
273
  /**
271
- * `client.connections` — the agent → control plane connectors proxy. Both
274
+ * `client.legacyConnections` — the agent → control plane connectors proxy
275
+ * (legacy connector model). The `connections_*` code prefix stays stable (it
276
+ * names the wire domain, not the client accessor). Both
272
277
  * methods (`list`, `invoke`) hit the `/api/v1/agent/connections/*` endpoints
273
278
  * over `HttpClient`, so the full status→domain remap (`connections_unauthorized`,
274
279
  * `connections_not_found`, `connections_unavailable`, …) is in play. The agent
@@ -640,6 +645,23 @@ interface ApprovalRequestOptions<T = unknown> {
640
645
  /** Same `(topic, idempotencyKey)` returns the same `approvalId` instead of creating a new one. */
641
646
  idempotencyKey?: string;
642
647
  metadata?: Record<string, unknown>;
648
+ /**
649
+ * The PROJECTED `runs.id` this approval belongs to, joined into the inbox so
650
+ * the pause appears against its run. Used by the workflow-HITL helper
651
+ * (`requestApproval`), which reads it from the invocation context (F5). Stays
652
+ * `NULL` for the legacy fire-and-forget agent-approval path. The column is a
653
+ * FK to `stackbone_platform.runs(id)` (`ON DELETE SET NULL`).
654
+ */
655
+ runId?: string;
656
+ /**
657
+ * The projected `run_steps.id` of the workflow step that requested this
658
+ * approval, anchoring the pause to the exact step (`requested_by_step_id`,
659
+ * A6). The workflow-HITL helper (`requestApproval`) reads it from the
660
+ * invocation context (F5); stays `NULL` when no step id is available (the
661
+ * common case today — see `InvocationContext.requestedByStepId`). The column
662
+ * is a FK to `stackbone_platform.run_steps(id)` (`ON DELETE SET NULL`).
663
+ */
664
+ requestedByStepId?: string;
643
665
  }
644
666
  interface ApprovalRequest {
645
667
  approvalId: string;
@@ -677,11 +699,13 @@ interface ApprovalListResult<T = unknown> {
677
699
  * `verify()` (local crypto — see `verify.ts`).
678
700
  *
679
701
  * The write populates only the columns the cloud `create()` used to set
680
- * (topic/payload/callback_url/idempotency_key/fallback/metadata/timeout_at;
681
- * `schema` was sourced from a DTO field the SDK options object does not carry,
682
- * so it stays NULL). `workspace_id`/`agent_id`/`run_id` stay NULL exactly as
683
- * they were on the control-plane path the idempotency `ON CONFLICT` relies on
684
- * `workspace_id` being NULL with `NULLS NOT DISTINCT` (migration 0008).
702
+ * (topic/payload/callback_url/idempotency_key/fallback/metadata/timeout_at),
703
+ * plus `run_id` / `requested_by_step_id` when the workflow-HITL helper supplies
704
+ * them from the invocation context (F5/A6). `schema` was sourced from a DTO
705
+ * field the SDK options object does not carry, so it stays NULL.
706
+ * `workspace_id`/`agent_id` stay NULL exactly as they were on the control-plane
707
+ * path — the idempotency `ON CONFLICT` relies on `workspace_id` being NULL with
708
+ * `NULLS NOT DISTINCT` (migration 0008).
685
709
  */
686
710
  declare class ApprovalFacade {
687
711
  private readonly _resolved;
@@ -708,6 +732,38 @@ declare class ApprovalFacade {
708
732
  private sql;
709
733
  }
710
734
 
735
+ /**
736
+ * Augmentable registry of the agent's typed config keys. By default it is
737
+ * empty, so `client.config` reads stay a loose `Record<string, unknown>`
738
+ * (today's behavior). Creators augment it from the generated ambient types
739
+ * (`.stackbone/config.d.ts`, derived from their `config.schema.ts`) so reads
740
+ * become strict:
741
+ *
742
+ * declare module '@stackbone/sdk' {
743
+ * interface ConfigRegistry {
744
+ * reply_tone: 'formal' | 'casual';
745
+ * max_retries: number;
746
+ * }
747
+ * }
748
+ *
749
+ * Once augmented, `client.config.get('reply_tone')` is typed `'formal' |
750
+ * 'casual'` and `get('unknownKey')` is a compile error. Mirrors the
751
+ * `QueueJobs` augmentable-interface pattern.
752
+ */
753
+ interface ConfigRegistry {
754
+ }
755
+
756
+ /**
757
+ * The effective shape of the agent's config, derived from the augmentable
758
+ * `ConfigRegistry`. The tuple wrap (`[X] extends [never]`) defeats the
759
+ * conditional-type distributivity that a bare `keyof ConfigRegistry extends
760
+ * never` would trigger:
761
+ *
762
+ * - empty registry -> `Record<string, unknown>` (today's loose behavior:
763
+ * any key, value `unknown`);
764
+ * - augmented registry -> `ConfigRegistry` itself (strict keys + value types).
765
+ */
766
+ type ConfigShape = [keyof ConfigRegistry] extends [never] ? Record<string, unknown> : ConfigRegistry;
711
767
  declare class ConfigFacade {
712
768
  private readonly _resolved;
713
769
  /** Lazy accessor for `client.database` — see `SecretsFacade`. */
@@ -715,14 +771,21 @@ declare class ConfigFacade {
715
771
  constructor(_resolved: ResolvedConfig,
716
772
  /** Lazy accessor for `client.database` — see `SecretsFacade`. */
717
773
  _getDatabase: () => DatabaseModule);
718
- get<T = unknown>(key: string): Promise<Result<T>>;
774
+ get<K extends keyof ConfigShape>(key: K): Promise<Result<ConfigShape[K]>>;
719
775
  /**
720
776
  * Keys absent from the agent's config come back as omissions in the
721
777
  * response — the returned map only contains entries the agent DB actually
722
778
  * has, so callers must access fields with `?.` (the return type is
723
779
  * `Partial<T>`).
724
780
  */
725
- getMany<T extends Record<string, unknown> = Record<string, unknown>>(keys: string[]): Promise<Result<Partial<T>>>;
781
+ getMany<K extends keyof ConfigShape>(keys: K[]): Promise<Result<Partial<Pick<ConfigShape, K>>>>;
782
+ /**
783
+ * Returns the agent's entire config payload as one typed object. An
784
+ * absent/null `agent_config` row resolves to `ok({})` — an empty config is
785
+ * "no config set", consistent with the facade reading the singleton row.
786
+ * Reads stay an unvalidated SELECT (no AJV on the read path).
787
+ */
788
+ getAll(): Promise<Result<ConfigShape>>;
726
789
  private loadPayload;
727
790
  private sql;
728
791
  }
@@ -1135,6 +1198,140 @@ declare class SecretsFacade {
1135
1198
  private sql;
1136
1199
  }
1137
1200
 
1201
+ /**
1202
+ * The shape of `stackbone.workflows` — the namespaced workflow trigger + schedule
1203
+ * surface. Every `name` is typed `WorkflowName` (a loose `string` until
1204
+ * `stackbone dev` generates `.stackbone/workflows.d.ts`, then the closed set of
1205
+ * declared workflow names — a typo is a compile error).
1206
+ */
1207
+ interface WorkflowsAccessor {
1208
+ /**
1209
+ * Start another workflow BY NAME as its own independent run, fire-and-forget;
1210
+ * resolves to `{ runId }` immediately. Durable `"use step"`. MUST be called from
1211
+ * inside a running workflow. See {@link startWorkflow}.
1212
+ */
1213
+ start(name: WorkflowName, input: unknown, opts?: StartWorkflowOptions): Promise<WorkflowStartHandle>;
1214
+ /**
1215
+ * Run another workflow BY NAME as a durable sub-routine: suspend until it
1216
+ * reaches a terminal state, then return its output validated against the
1217
+ * target's declared output schema. See {@link startWorkflowAndWait}.
1218
+ */
1219
+ startAndWait<TOutput = unknown>(name: WorkflowName, input: unknown, opts?: StartWorkflowAndWaitOptions): Promise<TOutput>;
1220
+ /**
1221
+ * Register (or upsert) a DYNAMIC recurring trigger that starts `name` on the
1222
+ * `cron` cadence. Idempotent by `name`. Prefer the declarative `export const
1223
+ * schedules` for cadences that ship with the workspace. See {@link scheduleWorkflow}.
1224
+ */
1225
+ schedule(name: WorkflowName, input: unknown, cron: string): Promise<void>;
1226
+ /** Cancel a dynamic scheduled trigger by `name`. See {@link unschedule}. */
1227
+ unschedule(name: WorkflowName): Promise<void>;
1228
+ /** List active triggers (declarative + dynamic). See {@link listSchedules}. */
1229
+ listSchedules(): Promise<ScheduledWorkflow[]>;
1230
+ }
1231
+
1232
+ /**
1233
+ * eve's serialized session cursor. Mirrors eve's nominal `SessionState`
1234
+ * interface (`{ continuationToken?, sessionId?, streamIndex }`) so a value the
1235
+ * creator reads from a real eve session is assignable to the lazy
1236
+ * `session(state)` resume parameter. NOT a loose `Record` — eve's `SessionState`
1237
+ * has a required `streamIndex`, and a `Record<string, unknown>` mirror would
1238
+ * reject it (the nominal interface lacks the record's index signature).
1239
+ */
1240
+ interface EveSessionState {
1241
+ readonly continuationToken?: string;
1242
+ readonly sessionId?: string;
1243
+ readonly streamIndex: number;
1244
+ }
1245
+ /**
1246
+ * One streamed turn event from an eve session's NDJSON stream. A peer-free
1247
+ * structural mirror of the slice of eve's `HandleMessageStreamEvent` a workflow
1248
+ * reads when it FORWARDS frames to its own output (`getWritable()`): the
1249
+ * discriminant `type` and the per-frame `data`. Eve's real union is far richer
1250
+ * (dozens of frame variants), but a workflow that drains the stream only narrows
1251
+ * on `type` and reads `data` off the matched frame — so this loose, open shape is
1252
+ * what the forward loop needs while keeping the optional `eve` peer out of the
1253
+ * main barrel's type graph. A creator who wants the full eve union types the
1254
+ * `getWritable<...>()` sink with eve's own `HandleMessageStreamEvent`.
1255
+ */
1256
+ interface EveStreamEvent {
1257
+ readonly type: string;
1258
+ readonly data?: unknown;
1259
+ readonly [key: string]: unknown;
1260
+ }
1261
+ /**
1262
+ * The turn payload eve's `session.send(...)` accepts. A bare string is shorthand
1263
+ * for `{ message }`; the object form carries follow-up text, HITL results, client
1264
+ * context, output schema, signal, and headers. Kept loose on purpose — the lazy
1265
+ * member forwards it verbatim to the real eve session.
1266
+ */
1267
+ type SendTurnInput<_TOutput = unknown> = string | Readonly<Record<string, unknown>>;
1268
+ /**
1269
+ * The aggregated result of one turn, returned by `EveMessageResponse.result()`.
1270
+ * Mirrors the slice of eve's `MessageResult<TOutput>` the workflow→agent hop
1271
+ * reads: the typed structured `data` (from the turn's `outputSchema`) plus the
1272
+ * terminal `status`. Eve's real `MessageResult` is richer and takes precedence
1273
+ * when the creator has `eve` installed.
1274
+ */
1275
+ interface EveMessageResult<TOutput = unknown> {
1276
+ readonly data: TOutput | undefined;
1277
+ readonly status: 'completed' | 'failed' | 'waiting';
1278
+ }
1279
+ /**
1280
+ * The response eve's `session.send(...)` returns. Mirrors the slice of eve's
1281
+ * `MessageResponse<TOutput>` the hop drives: collect the turn via `result()` OR
1282
+ * iterate the event stream with `for await...of` (the response is
1283
+ * `AsyncIterable`). Both consume the SAME single-use stream.
1284
+ */
1285
+ interface EveMessageResponse<TOutput = unknown> extends AsyncIterable<EveStreamEvent> {
1286
+ result(): Promise<EveMessageResult<TOutput>>;
1287
+ }
1288
+
1289
+ /**
1290
+ * The eve `Client` surface a lazy agent handle exposes. Narrowed to the
1291
+ * `session(...)` factory the workflow→agent path uses; the returned session is the
1292
+ * lazy `LazyAgentSession` below (structurally compatible with eve's `ClientSession`).
1293
+ */
1294
+ interface LazyAgentClient {
1295
+ session(state?: EveSessionState | string): LazyAgentSession;
1296
+ }
1297
+ /**
1298
+ * The eve `ClientSession` surface a lazy agent session exposes — a DROP-IN twin of
1299
+ * eve's native `ClientSession`, so a workflow written against the eager `eveAgent`
1300
+ * path keeps compiling verbatim when it swaps to `stackbone.agent`. `send` /
1301
+ * `stream` are the async leaves that resolve the `eve` peer on first use;
1302
+ * everything above them (selecting the agent, opening the session) stays
1303
+ * synchronous and peer-free. `send` returns eve's `MessageResponse<TOutput>` (so
1304
+ * `.result()` and `for await...of` both work), and `state` exposes the advanced
1305
+ * cursor a workflow persists between turns — readable once a turn has built the
1306
+ * real session.
1307
+ */
1308
+ interface LazyAgentSession {
1309
+ /**
1310
+ * Current session cursor (continuation token, session id, stream cursor), read
1311
+ * to persist + resume across turns. A DROP-IN twin of eve's `ClientSession.state`,
1312
+ * which is readable from construction: before the first `send` / `stream` it
1313
+ * echoes the seed passed to `session(state)` (a bare continuation-token string
1314
+ * normalizes to `{ continuationToken, streamIndex: 0 }`, an absent seed to the
1315
+ * initial `{ streamIndex: 0 }`), and after a turn it exposes the advanced cursor
1316
+ * off the real eve session. Never throws.
1317
+ */
1318
+ readonly state: EveSessionState;
1319
+ send<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<EveMessageResponse<TOutput>>;
1320
+ stream(options?: {
1321
+ startIndex?: number;
1322
+ }): AsyncIterable<EveStreamEvent>;
1323
+ }
1324
+ /**
1325
+ * `stackbone.agent` — select a sibling eve agent by its verbatim id and get a lazy
1326
+ * eve `Client`. A declared name (a key of the augmented `AgentRegistry`)
1327
+ * autocompletes and a typo is a compile error; with no generated registry the name
1328
+ * is a loose `string` (checked at runtime against `AGENT_URLS`). Same id-keyed
1329
+ * selection style — and same `AgentName` type — as the deprecated `eveAgent(...)`.
1330
+ */
1331
+ interface AgentAccessor {
1332
+ (name: AgentName): LazyAgentClient;
1333
+ }
1334
+
1138
1335
  interface StorageObject {
1139
1336
  key: string;
1140
1337
  size: number;
@@ -1374,8 +1571,9 @@ interface InvokeOptions {
1374
1571
  connection?: string;
1375
1572
  }
1376
1573
  /**
1377
- * `client.connections` — the agent's handle on the workspace's connector
1378
- * connections. The credentials never enter the agent container: each method
1574
+ * `client.legacyConnections` — the agent's handle on the workspace's connector
1575
+ * connections under the legacy connector model. The credentials never enter the
1576
+ * agent container: each method
1379
1577
  * makes an authenticated call to the control plane (the connector executor owns
1380
1578
  * the resolved credential, in a platform process).
1381
1579
  *
@@ -1583,6 +1781,15 @@ interface UnscheduleRequest {
1583
1781
  * Contract gating: every method awaits the `queues.jobs` module gate before
1584
1782
  * touching the network, so a stale datapath / missing capability surfaces as
1585
1783
  * a gating error rather than a failed POST.
1784
+ *
1785
+ * @deprecated CLASSIC v2 ONLY. This enqueues a job that wakes a `defineAgent`
1786
+ * handler over the scale-to-zero agent-jobs dispatcher — the path being retired
1787
+ * with `/invoke`. In runtime v3 (eve + workflows) a background job IS "start a
1788
+ * workflow": from a workflow use `startWorkflow(name, input)` /
1789
+ * `startWorkflowAndWait(name, input)` and `scheduleWorkflow(name, input, cron)`
1790
+ * from `@stackbone/sdk/workflow`, which run on the World's `flows` queue with
1791
+ * their own observable runs. `client.queues.*` keeps working while cloud +
1792
+ * self-host remain on classic v2; it disappears when v3 reaches production.
1586
1793
  */
1587
1794
  declare class QueuesModule {
1588
1795
  private readonly _http;
@@ -1590,9 +1797,17 @@ declare class QueuesModule {
1590
1797
  constructor(resolved: ResolvedConfig, _http: HttpClient,
1591
1798
  /** Test seam — see `ModuleGate`. Defaults to the lazy contract gate. */
1592
1799
  gate?: ModuleGate);
1800
+ /** @deprecated Classic v2 only. Prefer `startWorkflow(name, input)` from
1801
+ * `@stackbone/sdk/workflow` (a job → a workflow run on the World). */
1593
1802
  publish(request: PublishRequest): Promise<Result<PublishJobResponse>>;
1803
+ /** @deprecated Classic v2 only. Prefer `scheduleWorkflow(name, input, cron)`
1804
+ * from `@stackbone/sdk/workflow` (a cron → a workflow run on the World). */
1594
1805
  schedule(request: ScheduleRequest): Promise<Result<ScheduleJobResponse>>;
1806
+ /** @deprecated Classic v2 only. Prefer `unschedule(name)` from
1807
+ * `@stackbone/sdk/workflow`. */
1595
1808
  unschedule(request: UnscheduleRequest): Promise<Result<UnscheduleJobResponse>>;
1809
+ /** @deprecated Classic v2 only. Prefer `listSchedules()` from
1810
+ * `@stackbone/sdk/workflow`. */
1596
1811
  listSchedules(): Promise<Result<ListSchedulesResponse>>;
1597
1812
  }
1598
1813
 
@@ -1642,7 +1857,7 @@ declare class StackboneClient {
1642
1857
  private _secrets?;
1643
1858
  private _config?;
1644
1859
  private _queues?;
1645
- private _connections?;
1860
+ private _legacyConnections?;
1646
1861
  private _memory?;
1647
1862
  private _prompts?;
1648
1863
  private _httpClient?;
@@ -1666,14 +1881,69 @@ declare class StackboneClient {
1666
1881
  */
1667
1882
  get queues(): QueuesModule;
1668
1883
  /**
1669
- * Live surface — the agent's handle on the workspace's connector connections.
1670
- * `list` / `invoke` make authenticated calls to the control-plane connectors
1671
- * proxy (`/api/v1/agent/connections/*`); the credentials never enter the agent
1884
+ * Legacy surface — the agent's handle on the workspace's connector connections
1885
+ * under the OLD connector model. `list` / `invoke(connector, action, args)` make
1886
+ * authenticated calls to the control-plane connectors proxy
1887
+ * (`/api/v1/agent/connections/*`); the credentials never enter the agent
1672
1888
  * container. Gated against `connections.actions` so the handshake-blocked /
1673
1889
  * capability-missing paths are exercised the same way as the other gated
1674
1890
  * surfaces.
1891
+ *
1892
+ * Named `legacyConnections` (not `connections`) so it no longer sits one letter
1893
+ * from the new peer-free `connection(id)` entrypoint above — the two connector
1894
+ * entrypoints are now unambiguous. Behaviour is unchanged from the old
1895
+ * `connections` member.
1896
+ */
1897
+ get legacyConnections(): ConnectionsModule;
1898
+ /**
1899
+ * Peer-free connector entrypoint — `stackbone.connection(id)` selects a Stackbone
1900
+ * Connect connector by its verbatim id and returns a typed handle whose generated
1901
+ * operations (`.sendMail({ ... })`, typed via the `StackboneConnections` registry)
1902
+ * and dynamic `.call(operation, args)` escape hatch both resolve to the same broker
1903
+ * call (`POST /api/connect/execute`, HMAC scheme A). It is a plain HMAC fetch — it
1904
+ * imports NO `eve` peer — so it is wired directly onto the client with no lazy
1905
+ * loading and pulls no new peer into the main barrel.
1906
+ *
1907
+ * This is the namespaced form of the top-level `connection(...)` export (now
1908
+ * `@deprecated`); both delegate to the same implementation. Distinct from the
1909
+ * plural `connections` surface above, which is the control-plane connectors proxy
1910
+ * (`list` / `invoke`).
1911
+ */
1912
+ get connection(): ConnectionAccessor;
1913
+ /**
1914
+ * Namespaced sibling-agent entrypoint — `stackbone.agent(id)` selects a sibling
1915
+ * eve agent by its verbatim name and returns a lazy eve `Client`, so a workflow
1916
+ * step delegates with `stackbone.agent('support').session().send({ ... })`. The
1917
+ * name is typed against the augmentable `AgentRegistry` (declared names
1918
+ * autocomplete, a typo is a compile error).
1919
+ *
1920
+ * Peer isolation is load-bearing: selecting the agent and opening a session are
1921
+ * synchronous and import NO `eve` peer — only the session's already-async leaves
1922
+ * (`send` / `stream`) resolve `eve/client` via dynamic import on first use. So a
1923
+ * tool-only agent that imports `@stackbone/sdk` and never calls `agent(...)` never
1924
+ * eager-loads the optional `eve` peer and cannot crash-loop on a missing dep.
1925
+ *
1926
+ * This is the namespaced form of the top-level `eveAgent(...)` export (now
1927
+ * `@deprecated`) on the `@stackbone/sdk/workflow` subpath; both produce the same
1928
+ * signed workflow→agent call and the same eve `Client` API.
1929
+ */
1930
+ get agent(): AgentAccessor;
1931
+ /**
1932
+ * Namespaced workflow trigger + schedule surface — `stackbone.workflows.start(...)`
1933
+ * / `.startAndWait(...)` / `.schedule(...)` / `.unschedule(...)` / `.listSchedules()`.
1934
+ * Start another workflow by name (fire-and-forget or durable sub-routine) and
1935
+ * manage dynamic cron triggers, all from inside a running workflow.
1936
+ *
1937
+ * These are peer-free shims over the ambient `WorkflowStarter` / `WorkflowScheduler`
1938
+ * the runtime injects on first dispatch — they import NO `workflow` / `eve` peer,
1939
+ * so (like `connection` / `agent`) they are wired directly onto the client and
1940
+ * pull nothing new into the main barrel. This is the namespaced form of the loose
1941
+ * `startWorkflow(...)` / `scheduleWorkflow(...)` exports (now `@deprecated`) on the
1942
+ * `@stackbone/sdk/workflow` subpath; both delegate to the same implementation, so
1943
+ * `start` / `startAndWait` keep their `"use step"` durability. The peer-bound
1944
+ * authoring API (`requestApproval` / `defineHook` / `sleep`) stays on that subpath.
1675
1945
  */
1676
- get connections(): ConnectionsModule;
1946
+ get workflows(): WorkflowsAccessor;
1677
1947
  /**
1678
1948
  * Pending surface — runtime not built. Every method returns
1679
1949
  * `not_implemented`. Mem0 is a third-party integration, not a Stackbone
@@ -1782,15 +2052,6 @@ declare const createStructuredLogger: (opts?: StructuredLoggerOptions) => Logger
1782
2052
  * socket as it is produced. On a plain (buffered) invoke `stream` is
1783
2053
  * `undefined`, so a handler that wants to stream guards on it and falls
1784
2054
  * back to returning its `output` normally.
1785
- * - `progress` / `step` are the **live run progress** helpers (distinct from
1786
- * token streaming): they record `run_steps` rows on the run so the Studio
1787
- * runs timeline fills in as the handler works. `progress(message, data?)` is
1788
- * a coarse, point-in-time note; `step({ type, name })` opens a span and
1789
- * returns a handle whose `.finish()` closes it with a duration. Both are
1790
- * runtime-injected and fire-and-forget — they are wired to the install's
1791
- * Postgres by the wrapper, are absent (no-op) when no run writer is mounted
1792
- * (e.g. plain unit tests), and the wrapper throttles `progress` so a hot
1793
- * loop cannot flood the run with notes.
1794
2055
  */
1795
2056
  interface InvokeContext<I extends z.ZodType> {
1796
2057
  input: z.infer<I>;
@@ -1800,8 +2061,6 @@ interface InvokeContext<I extends z.ZodType> {
1800
2061
  client: StackboneClient;
1801
2062
  logger: Logger;
1802
2063
  stream?: InvokeStream;
1803
- progress?: InvokeProgress;
1804
- step?: InvokeStepFn;
1805
2064
  }
1806
2065
  /**
1807
2066
  * The streaming sink handed to a handler as `ctx.stream` when the caller asked
@@ -1815,60 +2074,6 @@ interface InvokeStream {
1815
2074
  /** Emit a named structured event with an optional JSON-serialisable payload. */
1816
2075
  event(name: string, data?: unknown): void;
1817
2076
  }
1818
- /**
1819
- * The closed set of step types `ctx.step` / `ctx.progress` may record. It
1820
- * mirrors the CHECK constraint on `stackbone_platform.run_steps.type`; an
1821
- * unknown type would be rejected by Postgres, so the contract enumerates the
1822
- * allowed values at the type layer too. `agent` is the catch-all a coarse
1823
- * `progress` note records under.
1824
- */
1825
- type RunStepType = 'agent' | 'llm_call' | 'db_query' | 'http_fetch' | 'queue_publish' | 'hitl_pause' | 'tool_call' | 'rag_query' | 'storage_op';
1826
- /**
1827
- * `ctx.progress` — a coarse, point-in-time note on the run, distinct from the
1828
- * token-level `ctx.stream`. The wrapper writes one `run_steps` row (type
1829
- * `agent`) per call, opened and closed in place, so it shows up immediately on
1830
- * the Studio timeline. Fire-and-forget: it returns nothing the handler must
1831
- * await, and the wrapper throttles calls to ~1/s so a hot loop cannot flood the
1832
- * run. `data` is an optional JSON-serialisable payload stored on the row.
1833
- */
1834
- type InvokeProgress = (message: string, data?: unknown) => void;
1835
- /** Opening descriptor for `ctx.step`. */
1836
- interface StepOptions {
1837
- /** One of the canonical `run_steps` types; defaults to `agent` when omitted. */
1838
- type?: RunStepType;
1839
- /** Human-readable label for the step (the `run_steps.name` column). */
1840
- name: string;
1841
- /** Optional JSON-serialisable payload stored on the opened row. */
1842
- data?: unknown;
1843
- }
1844
- /** Closing descriptor for a `StepHandle.finish`. */
1845
- interface StepFinishOptions {
1846
- /** Terminal status; defaults to `ok`. */
1847
- status?: 'ok' | 'error';
1848
- /** Failure detail recorded on the row when the step errored. */
1849
- error?: string;
1850
- /** Optional JSON-serialisable payload merged onto the row at finish. */
1851
- data?: unknown;
1852
- }
1853
- /**
1854
- * Handle returned by `ctx.step`. The handler calls `.finish()` when the work the
1855
- * step represents completes, which closes the open `run_steps` row with a
1856
- * duration and terminal status. Calling `.finish()` more than once is a no-op —
1857
- * the first close wins.
1858
- */
1859
- interface StepHandle {
1860
- /** The id of the opened `run_steps` row (useful for nesting / correlation). */
1861
- readonly id: string;
1862
- /** Close the step. Idempotent: only the first call writes a terminal row. */
1863
- finish(options?: StepFinishOptions): void;
1864
- }
1865
- /**
1866
- * `ctx.step` — opens a span on the run and returns a handle to close it. The
1867
- * wrapper writes a `run_steps` row in the `running` state on open and updates it
1868
- * to `ok`/`error` with a duration on `.finish()`. Fire-and-forget like
1869
- * `ctx.progress`; absent (no-op handle) when no run writer is mounted.
1870
- */
1871
- type InvokeStepFn = (options: StepOptions) => StepHandle;
1872
2077
  /**
1873
2078
  * The synchronous `invoke` capability. Mirrors the wrapper's three HTTP verbs
1874
2079
  * (`/invoke`, `/health`, `/schema`): `invoke` is the only request path, its
@@ -2007,6 +2212,54 @@ declare function defineAgent<T extends Record<string, z.ZodType>>(spec: AgentSpe
2007
2212
  [K in keyof T]: HandlerBlock<T[K]>;
2008
2213
  };
2009
2214
 
2215
+ /**
2216
+ * The minimal Standard Schema surface a workflow contract exposes. Kept
2217
+ * structural so the SDK needs no `@standard-schema/spec` dependency: a Zod,
2218
+ * Valibot or ArkType schema all satisfy it (each carries a `~standard` brand).
2219
+ * The build reads the real `~standard.validate` / `z.toJSONSchema` off the live
2220
+ * object; this type only marks "a Standard Schema goes here".
2221
+ */
2222
+ interface WorkspaceStandardSchema {
2223
+ readonly '~standard': unknown;
2224
+ }
2225
+ /** One agent declared in the workspace. */
2226
+ interface WorkspaceAgent {
2227
+ /** Name = the agent's package.json name and its folder under `agents/`. */
2228
+ name: string;
2229
+ dir: string;
2230
+ }
2231
+ /** One workflow declared in the workspace. */
2232
+ interface WorkspaceWorkflow {
2233
+ /** Name used to address/trigger the workflow from Studio + the CLI. */
2234
+ name: string;
2235
+ /** Path (relative to the workspace root) of the `*.workflow.ts` module. */
2236
+ module: string;
2237
+ /** Exported workflow function name inside that module. */
2238
+ export: string;
2239
+ /**
2240
+ * RESERVED inline-contract variant (forward-looking). The contract a workflow
2241
+ * declares is harvested by the build ONLY from sibling exports next to the
2242
+ * function (`export const inputSchema`/`outputSchema`) or a `<name>.contract.ts`
2243
+ * sibling — NOT from these config fields yet. They are typed so a creator may
2244
+ * co-locate the contract here ahead of the build learning to read it, but in
2245
+ * the current dev build they are inert (no schema is extracted from them).
2246
+ * Wiring the inline variant into extraction is a follow-up.
2247
+ */
2248
+ inputSchema?: WorkspaceStandardSchema;
2249
+ outputSchema?: WorkspaceStandardSchema;
2250
+ }
2251
+ /** The default export of `stackbone.config.ts`. */
2252
+ interface StackboneWorkspace {
2253
+ agents: WorkspaceAgent[];
2254
+ workflows: WorkspaceWorkflow[];
2255
+ }
2256
+ /**
2257
+ * Type + return a workspace registry. Identity at runtime — its only job is to
2258
+ * give the creator a typed `stackbone.config.ts` default export and to own the
2259
+ * convention in one place.
2260
+ */
2261
+ declare const defineWorkspace: (workspace: StackboneWorkspace) => StackboneWorkspace;
2262
+
2010
2263
  interface InvocationContext {
2011
2264
  /** The envelope's `invocationId` — surfaced on log lines as `trace_id`. */
2012
2265
  readonly invocationId: string;
@@ -2020,6 +2273,22 @@ interface InvocationContext {
2020
2273
  * without routing info (older tests, lifecycle hooks) still type-checks.
2021
2274
  */
2022
2275
  readonly handler?: string;
2276
+ /**
2277
+ * The projected `run_steps.id` of the workflow step currently executing, when
2278
+ * the runtime can attribute the active async tree to one step. The
2279
+ * workflow-HITL helper reads it so an approval row can be anchored to the
2280
+ * exact step that requested it (`approvals.requested_by_step_id`, A6).
2281
+ *
2282
+ * GAP (2026-06-20): no caller populates this yet. The emulator binds the
2283
+ * invocation context once per WHOLE flow dispatch (see the runtime-mount
2284
+ * `flowPost` wrap), not per step, and the Workflow World runs as a FLAT tree
2285
+ * whose events carry `writer: null` / `executionContext: null`, so the
2286
+ * per-step World id is not visible at the point a `"use step"` runs. The seam
2287
+ * is threaded end-to-end (context → ambient approval client → INSERT) so the
2288
+ * column is stamped the moment a step id becomes available, without another
2289
+ * surface change. Until then it stays `undefined` and the column stays NULL.
2290
+ */
2291
+ readonly requestedByStepId?: string;
2023
2292
  }
2024
2293
  /**
2025
2294
  * Runs `fn` with `context` bound as the active invocation. The context stays
@@ -2032,6 +2301,45 @@ declare function runWithInvocationContext<T>(context: InvocationContext, fn: ()
2032
2301
  * invoke (process boot, lifecycle events, tests that don't set one up).
2033
2302
  */
2034
2303
  declare function getInvocationContext(): InvocationContext | undefined;
2304
+ /**
2305
+ * Ergonomic wrapper for callers that already hold a single correlation id and
2306
+ * want to bind it as the active run/trace for `fn` — the durable workflow step
2307
+ * call-site is the first such caller (F5): it knows the projected `run_id` and
2308
+ * the World run id, and wraps a step's execution so the step's logs and SDK
2309
+ * operations correlate to its run.
2310
+ *
2311
+ * It does NOT generate ids — that stays a caller concern, exactly like
2312
+ * `runWithInvocationContext`. `runId` and `invocationId` default to the single
2313
+ * `id` you pass, so `runWithCallerId(runId, fn)` binds a context where the run
2314
+ * and trace share that id; pass distinct values (e.g. the World run id as the
2315
+ * trace) via the options form.
2316
+ */
2317
+ declare function runWithCallerId<T>(id: string, fn: () => T, options?: {
2318
+ readonly invocationId?: string;
2319
+ readonly handler?: string;
2320
+ }): T;
2321
+
2322
+ /**
2323
+ * The ambient, lazily-resolved Stackbone client. A `Proxy` over the cached
2324
+ * `StackboneClient`: every property access (the surface accessors
2325
+ * `storage` / `rag` / `queues` / `database` / `secrets` / `config` / `ai` /
2326
+ * `approval` / `legacyConnections` / `memory` / `prompts` / `contract`, the
2327
+ * peer-free connector entrypoint `connection(id)`, the sibling-agent entrypoint
2328
+ * `agent(id)`, plus the peer-free `workflows` trigger/schedule surface) is
2329
+ * forwarded to the singleton, which is created on the
2330
+ * first such access. Because each `StackboneClient` accessor is itself lazy +
2331
+ * cached, repeated access returns the same surface instance (one client, one
2332
+ * pool, per process). `connection` and `agent` are plain function members (no
2333
+ * lazy surface build) — the Proxy binds them to the real client and forwards them
2334
+ * like any other member. `agent` is special only in that the eve peer it needs is
2335
+ * resolved lazily on the first async turn, NOT at member access.
2336
+ *
2337
+ * No surface is constructed and no env var is read at import time. A surface op
2338
+ * that needs a genuinely-absent required env var (e.g. `STACKBONE_POSTGRES_URL`
2339
+ * for an agent-local op) fails with the surface's actionable, coded error
2340
+ * (`database_not_configured` etc.), never a silent `undefined`.
2341
+ */
2342
+ declare const stackbone: StackboneClient;
2035
2343
 
2036
2344
  /** The subset of the global `console` this bridge replaces. */
2037
2345
  interface ConsoleLike {
@@ -2242,4 +2550,4 @@ interface JsonSchemaDocument {
2242
2550
  */
2243
2551
  declare const analyzeAgentSchemas: (pair: AgentSchemaPair) => SchemaIntrospectionResult;
2244
2552
 
2245
- export { type AddMemoryRequest, type AgentSchemaPair, type AgentSpec, type AnyCapability, type ApprovalListOptions, type ApprovalListResult, type ApprovalRecord, type ApprovalRequest, type ApprovalRequestOptions, type ApprovalStatus, type ApprovalTool, type ApprovalToolSpec, type ApprovalTopic, type ApproverInfo, type ClientConfig, type CompilePromptResult, type ConsoleLike, type CreatePromptRequest, type Decision, type DecisionStatus, type DeleteAllMemoryRequest, type DeletePromptOptions, type DeletePromptResult, type EndSessionOptions, type EndSessionResult, type FatalConstruct, type GeneratedImage, type GetPromptOptions, INVOCATION_ID_HEADER, INVOKE_TIMEOUT_HARD_CAP_MS, type ImageGenerateParams, type ImagesResponse, type IngestAsyncHandle, type InstallConsoleCaptureOptions, type InvocationContext, type InvokeCapability, type InvokeContext, type InvokeEnvelopeError, type InvokeErrorEnvelope, type InvokeOptions, type InvokeProgress, type InvokeRequest, type InvokeResponse, type InvokeStepFn, type InvokeStream, type InvokeSuccessEnvelope, type JobCapability, type JsonSchemaDocument, type ListMemoryRequest, type ListMemoryResult, type ListOptions, type ListPromptsOptions, type ListPromptsResult, type LoadSystemSecretsArgs, type LogSink, type Logger, type LoggerBindings, type MemoryContent, type MemoryHistoryEntry, type MemoryHistoryEvent, type MemoryHit, type MemoryItem, type MemoryScope, type ModelsListResponse, type OpenRouterModel, type Prompt, type PublishRequest, RESERVED_ERROR_CODES, RESERVED_HANDLER_NAMES, RUN_ID_HEADER, type ReservedErrorCode, type Result, type RunStepType, STORED_TO_SDK_ENV, type ScheduleRequest, type SchemaDiagnostic, type SchemaHalf, type SchemaIntrospectionResult, type SdkError, type SdkErrorCode, type SearchMemoryOptions, type SignedUrl, type SignedUrlOptions, StackboneClient, type StepFinishOptions, type StepHandle, type StepOptions, type StorageBody, type StorageObject, type StructuredLoggerOptions, type SystemSecretRow, type SystemSecretsReader, type UnscheduleRequest, type UpdateMemoryOptions, type UpdatePromptOptions, type UploadOptions, type VerifyOptions, type WarnConstruct, analyzeAgentSchemas, createClient, createStructuredLogger, defineAgent, getInvocationContext, installInvocationConsoleCapture, invokeRequestSchema, isReservedErrorCode, isSdkErrorCode, loadSystemSecretsIntoEnv, rehydrateSystemSecretsRows, runWithInvocationContext };
2553
+ export { type AddMemoryRequest, type AgentAccessor, type AgentSchemaPair, type AgentSpec, type AnyCapability, type ApprovalListOptions, type ApprovalListResult, type ApprovalRecord, type ApprovalRequest, type ApprovalRequestOptions, type ApprovalStatus, type ApprovalTool, type ApprovalToolSpec, type ApprovalTopic, type ApproverInfo, type ClientConfig, type CompilePromptResult, type ConfigRegistry, type ConsoleLike, type CreatePromptRequest, type Decision, type DecisionStatus, type DeleteAllMemoryRequest, type DeletePromptOptions, type DeletePromptResult, type EndSessionOptions, type EndSessionResult, type EveMessageResponse, type EveMessageResult, type EveSessionState, type EveStreamEvent, type FatalConstruct, type GeneratedImage, type GetPromptOptions, INVOCATION_ID_HEADER, INVOKE_TIMEOUT_HARD_CAP_MS, type ImageGenerateParams, type ImagesResponse, type IngestAsyncHandle, type InstallConsoleCaptureOptions, type InvocationContext, type InvokeCapability, type InvokeContext, type InvokeEnvelopeError, type InvokeErrorEnvelope, type InvokeOptions, type InvokeRequest, type InvokeResponse, type InvokeStream, type InvokeSuccessEnvelope, type JobCapability, type JsonSchemaDocument, type LazyAgentClient, type LazyAgentSession, type ListMemoryRequest, type ListMemoryResult, type ListOptions, type ListPromptsOptions, type ListPromptsResult, type LoadSystemSecretsArgs, type LogSink, type Logger, type LoggerBindings, type MemoryContent, type MemoryHistoryEntry, type MemoryHistoryEvent, type MemoryHit, type MemoryItem, type MemoryScope, type ModelsListResponse, type OpenRouterModel, type Prompt, type PublishRequest, RESERVED_ERROR_CODES, RESERVED_HANDLER_NAMES, RUN_ID_HEADER, type ReservedErrorCode, type Result, STORED_TO_SDK_ENV, type ScheduleRequest, ScheduledWorkflow, type SchemaDiagnostic, type SchemaHalf, type SchemaIntrospectionResult, type SdkError, type SdkErrorCode, type SearchMemoryOptions, type SendTurnInput, type SignedUrl, type SignedUrlOptions, StackboneClient, type StackboneWorkspace, type StorageBody, type StorageObject, type StructuredLoggerOptions, type SystemSecretRow, type SystemSecretsReader, type UnscheduleRequest, type UpdateMemoryOptions, type UpdatePromptOptions, type UploadOptions, type VerifyOptions, type WarnConstruct, WorkflowStartHandle, type WorkflowsAccessor, type WorkspaceAgent, type WorkspaceStandardSchema, type WorkspaceWorkflow, analyzeAgentSchemas, createClient, createStructuredLogger, defineAgent, defineWorkspace, getInvocationContext, installInvocationConsoleCapture, invokeRequestSchema, isReservedErrorCode, isSdkErrorCode, loadSystemSecretsIntoEnv, rehydrateSystemSecretsRows, runWithCallerId, runWithInvocationContext, stackbone };