@stackbone/sdk 0.1.0-alpha.5 → 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.d.cts CHANGED
@@ -1,11 +1,14 @@
1
1
  import { AgentConnectionListResponse, InvokeConnectorActionResponse, PublishJobResponse, ScheduleJobResponse, UnscheduleJobResponse, ListSchedulesResponse, ContractResponse } from '@stackbone/validators';
2
- import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
3
2
  import { Sql } from 'postgres';
3
+ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
4
4
  import { IngestJobWriter, IngestRequest, IngestResponse, RagIngestProgress, DeleteOptions, DeleteResponse, RetrieveRequest, RetrieveHit, ChunkOptions, ParseInput, ParseOptions } from '@stackbone/rag-core';
5
5
  export { ChunkOptions, ChunkStrategy, DeleteOptions, DeleteResponse, IngestChunk, IngestRequest, IngestRequestAutoEmbed, IngestRequestPrecomputed, IngestResponse, ParseInput, ParseOptions, RagIngestProgress, RetrieveHit, RetrieveRequest, RetrieveRequestAutoEmbed, RetrieveRequestPrecomputed } from '@stackbone/rag-core';
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 { A as AgentName } from './workflow-scheduler-DXCNKDOS.cjs';
10
+ export { b as AgentRegistry, S as ScheduledWorkflow, c as WorkflowScheduler, a as WorkflowStartHandle, d as WorkflowStarter, W as WorkflowTriggerOptions, g as getWorkflowScheduler, e as getWorkflowStarter, s as setWorkflowScheduler, f as setWorkflowStarter } from './workflow-scheduler-DXCNKDOS.cjs';
11
+ import { a as ConnectionAccessor } from './call-connector-CYDw_yG5.cjs';
9
12
  import { S3Client } from '@aws-sdk/client-s3';
10
13
  import { z } from 'zod';
11
14
  export { z } from 'zod';
