@firststep-studio/sdk 0.16.0 → 0.18.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/dist/index.d.mts +708 -587
- package/dist/index.d.ts +708 -587
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +104 -0
- package/dist/index.mjs.map +1 -1
- package/llms.txt +64 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -285,693 +285,814 @@ declare function classifyWithUCP(endpoint: string, messages: ChatMessage[], opti
|
|
|
285
285
|
}): Promise<ClassificationResult>;
|
|
286
286
|
|
|
287
287
|
/**
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* Utilities for building render markers that FirstStep Studio's frontend
|
|
291
|
-
* can parse and display as rich UI components (cards, alerts, forms, etc.).
|
|
288
|
+
* Platform Client
|
|
292
289
|
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
290
|
+
* SDK client for handlers to call back to FirstStep Studio.
|
|
291
|
+
* Enables handlers to query platform data (chatbot list, etc.)
|
|
292
|
+
* using the same API token used for request signature verification.
|
|
296
293
|
*
|
|
297
294
|
* @example
|
|
298
295
|
* ```typescript
|
|
299
|
-
* import {
|
|
296
|
+
* import { createPlatformClient } from '@firststep-studio/sdk';
|
|
300
297
|
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
* }
|
|
298
|
+
* const client = createPlatformClient({
|
|
299
|
+
* studioUrl: 'https://studio-api.example.com',
|
|
300
|
+
* token: process.env.FIRSTSTEP_TOKEN,
|
|
301
|
+
* });
|
|
302
|
+
*
|
|
303
|
+
* const chatbots = await client.listChatbots();
|
|
304
|
+
* // [{ id: '...', name: 'Safety Navigator', configSlug: 'safety-nav' }, ...]
|
|
308
305
|
* ```
|
|
309
306
|
*/
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
};
|
|
318
|
-
type MarkerType = typeof MARKER_TYPES[keyof typeof MARKER_TYPES];
|
|
319
|
-
/**
|
|
320
|
-
* Helpline card payload.
|
|
321
|
-
* Renders a carousel of helpline cards with contact buttons (call, text, chat, WhatsApp).
|
|
322
|
-
*/
|
|
323
|
-
interface HelplineCardPayload {
|
|
324
|
-
helplines: HelplineCardItem[];
|
|
325
|
-
type?: 'throughline' | 'throughline_fallback' | 'stage';
|
|
326
|
-
fallback?: {
|
|
327
|
-
message: string;
|
|
328
|
-
linkText?: string;
|
|
329
|
-
linkUrl?: string;
|
|
330
|
-
icon?: string;
|
|
331
|
-
topic?: string;
|
|
332
|
-
topics?: string[];
|
|
333
|
-
};
|
|
307
|
+
interface PlatformClientConfig {
|
|
308
|
+
/** Studio backend API URL (e.g. https://studio-api.example.com) */
|
|
309
|
+
studioUrl: string;
|
|
310
|
+
/** API token (same as FIRSTSTEP_TOKEN used for signature verification) */
|
|
311
|
+
token: string;
|
|
312
|
+
/** Request timeout in ms (default: 10000) */
|
|
313
|
+
timeout?: number;
|
|
334
314
|
}
|
|
335
|
-
interface
|
|
336
|
-
/**
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
315
|
+
interface PlatformOrganization {
|
|
316
|
+
/** Studio organization ID */
|
|
317
|
+
id: string;
|
|
318
|
+
/** Display name (null if the organization record has been deleted) */
|
|
319
|
+
name: string | null;
|
|
320
|
+
/** URL-safe slug */
|
|
321
|
+
slug: string | null;
|
|
322
|
+
}
|
|
323
|
+
interface PlatformTokenInfo {
|
|
324
|
+
/** API token ID */
|
|
325
|
+
id: string;
|
|
326
|
+
/** Human-friendly token label */
|
|
327
|
+
name: string;
|
|
328
|
+
/** Authorized scopes */
|
|
329
|
+
scopes: string[];
|
|
330
|
+
/** Project IDs this token is scoped to (null = full org access) */
|
|
331
|
+
projectIds: string[] | null;
|
|
332
|
+
}
|
|
333
|
+
interface PlatformIdentity {
|
|
334
|
+
organization: PlatformOrganization;
|
|
335
|
+
token: PlatformTokenInfo;
|
|
336
|
+
}
|
|
337
|
+
interface PlatformChatbotRegisterInput {
|
|
338
|
+
/** Stable handler-side identifier used to upsert (e.g. handler config ID). */
|
|
339
|
+
externalId: string;
|
|
340
|
+
/** Display name shown in Studio's chatbot list. */
|
|
342
341
|
name: string;
|
|
342
|
+
/** Optional human description. */
|
|
343
343
|
description?: string;
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
highlightedTag?: string;
|
|
357
|
-
verified?: boolean;
|
|
344
|
+
/** Public URL where Studio should send protocol requests. */
|
|
345
|
+
handlerUrl: string;
|
|
346
|
+
/** Slug for multi-config routing on the handler side. */
|
|
347
|
+
configSlug?: string;
|
|
348
|
+
/** Optional capability flags advertised to Studio. */
|
|
349
|
+
capabilities?: {
|
|
350
|
+
streaming?: boolean;
|
|
351
|
+
formQuestions?: boolean;
|
|
352
|
+
knowledgeActions?: boolean;
|
|
353
|
+
integrations?: boolean;
|
|
354
|
+
[key: string]: unknown;
|
|
355
|
+
};
|
|
358
356
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
*/
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
357
|
+
interface PlatformChatbotRegistration {
|
|
358
|
+
/** Studio chatbot MongoDB ID (immutable across re-registrations). */
|
|
359
|
+
id: string;
|
|
360
|
+
/** Echoes back the externalId used as upsert key. */
|
|
361
|
+
externalId: string;
|
|
362
|
+
/** Resolved name as stored in Studio. */
|
|
363
|
+
name: string;
|
|
364
|
+
protocolConfig: Record<string, unknown>;
|
|
367
365
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
*/
|
|
372
|
-
|
|
373
|
-
|
|
366
|
+
interface PlatformChatbot {
|
|
367
|
+
/** Studio chatbot MongoDB ID */
|
|
368
|
+
id: string;
|
|
369
|
+
/** Chatbot display name */
|
|
370
|
+
name: string;
|
|
371
|
+
/** Handler URL (if external handler configured) */
|
|
372
|
+
handlerUrl?: string;
|
|
373
|
+
/** Config slug for multi-config routing */
|
|
374
|
+
configSlug?: string;
|
|
375
|
+
/** Handler type */
|
|
376
|
+
handlerType?: 'builtin' | 'external';
|
|
374
377
|
}
|
|
375
|
-
interface
|
|
378
|
+
interface PlatformKnowledgeSummary {
|
|
379
|
+
/** Studio knowledge MongoDB ID */
|
|
380
|
+
id: string;
|
|
381
|
+
/** Knowledge name */
|
|
376
382
|
name: string;
|
|
377
|
-
|
|
383
|
+
/** Optional description */
|
|
378
384
|
description?: string;
|
|
379
|
-
|
|
385
|
+
/** Knowledge type (e.g. 'text', 'database') */
|
|
380
386
|
type?: string;
|
|
381
|
-
|
|
382
|
-
|
|
387
|
+
/** Owning organization ID. Null for org-less system documents. */
|
|
388
|
+
organizationId: string | null;
|
|
389
|
+
/**
|
|
390
|
+
* True for handler-managed documents created through the protocol
|
|
391
|
+
* write API. System-owned knowledge is hidden from every Studio UI
|
|
392
|
+
* surface and only appears in `list` when `includeSystemOwned` is set.
|
|
393
|
+
*/
|
|
394
|
+
isSystemOwned?: boolean;
|
|
395
|
+
/** Whether semantic search (record embedding) is enabled. */
|
|
396
|
+
ragEnabled?: boolean;
|
|
397
|
+
/** Timestamps */
|
|
398
|
+
createdAt?: number | string;
|
|
399
|
+
updatedAt?: number | string;
|
|
383
400
|
}
|
|
384
401
|
/**
|
|
385
|
-
*
|
|
386
|
-
*
|
|
402
|
+
* Full knowledge document (shape mirrors the underlying mongoose doc).
|
|
403
|
+
* Kept loose because the schema is large and varies by knowledge `type`;
|
|
404
|
+
* narrow types can be added incrementally as callers need them.
|
|
387
405
|
*/
|
|
388
|
-
|
|
389
|
-
|
|
406
|
+
type PlatformKnowledge = PlatformKnowledgeSummary & Record<string, unknown>;
|
|
407
|
+
interface ListKnowledgeOptions {
|
|
408
|
+
/**
|
|
409
|
+
* Target organization to list knowledge from. If omitted, defaults to
|
|
410
|
+
* the org associated with the SDK token. Use this to read from a
|
|
411
|
+
* different org (e.g. a platform-operated shared library marked
|
|
412
|
+
* `publicReadable` in Studio).
|
|
413
|
+
*/
|
|
414
|
+
orgId?: string;
|
|
415
|
+
/**
|
|
416
|
+
* Include system-owned (handler-managed) knowledge in the listing.
|
|
417
|
+
* Only honored when listing the token's own org; other orgs never
|
|
418
|
+
* expose their system-owned documents.
|
|
419
|
+
*/
|
|
420
|
+
includeSystemOwned?: boolean;
|
|
421
|
+
/**
|
|
422
|
+
* 'system' lists ORG-LESS platform documents instead of org
|
|
423
|
+
* knowledge. orgId and includeSystemOwned are ignored in that mode.
|
|
424
|
+
*/
|
|
425
|
+
scope?: 'system';
|
|
390
426
|
}
|
|
391
|
-
|
|
427
|
+
/** Sheet definition for `knowledge.create`. */
|
|
428
|
+
interface CreateKnowledgeSheet {
|
|
429
|
+
/** Stable sheet id, referenced later by record writes and search. */
|
|
392
430
|
id: string;
|
|
393
431
|
name: string;
|
|
394
|
-
type?: string;
|
|
395
|
-
specialty: string[];
|
|
396
|
-
language: string[];
|
|
397
432
|
description?: string;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
website?: string;
|
|
433
|
+
/**
|
|
434
|
+
* Column definitions ({ id, name, type, ... }). Loose-typed; the
|
|
435
|
+
* Studio schema validates `type` against its column-type enum.
|
|
436
|
+
*/
|
|
437
|
+
columns?: Array<Record<string, unknown>>;
|
|
404
438
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
439
|
+
interface CreateKnowledgeOptions {
|
|
440
|
+
description?: string;
|
|
441
|
+
/**
|
|
442
|
+
* Enable semantic search at creation time. Defaults to false; can be
|
|
443
|
+
* flipped later with `setRagEnabled` (which also backfills embeddings
|
|
444
|
+
* for records inserted while the flag was off).
|
|
445
|
+
*/
|
|
446
|
+
ragEnabled?: boolean;
|
|
447
|
+
/**
|
|
448
|
+
* Create the knowledge as an ORG-LESS platform document: no
|
|
449
|
+
* organizationId at all, structurally invisible to every org-scoped
|
|
450
|
+
* Studio surface. This is the home for handler-managed data. Without
|
|
451
|
+
* it the document is created under the token's org (hidden from the
|
|
452
|
+
* UI by isSystemOwned, but org-bound).
|
|
453
|
+
*/
|
|
454
|
+
system?: boolean;
|
|
420
455
|
}
|
|
421
|
-
|
|
456
|
+
/** A raw record as returned by the protocol record-write endpoints. */
|
|
457
|
+
interface PlatformKnowledgeRecord {
|
|
422
458
|
id: string;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}>;
|
|
459
|
+
knowledgeId: string;
|
|
460
|
+
sheetId: string;
|
|
461
|
+
data: Record<string, unknown>;
|
|
462
|
+
createdAt?: number | string;
|
|
463
|
+
updatedAt?: number | string;
|
|
429
464
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
contact_mode?: string;
|
|
440
|
-
contact_value?: string;
|
|
441
|
-
submitEndpoint?: string;
|
|
465
|
+
interface KnowledgeSearchOptions {
|
|
466
|
+
/** Max records to return (server-side clamped to 1..50, default 10). */
|
|
467
|
+
limit?: number;
|
|
468
|
+
/**
|
|
469
|
+
* Optional sheet filter. Pass a sheet id (from the knowledge document)
|
|
470
|
+
* to restrict the search to that sheet. Omit to search across all
|
|
471
|
+
* sheets in the knowledge.
|
|
472
|
+
*/
|
|
473
|
+
sheetId?: string;
|
|
442
474
|
}
|
|
443
475
|
/**
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
* that can be yielded as a `text` chunk in handleStream().
|
|
448
|
-
*
|
|
449
|
-
* @example
|
|
450
|
-
* ```typescript
|
|
451
|
-
* // Emit helpline cards
|
|
452
|
-
* yield { type: 'text', content: renderMarkers.helplineCard({ helplines: [...] }) };
|
|
453
|
-
*
|
|
454
|
-
* // Emit emergency number
|
|
455
|
-
* yield { type: 'text', content: renderMarkers.emergency({ number: '911', countryName: 'United States' }) };
|
|
456
|
-
* ```
|
|
476
|
+
* A single hit from `client.knowledge.search`. `score` is the Atlas
|
|
477
|
+
* vector similarity score (cosine in our setup, so higher is closer).
|
|
478
|
+
* `data` mirrors the underlying record fields (column id -> value).
|
|
457
479
|
*/
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
/** Build a safety plan artifact marker */
|
|
468
|
-
safetyPlan: (payload: SafetyPlanPayload) => string;
|
|
469
|
-
/** Build a report draft card marker */
|
|
470
|
-
reportCard: (payload: ReportCardPayload) => string;
|
|
471
|
-
};
|
|
472
|
-
|
|
480
|
+
interface PlatformKnowledgeSearchHit {
|
|
481
|
+
id: string;
|
|
482
|
+
knowledgeId: string;
|
|
483
|
+
sheetId: string;
|
|
484
|
+
data: Record<string, unknown>;
|
|
485
|
+
score: number;
|
|
486
|
+
createdAt?: number | string;
|
|
487
|
+
updatedAt?: number | string;
|
|
488
|
+
}
|
|
473
489
|
/**
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* History, Routing Logs, Agent Transitions).
|
|
479
|
-
*
|
|
480
|
-
* Each function returns a ready-to-yield ProtocolStreamChunk. No need to
|
|
481
|
-
* construct the `{ type, content }` wrapper manually.
|
|
482
|
-
*
|
|
483
|
-
* @example
|
|
484
|
-
* ```typescript
|
|
485
|
-
* import { streamMetadata } from '@firststep-studio/sdk';
|
|
486
|
-
*
|
|
487
|
-
* // In your handleStream():
|
|
488
|
-
*
|
|
489
|
-
* // 1. Welcome path: declare your schema once
|
|
490
|
-
* yield streamMetadata.declareSchema({
|
|
491
|
-
* agents: [{ id: 'intake', title: 'Intake', order: 0 }],
|
|
492
|
-
* questions: [{ id: 'name', agentId: 'intake', title: 'Name', type: 'text' }],
|
|
493
|
-
* });
|
|
494
|
-
*
|
|
495
|
-
* // 2. After each turn: send collected field values
|
|
496
|
-
* yield streamMetadata.formDataUpdate({ name: 'Alice', age: '28' });
|
|
497
|
-
*
|
|
498
|
-
* // 3. On stage change: signal an agent transition
|
|
499
|
-
* yield streamMetadata.agentTransition({ id: 'support', title: 'Support' });
|
|
500
|
-
*
|
|
501
|
-
* // 4. On classification: send routing result
|
|
502
|
-
* yield streamMetadata.routingResult({
|
|
503
|
-
* decision: 'classified',
|
|
504
|
-
* reason: 'User mentioned self-harm',
|
|
505
|
-
* category: 'crisis',
|
|
506
|
-
* level: 'high',
|
|
507
|
-
* score: 92,
|
|
508
|
-
* });
|
|
509
|
-
* ```
|
|
490
|
+
* Helplines query params — passed verbatim to Throughline. Loose-typed
|
|
491
|
+
* so the SDK stays compatible with new Throughline query keys without
|
|
492
|
+
* a release. Required by Throughline today: `country_code`. Common
|
|
493
|
+
* optional keys: `topic`, `contact_method`, `limit`.
|
|
510
494
|
*/
|
|
511
|
-
|
|
512
|
-
|
|
495
|
+
type ThroughlineHelplinesQuery = Record<string, string | number | boolean | undefined>;
|
|
496
|
+
/** Query contract for Throughline GET /v2/helplines. */
|
|
497
|
+
interface ThroughlineV2HelplinesQuery {
|
|
498
|
+
countryCode: string;
|
|
499
|
+
topic?: string;
|
|
500
|
+
specialty?: string;
|
|
501
|
+
contactMethod?: 'phone' | 'sms' | 'onlineChat' | 'whatsapp' | 'tty' | 'reportingForm';
|
|
502
|
+
limit?: number;
|
|
503
|
+
priorityOnly?: boolean;
|
|
504
|
+
}
|
|
505
|
+
interface ThroughlineV2Description {
|
|
506
|
+
language: string;
|
|
507
|
+
fullDescription: string;
|
|
508
|
+
shortDescription?: string | null;
|
|
509
|
+
}
|
|
510
|
+
interface ThroughlineV2Country {
|
|
511
|
+
name: string;
|
|
512
|
+
code: string;
|
|
513
|
+
emergencyNumber?: string;
|
|
514
|
+
}
|
|
515
|
+
interface ThroughlineV2OpeningSpan {
|
|
516
|
+
localDayOfWeek: 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday' | 'sunday';
|
|
517
|
+
open: string;
|
|
518
|
+
close: string;
|
|
519
|
+
}
|
|
520
|
+
interface ThroughlineV2ContactMethod {
|
|
521
|
+
type: 'phone' | 'sms' | 'onlineChat' | 'whatsapp' | 'tty' | 'reportingForm';
|
|
522
|
+
value: string;
|
|
523
|
+
accessibilityNotes?: string | null;
|
|
524
|
+
alwaysOpen: boolean;
|
|
525
|
+
/** null when the application's API tier does not expose opening hours. */
|
|
526
|
+
openingHours: ThroughlineV2OpeningSpan[] | null;
|
|
527
|
+
}
|
|
528
|
+
interface ThroughlineV2Helpline {
|
|
529
|
+
id: string;
|
|
530
|
+
name: string;
|
|
531
|
+
descriptions: ThroughlineV2Description[];
|
|
532
|
+
website?: string;
|
|
533
|
+
country: ThroughlineV2Country;
|
|
534
|
+
timezone: string;
|
|
535
|
+
primaryTopics: string[];
|
|
536
|
+
secondaryTopics: string[];
|
|
537
|
+
supportedLanguages: string[];
|
|
538
|
+
specialties: string[];
|
|
539
|
+
/** Omitted on API tiers that do not expose support types. */
|
|
540
|
+
supportTypes?: string[];
|
|
541
|
+
interpretationServiceProvided: boolean;
|
|
542
|
+
membershipOrganizations: string[];
|
|
543
|
+
contactMethods: ThroughlineV2ContactMethod[];
|
|
544
|
+
}
|
|
545
|
+
interface ThroughlineV2HelplinesResponse {
|
|
546
|
+
helplines: ThroughlineV2Helpline[];
|
|
547
|
+
}
|
|
548
|
+
declare class PlatformError extends Error {
|
|
549
|
+
status: number;
|
|
550
|
+
constructor(message: string, status: number);
|
|
551
|
+
}
|
|
552
|
+
declare class PlatformClient {
|
|
553
|
+
private studioUrl;
|
|
554
|
+
private token;
|
|
555
|
+
private timeout;
|
|
556
|
+
constructor(config: PlatformClientConfig);
|
|
557
|
+
private request;
|
|
513
558
|
/**
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
* Yield this once during session initialization (welcome message).
|
|
517
|
-
* The Studio proxy stores it in `chatbot.externalSchema` so that
|
|
518
|
-
* Dashboard Form Insights can display question-level analytics.
|
|
519
|
-
*
|
|
520
|
-
* @param schema - Agents and questions your handler uses
|
|
521
|
-
* @returns A metadata stream chunk ready to yield or queue.push
|
|
559
|
+
* Resolve the organization and token metadata for the configured token.
|
|
560
|
+
* Useful for connection state UI ("Connected to {orgName}") and audit.
|
|
522
561
|
*/
|
|
523
|
-
|
|
562
|
+
getMe(): Promise<PlatformIdentity>;
|
|
524
563
|
/**
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
* Call this after each turn when new fields are captured.
|
|
528
|
-
* Values are incrementally merged into `ChatSession.formData`.
|
|
529
|
-
*
|
|
530
|
-
* @param fields - Key-value pairs of field IDs to their collected values
|
|
531
|
-
* @returns A metadata stream chunk ready to yield or queue.push
|
|
564
|
+
* List chatbots accessible to this handler's organization.
|
|
565
|
+
* Studio resolves the organization from the API token.
|
|
532
566
|
*/
|
|
533
|
-
|
|
567
|
+
listChatbots(): Promise<PlatformChatbot[]>;
|
|
534
568
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
* the Dashboard can show the conversation's agent flow.
|
|
539
|
-
*
|
|
540
|
-
* @param agent - The agent/stage being transitioned to
|
|
541
|
-
* @returns A metadata stream chunk ready to yield or queue.push
|
|
569
|
+
* Register or update an external-handler chatbot under the token's
|
|
570
|
+
* organization. Idempotent: identified by `externalId`, so handlers
|
|
571
|
+
* can call this on every config save without creating duplicates.
|
|
542
572
|
*/
|
|
543
|
-
|
|
573
|
+
registerChatbot(input: PlatformChatbotRegisterInput): Promise<PlatformChatbotRegistration>;
|
|
544
574
|
/**
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
* The Studio proxy records this in `ChatSession.routingLogs` as a
|
|
548
|
-
* classification event with category, level, and confidence score.
|
|
549
|
-
*
|
|
550
|
-
* @param result - Classification/routing decision details
|
|
551
|
-
* @returns A metadata stream chunk ready to yield or queue.push
|
|
575
|
+
* Mark the chatbot identified by `externalId` as disconnected.
|
|
576
|
+
* The Studio record is preserved (history, analytics survive).
|
|
552
577
|
*/
|
|
553
|
-
|
|
578
|
+
unregisterChatbot(externalId: string): Promise<{
|
|
579
|
+
ok: boolean;
|
|
580
|
+
modified: number;
|
|
581
|
+
}>;
|
|
554
582
|
/**
|
|
555
|
-
*
|
|
583
|
+
* Knowledge / resource surface.
|
|
556
584
|
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
* Studio stores the request as a pending offer instead.
|
|
585
|
+
* Reads are allowed when the SDK token's org matches the target org,
|
|
586
|
+
* OR when the target org has `publicReadable: true` on the Studio side.
|
|
560
587
|
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
588
|
+
* Writes target system-owned (handler-managed) knowledge only: the
|
|
589
|
+
* protocol API stamps everything created here `isSystemOwned: true`,
|
|
590
|
+
* which keeps it out of every Studio UI surface — Studio acts as a
|
|
591
|
+
* plain storage + RAG layer for it. UI-managed knowledge cannot be
|
|
592
|
+
* modified through this surface.
|
|
563
593
|
*/
|
|
564
|
-
|
|
594
|
+
knowledge: {
|
|
595
|
+
/**
|
|
596
|
+
* List knowledge items for an organization.
|
|
597
|
+
* Defaults to the SDK token's own org if `orgId` is omitted.
|
|
598
|
+
*/
|
|
599
|
+
list: (options?: ListKnowledgeOptions) => Promise<PlatformKnowledgeSummary[]>;
|
|
600
|
+
/**
|
|
601
|
+
* Fetch a single knowledge item by its Studio ID. The caller must
|
|
602
|
+
* have read access to the knowledge's owning org (same-org or
|
|
603
|
+
* publicReadable).
|
|
604
|
+
*/
|
|
605
|
+
get: (id: string) => Promise<PlatformKnowledge>;
|
|
606
|
+
/**
|
|
607
|
+
* Semantic search over a knowledge's records. Studio embeds the
|
|
608
|
+
* query server-side (Gemini gemini-embedding-001) and runs Atlas
|
|
609
|
+
* Vector Search against the `vector_index` on `knowledge_records`.
|
|
610
|
+
*
|
|
611
|
+
* Same read access rules as `get` — same-org or publicReadable.
|
|
612
|
+
*
|
|
613
|
+
* Returns an empty array (not an error) when the Atlas index is
|
|
614
|
+
* absent or when nothing matches, so handler code can treat
|
|
615
|
+
* "no hits" and "RAG not configured yet" identically.
|
|
616
|
+
*/
|
|
617
|
+
search: (id: string, query: string, options?: KnowledgeSearchOptions) => Promise<PlatformKnowledgeSearchHit[]>;
|
|
618
|
+
/**
|
|
619
|
+
* Turn semantic search on or off for a knowledge.
|
|
620
|
+
*
|
|
621
|
+
* Writes are strictly same-org — `publicReadable` does NOT confer
|
|
622
|
+
* write access. Flipping `false -> true` schedules a background
|
|
623
|
+
* backfill of existing records on the Studio side; this call
|
|
624
|
+
* returns as soon as the flag is persisted, not when the backfill
|
|
625
|
+
* finishes.
|
|
626
|
+
*
|
|
627
|
+
* Idempotent: setting the flag to its current value is a no-op
|
|
628
|
+
* (`backfillTriggered` will be `false`).
|
|
629
|
+
*/
|
|
630
|
+
setRagEnabled: (id: string, enabled: boolean) => Promise<{
|
|
631
|
+
id: string;
|
|
632
|
+
ragEnabled: boolean;
|
|
633
|
+
backfillTriggered: boolean;
|
|
634
|
+
}>;
|
|
635
|
+
/**
|
|
636
|
+
* Create a system-owned database knowledge under the token's org.
|
|
637
|
+
*
|
|
638
|
+
* 409 (surfaced as an error) means a knowledge of the same name
|
|
639
|
+
* already exists in the org. Idempotent callers should recover by
|
|
640
|
+
* listing with `includeSystemOwned: true` and matching on name.
|
|
641
|
+
*/
|
|
642
|
+
create: (name: string, sheets: CreateKnowledgeSheet[], options?: CreateKnowledgeOptions) => Promise<PlatformKnowledge>;
|
|
643
|
+
/**
|
|
644
|
+
* Delete a system-owned knowledge and all of its records.
|
|
645
|
+
* Refused (403) for UI-managed knowledge.
|
|
646
|
+
*/
|
|
647
|
+
delete: (id: string) => Promise<{
|
|
648
|
+
deletedRecords: number;
|
|
649
|
+
}>;
|
|
650
|
+
/**
|
|
651
|
+
* List a sheet's records (newest first). Full-list surfaces (admin
|
|
652
|
+
* tables, exact name matching) where semantic search is the wrong
|
|
653
|
+
* tool. `limit` defaults to 500 (server max 2000).
|
|
654
|
+
*/
|
|
655
|
+
listRecords: (id: string, sheetId: string, options?: {
|
|
656
|
+
limit?: number;
|
|
657
|
+
offset?: number;
|
|
658
|
+
}) => Promise<{
|
|
659
|
+
records: PlatformKnowledgeRecord[];
|
|
660
|
+
total: number;
|
|
661
|
+
}>;
|
|
662
|
+
/**
|
|
663
|
+
* Append one record to a sheet. Embeds async when ragEnabled.
|
|
664
|
+
*/
|
|
665
|
+
addRecord: (id: string, sheetId: string, data: Record<string, unknown>) => Promise<PlatformKnowledgeRecord>;
|
|
666
|
+
/**
|
|
667
|
+
* Replace a record's data payload. Re-embeds async when ragEnabled.
|
|
668
|
+
*/
|
|
669
|
+
updateRecord: (id: string, recordId: string, data: Record<string, unknown>) => Promise<PlatformKnowledgeRecord>;
|
|
670
|
+
/** Delete one record. */
|
|
671
|
+
deleteRecord: (id: string, recordId: string) => Promise<void>;
|
|
672
|
+
/**
|
|
673
|
+
* Bulk-insert records into one sheet (each array entry becomes one
|
|
674
|
+
* record's `data`). With `replace: true` the sheet's existing
|
|
675
|
+
* records are deleted first — the full-resync primitive backfills
|
|
676
|
+
* use. Server caps a single call at 5000 records.
|
|
677
|
+
*/
|
|
678
|
+
bulkRecords: (id: string, sheetId: string, records: Array<Record<string, unknown>>, options?: {
|
|
679
|
+
replace?: boolean;
|
|
680
|
+
}) => Promise<{
|
|
681
|
+
insertedCount: number;
|
|
682
|
+
deletedCount: number;
|
|
683
|
+
}>;
|
|
684
|
+
};
|
|
565
685
|
/**
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
* The Studio proxy pops the handoff stack and delivers the return
|
|
569
|
-
* result to the parent handler on the next user message.
|
|
686
|
+
* Throughline (find-a-helpline) surface.
|
|
570
687
|
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
*
|
|
688
|
+
* Handlers used to call api.throughlinecare.com directly, which meant
|
|
689
|
+
* each handler had to hold OAuth client credentials and re-implement
|
|
690
|
+
* token caching. Studio holds the per-org credentials on
|
|
691
|
+
* `Organization.throughline.{clientId,clientSecret}` and proxies the
|
|
692
|
+
* Throughline endpoints; the SDK token identifies the org server-side
|
|
693
|
+
* so callers never see the secret.
|
|
577
694
|
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
695
|
+
* Responses are returned as parsed JSON. Studio does not reshape the
|
|
696
|
+
* Throughline body — these surfaces stay compatible with future
|
|
697
|
+
* Throughline API additions without a Studio or SDK release.
|
|
581
698
|
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
699
|
+
* Caching (24h on countries + topics, none on helplines) is server-
|
|
700
|
+
* side; the SDK is stateless.
|
|
584
701
|
*/
|
|
585
|
-
|
|
586
|
-
|
|
702
|
+
throughline: {
|
|
703
|
+
/**
|
|
704
|
+
* GET /v1/countries — Throughline's country catalog (codes,
|
|
705
|
+
* names, emergency numbers). Cached 24h server-side.
|
|
706
|
+
*/
|
|
707
|
+
getCountries: () => Promise<unknown>;
|
|
708
|
+
/**
|
|
709
|
+
* GET /v1/topics — Throughline's topic taxonomy used to filter
|
|
710
|
+
* helpline searches. Cached 24h server-side.
|
|
711
|
+
*/
|
|
712
|
+
getTopics: () => Promise<unknown>;
|
|
713
|
+
/**
|
|
714
|
+
* GET /v1/helplines?country_code=...&topic=...&... — live search,
|
|
715
|
+
* not cached. The query object is forwarded verbatim to Throughline,
|
|
716
|
+
* so any new key Throughline adds will work without an SDK change.
|
|
717
|
+
* Required by Throughline today: `country_code`.
|
|
718
|
+
*/
|
|
719
|
+
getHelplines: (query: ThroughlineHelplinesQuery) => Promise<unknown>;
|
|
720
|
+
/**
|
|
721
|
+
* GET /v2/helplines through Studio's platform-held credential.
|
|
722
|
+
* This is opt-in and does not replace the organization-configured v1
|
|
723
|
+
* integration exposed by getHelplines().
|
|
724
|
+
*/
|
|
725
|
+
getHelplinesV2: (query: ThroughlineV2HelplinesQuery) => Promise<ThroughlineV2HelplinesResponse>;
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Create a PlatformClient for calling back to FirstStep Studio.
|
|
730
|
+
*/
|
|
731
|
+
declare function createPlatformClient(config: PlatformClientConfig): PlatformClient;
|
|
587
732
|
|
|
588
733
|
/**
|
|
589
|
-
*
|
|
734
|
+
* Render Markers
|
|
590
735
|
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
736
|
+
* Utilities for building render markers that FirstStep Studio's frontend
|
|
737
|
+
* can parse and display as rich UI components (cards, alerts, forms, etc.).
|
|
738
|
+
*
|
|
739
|
+
* This module is the single source of truth for render marker specs.
|
|
740
|
+
* - Handlers (producers) use the builder functions to emit markers
|
|
741
|
+
* - Studio frontend (consumer) uses the types and MARKER_TYPES constants to parse them
|
|
594
742
|
*
|
|
595
743
|
* @example
|
|
596
744
|
* ```typescript
|
|
597
|
-
* import {
|
|
598
|
-
*
|
|
599
|
-
* const client = createPlatformClient({
|
|
600
|
-
* studioUrl: 'https://studio-api.example.com',
|
|
601
|
-
* token: process.env.FIRSTSTEP_TOKEN,
|
|
602
|
-
* });
|
|
745
|
+
* import { renderMarkers } from '@firststep-studio/sdk';
|
|
603
746
|
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
747
|
+
* // In your handleStream():
|
|
748
|
+
* yield {
|
|
749
|
+
* type: 'text',
|
|
750
|
+
* content: renderMarkers.helplineCard({
|
|
751
|
+
* helplines: [{ name: '988 Lifeline', phoneNumber: '988', categories: ['crisis'], status: 'open', statusLabel: 'Available' }],
|
|
752
|
+
* }),
|
|
753
|
+
* };
|
|
606
754
|
* ```
|
|
607
755
|
*/
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
projectIds: string[] | null;
|
|
633
|
-
}
|
|
634
|
-
interface PlatformIdentity {
|
|
635
|
-
organization: PlatformOrganization;
|
|
636
|
-
token: PlatformTokenInfo;
|
|
637
|
-
}
|
|
638
|
-
interface PlatformChatbotRegisterInput {
|
|
639
|
-
/** Stable handler-side identifier used to upsert (e.g. handler config ID). */
|
|
640
|
-
externalId: string;
|
|
641
|
-
/** Display name shown in Studio's chatbot list. */
|
|
642
|
-
name: string;
|
|
643
|
-
/** Optional human description. */
|
|
644
|
-
description?: string;
|
|
645
|
-
/** Public URL where Studio should send protocol requests. */
|
|
646
|
-
handlerUrl: string;
|
|
647
|
-
/** Slug for multi-config routing on the handler side. */
|
|
648
|
-
configSlug?: string;
|
|
649
|
-
/** Optional capability flags advertised to Studio. */
|
|
650
|
-
capabilities?: {
|
|
651
|
-
streaming?: boolean;
|
|
652
|
-
formQuestions?: boolean;
|
|
653
|
-
knowledgeActions?: boolean;
|
|
654
|
-
integrations?: boolean;
|
|
655
|
-
[key: string]: unknown;
|
|
756
|
+
declare const MARKER_TYPES: {
|
|
757
|
+
readonly HELPLINE_CARD: "RENDER_HELPLINE_CARD";
|
|
758
|
+
readonly HELPLINE_CARD_V2: "RENDER_HELPLINE_CARD_V2";
|
|
759
|
+
readonly EMERGENCY: "RENDER_EMERGENCY";
|
|
760
|
+
readonly RESOURCE_CARD: "RENDER_RESOURCE_CARD";
|
|
761
|
+
readonly PROVIDER_CARD: "RENDER_PROVIDER_CARD";
|
|
762
|
+
readonly SAFETY_PLAN: "RENDER_SAFETY_PLAN";
|
|
763
|
+
readonly REPORT_CARD: "RENDER_REPORT_CARD";
|
|
764
|
+
};
|
|
765
|
+
type MarkerType = typeof MARKER_TYPES[keyof typeof MARKER_TYPES];
|
|
766
|
+
/**
|
|
767
|
+
* Helpline card payload.
|
|
768
|
+
* Renders a carousel of helpline cards with contact buttons (call, text, chat, WhatsApp).
|
|
769
|
+
*/
|
|
770
|
+
interface HelplineCardPayload {
|
|
771
|
+
helplines: HelplineCardItem[];
|
|
772
|
+
type?: 'throughline' | 'throughline_fallback' | 'stage';
|
|
773
|
+
fallback?: {
|
|
774
|
+
message: string;
|
|
775
|
+
linkText?: string;
|
|
776
|
+
linkUrl?: string;
|
|
777
|
+
icon?: string;
|
|
778
|
+
topic?: string;
|
|
779
|
+
topics?: string[];
|
|
656
780
|
};
|
|
657
781
|
}
|
|
658
|
-
interface
|
|
659
|
-
/**
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
782
|
+
interface HelplineCardItem {
|
|
783
|
+
/**
|
|
784
|
+
* Stable helpline id from the throughline API. Lets consumers count
|
|
785
|
+
* distinct helplines across display/click events; name-keyed tracking
|
|
786
|
+
* cannot. Optional: older producers omit it.
|
|
787
|
+
*/
|
|
788
|
+
id?: string;
|
|
664
789
|
name: string;
|
|
665
|
-
|
|
790
|
+
description?: string;
|
|
791
|
+
categories: string[];
|
|
792
|
+
status: 'open' | 'closed';
|
|
793
|
+
statusLabel: string;
|
|
794
|
+
statusBadge?: string;
|
|
795
|
+
hoursText?: string;
|
|
796
|
+
supportTypes?: string;
|
|
797
|
+
smsNumber?: string;
|
|
798
|
+
phoneNumber?: string;
|
|
799
|
+
website?: string;
|
|
800
|
+
webchat?: string;
|
|
801
|
+
whatsapp?: string;
|
|
802
|
+
specialties?: string[];
|
|
803
|
+
highlightedTag?: string;
|
|
804
|
+
verified?: boolean;
|
|
666
805
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
/** Handler URL (if external handler configured) */
|
|
673
|
-
handlerUrl?: string;
|
|
674
|
-
/** Config slug for multi-config routing */
|
|
675
|
-
configSlug?: string;
|
|
676
|
-
/** Handler type */
|
|
677
|
-
handlerType?: 'builtin' | 'external';
|
|
806
|
+
|
|
807
|
+
/** Raw Throughline v2 card contract plus handler presentation metadata. */
|
|
808
|
+
interface HelplineCardV2Payload {
|
|
809
|
+
helplines: HelplineCardV2Item[];
|
|
810
|
+
type?: 'throughline' | 'stage';
|
|
678
811
|
}
|
|
679
|
-
interface
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
812
|
+
interface HelplineCardV2Item extends ThroughlineV2Helpline {
|
|
813
|
+
isTopMatch?: boolean;
|
|
814
|
+
matchReason?: string | null;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Emergency number payload.
|
|
818
|
+
* Renders a prominent alert card with a large call button.
|
|
819
|
+
*/
|
|
820
|
+
interface EmergencyPayload {
|
|
821
|
+
number: string;
|
|
822
|
+
countryName?: string;
|
|
823
|
+
countryCode?: string;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Resource card payload.
|
|
827
|
+
* Renders a carousel of resource cards with video thumbnails, tags, and visit buttons.
|
|
828
|
+
*/
|
|
829
|
+
interface ResourceCardPayload {
|
|
830
|
+
resources: ResourceCardItem[];
|
|
831
|
+
}
|
|
832
|
+
interface ResourceCardItem {
|
|
683
833
|
name: string;
|
|
684
|
-
|
|
834
|
+
url?: string;
|
|
685
835
|
description?: string;
|
|
686
|
-
|
|
836
|
+
video_url?: string;
|
|
687
837
|
type?: string;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* True for handler-managed documents created through the protocol
|
|
692
|
-
* write API. System-owned knowledge is hidden from every Studio UI
|
|
693
|
-
* surface and only appears in `list` when `includeSystemOwned` is set.
|
|
694
|
-
*/
|
|
695
|
-
isSystemOwned?: boolean;
|
|
696
|
-
/** Whether semantic search (record embedding) is enabled. */
|
|
697
|
-
ragEnabled?: boolean;
|
|
698
|
-
/** Timestamps */
|
|
699
|
-
createdAt?: number | string;
|
|
700
|
-
updatedAt?: number | string;
|
|
838
|
+
tags?: string[];
|
|
839
|
+
highlightedTag?: string;
|
|
701
840
|
}
|
|
702
841
|
/**
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
* narrow types can be added incrementally as callers need them.
|
|
842
|
+
* Provider card payload.
|
|
843
|
+
* Renders a carousel of provider directory cards with specialty/language tags and contact info.
|
|
706
844
|
*/
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
/**
|
|
710
|
-
* Target organization to list knowledge from. If omitted, defaults to
|
|
711
|
-
* the org associated with the SDK token. Use this to read from a
|
|
712
|
-
* different org (e.g. a platform-operated shared library marked
|
|
713
|
-
* `publicReadable` in Studio).
|
|
714
|
-
*/
|
|
715
|
-
orgId?: string;
|
|
716
|
-
/**
|
|
717
|
-
* Include system-owned (handler-managed) knowledge in the listing.
|
|
718
|
-
* Only honored when listing the token's own org; other orgs never
|
|
719
|
-
* expose their system-owned documents.
|
|
720
|
-
*/
|
|
721
|
-
includeSystemOwned?: boolean;
|
|
722
|
-
/**
|
|
723
|
-
* 'system' lists ORG-LESS platform documents instead of org
|
|
724
|
-
* knowledge. orgId and includeSystemOwned are ignored in that mode.
|
|
725
|
-
*/
|
|
726
|
-
scope?: 'system';
|
|
845
|
+
interface ProviderCardPayload {
|
|
846
|
+
providers: ProviderCardItem[];
|
|
727
847
|
}
|
|
728
|
-
|
|
729
|
-
interface CreateKnowledgeSheet {
|
|
730
|
-
/** Stable sheet id, referenced later by record writes and search. */
|
|
848
|
+
interface ProviderCardItem {
|
|
731
849
|
id: string;
|
|
732
850
|
name: string;
|
|
851
|
+
type?: string;
|
|
852
|
+
specialty: string[];
|
|
853
|
+
language: string[];
|
|
733
854
|
description?: string;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
855
|
+
location?: string;
|
|
856
|
+
open_hours?: string;
|
|
857
|
+
contact_phone?: string;
|
|
858
|
+
contact_email?: string;
|
|
859
|
+
address?: string;
|
|
860
|
+
website?: string;
|
|
739
861
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
system?: boolean;
|
|
862
|
+
/**
|
|
863
|
+
* Safety plan payload.
|
|
864
|
+
* Renders a multi-section table with expandable sections and save/export actions.
|
|
865
|
+
*/
|
|
866
|
+
interface SafetyPlanPayload {
|
|
867
|
+
sections: SafetyPlanSection[];
|
|
868
|
+
helplines?: Array<{
|
|
869
|
+
name: string;
|
|
870
|
+
phone?: string;
|
|
871
|
+
}>;
|
|
872
|
+
actions?: {
|
|
873
|
+
savePng?: boolean;
|
|
874
|
+
saveTxt?: boolean;
|
|
875
|
+
copy?: boolean;
|
|
876
|
+
};
|
|
756
877
|
}
|
|
757
|
-
|
|
758
|
-
interface PlatformKnowledgeRecord {
|
|
878
|
+
interface SafetyPlanSection {
|
|
759
879
|
id: string;
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
880
|
+
title: string;
|
|
881
|
+
items: Array<string | {
|
|
882
|
+
name: string;
|
|
883
|
+
phone?: string;
|
|
884
|
+
description?: string;
|
|
885
|
+
}>;
|
|
765
886
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
887
|
+
/**
|
|
888
|
+
* Report card payload.
|
|
889
|
+
* Renders a summary card of collected report data with a submit button.
|
|
890
|
+
*/
|
|
891
|
+
interface ReportCardPayload {
|
|
892
|
+
topic: string;
|
|
893
|
+
location?: string;
|
|
894
|
+
description?: string;
|
|
895
|
+
perpetrator_known?: boolean;
|
|
896
|
+
contact_mode?: string;
|
|
897
|
+
contact_value?: string;
|
|
898
|
+
submitEndpoint?: string;
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* The marker families that constitute a *recommendation*: the handler put
|
|
902
|
+
* something in front of the user and expects them to act on it. Safety plans
|
|
903
|
+
* and report cards are excluded: they summarise what the user already said
|
|
904
|
+
* rather than recommending anything, so rating their "satisfaction" would
|
|
905
|
+
* measure a different thing and drag the average with it.
|
|
906
|
+
*/
|
|
907
|
+
type RecommendationKind = 'helpline' | 'resource' | 'provider' | 'emergency';
|
|
908
|
+
/**
|
|
909
|
+
* One recommended thing, flattened out of a card carousel.
|
|
910
|
+
*
|
|
911
|
+
* A single marker usually carries several of these (a helpline carousel is
|
|
912
|
+
* one marker, five helplines), and each one is separately good or bad for the
|
|
913
|
+
* user in front of it, so the unit here is the item, not the card.
|
|
914
|
+
*/
|
|
915
|
+
interface RecommendedItem {
|
|
916
|
+
kind: RecommendationKind;
|
|
769
917
|
/**
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
918
|
+
* Stable producer-side id when there is one. Lets a consumer tally the same
|
|
919
|
+
* helpline or provider across sessions; label-keyed tallies cannot, because
|
|
920
|
+
* two helplines can share a display name across countries.
|
|
773
921
|
*/
|
|
774
|
-
|
|
922
|
+
id?: string;
|
|
923
|
+
/** The card's headline, as the user reads it. */
|
|
924
|
+
label: string;
|
|
925
|
+
/**
|
|
926
|
+
* One line of gist for a consumer that never sees the rendered card: an
|
|
927
|
+
* evaluator, a log, a transcript export.
|
|
928
|
+
*/
|
|
929
|
+
detail?: string;
|
|
775
930
|
}
|
|
776
931
|
/**
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
932
|
+
* Pull one marker's JSON payload out of a message.
|
|
933
|
+
*
|
|
934
|
+
* Tolerates whitespace and newlines between the tags and the payload, because
|
|
935
|
+
* producers differ on that: the SDK builders emit no padding, the Studio
|
|
936
|
+
* frontend's own helpline blocks emit `\n`.
|
|
780
937
|
*/
|
|
781
|
-
|
|
782
|
-
id: string;
|
|
783
|
-
knowledgeId: string;
|
|
784
|
-
sheetId: string;
|
|
785
|
-
data: Record<string, unknown>;
|
|
786
|
-
score: number;
|
|
787
|
-
createdAt?: number | string;
|
|
788
|
-
updatedAt?: number | string;
|
|
789
|
-
}
|
|
938
|
+
declare function parseMarkerPayload<T = unknown>(content: string, type: string): T | null;
|
|
790
939
|
/**
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
940
|
+
* Normalise every recommendation marker in an assistant message into a flat
|
|
941
|
+
* list of recommended items.
|
|
942
|
+
*
|
|
943
|
+
* This is the read side of the builders above, and it lives here for the same
|
|
944
|
+
* reason they do: the marker spec should have one owner. Consumers that want
|
|
945
|
+
* to know "what did this turn recommend" (evaluators, analytics, transcript
|
|
946
|
+
* exporters) otherwise each grow their own regex, and they drift. One reads
|
|
947
|
+
* `payload.title` off a resource card that has never had one.
|
|
948
|
+
*/
|
|
949
|
+
declare function extractRecommendedItems(content: string): RecommendedItem[];
|
|
950
|
+
/**
|
|
951
|
+
* Render marker builder functions.
|
|
952
|
+
*
|
|
953
|
+
* Each function takes a typed payload and returns a render marker string
|
|
954
|
+
* that can be yielded as a `text` chunk in handleStream().
|
|
955
|
+
*
|
|
956
|
+
* @example
|
|
957
|
+
* ```typescript
|
|
958
|
+
* // Emit helpline cards
|
|
959
|
+
* yield { type: 'text', content: renderMarkers.helplineCard({ helplines: [...] }) };
|
|
960
|
+
*
|
|
961
|
+
* // Emit emergency number
|
|
962
|
+
* yield { type: 'text', content: renderMarkers.emergency({ number: '911', countryName: 'United States' }) };
|
|
963
|
+
* ```
|
|
964
|
+
*/
|
|
965
|
+
declare const renderMarkers: {
|
|
966
|
+
/** Build a helpline card carousel marker */
|
|
967
|
+
helplineCard: (payload: HelplineCardPayload) => string;
|
|
968
|
+
/** Build a Throughline v2 helpline card carousel marker. */
|
|
969
|
+
helplineCardV2: (payload: HelplineCardV2Payload) => string;
|
|
970
|
+
/** Build an emergency number alert marker */
|
|
971
|
+
emergency: (payload: EmergencyPayload) => string;
|
|
972
|
+
/** Build a resource card carousel marker */
|
|
973
|
+
resourceCard: (payload: ResourceCardPayload) => string;
|
|
974
|
+
/** Build a provider card carousel marker */
|
|
975
|
+
providerCard: (payload: ProviderCardPayload) => string;
|
|
976
|
+
/** Build a safety plan artifact marker */
|
|
977
|
+
safetyPlan: (payload: SafetyPlanPayload) => string;
|
|
978
|
+
/** Build a report draft card marker */
|
|
979
|
+
reportCard: (payload: ReportCardPayload) => string;
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
/**
|
|
983
|
+
* Stream Metadata Builders
|
|
984
|
+
*
|
|
985
|
+
* Utilities for building typed metadata stream chunks that FirstStep Studio's
|
|
986
|
+
* proxy persists to MongoDB for Dashboard features (Form Insights, Session
|
|
987
|
+
* History, Routing Logs, Agent Transitions).
|
|
988
|
+
*
|
|
989
|
+
* Each function returns a ready-to-yield ProtocolStreamChunk. No need to
|
|
990
|
+
* construct the `{ type, content }` wrapper manually.
|
|
991
|
+
*
|
|
992
|
+
* @example
|
|
993
|
+
* ```typescript
|
|
994
|
+
* import { streamMetadata } from '@firststep-studio/sdk';
|
|
995
|
+
*
|
|
996
|
+
* // In your handleStream():
|
|
997
|
+
*
|
|
998
|
+
* // 1. Welcome path: declare your schema once
|
|
999
|
+
* yield streamMetadata.declareSchema({
|
|
1000
|
+
* agents: [{ id: 'intake', title: 'Intake', order: 0 }],
|
|
1001
|
+
* questions: [{ id: 'name', agentId: 'intake', title: 'Name', type: 'text' }],
|
|
1002
|
+
* });
|
|
1003
|
+
*
|
|
1004
|
+
* // 2. After each turn: send collected field values
|
|
1005
|
+
* yield streamMetadata.formDataUpdate({ name: 'Alice', age: '28' });
|
|
1006
|
+
*
|
|
1007
|
+
* // 3. On stage change: signal an agent transition
|
|
1008
|
+
* yield streamMetadata.agentTransition({ id: 'support', title: 'Support' });
|
|
1009
|
+
*
|
|
1010
|
+
* // 4. On classification: send routing result
|
|
1011
|
+
* yield streamMetadata.routingResult({
|
|
1012
|
+
* decision: 'classified',
|
|
1013
|
+
* reason: 'User mentioned self-harm',
|
|
1014
|
+
* category: 'crisis',
|
|
1015
|
+
* level: 'high',
|
|
1016
|
+
* score: 92,
|
|
1017
|
+
* });
|
|
1018
|
+
* ```
|
|
795
1019
|
*/
|
|
796
|
-
|
|
797
|
-
declare
|
|
798
|
-
status: number;
|
|
799
|
-
constructor(message: string, status: number);
|
|
800
|
-
}
|
|
801
|
-
declare class PlatformClient {
|
|
802
|
-
private studioUrl;
|
|
803
|
-
private token;
|
|
804
|
-
private timeout;
|
|
805
|
-
constructor(config: PlatformClientConfig);
|
|
806
|
-
private request;
|
|
1020
|
+
|
|
1021
|
+
declare const streamMetadata: {
|
|
807
1022
|
/**
|
|
808
|
-
*
|
|
809
|
-
*
|
|
1023
|
+
* Declare the form schema (agents + questions) for Dashboard Form Insights.
|
|
1024
|
+
*
|
|
1025
|
+
* Yield this once during session initialization (welcome message).
|
|
1026
|
+
* The Studio proxy stores it in `chatbot.externalSchema` so that
|
|
1027
|
+
* Dashboard Form Insights can display question-level analytics.
|
|
1028
|
+
*
|
|
1029
|
+
* @param schema - Agents and questions your handler uses
|
|
1030
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
810
1031
|
*/
|
|
811
|
-
|
|
1032
|
+
declareSchema(schema: SchemaDeclarationPayload): ProtocolStreamChunk;
|
|
812
1033
|
/**
|
|
813
|
-
*
|
|
814
|
-
*
|
|
1034
|
+
* Send collected form field values for Dashboard persistence.
|
|
1035
|
+
*
|
|
1036
|
+
* Call this after each turn when new fields are captured.
|
|
1037
|
+
* Values are incrementally merged into `ChatSession.formData`.
|
|
1038
|
+
*
|
|
1039
|
+
* @param fields - Key-value pairs of field IDs to their collected values
|
|
1040
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
815
1041
|
*/
|
|
816
|
-
|
|
1042
|
+
formDataUpdate(fields: Record<string, string | number>): ProtocolStreamChunk;
|
|
817
1043
|
/**
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
1044
|
+
* Signal an agent/stage transition for routing logs.
|
|
1045
|
+
*
|
|
1046
|
+
* The Studio proxy records this in `ChatSession.routingLogs` so
|
|
1047
|
+
* the Dashboard can show the conversation's agent flow.
|
|
1048
|
+
*
|
|
1049
|
+
* @param agent - The agent/stage being transitioned to
|
|
1050
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
821
1051
|
*/
|
|
822
|
-
|
|
1052
|
+
agentTransition(agent: AgentTransitionPayload): ProtocolStreamChunk;
|
|
823
1053
|
/**
|
|
824
|
-
*
|
|
825
|
-
*
|
|
1054
|
+
* Send a routing/classification result for routing logs.
|
|
1055
|
+
*
|
|
1056
|
+
* The Studio proxy records this in `ChatSession.routingLogs` as a
|
|
1057
|
+
* classification event with category, level, and confidence score.
|
|
1058
|
+
*
|
|
1059
|
+
* @param result - Classification/routing decision details
|
|
1060
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
826
1061
|
*/
|
|
827
|
-
|
|
828
|
-
ok: boolean;
|
|
829
|
-
modified: number;
|
|
830
|
-
}>;
|
|
1062
|
+
routingResult(result: RoutingClassificationPayload): ProtocolStreamChunk;
|
|
831
1063
|
/**
|
|
832
|
-
*
|
|
1064
|
+
* Request a handoff to another chatbot.
|
|
833
1065
|
*
|
|
834
|
-
*
|
|
835
|
-
*
|
|
1066
|
+
* The Studio proxy pushes a handoff stack entry and routes subsequent
|
|
1067
|
+
* user messages to the target handler. If `options.consent` is set,
|
|
1068
|
+
* Studio stores the request as a pending offer instead.
|
|
836
1069
|
*
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
* which keeps it out of every Studio UI surface — Studio acts as a
|
|
840
|
-
* plain storage + RAG layer for it. UI-managed knowledge cannot be
|
|
841
|
-
* modified through this surface.
|
|
1070
|
+
* @param payload - Handoff target, reason, context, and options
|
|
1071
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
842
1072
|
*/
|
|
843
|
-
|
|
844
|
-
/**
|
|
845
|
-
* List knowledge items for an organization.
|
|
846
|
-
* Defaults to the SDK token's own org if `orgId` is omitted.
|
|
847
|
-
*/
|
|
848
|
-
list: (options?: ListKnowledgeOptions) => Promise<PlatformKnowledgeSummary[]>;
|
|
849
|
-
/**
|
|
850
|
-
* Fetch a single knowledge item by its Studio ID. The caller must
|
|
851
|
-
* have read access to the knowledge's owning org (same-org or
|
|
852
|
-
* publicReadable).
|
|
853
|
-
*/
|
|
854
|
-
get: (id: string) => Promise<PlatformKnowledge>;
|
|
855
|
-
/**
|
|
856
|
-
* Semantic search over a knowledge's records. Studio embeds the
|
|
857
|
-
* query server-side (Gemini gemini-embedding-001) and runs Atlas
|
|
858
|
-
* Vector Search against the `vector_index` on `knowledge_records`.
|
|
859
|
-
*
|
|
860
|
-
* Same read access rules as `get` — same-org or publicReadable.
|
|
861
|
-
*
|
|
862
|
-
* Returns an empty array (not an error) when the Atlas index is
|
|
863
|
-
* absent or when nothing matches, so handler code can treat
|
|
864
|
-
* "no hits" and "RAG not configured yet" identically.
|
|
865
|
-
*/
|
|
866
|
-
search: (id: string, query: string, options?: KnowledgeSearchOptions) => Promise<PlatformKnowledgeSearchHit[]>;
|
|
867
|
-
/**
|
|
868
|
-
* Turn semantic search on or off for a knowledge.
|
|
869
|
-
*
|
|
870
|
-
* Writes are strictly same-org — `publicReadable` does NOT confer
|
|
871
|
-
* write access. Flipping `false -> true` schedules a background
|
|
872
|
-
* backfill of existing records on the Studio side; this call
|
|
873
|
-
* returns as soon as the flag is persisted, not when the backfill
|
|
874
|
-
* finishes.
|
|
875
|
-
*
|
|
876
|
-
* Idempotent: setting the flag to its current value is a no-op
|
|
877
|
-
* (`backfillTriggered` will be `false`).
|
|
878
|
-
*/
|
|
879
|
-
setRagEnabled: (id: string, enabled: boolean) => Promise<{
|
|
880
|
-
id: string;
|
|
881
|
-
ragEnabled: boolean;
|
|
882
|
-
backfillTriggered: boolean;
|
|
883
|
-
}>;
|
|
884
|
-
/**
|
|
885
|
-
* Create a system-owned database knowledge under the token's org.
|
|
886
|
-
*
|
|
887
|
-
* 409 (surfaced as an error) means a knowledge of the same name
|
|
888
|
-
* already exists in the org. Idempotent callers should recover by
|
|
889
|
-
* listing with `includeSystemOwned: true` and matching on name.
|
|
890
|
-
*/
|
|
891
|
-
create: (name: string, sheets: CreateKnowledgeSheet[], options?: CreateKnowledgeOptions) => Promise<PlatformKnowledge>;
|
|
892
|
-
/**
|
|
893
|
-
* Delete a system-owned knowledge and all of its records.
|
|
894
|
-
* Refused (403) for UI-managed knowledge.
|
|
895
|
-
*/
|
|
896
|
-
delete: (id: string) => Promise<{
|
|
897
|
-
deletedRecords: number;
|
|
898
|
-
}>;
|
|
899
|
-
/**
|
|
900
|
-
* List a sheet's records (newest first). Full-list surfaces (admin
|
|
901
|
-
* tables, exact name matching) where semantic search is the wrong
|
|
902
|
-
* tool. `limit` defaults to 500 (server max 2000).
|
|
903
|
-
*/
|
|
904
|
-
listRecords: (id: string, sheetId: string, options?: {
|
|
905
|
-
limit?: number;
|
|
906
|
-
offset?: number;
|
|
907
|
-
}) => Promise<{
|
|
908
|
-
records: PlatformKnowledgeRecord[];
|
|
909
|
-
total: number;
|
|
910
|
-
}>;
|
|
911
|
-
/**
|
|
912
|
-
* Append one record to a sheet. Embeds async when ragEnabled.
|
|
913
|
-
*/
|
|
914
|
-
addRecord: (id: string, sheetId: string, data: Record<string, unknown>) => Promise<PlatformKnowledgeRecord>;
|
|
915
|
-
/**
|
|
916
|
-
* Replace a record's data payload. Re-embeds async when ragEnabled.
|
|
917
|
-
*/
|
|
918
|
-
updateRecord: (id: string, recordId: string, data: Record<string, unknown>) => Promise<PlatformKnowledgeRecord>;
|
|
919
|
-
/** Delete one record. */
|
|
920
|
-
deleteRecord: (id: string, recordId: string) => Promise<void>;
|
|
921
|
-
/**
|
|
922
|
-
* Bulk-insert records into one sheet (each array entry becomes one
|
|
923
|
-
* record's `data`). With `replace: true` the sheet's existing
|
|
924
|
-
* records are deleted first — the full-resync primitive backfills
|
|
925
|
-
* use. Server caps a single call at 5000 records.
|
|
926
|
-
*/
|
|
927
|
-
bulkRecords: (id: string, sheetId: string, records: Array<Record<string, unknown>>, options?: {
|
|
928
|
-
replace?: boolean;
|
|
929
|
-
}) => Promise<{
|
|
930
|
-
insertedCount: number;
|
|
931
|
-
deletedCount: number;
|
|
932
|
-
}>;
|
|
933
|
-
};
|
|
1073
|
+
handoffRequest(payload: HandoffRequestPayload): ProtocolStreamChunk;
|
|
934
1074
|
/**
|
|
935
|
-
*
|
|
1075
|
+
* Return from a handoff back to the parent handler.
|
|
936
1076
|
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
* token caching. Studio holds the per-org credentials on
|
|
940
|
-
* `Organization.throughline.{clientId,clientSecret}` and proxies the
|
|
941
|
-
* Throughline endpoints; the SDK token identifies the org server-side
|
|
942
|
-
* so callers never see the secret.
|
|
1077
|
+
* The Studio proxy pops the handoff stack and delivers the return
|
|
1078
|
+
* result to the parent handler on the next user message.
|
|
943
1079
|
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
|
|
1080
|
+
* @param payload - Summary and artifacts from the completed handoff
|
|
1081
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
1082
|
+
*/
|
|
1083
|
+
handoffReturn(payload: HandoffReturnPayload): ProtocolStreamChunk;
|
|
1084
|
+
/**
|
|
1085
|
+
* Offer a handoff with user consent required.
|
|
947
1086
|
*
|
|
948
|
-
*
|
|
949
|
-
*
|
|
1087
|
+
* Studio stores this as a pending offer, sends an SSE event to the
|
|
1088
|
+
* frontend, and waits for the user to accept or decline before
|
|
1089
|
+
* executing the handoff.
|
|
1090
|
+
*
|
|
1091
|
+
* @param payload - Offer display info and the pending handoff request
|
|
1092
|
+
* @returns A metadata stream chunk ready to yield or queue.push
|
|
950
1093
|
*/
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
* GET /v1/countries — Throughline's country catalog (codes,
|
|
954
|
-
* names, emergency numbers). Cached 24h server-side.
|
|
955
|
-
*/
|
|
956
|
-
getCountries: () => Promise<unknown>;
|
|
957
|
-
/**
|
|
958
|
-
* GET /v1/topics — Throughline's topic taxonomy used to filter
|
|
959
|
-
* helpline searches. Cached 24h server-side.
|
|
960
|
-
*/
|
|
961
|
-
getTopics: () => Promise<unknown>;
|
|
962
|
-
/**
|
|
963
|
-
* GET /v1/helplines?country_code=...&topic=...&... — live search,
|
|
964
|
-
* not cached. The query object is forwarded verbatim to Throughline,
|
|
965
|
-
* so any new key Throughline adds will work without an SDK change.
|
|
966
|
-
* Required by Throughline today: `country_code`.
|
|
967
|
-
*/
|
|
968
|
-
getHelplines: (query: ThroughlineHelplinesQuery) => Promise<unknown>;
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
/**
|
|
972
|
-
* Create a PlatformClient for calling back to FirstStep Studio.
|
|
973
|
-
*/
|
|
974
|
-
declare function createPlatformClient(config: PlatformClientConfig): PlatformClient;
|
|
1094
|
+
handoffOffer(payload: HandoffOfferPayload): ProtocolStreamChunk;
|
|
1095
|
+
};
|
|
975
1096
|
|
|
976
1097
|
/**
|
|
977
1098
|
* Verify an HMAC-SHA256 request signature.
|
|
@@ -1240,4 +1361,4 @@ declare class LLMClient {
|
|
|
1240
1361
|
*/
|
|
1241
1362
|
declare function createLLMClient(config: LLMClientConfig): LLMClient;
|
|
1242
1363
|
|
|
1243
|
-
export { AgentTransitionPayload, ChatMessage, type ClassificationResult, type CreateKnowledgeOptions, type CreateKnowledgeSheet, type EmergencyPayload, HandoffOfferPayload, HandoffRequestPayload, HandoffReturnPayload, type HelplineCardItem, type HelplineCardPayload, 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 ReportCardPayload, type ResourceCardItem, type ResourceCardPayload, RoutingClassificationPayload, type SafetyPlanPayload, type SafetyPlanSection, SchemaDeclarationPayload, type ThroughlineHelplinesQuery, type UCPClassifyRequest, type UCPClassifyResponse, UCPClient, type UCPClientConfig, type UCPEndpointConfig, UCPError, type UCPErrorResponse, type UCPInfoResponse, type UCPMessage, classifyWithUCP, createAuthHeader, createLLMClient, createPlatformClient, createRequestSignature, createUCPClient, isValidToken, renderMarkers, streamMetadata, verifyRequestSignature };
|
|
1364
|
+
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 };
|