@firststep-studio/sdk 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -39,30 +39,235 @@ createServer(handler, {
39
39
 
40
40
  See `llms.txt` for full API specification.
41
41
 
42
- ## Release notes
43
-
44
- ### 0.19.0
45
-
46
- - **Cohere model support.** `llm.generate` and `llm.generateStream` accept
47
- `provider: 'cohere'` with a `command-*` model (Command A, Command A+,
48
- Command R, Command R+, Command R7B), routed through Studio's `/api/llm/*`
49
- proxy the same way Gemini requests are. Text generation, JSON output,
50
- streaming, finish reasons and token usage are supported. Gemini-only
51
- features (explicit prompt caches, thinking/safety settings, image parts,
52
- function-calling payloads) are outside the Cohere adapter's contract.
53
- - **Observable SSE stream errors.** `generateStream` only ever skipped a
54
- chunk it could not parse as JSON at all (stray SSE comments/heartbeats). A
55
- vendor error frame is valid JSON, so it used to be yielded as an ordinary
56
- stream value, a plain object with an `error` field, indistinguishable from
57
- a successful chunk to anything not inspecting its shape, so a failed turn
58
- could look like a normal (if malformed) reply. A chunk shaped as an error
59
- now throws `LLMError` instead of being yielded as data, with `status`
60
- normalized to a numeric HTTP status: Gemini's numeric `code` or Cohere's
61
- numeric `status` field is used when present, otherwise `502`. This throw
62
- happens on the `.next()` call that reaches the error frame, not when
63
- `generateStream()` creates the generator, so the `try/catch` must wrap the
64
- entire iteration (the whole `for await` loop, or every subsequent manual
65
- `.next()` call) and not just the call that obtains the stream.
66
- - **Handler adoption required.** Handler must upgrade to this SDK version to
67
- pick up both changes. Existing Gemini configurations keep their current
68
- defaults.
42
+ ## Session failure handling
43
+
44
+ For external handlers with Studio session capability, `context.session` rejects
45
+ HTTP failures, network failures, invalid JSON and unsuccessful response envelopes.
46
+ Errors identify the session operation and include the HTTP status when available.
47
+ The SDK does not log these errors; callers own logging and recovery. Network errors
48
+ retain their original cause, while HTTP bodies and JSON parser details are omitted.
49
+ On an HTTP failure, the SDK also makes a best-effort attempt to cancel the
50
+ response body before throwing, to release the upstream connection promptly; a
51
+ failed cancellation never replaces or masks the HTTP error, and is never logged.
52
+
53
+ Await reads and writes that the next turn depends on. A rejected read must not be
54
+ interpreted as a fresh session, and a rejected write must not be acknowledged as
55
+ saved. An acknowledged empty session still uses the existing initialization
56
+ behavior. Session state remains ephemeral; durable storage is a separate resource.
57
+
58
+ This contract only covers what the SDK itself can see: HTTP, network and
59
+ protocol-envelope failures on the request the SDK made. It says nothing about
60
+ what happens upstream inside Studio's protocol-resources API before that
61
+ response is produced. In particular, Studio's `ProtocolSessionService` falls
62
+ back from Redis to a process-local in-memory store when Redis is unavailable
63
+ or a Redis call fails mid-request, and that fallback still returns a normal,
64
+ successful HTTP response, so the SDK cannot detect that it happened.
65
+ `context.session` is ephemeral by design even when Redis is healthy, so the
66
+ fallback is not a loss of some durability guarantee that otherwise existed.
67
+ Its concrete effect is different: while it is active, the handler's existing
68
+ Redis-held session state and message history become unreachable, so a
69
+ session that already exists in Redis can read back as if it were fresh and
70
+ empty; and any reads or writes served from the in-memory store are not
71
+ shared across other backend processes and do not survive a restart of the
72
+ process that served them. Follow-up: [TLE-672](https://linear.app/throughlinecare/issue/TLE-672/make-redis-session-fallback-visible-to-callers).
73
+
74
+ ## Publishing a release
75
+
76
+ Publishing to npm is a GitHub Actions button, not a local command:
77
+
78
+ 1. Bump `version` in `packages/sdk/package.json` through a normal reviewed PR
79
+ and merge it to `main`. This workflow never edits that file itself.
80
+ 2. On `main`, go to Actions > "Publish SDK" > Run workflow, and enter the
81
+ exact version just merged (e.g. `0.21.0`).
82
+ 3. The workflow runs three jobs: `validate` (builds, typechecks, runs the
83
+ full test suite, and packs the tarball that will actually be published),
84
+ `publish` (ships that exact tarball to npm), and `verify` (confirms the
85
+ registry serves that version as `latest` with matching integrity, and
86
+ writes a summary).
87
+
88
+ A dispatch from anything but `main` fails fast, in `validate`'s first step,
89
+ with a message naming the problem ref. That check alone is **not** the
90
+ security boundary, and should not be read as one: `workflow_dispatch` runs
91
+ the workflow file checked out from whichever ref the dispatcher selects, so a
92
+ dispatch from another branch would run that branch's own copy of this file,
93
+ which could simply have had the check edited out. The actual security
94
+ boundary is the `sdk-production` GitHub Environment's deployment branch rule
95
+ (described under "One-time setup" below), which restricts which branch can
96
+ reach the `publish` job's `id-token: write` permission at all, independent of
97
+ anything in the workflow YAML itself. **The `sdk-production` environment now
98
+ exists, with its custom branch policy restricting it to `main` confirmed
99
+ configured.** Required reviewers are not configured on the environment:
100
+ adding one through the GitHub API returned a 422, because this private
101
+ repository's billing plan does not support required reviewers on
102
+ environments. `workflow_dispatch` can itself be triggered either from the
103
+ Actions UI or via the GitHub API, so it is not exclusively a human action on
104
+ its own; the control this design relies on is that maintainers dispatch it
105
+ manually, as intended, with the version input and the main-only branch
106
+ restriction as the checks that run. Per current owner decision, a separate
107
+ GitHub-enforced required-reviewers step on the environment is not required
108
+ for using this workflow; that remains the current policy, not a claim about
109
+ what was intended or required previously.
110
+
111
+ The workflow always builds and publishes the exact commit that was
112
+ dispatched (`github.sha`), not whatever `main` points to by the time the run
113
+ reaches the `publish` job. That way a later push to `main` during a long
114
+ approval wait cannot change what ships. It refuses a version that does not
115
+ match the committed manifest, refuses a version already on the registry, and
116
+ refuses moving the `latest` dist-tag backwards; it re-checks those last two
117
+ immediately before publishing too, in case the approval wait let someone
118
+ else ship a release in the meantime. This workflow targets an existing,
119
+ already-published package only, so an empty or malformed registry read
120
+ (including a bare `{}` on an HTTP 200) is always refused rather than read as
121
+ "nothing published yet"; it has no first-ever-release path. The policy
122
+ checks live in `scripts/sdk-publish-policy.mjs`
123
+ (unit-tested in `scripts/sdk-publish-policy.test.mjs`); the workflow calls
124
+ them through the thin CLI wrapper `scripts/sdk-publish-cli.mjs`
125
+ (unit-tested in `scripts/sdk-publish-cli.test.mjs`).
126
+
127
+ The "refuses moving `latest` backwards" rule is deliberately strict:
128
+ **`latest` only ever moves forward, monotonically, by whatever version was
129
+ most recently merged and dispatched.** There is no supported path through
130
+ this workflow for publishing a patch onto an older release line once a newer
131
+ one is `latest` (e.g. shipping `0.19.5` as a backport fix after `0.21.0` is
132
+ already out). `assertNotDowngrade` refuses that the same way it refuses an
133
+ actual downgrade, on purpose, because the two are indistinguishable from the
134
+ registry's dist-tags alone. If a maintenance-branch backport policy is ever
135
+ needed, it is a separate, deliberately-designed workflow (almost certainly
136
+ publishing to a non-`latest` dist-tag), not an extension of this one.
137
+
138
+ ### Registry read freshness
139
+
140
+ The npm registry's packument endpoint (what `check-registry` and `verify`
141
+ both read) sits behind a CDN that can serve a cached response for a
142
+ noticeable window. Both call sites go through the same helper
143
+ (`fetchPackageMeta` in `scripts/sdk-publish-cli.mjs`, built on
144
+ `fetchJsonWithRetry` in `scripts/sdk-publish-policy.mjs`), which requests
145
+ cache revalidation (`Cache-Control: no-cache`, `Pragma: no-cache`) **and**
146
+ appends a cache-busting query parameter to the URL
147
+ (`withCacheBustingParam`) on every attempt, since a CDN that keys its cache
148
+ on request headers and one that keys on the exact URL are both real,
149
+ observed behaviors and neither is something this code can detect or rely on
150
+ alone. Both are best-effort: whether a given CDN honors either is outside
151
+ this repo's control, and no claim of "always fresh" is made here or
152
+ anywhere else in this workflow. `verify`'s own outer polling loop (distinct
153
+ from that per-request retry) is sized with a bounded fallback in mind: it
154
+ waits up to ~350s (`VERIFY_MAX_ATTEMPTS` * `VERIFY_DELAY_MS` in
155
+ `scripts/sdk-publish-cli.mjs`), comfortable margin over a ~300s cache
156
+ window, for the case neither mitigation fully bypasses the CDN.
157
+ `check-registry` is intentionally not widened the same way: it is a quick,
158
+ bounded gate (2-minute step timeout) run twice (once in `validate`, once
159
+ immediately before `npm publish`), not a long poll, so a CDN that ignores
160
+ both mitigations for its full window is a residual risk there.
161
+
162
+ That residual risk is **not** symmetric, and `verify` does not backstop
163
+ both halves of it the same way. A stale `check-registry` read that hides an
164
+ already-published `REQUESTED` is caught at actual publish time: npm itself
165
+ refuses to publish over a version number that already exists, independent
166
+ of anything this workflow read beforehand. A stale read that hides a
167
+ *newer* `latest` than `check-registry` saw is not caught anywhere after the
168
+ fact: `npm publish --tag latest` unconditionally moves the `latest`
169
+ dist-tag to whatever was just published, with no server-side semver
170
+ ordering check, and `verify` only confirms that `REQUESTED` becomes
171
+ `latest`, which is trivially true immediately after any successful publish
172
+ with that tag. So a downgrade let through by a stale pre-publish read would
173
+ publish successfully, and `verify` would pass, having confirmed the publish
174
+ happened, not that it was the right thing to publish. The realistic
175
+ exposure is narrow: this workflow's `concurrency: group: publish-sdk`
176
+ setting means no two runs of this workflow can race each other, so the only
177
+ way a stale read here actually causes a downgrade is an `npm publish`
178
+ bypassing this workflow entirely, out of band, which is already a process
179
+ violation this code cannot fully close through registry reads alone.
180
+
181
+ Before publishing, `validate` also extracts the packed tarball and checks it
182
+ has the files the package is supposed to ship, that every file declared in
183
+ `package.json`'s `main`/`module`/`types`/`exports` actually resolves to a
184
+ file in the tarball, that its `package.json` name and version match what was
185
+ approved, and that both the CommonJS and ESM build of both public entry
186
+ points (the root export and `./server`) actually load. After publishing, `verify` polls the registry
187
+ until the version is live and compares three independent copies of the same
188
+ bytes: the registry's own `dist.integrity` metadata, the local tarball
189
+ `validate` built and tested, and the tarball actually downloaded from the
190
+ registry. It fails if any of them disagree.
191
+
192
+ That download is itself size-bounded (`downloadTarballWithLimit` in
193
+ `scripts/sdk-publish-policy.mjs`): it reads the response as a stream, hashing
194
+ incrementally and counting actual bytes as they arrive, and aborts the moment
195
+ the running total crosses a generous but finite ceiling
196
+ (`MAX_TARBALL_BYTES`, 50 MiB against an actual packed size of a few hundred
197
+ KB) rather than buffering an unbounded response into memory first. A declared
198
+ `Content-Length` over that ceiling is refused before any body bytes are read;
199
+ a missing or understated one does not grant an exemption, since the limit is
200
+ also enforced from the streamed byte count directly; and a declared length
201
+ that does not match the actual streamed count at all is refused too, even
202
+ when both are within the ceiling. The tarball URL's host is also checked
203
+ against the configured registry before anything is fetched.
204
+
205
+ Publishing uses npm's
206
+ [trusted publishing](https://docs.npmjs.com/trusted-publishers/) (OIDC): the
207
+ `publish` job exchanges a short-lived GitHub Actions `id-token` for a
208
+ publish credential directly with npm. There is no `NPM_TOKEN` secret
209
+ anywhere in this flow. This requires npm >= 11.5.1 and Node >= 22.14.0; Node
210
+ 22 ships an older bundled npm (22.23.2 ships 10.9.8), so both `validate` and
211
+ `publish` install a pinned, compatible npm (currently 11.21.0) right after
212
+ `actions/setup-node`, and the actual installed versions are checked against
213
+ those floors rather than assumed.
214
+
215
+ ### If publish succeeds but verify fails
216
+
217
+ Do not re-run the workflow with the same version. `npm publish` has already
218
+ happened and is immutable; re-dispatching the same version will correctly be
219
+ refused by the already-published check, which is a symptom of the situation,
220
+ not a way to retry it. Instead check the registry by hand
221
+ (`npm view @firststep-studio/sdk`) to see what actually landed, find out why
222
+ `verify` disagreed (a slow registry propagation is recoverable by re-running
223
+ just the `verify` job; a genuine integrity mismatch is not and needs
224
+ investigation before anything else is published). If a corrected release is
225
+ still needed, it goes out as the next version through the normal PR + bump +
226
+ dispatch flow, not a republish of the one that already shipped.
227
+
228
+ ### One-time setup this workflow depends on (partially done)
229
+
230
+ Trusted publishing and the production environment are both configured on
231
+ npmjs.com and github.com, outside this repo's source, and are not something a
232
+ PR can set up:
233
+
234
+ - On npmjs.com, under the `@firststep-studio/sdk` package's trusted
235
+ publisher settings, add a GitHub Actions trusted publisher with:
236
+ - Organization or user: `ThroughLineCare`
237
+ - Repository: `firststep-studio`
238
+ - Workflow filename: `publish-sdk.yml`. Use **the bare filename only**,
239
+ not the `.github/workflows/` path. npm's trusted-publisher form matches
240
+ on filename, not path.
241
+ - Environment name: `sdk-production`
242
+
243
+ All four have to match what the workflow run actually presents, or npm
244
+ rejects the OIDC exchange. npm's own trusted-publishing docs state the
245
+ first publish from a newly configured trusted publisher must succeed
246
+ within 2 days of setting it up, or the configuration expires and needs to
247
+ be redone:
248
+ <https://docs.npmjs.com/trusted-publishers/#trusted-publisher-configuration-expiry>.
249
+ Dispatch a real publish reasonably soon after configuring this, not at an
250
+ arbitrary later date.
251
+ - On github.com, under this repo's Settings > Environments: the
252
+ `sdk-production` environment **now exists**, with its custom deployment
253
+ branch policy restricting it to `main` confirmed configured. This
254
+ environment's deployment branch rule is the actual security boundary
255
+ described above under "Publishing a release", and that half is in place.
256
+ **Required reviewers are not configured**: adding one through the GitHub
257
+ API returned HTTP 422, because this private repository's current billing
258
+ plan does not support required reviewers on environments. `workflow_dispatch`
259
+ can be invoked via the API as well as the UI, so the control this design
260
+ relies on is that maintainers dispatch it manually, as the workflow is
261
+ intended to be used, with the version-input and main-only-branch checks
262
+ that run on every dispatch. Per current owner decision, a separate
263
+ required-reviewers approval step on the environment is not required to use
264
+ this workflow; if the billing plan changes later, adding one would be an
265
+ additional, optional layer on top of this policy.
266
+ - This repository is **private** (confirmed via `gh repo view`). Per npm's
267
+ trusted-publishing docs, provenance attestations are not generated for a
268
+ trusted-publish from a private repository, because the attestation depends
269
+ on a publicly fetchable build log. The `publish` job sets
270
+ `NPM_CONFIG_PROVENANCE=false` explicitly so this is a deliberate no-op
271
+ rather than a failure partway through a publish. If this repository is
272
+ ever made public, provenance can be enabled by removing that environment
273
+ variable from the `publish` job.
package/dist/index.d.mts CHANGED
@@ -354,6 +354,16 @@ interface PlatformChatbotRegisterInput {
354
354
  [key: string]: unknown;
355
355
  };
356
356
  }
357
+ /** Whether a bot's deployment runs the age and consent onboarding, with a link to show it. */
358
+ interface PlatformDeploymentPreview {
359
+ /** True when the deployment's web chat shows the onboarding. */
360
+ onboardingEnabled: boolean;
361
+ deploymentSlug: string;
362
+ /** Opens the onboarding without a Studio login. Null when the onboarding is off. */
363
+ previewUrl: string | null;
364
+ /** ISO time the link stops working (30 minutes). Null when the onboarding is off. */
365
+ expiresAt: string | null;
366
+ }
357
367
  interface PlatformChatbotRegistration {
358
368
  /** Studio chatbot MongoDB ID (immutable across re-registrations). */
359
369
  id: string;
@@ -571,6 +581,13 @@ declare class PlatformClient {
571
581
  * can call this on every config save without creating duplicates.
572
582
  */
573
583
  registerChatbot(input: PlatformChatbotRegisterInput): Promise<PlatformChatbotRegistration>;
584
+ /**
585
+ * Ask whether the deployment of the chatbot identified by `externalId` runs
586
+ * the age and consent onboarding and, if so, get a fresh preview link to it.
587
+ * Each call with the onboarding on mints a new 30-minute link, so call it
588
+ * when the link is needed rather than caching the result.
589
+ */
590
+ getDeploymentPreview(externalId: string): Promise<PlatformDeploymentPreview>;
574
591
  /**
575
592
  * Mark the chatbot identified by `externalId` as disconnected.
576
593
  * The Studio record is preserved (history, analytics survive).
@@ -1365,4 +1382,4 @@ declare class LLMClient {
1365
1382
  */
1366
1383
  declare function createLLMClient(config: LLMClientConfig): LLMClient;
1367
1384
 
1368
- export { AgentTransitionPayload, ChatMessage, type ClassificationResult, type CreateKnowledgeOptions, type CreateKnowledgeSheet, type EmergencyPayload, HandoffOfferPayload, HandoffRequestPayload, HandoffReturnPayload, type HelplineCardItem, type HelplineCardPayload, type HelplineCardV2Item, type HelplineCardV2Payload, type KnowledgeSearchOptions, type LLMCacheCreateRequest, type LLMCachedContent, type LLMCandidate, LLMClient, type LLMClientConfig, type LLMContent, LLMError, type LLMGenerateRequest, type LLMGenerateResponse, type LLMGenerationConfig, type LLMPart, type LLMSafetySetting, type LLMUsageMetadata, type ListKnowledgeOptions, MARKER_TYPES, type MarkerType, type PlatformChatbot, PlatformClient, type PlatformClientConfig, PlatformError, type PlatformKnowledge, type PlatformKnowledgeRecord, type PlatformKnowledgeSearchHit, type PlatformKnowledgeSummary, ProtocolStreamChunk, type ProviderCardItem, type ProviderCardPayload, type RecommendationKind, type RecommendedItem, type ReportCardPayload, type ResourceCardItem, type ResourceCardPayload, RoutingClassificationPayload, type SafetyPlanPayload, type SafetyPlanSection, SchemaDeclarationPayload, type ThroughlineHelplinesQuery, type ThroughlineV2ContactMethod, type ThroughlineV2Country, type ThroughlineV2Description, type ThroughlineV2Helpline, type ThroughlineV2HelplinesQuery, type ThroughlineV2HelplinesResponse, type ThroughlineV2OpeningSpan, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createLLMClient, createPlatformClient, createRequestSignature, createUCPClient, extractRecommendedItems, isValidToken, parseMarkerPayload, renderMarkers, streamMetadata, verifyRequestSignature };
1385
+ export { AgentTransitionPayload, ChatMessage, type ClassificationResult, type CreateKnowledgeOptions, type CreateKnowledgeSheet, type EmergencyPayload, HandoffOfferPayload, HandoffRequestPayload, HandoffReturnPayload, type HelplineCardItem, type HelplineCardPayload, type HelplineCardV2Item, type HelplineCardV2Payload, type KnowledgeSearchOptions, type LLMCacheCreateRequest, type LLMCachedContent, type LLMCandidate, LLMClient, type LLMClientConfig, type LLMContent, LLMError, type LLMGenerateRequest, type LLMGenerateResponse, type LLMGenerationConfig, type LLMPart, type LLMSafetySetting, type LLMUsageMetadata, type ListKnowledgeOptions, MARKER_TYPES, type MarkerType, type PlatformChatbot, PlatformClient, type PlatformClientConfig, type PlatformDeploymentPreview, PlatformError, type PlatformKnowledge, type PlatformKnowledgeRecord, type PlatformKnowledgeSearchHit, type PlatformKnowledgeSummary, ProtocolStreamChunk, type ProviderCardItem, type ProviderCardPayload, type RecommendationKind, type RecommendedItem, type ReportCardPayload, type ResourceCardItem, type ResourceCardPayload, RoutingClassificationPayload, type SafetyPlanPayload, type SafetyPlanSection, SchemaDeclarationPayload, type ThroughlineHelplinesQuery, type ThroughlineV2ContactMethod, type ThroughlineV2Country, type ThroughlineV2Description, type ThroughlineV2Helpline, type ThroughlineV2HelplinesQuery, type ThroughlineV2HelplinesResponse, type ThroughlineV2OpeningSpan, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createLLMClient, createPlatformClient, createRequestSignature, createUCPClient, extractRecommendedItems, isValidToken, parseMarkerPayload, renderMarkers, streamMetadata, verifyRequestSignature };
package/dist/index.d.ts CHANGED
@@ -354,6 +354,16 @@ interface PlatformChatbotRegisterInput {
354
354
  [key: string]: unknown;
355
355
  };
356
356
  }
357
+ /** Whether a bot's deployment runs the age and consent onboarding, with a link to show it. */
358
+ interface PlatformDeploymentPreview {
359
+ /** True when the deployment's web chat shows the onboarding. */
360
+ onboardingEnabled: boolean;
361
+ deploymentSlug: string;
362
+ /** Opens the onboarding without a Studio login. Null when the onboarding is off. */
363
+ previewUrl: string | null;
364
+ /** ISO time the link stops working (30 minutes). Null when the onboarding is off. */
365
+ expiresAt: string | null;
366
+ }
357
367
  interface PlatformChatbotRegistration {
358
368
  /** Studio chatbot MongoDB ID (immutable across re-registrations). */
359
369
  id: string;
@@ -571,6 +581,13 @@ declare class PlatformClient {
571
581
  * can call this on every config save without creating duplicates.
572
582
  */
573
583
  registerChatbot(input: PlatformChatbotRegisterInput): Promise<PlatformChatbotRegistration>;
584
+ /**
585
+ * Ask whether the deployment of the chatbot identified by `externalId` runs
586
+ * the age and consent onboarding and, if so, get a fresh preview link to it.
587
+ * Each call with the onboarding on mints a new 30-minute link, so call it
588
+ * when the link is needed rather than caching the result.
589
+ */
590
+ getDeploymentPreview(externalId: string): Promise<PlatformDeploymentPreview>;
574
591
  /**
575
592
  * Mark the chatbot identified by `externalId` as disconnected.
576
593
  * The Studio record is preserved (history, analytics survive).
@@ -1365,4 +1382,4 @@ declare class LLMClient {
1365
1382
  */
1366
1383
  declare function createLLMClient(config: LLMClientConfig): LLMClient;
1367
1384
 
1368
- export { AgentTransitionPayload, ChatMessage, type ClassificationResult, type CreateKnowledgeOptions, type CreateKnowledgeSheet, type EmergencyPayload, HandoffOfferPayload, HandoffRequestPayload, HandoffReturnPayload, type HelplineCardItem, type HelplineCardPayload, type HelplineCardV2Item, type HelplineCardV2Payload, type KnowledgeSearchOptions, type LLMCacheCreateRequest, type LLMCachedContent, type LLMCandidate, LLMClient, type LLMClientConfig, type LLMContent, LLMError, type LLMGenerateRequest, type LLMGenerateResponse, type LLMGenerationConfig, type LLMPart, type LLMSafetySetting, type LLMUsageMetadata, type ListKnowledgeOptions, MARKER_TYPES, type MarkerType, type PlatformChatbot, PlatformClient, type PlatformClientConfig, PlatformError, type PlatformKnowledge, type PlatformKnowledgeRecord, type PlatformKnowledgeSearchHit, type PlatformKnowledgeSummary, ProtocolStreamChunk, type ProviderCardItem, type ProviderCardPayload, type RecommendationKind, type RecommendedItem, type ReportCardPayload, type ResourceCardItem, type ResourceCardPayload, RoutingClassificationPayload, type SafetyPlanPayload, type SafetyPlanSection, SchemaDeclarationPayload, type ThroughlineHelplinesQuery, type ThroughlineV2ContactMethod, type ThroughlineV2Country, type ThroughlineV2Description, type ThroughlineV2Helpline, type ThroughlineV2HelplinesQuery, type ThroughlineV2HelplinesResponse, type ThroughlineV2OpeningSpan, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createLLMClient, createPlatformClient, createRequestSignature, createUCPClient, extractRecommendedItems, isValidToken, parseMarkerPayload, renderMarkers, streamMetadata, verifyRequestSignature };
1385
+ export { AgentTransitionPayload, ChatMessage, type ClassificationResult, type CreateKnowledgeOptions, type CreateKnowledgeSheet, type EmergencyPayload, HandoffOfferPayload, HandoffRequestPayload, HandoffReturnPayload, type HelplineCardItem, type HelplineCardPayload, type HelplineCardV2Item, type HelplineCardV2Payload, type KnowledgeSearchOptions, type LLMCacheCreateRequest, type LLMCachedContent, type LLMCandidate, LLMClient, type LLMClientConfig, type LLMContent, LLMError, type LLMGenerateRequest, type LLMGenerateResponse, type LLMGenerationConfig, type LLMPart, type LLMSafetySetting, type LLMUsageMetadata, type ListKnowledgeOptions, MARKER_TYPES, type MarkerType, type PlatformChatbot, PlatformClient, type PlatformClientConfig, type PlatformDeploymentPreview, PlatformError, type PlatformKnowledge, type PlatformKnowledgeRecord, type PlatformKnowledgeSearchHit, type PlatformKnowledgeSummary, ProtocolStreamChunk, type ProviderCardItem, type ProviderCardPayload, type RecommendationKind, type RecommendedItem, type ReportCardPayload, type ResourceCardItem, type ResourceCardPayload, RoutingClassificationPayload, type SafetyPlanPayload, type SafetyPlanSection, SchemaDeclarationPayload, type ThroughlineHelplinesQuery, type ThroughlineV2ContactMethod, type ThroughlineV2Country, type ThroughlineV2Description, type ThroughlineV2Helpline, type ThroughlineV2HelplinesQuery, type ThroughlineV2HelplinesResponse, type ThroughlineV2OpeningSpan, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createLLMClient, createPlatformClient, createRequestSignature, createUCPClient, extractRecommendedItems, isValidToken, parseMarkerPayload, renderMarkers, streamMetadata, verifyRequestSignature };
package/dist/index.js CHANGED
@@ -742,6 +742,19 @@ var PlatformClient = class {
742
742
  { method: "POST", body: input }
743
743
  );
744
744
  }
745
+ /**
746
+ * Ask whether the deployment of the chatbot identified by `externalId` runs
747
+ * the age and consent onboarding and, if so, get a fresh preview link to it.
748
+ * Each call with the onboarding on mints a new 30-minute link, so call it
749
+ * when the link is needed rather than caching the result.
750
+ */
751
+ async getDeploymentPreview(externalId) {
752
+ return this.request(
753
+ `/api/protocol/chatbots/${encodeURIComponent(externalId)}/preview`,
754
+ "Failed to get deployment preview",
755
+ { method: "POST" }
756
+ );
757
+ }
745
758
  /**
746
759
  * Mark the chatbot identified by `externalId` as disconnected.
747
760
  * The Studio record is preserved (history, analytics survive).