@@ -77,7 +80,7 @@ interface ClientConfig {
77
80
  * RAG-related defaults parsed from `agent.yaml.rag` by the CLI/orchestrator
78
81
  * and forwarded here. The SDK never reads `agent.yaml` itself — keeping
79
82
  * filesystem ownership in the CLI. Defaults follow ADR
80
- * `2026-05-10-rag-consolidation-on-client-database` (D2/D6).
83
+ * `2026-06-05-rag` (D2/D6).
81
84
  */
82
85
  rag?: {
83
86
  /**
@@ -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
@@ -483,6 +488,43 @@ declare class DatabaseModule {
483
488
  delete: DrizzleClient['delete'];
484
489
  execute: DrizzleClient['execute'];
485
490
  transaction: DrizzleClient['transaction'];
491
+ /**
492
+ * Cross-surface raw-SQL runner carrying the SAME cold-start resilience the
493
+ * query-builder verbs above get. Sibling agent-local surfaces (`approval`,
494
+ * `config`, `secrets`, `prompts`) that issue tagged-template queries over the
495
+ * shared postgres-js `Sql` MUST execute them through this instead of caching
496
+ * `shared().$client` once and calling it directly. Otherwise a dead pooled
497
+ * socket — Fly Machines suspending the Machine between invokes, or a
498
+ * WSL2/Docker localhost relay dropping an idle connection during a long LLM
499
+ * step — surfaces as an unretried `CONNECTION_ENDED`/`ECONNRESET`. That is
500
+ * exactly the asymmetry that let `client.approval.request` fail while the
501
+ * `client.database.insert` right before it recovered.
502
+ *
503
+ * `fn` receives a FRESH `$client` on each attempt, so the single retry runs
504
+ * against the rebuilt pool. Whole-operation granularity is replayed as a
505
+ * unit — pass a multi-statement `sql.begin(...)` transaction or a helper that
506
+ * fires several queries and the replay re-runs all of it; postgres-js never
507
+ * commits a half-applied tx, so that is safe. SQLSTATE application errors
508
+ * pass straight through without a retry. Like `shared()`/`raw()`, the
509
+ * contract gate is intentionally NOT consulted here — gating surfaces gate at
510
+ * their own call sites.
511
+ */
512
+ runShared<T>(fn: (sql: Sql) => Promise<T> | T): Promise<T>;
513
+ /**
514
+ * `Result`-shaped sibling of `runShared` for surfaces whose driver swallows
515
+ * the dead-socket error into a returned `Result.err.cause` instead of
516
+ * throwing it — today only `client.rag`, whose `RagPipeline` returns a
517
+ * `Result` rather than throwing. `attempt` runs once; if it comes back with a
518
+ * pool-terminated `cause`, the pool is rebuilt and `attempt` replays exactly
519
+ * once, then its result (success or the fresh error) is returned verbatim.
520
+ * The `Result` contract is preserved end to end: a still-dead socket on the
521
+ * replay surfaces as the surface's own `Result.err`, never as a raw throw.
522
+ */
523
+ runSharedResult<T extends {
524
+ error?: {
525
+ cause?: unknown;
526
+ } | null;
527
+ }>(attempt: () => Promise<T>): Promise<T>;
486
528
  /**
487
529
  * Canonical accessor for the **shared-handles pattern**. Returns the
488
530
  * process-wide Drizzle handle backing `client.database`. Cross-surface
@@ -603,6 +645,23 @@ interface ApprovalRequestOptions<T = unknown> {
603
645
  /** Same `(topic, idempotencyKey)` returns the same `approvalId` instead of creating a new one. */
604
646
  idempotencyKey?: string;
605
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;
606
665
  }
607
666
  interface ApprovalRequest {
608
667
  approvalId: string;
@@ -640,11 +699,13 @@ interface ApprovalListResult<T = unknown> {
640
699
  * `verify()` (local crypto — see `verify.ts`).
641
700
  *
642
701
  * The write populates only the columns the cloud `create()` used to set
643
- * (topic/payload/callback_url/idempotency_key/fallback/metadata/timeout_at;
644
- * `schema` was sourced from a DTO field the SDK options object does not carry,
645
- * so it stays NULL). `workspace_id`/`agent_id`/`run_id` stay NULL exactly as
646
- * they were on the control-plane path the idempotency `ON CONFLICT` relies on
647
- * `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).
648
709
  */
649
710
  declare class ApprovalFacade {
650
711
  private readonly _resolved;
@@ -671,6 +732,38 @@ declare class ApprovalFacade {
671
732
  private sql;
672
733
  }
673
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;
674
767
  declare class ConfigFacade {
675
768
  private readonly _resolved;
676
769
  /** Lazy accessor for `client.database` — see `SecretsFacade`. */
@@ -678,14 +771,21 @@ declare class ConfigFacade {
678
771
  constructor(_resolved: ResolvedConfig,
679
772
  /** Lazy accessor for `client.database` — see `SecretsFacade`. */
680
773
  _getDatabase: () => DatabaseModule);
681
- get<T = unknown>(key: string): Promise<Result<T>>;
774
+ get<K extends keyof ConfigShape>(key: K): Promise<Result<ConfigShape[K]>>;
682
775
  /**
683
776
  * Keys absent from the agent's config come back as omissions in the
684
777
  * response — the returned map only contains entries the agent DB actually
685
778
  * has, so callers must access fields with `?.` (the return type is
686
779
  * `Partial<T>`).
687
780
  */
688
- 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>>;
689
789
  private loadPayload;
690
790
  private sql;
691
791
  }
@@ -949,7 +1049,7 @@ interface IngestAsyncHandle {
949
1049
  * Implementation note: `RagModule` is a thin facade over `RagPipeline`. The
950
1050
  * pipeline owns parse → chunk → embed → persist; the facade resolves the
951
1051
  * shared `client.database` pool, builds an `Embedder` on demand, and maps
952
- * configuration errors. See ADR `2026-05-10-rag-consolidation-on-client-database`.
1052
+ * configuration errors. See ADR `2026-06-05-rag`.
953
1053
  *
954
1054
  * Connection ownership: this module never opens its own postgres pool. It
955
1055
  * reaches the underlying `postgres-js` `Sql` through the **shared-handles
@@ -1098,6 +1198,109 @@ declare class SecretsFacade {
1098
1198
  private sql;
1099
1199
  }
1100
1200
 
1201
+ /**
1202
+ * eve's serialized session cursor. Mirrors eve's nominal `SessionState`
1203
+ * interface (`{ continuationToken?, sessionId?, streamIndex }`) so a value the
1204
+ * creator reads from a real eve session is assignable to the lazy
1205
+ * `session(state)` resume parameter. NOT a loose `Record` — eve's `SessionState`
1206
+ * has a required `streamIndex`, and a `Record<string, unknown>` mirror would
1207
+ * reject it (the nominal interface lacks the record's index signature).
1208
+ */
1209
+ interface EveSessionState {
1210
+ readonly continuationToken?: string;
1211
+ readonly sessionId?: string;
1212
+ readonly streamIndex: number;
1213
+ }
1214
+ /**
1215
+ * One streamed turn event from an eve session's NDJSON stream. A peer-free
1216
+ * structural mirror of the slice of eve's `HandleMessageStreamEvent` a workflow
1217
+ * reads when it FORWARDS frames to its own output (`getWritable()`): the
1218
+ * discriminant `type` and the per-frame `data`. Eve's real union is far richer
1219
+ * (dozens of frame variants), but a workflow that drains the stream only narrows
1220
+ * on `type` and reads `data` off the matched frame — so this loose, open shape is
1221
+ * what the forward loop needs while keeping the optional `eve` peer out of the
1222
+ * main barrel's type graph. A creator who wants the full eve union types the
1223
+ * `getWritable<...>()` sink with eve's own `HandleMessageStreamEvent`.
1224
+ */
1225
+ interface EveStreamEvent {
1226
+ readonly type: string;
1227
+ readonly data?: unknown;
1228
+ readonly [key: string]: unknown;
1229
+ }
1230
+ /**
1231
+ * The turn payload eve's `session.send(...)` accepts. A bare string is shorthand
1232
+ * for `{ message }`; the object form carries follow-up text, HITL results, client
1233
+ * context, output schema, signal, and headers. Kept loose on purpose — the lazy
1234
+ * member forwards it verbatim to the real eve session.
1235
+ */
1236
+ type SendTurnInput<_TOutput = unknown> = string | Readonly<Record<string, unknown>>;
1237
+ /**
1238
+ * The aggregated result of one turn, returned by `EveMessageResponse.result()`.
1239
+ * Mirrors the slice of eve's `MessageResult<TOutput>` the workflow→agent hop
1240
+ * reads: the typed structured `data` (from the turn's `outputSchema`) plus the
1241
+ * terminal `status`. Eve's real `MessageResult` is richer and takes precedence
1242
+ * when the creator has `eve` installed.
1243
+ */
1244
+ interface EveMessageResult<TOutput = unknown> {
1245
+ readonly data: TOutput | undefined;
1246
+ readonly status: 'completed' | 'failed' | 'waiting';
1247
+ }
1248
+ /**
1249
+ * The response eve's `session.send(...)` returns. Mirrors the slice of eve's
1250
+ * `MessageResponse<TOutput>` the hop drives: collect the turn via `result()` OR
1251
+ * iterate the event stream with `for await...of` (the response is
1252
+ * `AsyncIterable`). Both consume the SAME single-use stream.
1253
+ */
1254
+ interface EveMessageResponse<TOutput = unknown> extends AsyncIterable<EveStreamEvent> {
1255
+ result(): Promise<EveMessageResult<TOutput>>;
1256
+ }
1257
+
1258
+ /**
1259
+ * The eve `Client` surface a lazy agent handle exposes. Narrowed to the
1260
+ * `session(...)` factory the workflow→agent path uses; the returned session is the
1261
+ * lazy `LazyAgentSession` below (structurally compatible with eve's `ClientSession`).
1262
+ */
1263
+ interface LazyAgentClient {
1264
+ session(state?: EveSessionState | string): LazyAgentSession;
1265
+ }
1266
+ /**
1267
+ * The eve `ClientSession` surface a lazy agent session exposes — a DROP-IN twin of
1268
+ * eve's native `ClientSession`, so a workflow written against the eager `eveAgent`
1269
+ * path keeps compiling verbatim when it swaps to `stackbone.agent`. `send` /
1270
+ * `stream` are the async leaves that resolve the `eve` peer on first use;
1271
+ * everything above them (selecting the agent, opening the session) stays
1272
+ * synchronous and peer-free. `send` returns eve's `MessageResponse<TOutput>` (so
1273
+ * `.result()` and `for await...of` both work), and `state` exposes the advanced
1274
+ * cursor a workflow persists between turns — readable once a turn has built the
1275
+ * real session.
1276
+ */
1277
+ interface LazyAgentSession {
1278
+ /**
1279
+ * Current session cursor (continuation token, session id, stream cursor), read
1280
+ * to persist + resume across turns. A DROP-IN twin of eve's `ClientSession.state`,
1281
+ * which is readable from construction: before the first `send` / `stream` it
1282
+ * echoes the seed passed to `session(state)` (a bare continuation-token string
1283
+ * normalizes to `{ continuationToken, streamIndex: 0 }`, an absent seed to the
1284
+ * initial `{ streamIndex: 0 }`), and after a turn it exposes the advanced cursor
1285
+ * off the real eve session. Never throws.
1286
+ */
1287
+ readonly state: EveSessionState;
1288
+ send<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<EveMessageResponse<TOutput>>;
1289
+ stream(options?: {
1290
+ startIndex?: number;
1291
+ }): AsyncIterable<EveStreamEvent>;
1292
+ }
1293
+ /**
1294
+ * `stackbone.agent` — select a sibling eve agent by its verbatim id and get a lazy
1295
+ * eve `Client`. A declared name (a key of the augmented `AgentRegistry`)
1296
+ * autocompletes and a typo is a compile error; with no generated registry the name
1297
+ * is a loose `string` (checked at runtime against `AGENT_URLS`). Same id-keyed
1298
+ * selection style — and same `AgentName` type — as the deprecated `eveAgent(...)`.
1299
+ */
1300
+ interface AgentAccessor {
1301
+ (name: AgentName): LazyAgentClient;
1302
+ }
1303
+
1101
1304
  interface StorageObject {
1102
1305
  key: string;
1103
1306
  size: number;
@@ -1337,8 +1540,9 @@ interface InvokeOptions {
1337
1540
  connection?: string;
1338
1541
  }
1339
1542
  /**
1340
- * `client.connections` — the agent's handle on the workspace's connector
1341
- * connections. The credentials never enter the agent container: each method
1543
+ * `client.legacyConnections` — the agent's handle on the workspace's connector
1544
+ * connections under the legacy connector model. The credentials never enter the
1545
+ * agent container: each method
1342
1546
  * makes an authenticated call to the control plane (the connector executor owns
1343
1547
  * the resolved credential, in a platform process).
1344
1548
  *
@@ -1546,6 +1750,15 @@ interface UnscheduleRequest {
1546
1750
  * Contract gating: every method awaits the `queues.jobs` module gate before
1547
1751
  * touching the network, so a stale datapath / missing capability surfaces as
1548
1752
  * a gating error rather than a failed POST.
1753
+ *
1754
+ * @deprecated CLASSIC v2 ONLY. This enqueues a job that wakes a `defineAgent`
1755
+ * handler over the scale-to-zero agent-jobs dispatcher — the path being retired
1756
+ * with `/invoke`. In runtime v3 (eve + workflows) a background job IS "start a
1757
+ * workflow": from a workflow use `startWorkflow(name, input)` /
1758
+ * `startWorkflowAndWait(name, input)` and `scheduleWorkflow(name, input, cron)`
1759
+ * from `@stackbone/sdk/workflow`, which run on the World's `flows` queue with
1760
+ * their own observable runs. `client.queues.*` keeps working while cloud +
1761
+ * self-host remain on classic v2; it disappears when v3 reaches production.
1549
1762
  */
1550
1763
  declare class QueuesModule {
1551
1764
  private readonly _http;
@@ -1553,9 +1766,17 @@ declare class QueuesModule {
1553
1766
  constructor(resolved: ResolvedConfig, _http: HttpClient,
1554
1767
  /** Test seam — see `ModuleGate`. Defaults to the lazy contract gate. */
1555
1768
  gate?: ModuleGate);
1769
+ /** @deprecated Classic v2 only. Prefer `startWorkflow(name, input)` from
1770
+ * `@stackbone/sdk/workflow` (a job → a workflow run on the World). */
1556
1771
  publish(request: PublishRequest): Promise<Result<PublishJobResponse>>;
1772
+ /** @deprecated Classic v2 only. Prefer `scheduleWorkflow(name, input, cron)`
1773
+ * from `@stackbone/sdk/workflow` (a cron → a workflow run on the World). */
1557
1774
  schedule(request: ScheduleRequest): Promise<Result<ScheduleJobResponse>>;
1775
+ /** @deprecated Classic v2 only. Prefer `unschedule(name)` from
1776
+ * `@stackbone/sdk/workflow`. */
1558
1777
  unschedule(request: UnscheduleRequest): Promise<Result<UnscheduleJobResponse>>;
1778
+ /** @deprecated Classic v2 only. Prefer `listSchedules()` from
1779
+ * `@stackbone/sdk/workflow`. */
1559
1780
  listSchedules(): Promise<Result<ListSchedulesResponse>>;
1560
1781
  }
1561
1782
 
@@ -1605,7 +1826,7 @@ declare class StackboneClient {
1605
1826
  private _secrets?;
1606
1827
  private _config?;
1607
1828
  private _queues?;
1608
- private _connections?;
1829
+ private _legacyConnections?;
1609
1830
  private _memory?;
1610
1831
  private _prompts?;
1611
1832
  private _httpClient?;
@@ -1629,14 +1850,53 @@ declare class StackboneClient {
1629
1850
  */
1630
1851
  get queues(): QueuesModule;
1631
1852
  /**
1632
- * Live surface — the agent's handle on the workspace's connector connections.
1633
- * `list` / `invoke` make authenticated calls to the control-plane connectors
1634
- * proxy (`/api/v1/agent/connections/*`); the credentials never enter the agent
1853
+ * Legacy surface — the agent's handle on the workspace's connector connections
1854
+ * under the OLD connector model. `list` / `invoke(connector, action, args)` make
1855
+ * authenticated calls to the control-plane connectors proxy
1856
+ * (`/api/v1/agent/connections/*`); the credentials never enter the agent
1635
1857
  * container. Gated against `connections.actions` so the handshake-blocked /
1636
1858
  * capability-missing paths are exercised the same way as the other gated
1637
1859
  * surfaces.
1860
+ *
1861
+ * Named `legacyConnections` (not `connections`) so it no longer sits one letter
1862
+ * from the new peer-free `connection(id)` entrypoint above — the two connector
1863
+ * entrypoints are now unambiguous. Behaviour is unchanged from the old
1864
+ * `connections` member.
1865
+ */
1866
+ get legacyConnections(): ConnectionsModule;
1867
+ /**
1868
+ * Peer-free connector entrypoint — `stackbone.connection(id)` selects a Stackbone
1869
+ * Connect connector by its verbatim id and returns a typed handle whose generated
1870
+ * operations (`.sendMail({ ... })`, typed via the `StackboneConnections` registry)
1871
+ * and dynamic `.call(operation, args)` escape hatch both resolve to the same broker
1872
+ * call (`POST /api/connect/execute`, HMAC scheme A). It is a plain HMAC fetch — it
1873
+ * imports NO `eve` peer — so it is wired directly onto the client with no lazy
1874
+ * loading and pulls no new peer into the main barrel.
1875
+ *
1876
+ * This is the namespaced form of the top-level `connection(...)` export (now
1877
+ * `@deprecated`); both delegate to the same implementation. Distinct from the
1878
+ * plural `connections` surface above, which is the control-plane connectors proxy
1879
+ * (`list` / `invoke`).
1880
+ */
1881
+ get connection(): ConnectionAccessor;
1882
+ /**
1883
+ * Namespaced sibling-agent entrypoint — `stackbone.agent(id)` selects a sibling
1884
+ * eve agent by its verbatim name and returns a lazy eve `Client`, so a workflow
1885
+ * step delegates with `stackbone.agent('support').session().send({ ... })`. The
1886
+ * name is typed against the augmentable `AgentRegistry` (declared names
1887
+ * autocomplete, a typo is a compile error).
1888
+ *
1889
+ * Peer isolation is load-bearing: selecting the agent and opening a session are
1890
+ * synchronous and import NO `eve` peer — only the session's already-async leaves
1891
+ * (`send` / `stream`) resolve `eve/client` via dynamic import on first use. So a
1892
+ * tool-only agent that imports `@stackbone/sdk` and never calls `agent(...)` never
1893
+ * eager-loads the optional `eve` peer and cannot crash-loop on a missing dep.
1894
+ *
1895
+ * This is the namespaced form of the top-level `eveAgent(...)` export (now
1896
+ * `@deprecated`) on the `@stackbone/sdk/workflow` subpath; both produce the same
1897
+ * signed workflow→agent call and the same eve `Client` API.
1638
1898
  */
1639
- get connections(): ConnectionsModule;
1899
+ get agent(): AgentAccessor;
1640
1900
  /**
1641
1901
  * Pending surface — runtime not built. Every method returns
1642
1902
  * `not_implemented`. Mem0 is a third-party integration, not a Stackbone
@@ -1738,6 +1998,13 @@ declare const createStructuredLogger: (opts?: StructuredLoggerOptions) => Logger
1738
1998
  * - `logger` is a child of the wrapper's structured logger already
1739
1999
  * bound to `invocationId` and `runId`, so the handler does not have to
1740
2000
  * pass them on every line. The actual JSON format lands in F6.
2001
+ * - `stream` is present **only** when the caller requested a streamed reply
2002
+ * (an SSE `/invoke`). The handler pushes incremental output through it —
2003
+ * `delta(text)` for token-by-token text and `event(name, data?)` for a
2004
+ * named structured event — and the wrapper relays each onto the open
2005
+ * socket as it is produced. On a plain (buffered) invoke `stream` is
2006
+ * `undefined`, so a handler that wants to stream guards on it and falls
2007
+ * back to returning its `output` normally.
1741
2008
  */
1742
2009
  interface InvokeContext<I extends z.ZodType> {
1743
2010
  input: z.infer<I>;
@@ -1746,6 +2013,19 @@ interface InvokeContext<I extends z.ZodType> {
1746
2013
  runId: string;
1747
2014
  client: StackboneClient;
1748
2015
  logger: Logger;
2016
+ stream?: InvokeStream;
2017
+ }
2018
+ /**
2019
+ * The streaming sink handed to a handler as `ctx.stream` when the caller asked
2020
+ * for a streamed `/invoke`. Both methods are fire-and-forget — the handler
2021
+ * emits, the wrapper relays — so neither returns a promise the handler must
2022
+ * await.
2023
+ */
2024
+ interface InvokeStream {
2025
+ /** Emit an incremental chunk of text (e.g. a model token). */
2026
+ delta(text: string): void;
2027
+ /** Emit a named structured event with an optional JSON-serialisable payload. */
2028
+ event(name: string, data?: unknown): void;
1749
2029
  }
1750
2030
  /**
1751
2031
  * The synchronous `invoke` capability. Mirrors the wrapper's three HTTP verbs
@@ -1885,6 +2165,54 @@ declare function defineAgent<T extends Record<string, z.ZodType>>(spec: AgentSpe
1885
2165
  [K in keyof T]: HandlerBlock<T[K]>;
1886
2166
  };
1887
2167
 
2168
+ /**
2169
+ * The minimal Standard Schema surface a workflow contract exposes. Kept
2170
+ * structural so the SDK needs no `@standard-schema/spec` dependency: a Zod,
2171
+ * Valibot or ArkType schema all satisfy it (each carries a `~standard` brand).
2172
+ * The build reads the real `~standard.validate` / `z.toJSONSchema` off the live
2173
+ * object; this type only marks "a Standard Schema goes here".
2174
+ */
2175
+ interface WorkspaceStandardSchema {
2176
+ readonly '~standard': unknown;
2177
+ }
2178
+ /** One agent declared in the workspace. */
2179
+ interface WorkspaceAgent {
2180
+ /** Name = the agent's package.json name and its folder under `agents/`. */
2181
+ name: string;
2182
+ dir: string;
2183
+ }
2184
+ /** One workflow declared in the workspace. */
2185
+ interface WorkspaceWorkflow {
2186
+ /** Name used to address/trigger the workflow from Studio + the CLI. */
2187
+ name: string;
2188
+ /** Path (relative to the workspace root) of the `*.workflow.ts` module. */
2189
+ module: string;
2190
+ /** Exported workflow function name inside that module. */
2191
+ export: string;
2192
+ /**
2193
+ * RESERVED inline-contract variant (forward-looking). The contract a workflow
2194
+ * declares is harvested by the build ONLY from sibling exports next to the
2195
+ * function (`export const inputSchema`/`outputSchema`) or a `<name>.contract.ts`
2196
+ * sibling — NOT from these config fields yet. They are typed so a creator may
2197
+ * co-locate the contract here ahead of the build learning to read it, but in
2198
+ * the current dev build they are inert (no schema is extracted from them).
2199
+ * Wiring the inline variant into extraction is a follow-up.
2200
+ */
2201
+ inputSchema?: WorkspaceStandardSchema;
2202
+ outputSchema?: WorkspaceStandardSchema;
2203
+ }
2204
+ /** The default export of `stackbone.config.ts`. */
2205
+ interface StackboneWorkspace {
2206
+ agents: WorkspaceAgent[];
2207
+ workflows: WorkspaceWorkflow[];
2208
+ }
2209
+ /**
2210
+ * Type + return a workspace registry. Identity at runtime — its only job is to
2211
+ * give the creator a typed `stackbone.config.ts` default export and to own the
2212
+ * convention in one place.
2213
+ */
2214
+ declare const defineWorkspace: (workspace: StackboneWorkspace) => StackboneWorkspace;
2215
+
1888
2216
  interface InvocationContext {
1889
2217
  /** The envelope's `invocationId` — surfaced on log lines as `trace_id`. */
1890
2218
  readonly invocationId: string;
@@ -1898,6 +2226,22 @@ interface InvocationContext {
1898
2226
  * without routing info (older tests, lifecycle hooks) still type-checks.
1899
2227
  */
1900
2228
  readonly handler?: string;
2229
+ /**
2230
+ * The projected `run_steps.id` of the workflow step currently executing, when
2231
+ * the runtime can attribute the active async tree to one step. The
2232
+ * workflow-HITL helper reads it so an approval row can be anchored to the
2233
+ * exact step that requested it (`approvals.requested_by_step_id`, A6).
2234
+ *
2235
+ * GAP (2026-06-20): no caller populates this yet. The emulator binds the
2236
+ * invocation context once per WHOLE flow dispatch (see the runtime-mount
2237
+ * `flowPost` wrap), not per step, and the Workflow World runs as a FLAT tree
2238
+ * whose events carry `writer: null` / `executionContext: null`, so the
2239
+ * per-step World id is not visible at the point a `"use step"` runs. The seam
2240
+ * is threaded end-to-end (context → ambient approval client → INSERT) so the
2241
+ * column is stamped the moment a step id becomes available, without another
2242
+ * surface change. Until then it stays `undefined` and the column stays NULL.
2243
+ */
2244
+ readonly requestedByStepId?: string;
1901
2245
  }
1902
2246
  /**
1903
2247
  * Runs `fn` with `context` bound as the active invocation. The context stays
@@ -1910,6 +2254,44 @@ declare function runWithInvocationContext<T>(context: InvocationContext, fn: ()
1910
2254
  * invoke (process boot, lifecycle events, tests that don't set one up).
1911
2255
  */
1912
2256
  declare function getInvocationContext(): InvocationContext | undefined;
2257
+ /**
2258
+ * Ergonomic wrapper for callers that already hold a single correlation id and
2259
+ * want to bind it as the active run/trace for `fn` — the durable workflow step
2260
+ * call-site is the first such caller (F5): it knows the projected `run_id` and
2261
+ * the World run id, and wraps a step's execution so the step's logs and SDK
2262
+ * operations correlate to its run.
2263
+ *
2264
+ * It does NOT generate ids — that stays a caller concern, exactly like
2265
+ * `runWithInvocationContext`. `runId` and `invocationId` default to the single
2266
+ * `id` you pass, so `runWithCallerId(runId, fn)` binds a context where the run
2267
+ * and trace share that id; pass distinct values (e.g. the World run id as the
2268
+ * trace) via the options form.
2269
+ */
2270
+ declare function runWithCallerId<T>(id: string, fn: () => T, options?: {
2271
+ readonly invocationId?: string;
2272
+ readonly handler?: string;
2273
+ }): T;
2274
+
2275
+ /**
2276
+ * The ambient, lazily-resolved Stackbone client. A `Proxy` over the cached
2277
+ * `StackboneClient`: every property access (the surface accessors
2278
+ * `storage` / `rag` / `queues` / `database` / `secrets` / `config` / `ai` /
2279
+ * `approval` / `legacyConnections` / `memory` / `prompts` / `contract`, the
2280
+ * peer-free connector entrypoint `connection(id)`, plus the sibling-agent
2281
+ * entrypoint `agent(id)`) is forwarded to the singleton, which is created on the
2282
+ * first such access. Because each `StackboneClient` accessor is itself lazy +
2283
+ * cached, repeated access returns the same surface instance (one client, one
2284
+ * pool, per process). `connection` and `agent` are plain function members (no
2285
+ * lazy surface build) — the Proxy binds them to the real client and forwards them
2286
+ * like any other member. `agent` is special only in that the eve peer it needs is
2287
+ * resolved lazily on the first async turn, NOT at member access.
2288
+ *
2289
+ * No surface is constructed and no env var is read at import time. A surface op
2290
+ * that needs a genuinely-absent required env var (e.g. `STACKBONE_POSTGRES_URL`
2291
+ * for an agent-local op) fails with the surface's actionable, coded error
2292
+ * (`database_not_configured` etc.), never a silent `undefined`.
2293
+ */
2294
+ declare const stackbone: StackboneClient;
1913
2295
 
1914
2296
  /** The subset of the global `console` this bridge replaces. */
1915
2297
  interface ConsoleLike {
@@ -2120,4 +2502,4 @@ interface JsonSchemaDocument {
2120
2502
  */
2121
2503
  declare const analyzeAgentSchemas: (pair: AgentSchemaPair) => SchemaIntrospectionResult;
2122
2504
 
2123
- 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 InvokeRequest, type InvokeResponse, 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, STORED_TO_SDK_ENV, type ScheduleRequest, type SchemaDiagnostic, type SchemaHalf, type SchemaIntrospectionResult, type SdkError, type SdkErrorCode, type SearchMemoryOptions, type SignedUrl, type SignedUrlOptions, StackboneClient, 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 };
2505
+ 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, 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, type WorkspaceAgent, type WorkspaceStandardSchema, type WorkspaceWorkflow, analyzeAgentSchemas, createClient, createStructuredLogger, defineAgent, defineWorkspace, getInvocationContext, installInvocationConsoleCapture, invokeRequestSchema, isReservedErrorCode, isSdkErrorCode, loadSystemSecretsIntoEnv, rehydrateSystemSecretsRows, runWithCallerId, runWithInvocationContext, stackbone };