@aginies/webuikit 0.2.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.
@@ -0,0 +1,965 @@
1
+ import * as react from 'react';
2
+ import { ButtonHTMLAttributes, HTMLAttributes, InputHTMLAttributes, TextareaHTMLAttributes, ReactNode } from 'react';
3
+
4
+ /**
5
+ * Thin browser client for the Aginies platform: activation handshake, hosted-chat
6
+ * configuration and streaming chat turns. No framework dependency; the React layer
7
+ * wraps it.
8
+ */
9
+ interface AginiesConfig {
10
+ /** Platform origin, e.g. `https://app.example.com`. No trailing slash. */
11
+ baseUrl: string;
12
+ /** Activation token issued for the deployment. Without it nothing renders. */
13
+ token: string;
14
+ /** UI language. Defaults to the document language, then English. */
15
+ locale?: 'tr' | 'en';
16
+ /** Fetch implementation override (tests, SSR). */
17
+ fetch?: typeof fetch;
18
+ }
19
+ interface ActivationConfig {
20
+ apiBase: string;
21
+ brand: {
22
+ name: string;
23
+ logoUrl: string | null;
24
+ };
25
+ theme: Record<string, string | undefined> | null;
26
+ /** Widget modules the activation unlocks; empty means all. */
27
+ modules?: string[];
28
+ /** The tenant a tenant key belongs to. Absent for a static activation key. */
29
+ tenant?: {
30
+ id: string;
31
+ name: string;
32
+ };
33
+ }
34
+ /**
35
+ * The session a tenant key buys: a short-lived bearer the client sends on every
36
+ * platform call and renews by re-activating when it is refused.
37
+ */
38
+ interface ActivationSession {
39
+ token: string;
40
+ /** Unix seconds. */
41
+ expiresAt: number;
42
+ }
43
+ type ActivationState = {
44
+ status: 'idle';
45
+ } | {
46
+ status: 'activating';
47
+ } | {
48
+ status: 'active';
49
+ config: ActivationConfig;
50
+ } | {
51
+ status: 'rejected';
52
+ reason: string;
53
+ };
54
+ interface ChatConfig {
55
+ id: string;
56
+ title: string;
57
+ description: string;
58
+ customizations: {
59
+ primaryColor?: string;
60
+ welcomeMessage?: string;
61
+ imageUrl?: string;
62
+ logoUrl?: string;
63
+ headerText?: string;
64
+ };
65
+ authType: 'public' | 'password' | 'email' | 'sso';
66
+ outputConfigs?: Array<{
67
+ blockId: string;
68
+ path?: string;
69
+ }>;
70
+ }
71
+ interface ChatAuthRequired {
72
+ authRequired: ChatConfig['authType'];
73
+ title?: string;
74
+ description?: string;
75
+ }
76
+ interface ChatFilePayload {
77
+ name: string;
78
+ type: string;
79
+ size: number;
80
+ data: string;
81
+ lastModified?: number;
82
+ }
83
+ interface SendMessageInput {
84
+ input?: string;
85
+ conversationId?: string;
86
+ password?: string;
87
+ email?: string;
88
+ files?: ChatFilePayload[];
89
+ }
90
+ /** One server-sent event from a chat turn, already decoded. */
91
+ type ChatStreamEvent = {
92
+ type: 'chunk';
93
+ blockId?: string;
94
+ text: string;
95
+ } | {
96
+ type: 'final';
97
+ data: unknown;
98
+ } | {
99
+ type: 'error';
100
+ message: string;
101
+ } | {
102
+ type: 'done';
103
+ };
104
+ declare class AginiesError extends Error {
105
+ readonly status: number;
106
+ readonly code?: string;
107
+ constructor(message: string, status: number, code?: string);
108
+ }
109
+ declare class AginiesClient {
110
+ readonly baseUrl: string;
111
+ readonly token: string;
112
+ readonly locale: 'tr' | 'en';
113
+ private readonly fetchImpl;
114
+ private state;
115
+ private listeners;
116
+ private activation;
117
+ private session;
118
+ constructor(config: AginiesConfig);
119
+ getState(): ActivationState;
120
+ subscribe(listener: (s: ActivationState) => void): () => void;
121
+ private setState;
122
+ /**
123
+ * Runs the activation handshake once and caches the outcome. Components render only
124
+ * while the state is `active`; a rejected activation is final for this client.
125
+ */
126
+ activate(): Promise<ActivationState>;
127
+ private assertActive;
128
+ /** The current tenant session, if the activation issued one. */
129
+ getSession(): ActivationSession | null;
130
+ /** Whether `module` may render under this activation. */
131
+ hasModule(module: string): boolean;
132
+ /**
133
+ * Re-runs the handshake to obtain a fresh session. Used when a call is refused with
134
+ * an expired bearer; the activation state stays `active` unless the platform now
135
+ * rejects the key.
136
+ */
137
+ private renewSession;
138
+ private withSession;
139
+ /**
140
+ * A platform request carrying cookies and, when a tenant session exists, its bearer.
141
+ * A 401/403 on a session that has expired triggers one renewal and one retry.
142
+ */
143
+ private request;
144
+ /** A raw request against the platform for endpoints the client does not wrap. */
145
+ fetchRaw(path: string, init?: RequestInit): Promise<Response>;
146
+ /** Hosted-chat configuration. Resolves to an auth requirement instead of throwing on 401. */
147
+ getChat(identifier: string): Promise<ChatConfig | ChatAuthRequired>;
148
+ /**
149
+ * Sends one turn and yields the streamed events. Authentication for password / e-mail
150
+ * chats travels in the same body on the first call; the platform then sets a cookie.
151
+ */
152
+ sendMessage(identifier: string, input: SendMessageInput, signal?: AbortSignal): AsyncGenerator<ChatStreamEvent>;
153
+ }
154
+ /** Parses an SSE body into chat events. Exported for tests. */
155
+ declare function parseSSE(stream: ReadableStream<Uint8Array>): AsyncGenerator<ChatStreamEvent>;
156
+
157
+ /**
158
+ * Human-in-the-loop approvals. A run that reaches a "Human in the Loop" block pauses;
159
+ * the platform stores its state and hands out a resume link. This module reads the
160
+ * paused execution (`GET /api/resume/:workflowId/:executionId[/:contextId]`) and resumes
161
+ * it with the approver's input (`POST …/:contextId`), through the activated client so a
162
+ * tenant session travels along.
163
+ */
164
+
165
+ type ResumeStatus = 'paused' | 'resumed' | 'failed' | 'queued' | 'resuming';
166
+ interface ResumeQueueEntry {
167
+ id: string;
168
+ contextId: string;
169
+ status: string;
170
+ queuedAt: string | null;
171
+ claimedAt: string | null;
172
+ completedAt: string | null;
173
+ failureReason: string | null;
174
+ newExecutionId: string;
175
+ resumeInput: unknown;
176
+ }
177
+ interface PausePoint {
178
+ contextId: string;
179
+ triggerBlockId: string;
180
+ /** The block's paused output; `data.inputFormat` describes the approver's form. */
181
+ response: {
182
+ data?: Record<string, unknown>;
183
+ } | null;
184
+ registeredAt: string;
185
+ resumeStatus: ResumeStatus;
186
+ snapshotReady: boolean;
187
+ queuePosition?: number | null;
188
+ latestResumeEntry?: ResumeQueueEntry | null;
189
+ }
190
+ interface PausedExecution {
191
+ id: string;
192
+ workflowId: string;
193
+ executionId: string;
194
+ status: string;
195
+ totalPauseCount: number;
196
+ resumedCount: number;
197
+ pausedAt: string | null;
198
+ updatedAt: string | null;
199
+ expiresAt: string | null;
200
+ metadata: Record<string, unknown> | null;
201
+ pausePoints: PausePoint[];
202
+ queue?: ResumeQueueEntry[];
203
+ }
204
+ interface PauseContext {
205
+ execution: PausedExecution;
206
+ pausePoint: PausePoint;
207
+ queue: ResumeQueueEntry[];
208
+ activeResumeEntry?: ResumeQueueEntry | null;
209
+ }
210
+ interface ResumeOutcome {
211
+ status: 'started' | 'queued';
212
+ executionId: string;
213
+ queuePosition?: number | null;
214
+ message?: string;
215
+ }
216
+ /** One field of the approver's form, as the block author configured it. */
217
+ interface ResumeField {
218
+ id: string;
219
+ name: string;
220
+ label: string;
221
+ type: string;
222
+ description?: string;
223
+ placeholder?: string;
224
+ value?: unknown;
225
+ required: boolean;
226
+ options?: unknown[];
227
+ rows?: number;
228
+ }
229
+ declare function getPausedExecution(client: AginiesClient, workflowId: string, executionId: string): Promise<PausedExecution>;
230
+ declare function getPauseContext(client: AginiesClient, workflowId: string, executionId: string, contextId: string): Promise<PauseContext>;
231
+ declare function listPausedExecutions(client: AginiesClient, workflowId: string, status?: string): Promise<PausedExecution[]>;
232
+ /** Resumes one pause point with the approver's submission, keyed by field name. */
233
+ declare function resumeExecution(client: AginiesClient, workflowId: string, executionId: string, contextId: string, submission: Record<string, unknown> | null): Promise<ResumeOutcome>;
234
+ /** Reads the approver's form out of a pause point, tolerating partial definitions. */
235
+ declare function fieldsOf(point: PausePoint | null | undefined): ResumeField[];
236
+ /** The paused output shown to the approver: everything in `data` except form plumbing. */
237
+ declare function outputOf(point: PausePoint | null | undefined): Record<string, unknown>;
238
+ /** Formats a stored value for an input of this field's type. */
239
+ declare function formatFieldValue(field: ResumeField, value: unknown): string;
240
+ /** Parses an input's text back into the field's type; `error` names what went wrong. */
241
+ declare function parseFieldValue(field: ResumeField, raw: string): {
242
+ value?: unknown;
243
+ error?: 'number' | 'json';
244
+ };
245
+ /** Initial input text per field, from the block's defaults. */
246
+ declare function initialValues(fields: ResumeField[]): Record<string, string>;
247
+ /**
248
+ * Builds the submission from the inputs, or reports the fields that are missing or
249
+ * malformed. Empty optional fields are left out of the submission.
250
+ */
251
+ declare function buildSubmission(fields: ResumeField[], values: Record<string, string>): {
252
+ submission: Record<string, unknown>;
253
+ errors: Record<string, 'required' | 'number' | 'json'>;
254
+ };
255
+
256
+ type ApprovalStatus = 'loading' | 'ready' | 'submitting' | 'resumed' | 'queued' | 'not-found' | 'error';
257
+ /**
258
+ * State for one paused run: which pause point is selected, the approver's form, the
259
+ * outcome of resuming. `ApprovalPanel` renders it; use the hook for a custom UI.
260
+ */
261
+ declare function useApproval(workflowId: string, executionId: string, contextId?: string): {
262
+ status: ApprovalStatus;
263
+ execution: PausedExecution | null;
264
+ pausePoint: PausePoint | null;
265
+ fields: ResumeField[];
266
+ values: Record<string, string>;
267
+ errors: Record<string, string>;
268
+ error: string | null;
269
+ outcome: ResumeOutcome | null;
270
+ select: (nextContextId: string) => void;
271
+ setValue: (name: string, value: string) => void;
272
+ submit: () => Promise<void>;
273
+ reload: () => Promise<void>;
274
+ };
275
+ interface ApprovalPanelProps {
276
+ /** Id of the agent (workflow) whose run is paused. */
277
+ workflowId: string;
278
+ /** The paused execution, from the resume link the approver received. */
279
+ executionId: string;
280
+ /** A specific pause point; defaults to the first one still paused. */
281
+ contextId?: string;
282
+ title?: string;
283
+ description?: string;
284
+ /** Label of the resume button; defaults to "Approve and continue". */
285
+ submitLabel?: string;
286
+ /** Called after the platform accepted the resume. */
287
+ onResumed?: (outcome: ResumeOutcome) => void;
288
+ /** Hide the paused output block. */
289
+ hideOutput?: boolean;
290
+ className?: string;
291
+ }
292
+ declare function ApprovalPanel({ workflowId, executionId, contextId, title, description, submitLabel, onResumed, hideOutput, className, }: ApprovalPanelProps): react.JSX.Element | null;
293
+
294
+ /**
295
+ * Structured replies: an agent may answer with a JSON document of items (text, buttons,
296
+ * table, cards, pie, image) instead of prose. This mirrors the contract the platform's
297
+ * hosted chat renders, so a workflow tuned for one renders identically in the widget.
298
+ */
299
+ interface StructuredButton {
300
+ label: string;
301
+ action: string;
302
+ }
303
+ interface StructuredTable {
304
+ headers: string[];
305
+ rows: string[][];
306
+ }
307
+ interface StructuredCard {
308
+ title: string;
309
+ subtitle: string;
310
+ body: string;
311
+ image: string;
312
+ }
313
+ interface StructuredPie {
314
+ labels: string[];
315
+ data: number[];
316
+ }
317
+ interface StructuredImage {
318
+ url: string;
319
+ caption: string;
320
+ }
321
+ interface StructuredItem {
322
+ text: {
323
+ content: string;
324
+ };
325
+ buttons: StructuredButton[];
326
+ table: StructuredTable;
327
+ cards: StructuredCard[];
328
+ pie: StructuredPie;
329
+ image: StructuredImage;
330
+ }
331
+ interface StructuredResponse {
332
+ items: StructuredItem[];
333
+ }
334
+ /** Parses a reply into a structured response, or null when it is ordinary prose. */
335
+ declare function parseStructured(raw: string): StructuredResponse | null;
336
+ interface StructuredUIProps {
337
+ response: StructuredResponse;
338
+ /** Called with the button's action text; the widget sends it as the next message. */
339
+ onAction?: (action: string) => void;
340
+ }
341
+ declare function StructuredUI({ response, onAction }: StructuredUIProps): react.JSX.Element;
342
+
343
+ /** A file the visitor attached to a message, as shown in the transcript. */
344
+ interface ChatAttachment {
345
+ name: string;
346
+ type: string;
347
+ size: number;
348
+ }
349
+ interface ChatMessage {
350
+ id: string;
351
+ role: 'user' | 'assistant';
352
+ content: string;
353
+ attachments?: ChatAttachment[];
354
+ structured?: StructuredResponse | null;
355
+ streaming?: boolean;
356
+ error?: boolean;
357
+ }
358
+ /** Outcome of asking the platform to e-mail a verification code. */
359
+ type CodeRequestResult = 'sent' | 'unauthorized' | 'error';
360
+ /** Per-file and per-message limits for attachments; the platform rejects larger uploads. */
361
+ declare const ATTACHMENT_LIMITS: {
362
+ readonly maxFiles: 5;
363
+ readonly maxBytes: number;
364
+ };
365
+ type AuthNeed = 'password' | 'email' | 'sso' | null;
366
+ /**
367
+ * Chat state for one hosted-chat deployment: configuration, authentication, messages and
368
+ * the streaming turn in flight. `ChatWidget` renders it; use the hook directly for a custom UI.
369
+ */
370
+ declare function useChat(identifier: string, enabled?: boolean): {
371
+ config: ChatConfig | null;
372
+ authNeed: AuthNeed;
373
+ authTitle: string | undefined;
374
+ loadError: string | null;
375
+ messages: ChatMessage[];
376
+ busy: boolean;
377
+ send: (text: string, files?: ChatFilePayload[]) => Promise<void>;
378
+ stop: () => void;
379
+ authenticate: ({ password }: {
380
+ password: string;
381
+ }) => Promise<boolean>;
382
+ requestCode: (email: string) => Promise<CodeRequestResult>;
383
+ verifyCode: (email: string, otp: string) => Promise<boolean>;
384
+ reload: () => Promise<void>;
385
+ };
386
+ interface ChatWidgetProps {
387
+ /** Identifier of the deployed chat, the last segment of its hosted URL. */
388
+ identifier: string;
389
+ /** `bubble` floats a launcher in a corner; `inline` fills its container; `full` fills the viewport. */
390
+ mode?: 'bubble' | 'inline' | 'full';
391
+ /** Corner for `bubble` mode. */
392
+ position?: 'right' | 'left';
393
+ /** Text on the launcher; defaults to the chat title. */
394
+ launcherLabel?: string;
395
+ /** Start open (bubble mode). */
396
+ defaultOpen?: boolean;
397
+ /** Theme for the widget subtree; `auto` follows the host page. */
398
+ theme?: 'dark' | 'light' | 'auto';
399
+ className?: string;
400
+ }
401
+ declare function ChatWidget({ identifier, mode, position, launcherLabel, defaultOpen, theme, className, }: ChatWidgetProps): react.JSX.Element | null;
402
+
403
+ /**
404
+ * Small Markdown renderer for agent replies. It builds React elements directly, so nothing
405
+ * from the model reaches the DOM as HTML. Covers what agents actually write: paragraphs,
406
+ * headings, emphasis, inline and fenced code, links, lists, blockquotes, tables and rules.
407
+ */
408
+ declare function Markdown({ text, className }: {
409
+ text: string;
410
+ className?: string;
411
+ }): react.JSX.Element;
412
+
413
+ /** Joins class names, dropping falsy entries. */
414
+ declare function cx(...parts: Array<string | false | null | undefined>): string;
415
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
416
+ /** `primary` is the text fill, `signal` the accent fill, `outline` the quiet default. */
417
+ variant?: 'primary' | 'signal' | 'outline' | 'ghost' | 'destructive';
418
+ size?: 'sm' | 'md' | 'lg';
419
+ }
420
+ declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
421
+ interface TagProps extends HTMLAttributes<HTMLSpanElement> {
422
+ tone?: 'default' | 'signal' | 'ok' | 'warn' | 'bad';
423
+ }
424
+ declare function Tag({ tone, className, ...props }: TagProps): react.JSX.Element;
425
+ interface ChipProps extends ButtonHTMLAttributes<HTMLButtonElement> {
426
+ pressed?: boolean;
427
+ }
428
+ declare function Chip({ pressed, className, type, ...props }: ChipProps): react.JSX.Element;
429
+ interface PanelProps extends HTMLAttributes<HTMLDivElement> {
430
+ level?: 1 | 2;
431
+ }
432
+ declare function Panel({ level, className, ...props }: PanelProps): react.JSX.Element;
433
+ declare function Eyebrow({ className, quiet, ...props }: HTMLAttributes<HTMLParagraphElement> & {
434
+ quiet?: boolean;
435
+ }): react.JSX.Element;
436
+ interface StatProps extends HTMLAttributes<HTMLDivElement> {
437
+ value: string;
438
+ label: string;
439
+ }
440
+ declare function Stat({ value, label, className, ...props }: StatProps): react.JSX.Element;
441
+ interface FieldProps extends HTMLAttributes<HTMLLabelElement> {
442
+ label: string;
443
+ htmlFor?: string;
444
+ /** Help text under the control; replaced by `error` when one is set. */
445
+ hint?: string;
446
+ error?: string;
447
+ }
448
+ declare function Field({ label, hint, error, className, children, ...props }: FieldProps): react.JSX.Element;
449
+ declare const Input: react.ForwardRefExoticComponent<InputHTMLAttributes<HTMLInputElement> & react.RefAttributes<HTMLInputElement>>;
450
+ declare const Textarea: react.ForwardRefExoticComponent<TextareaHTMLAttributes<HTMLTextAreaElement> & react.RefAttributes<HTMLTextAreaElement>>;
451
+ declare function Spinner({ className, label }: {
452
+ className?: string;
453
+ label?: string;
454
+ }): react.JSX.Element;
455
+
456
+ type Locale = 'tr' | 'en';
457
+ declare const STRINGS: {
458
+ readonly chat: {
459
+ readonly open: {
460
+ readonly tr: "Sohbeti aç";
461
+ readonly en: "Open chat";
462
+ };
463
+ readonly close: {
464
+ readonly tr: "Kapat";
465
+ readonly en: "Close";
466
+ };
467
+ readonly placeholder: {
468
+ readonly tr: "Mesajınızı yazın…";
469
+ readonly en: "Type your message…";
470
+ };
471
+ readonly send: {
472
+ readonly tr: "Gönder";
473
+ readonly en: "Send";
474
+ };
475
+ readonly stop: {
476
+ readonly tr: "Durdur";
477
+ readonly en: "Stop";
478
+ };
479
+ readonly attach: {
480
+ readonly tr: "Dosya ekle";
481
+ readonly en: "Attach file";
482
+ };
483
+ readonly attachments: {
484
+ readonly tr: "Ekler";
485
+ readonly en: "Attachments";
486
+ };
487
+ readonly removeFile: {
488
+ readonly tr: "Dosyayı kaldır";
489
+ readonly en: "Remove file";
490
+ };
491
+ readonly tooManyFiles: {
492
+ readonly tr: "En fazla 5 dosya ekleyebilirsiniz.";
493
+ readonly en: "You can attach up to 5 files.";
494
+ };
495
+ readonly fileTooLarge: {
496
+ readonly tr: "Dosyalar 10 MB'tan küçük olmalı.";
497
+ readonly en: "Files must be smaller than 10 MB.";
498
+ };
499
+ readonly welcome: {
500
+ readonly tr: "Merhaba! Size nasıl yardımcı olabilirim?";
501
+ readonly en: "Hi there! How can I help you today?";
502
+ };
503
+ readonly thinking: {
504
+ readonly tr: "Yanıt hazırlanıyor";
505
+ readonly en: "Working on it";
506
+ };
507
+ readonly stopped: {
508
+ readonly tr: "Yanıt durduruldu.";
509
+ readonly en: "Response stopped.";
510
+ };
511
+ readonly error: {
512
+ readonly tr: "Bir sorun oluştu. Lütfen tekrar deneyin.";
513
+ readonly en: "Something went wrong. Please try again.";
514
+ };
515
+ readonly unavailable: {
516
+ readonly tr: "Bu sohbet şu anda kullanılamıyor.";
517
+ readonly en: "This chat is currently unavailable.";
518
+ };
519
+ readonly poweredBy: {
520
+ readonly tr: "Aginies ile";
521
+ readonly en: "Powered by Aginies";
522
+ };
523
+ readonly you: {
524
+ readonly tr: "Siz";
525
+ readonly en: "You";
526
+ };
527
+ readonly assistant: {
528
+ readonly tr: "Ajan";
529
+ readonly en: "Agent";
530
+ };
531
+ };
532
+ readonly auth: {
533
+ readonly passwordTitle: {
534
+ readonly tr: "Bu sohbet parola korumalı";
535
+ readonly en: "This chat is password protected";
536
+ };
537
+ readonly passwordHint: {
538
+ readonly tr: "Devam etmek için parolayı girin.";
539
+ readonly en: "Enter the password to continue.";
540
+ };
541
+ readonly password: {
542
+ readonly tr: "Parola";
543
+ readonly en: "Password";
544
+ };
545
+ readonly emailTitle: {
546
+ readonly tr: "E-posta ile doğrulama";
547
+ readonly en: "Verify with your e-mail";
548
+ };
549
+ readonly emailHint: {
550
+ readonly tr: "İş e-postanızı girin; size bir kod göndereceğiz.";
551
+ readonly en: "Enter your work e-mail; we will send you a code.";
552
+ };
553
+ readonly email: {
554
+ readonly tr: "E-posta";
555
+ readonly en: "E-mail";
556
+ };
557
+ readonly code: {
558
+ readonly tr: "Doğrulama kodu";
559
+ readonly en: "Verification code";
560
+ };
561
+ readonly codeHint: {
562
+ readonly tr: "E-postanıza gelen 6 haneli kodu girin.";
563
+ readonly en: "Enter the 6-digit code from your e-mail.";
564
+ };
565
+ readonly continue: {
566
+ readonly tr: "Devam et";
567
+ readonly en: "Continue";
568
+ };
569
+ readonly sendCode: {
570
+ readonly tr: "Kod gönder";
571
+ readonly en: "Send code";
572
+ };
573
+ readonly verify: {
574
+ readonly tr: "Doğrula";
575
+ readonly en: "Verify";
576
+ };
577
+ readonly back: {
578
+ readonly tr: "Geri";
579
+ readonly en: "Back";
580
+ };
581
+ readonly invalidPassword: {
582
+ readonly tr: "Parola yanlış.";
583
+ readonly en: "Wrong password.";
584
+ };
585
+ readonly invalidEmail: {
586
+ readonly tr: "Bu e-posta adresi yetkili değil.";
587
+ readonly en: "This e-mail address is not allowed.";
588
+ };
589
+ readonly invalidCode: {
590
+ readonly tr: "Kod geçersiz veya süresi dolmuş.";
591
+ readonly en: "The code is invalid or has expired.";
592
+ };
593
+ readonly codeSent: {
594
+ readonly tr: "Kod gönderildi.";
595
+ readonly en: "Code sent.";
596
+ };
597
+ readonly codeError: {
598
+ readonly tr: "Kod gönderilemedi. Lütfen tekrar deneyin.";
599
+ readonly en: "The code could not be sent. Please try again.";
600
+ };
601
+ readonly resend: {
602
+ readonly tr: "Kodu yeniden gönder";
603
+ readonly en: "Resend code";
604
+ };
605
+ readonly ssoTitle: {
606
+ readonly tr: "Kurumsal giriş gerekli";
607
+ readonly en: "Sign in with your organisation";
608
+ };
609
+ readonly ssoHint: {
610
+ readonly tr: "Bu sohbet kurumsal kimlikle açılır.";
611
+ readonly en: "This chat opens with your organisation account.";
612
+ };
613
+ readonly ssoButton: {
614
+ readonly tr: "Kurumsal giriş";
615
+ readonly en: "Sign in";
616
+ };
617
+ };
618
+ readonly run: {
619
+ readonly submit: {
620
+ readonly tr: "Çalıştır";
621
+ readonly en: "Run";
622
+ };
623
+ readonly cancel: {
624
+ readonly tr: "İptal";
625
+ readonly en: "Cancel";
626
+ };
627
+ readonly running: {
628
+ readonly tr: "Çalışıyor";
629
+ readonly en: "Running";
630
+ };
631
+ readonly done: {
632
+ readonly tr: "Tamamlandı";
633
+ readonly en: "Completed";
634
+ };
635
+ readonly error: {
636
+ readonly tr: "Hata";
637
+ readonly en: "Error";
638
+ };
639
+ readonly failed: {
640
+ readonly tr: "Çalıştırma başarısız oldu.";
641
+ readonly en: "The run failed.";
642
+ };
643
+ readonly unauthorized: {
644
+ readonly tr: "API anahtarı reddedildi.";
645
+ readonly en: "The API key was rejected.";
646
+ };
647
+ readonly steps: {
648
+ readonly tr: "Adımlar";
649
+ readonly en: "Steps";
650
+ };
651
+ readonly execution: {
652
+ readonly tr: "çalıştırma";
653
+ readonly en: "execution";
654
+ };
655
+ };
656
+ readonly approval: {
657
+ readonly eyebrow: {
658
+ readonly tr: "İnsan onayı";
659
+ readonly en: "Human approval";
660
+ };
661
+ readonly title: {
662
+ readonly tr: "Onay bekleyen adım";
663
+ readonly en: "A step is waiting for approval";
664
+ };
665
+ readonly execution: {
666
+ readonly tr: "çalıştırma";
667
+ readonly en: "execution";
668
+ };
669
+ readonly pausedAt: {
670
+ readonly tr: "duraklatıldı";
671
+ readonly en: "paused";
672
+ };
673
+ readonly points: {
674
+ readonly tr: "Onay noktaları";
675
+ readonly en: "Approval points";
676
+ };
677
+ readonly point: {
678
+ readonly tr: "Nokta";
679
+ readonly en: "Point";
680
+ };
681
+ readonly output: {
682
+ readonly tr: "Ajanın önerisi";
683
+ readonly en: "What the agent proposes";
684
+ };
685
+ readonly queuePosition: {
686
+ readonly tr: "Sıra";
687
+ readonly en: "Queue position";
688
+ };
689
+ readonly submit: {
690
+ readonly tr: "Onayla ve devam et";
691
+ readonly en: "Approve and continue";
692
+ };
693
+ readonly submitting: {
694
+ readonly tr: "Gönderiliyor";
695
+ readonly en: "Submitting";
696
+ };
697
+ readonly refresh: {
698
+ readonly tr: "Yenile";
699
+ readonly en: "Refresh";
700
+ };
701
+ readonly required: {
702
+ readonly tr: "Bu alan zorunlu.";
703
+ readonly en: "This field is required.";
704
+ };
705
+ readonly notANumber: {
706
+ readonly tr: "Sayı girin.";
707
+ readonly en: "Enter a number.";
708
+ };
709
+ readonly notJson: {
710
+ readonly tr: "Geçerli JSON girin.";
711
+ readonly en: "Enter valid JSON.";
712
+ };
713
+ readonly notFound: {
714
+ readonly tr: "Bu onay bulunamadı; süresi dolmuş veya tamamlanmış olabilir.";
715
+ readonly en: "This approval could not be found; it may have expired or been completed.";
716
+ };
717
+ readonly loadError: {
718
+ readonly tr: "Onay yüklenemedi.";
719
+ readonly en: "The approval could not be loaded.";
720
+ };
721
+ readonly resumeError: {
722
+ readonly tr: "Devam ettirilemedi.";
723
+ readonly en: "The run could not be resumed.";
724
+ };
725
+ readonly resumedMessage: {
726
+ readonly tr: "Ajan kaldığı yerden devam ediyor.";
727
+ readonly en: "The agent is continuing from where it paused.";
728
+ };
729
+ readonly queuedMessage: {
730
+ readonly tr: "Onay sıraya alındı; önceki devam işlemleri bitince çalışacak.";
731
+ readonly en: "The approval is queued; it runs after the earlier resumes finish.";
732
+ };
733
+ readonly paused: {
734
+ readonly tr: "Onay bekliyor";
735
+ readonly en: "Awaiting approval";
736
+ };
737
+ readonly queued: {
738
+ readonly tr: "Sırada";
739
+ readonly en: "Queued";
740
+ };
741
+ readonly resuming: {
742
+ readonly tr: "Devam ediyor";
743
+ readonly en: "Resuming";
744
+ };
745
+ readonly resumed: {
746
+ readonly tr: "Devam etti";
747
+ readonly en: "Resumed";
748
+ };
749
+ readonly failed: {
750
+ readonly tr: "Başarısız";
751
+ readonly en: "Failed";
752
+ };
753
+ };
754
+ readonly common: {
755
+ readonly loading: {
756
+ readonly tr: "Yükleniyor";
757
+ readonly en: "Loading";
758
+ };
759
+ readonly retry: {
760
+ readonly tr: "Tekrar dene";
761
+ readonly en: "Retry";
762
+ };
763
+ readonly notActivated: {
764
+ readonly tr: "Aginies UI paketi etkinleştirilmedi.";
765
+ readonly en: "The Aginies UI package is not activated.";
766
+ };
767
+ };
768
+ };
769
+ type Section = keyof typeof STRINGS;
770
+ type Key<S extends Section> = keyof (typeof STRINGS)[S];
771
+ /** Returns a translator bound to a locale: `t('chat', 'send')`. */
772
+ declare function translator(locale: Locale): <S extends Section>(section: S, key: Key<S>) => string;
773
+ type Translator = ReturnType<typeof translator>;
774
+
775
+ /**
776
+ * Observability widgets. Data-driven: they render whatever the host passes, so they work
777
+ * with the platform's log and stats endpoints, a data warehouse or static numbers alike.
778
+ */
779
+ interface StatItem {
780
+ value: string;
781
+ label: string;
782
+ /** Small trend note, e.g. "+4.2% vs last week". */
783
+ delta?: string;
784
+ tone?: 'default' | 'ok' | 'warn' | 'bad';
785
+ }
786
+ declare function StatTiles({ items, className, ...props }: {
787
+ items: StatItem[];
788
+ } & HTMLAttributes<HTMLDivElement>): react.JSX.Element;
789
+ interface HeatmapRow {
790
+ label: string;
791
+ /** Success rates 0–1 per column (e.g. per day or per hour); null for no runs. */
792
+ values: Array<number | null>;
793
+ }
794
+ interface SuccessHeatmapProps extends HTMLAttributes<HTMLDivElement> {
795
+ rows: HeatmapRow[];
796
+ /** Column labels, same length as each row's values. */
797
+ columns?: string[];
798
+ /** Below `warn` a cell reads as warning, below `bad` as failure. Defaults 0.95 / 0.85. */
799
+ thresholds?: {
800
+ warn: number;
801
+ bad: number;
802
+ };
803
+ /** Formats the tooltip; default "97.2%". */
804
+ format?: (value: number) => string;
805
+ }
806
+ declare function SuccessHeatmap({ rows, columns, thresholds, format, className, ...props }: SuccessHeatmapProps): react.JSX.Element;
807
+ interface TimelineStep {
808
+ id: string;
809
+ name: string;
810
+ /** Step kind in the platform vocabulary; drives the glyph and colour. */
811
+ kind?: 'ingest' | 'plan' | 'retrieve' | 'reason' | 'tool' | 'verify' | 'approval' | 'write' | 'notify';
812
+ status: 'done' | 'running' | 'error' | 'waiting';
813
+ /** Offset from the run start in ms. */
814
+ startMs: number;
815
+ durationMs?: number;
816
+ tokens?: number;
817
+ costUsd?: number;
818
+ detail?: string;
819
+ }
820
+ interface RunTimelineProps extends HTMLAttributes<HTMLOListElement> {
821
+ steps: TimelineStep[];
822
+ /** Total run duration for the bar scale; defaults to the last step's end. */
823
+ totalMs?: number;
824
+ }
825
+ declare function RunTimeline({ steps, totalMs, className, ...props }: RunTimelineProps): react.JSX.Element;
826
+ interface CostBarItem {
827
+ label: string;
828
+ value: number;
829
+ /** Optional right-hand caption, e.g. "1,240 runs". */
830
+ note?: string;
831
+ }
832
+ interface CostBarsProps extends HTMLAttributes<HTMLDivElement> {
833
+ items: CostBarItem[];
834
+ /** Formats the value; default USD with two decimals. */
835
+ format?: (value: number) => string;
836
+ }
837
+ declare function CostBars({ items, format, className, ...props }: CostBarsProps): react.JSX.Element;
838
+
839
+ /**
840
+ * Creates the shared client and starts the activation handshake. Call it once, before
841
+ * rendering any widget; `AginiesProvider` picks the client up automatically.
842
+ */
843
+ declare function init(config: AginiesConfig): AginiesClient;
844
+ /** The client created by `init()`, if any. */
845
+ declare function getClient(): AginiesClient | null;
846
+ interface AginiesContextValue {
847
+ client: AginiesClient;
848
+ state: ActivationState;
849
+ locale: Locale;
850
+ t: Translator;
851
+ }
852
+ /**
853
+ * Whether the activation unlocks `module` (`chat`, `run`, `observability`, `approval`).
854
+ * A widget whose module is locked renders nothing and warns once.
855
+ */
856
+ declare function useModule(module: string): boolean;
857
+ interface AginiesProviderProps {
858
+ /** A client from `init()` or `new AginiesClient()`. Defaults to the one `init()` made. */
859
+ client?: AginiesClient;
860
+ /** Override the client's locale for this subtree. */
861
+ locale?: Locale;
862
+ /** Rendered while the activation handshake runs. Defaults to nothing. */
863
+ fallback?: ReactNode;
864
+ children: ReactNode;
865
+ }
866
+ /**
867
+ * Provides the activated client to every widget below it. Children render only once the
868
+ * activation succeeds; a rejected activation renders nothing and logs one warning, so a
869
+ * page with a wrong or missing token degrades to plain content.
870
+ */
871
+ declare function AginiesProvider({ client, locale, fallback, children, }: AginiesProviderProps): react.JSX.Element | null;
872
+ /** Access to the activated client, its configuration and the translator. */
873
+ declare function useAginies(): AginiesContextValue;
874
+
875
+ interface RunStep {
876
+ blockId: string;
877
+ name: string;
878
+ status: 'running' | 'done' | 'error';
879
+ durationMs?: number;
880
+ }
881
+ type RunStatus = 'idle' | 'running' | 'done' | 'error';
882
+ /**
883
+ * State for one deployed agent: run it with structured input, follow the streamed text
884
+ * and steps, read the final output. `AgentRunner` renders it; use the hook for a custom UI.
885
+ */
886
+ declare function useAgentRun(workflowId: string, apiKey: string): {
887
+ status: RunStatus;
888
+ text: string;
889
+ steps: RunStep[];
890
+ output: unknown;
891
+ error: string | null;
892
+ executionId: string | undefined;
893
+ run: (input: unknown) => Promise<void>;
894
+ cancel: () => void;
895
+ };
896
+ interface RunField {
897
+ name: string;
898
+ label: string;
899
+ type?: 'text' | 'textarea' | 'number' | 'select' | 'boolean';
900
+ required?: boolean;
901
+ placeholder?: string;
902
+ options?: Array<{
903
+ value: string;
904
+ label: string;
905
+ }>;
906
+ defaultValue?: string | number | boolean;
907
+ }
908
+ interface AgentRunnerProps {
909
+ /** Id of the deployed agent (workflow). */
910
+ workflowId: string;
911
+ /** An `execute`-scoped API key for this agent. Visible to the page; never a personal key. */
912
+ apiKey: string;
913
+ /** Form fields; their values become the agent's input object. Omit for a single text box. */
914
+ fields?: RunField[];
915
+ title?: string;
916
+ description?: string;
917
+ submitLabel?: string;
918
+ /** Called with the final output of a successful run. */
919
+ onResult?: (output: unknown) => void;
920
+ className?: string;
921
+ }
922
+ declare function AgentRunner({ workflowId, apiKey, fields, title, description, submitLabel, onResult, className, }: AgentRunnerProps): react.JSX.Element | null;
923
+
924
+ /**
925
+ * Runs a deployed agent through `POST /api/workflows/:id/execute` and normalises its
926
+ * server-sent events. The platform emits two shapes depending on the run mode — the
927
+ * executor's typed events (`stream:chunk`, `block:completed`, `execution:completed`, …)
928
+ * and the streaming-response shape shared with chat (`{ blockId, chunk }`, `{ event:
929
+ * 'final', data }`) — and both are folded into one small event vocabulary here.
930
+ */
931
+
932
+ type RunEvent = {
933
+ type: 'started';
934
+ executionId?: string;
935
+ } | {
936
+ type: 'chunk';
937
+ blockId?: string;
938
+ text: string;
939
+ } | {
940
+ type: 'step';
941
+ blockId: string;
942
+ name: string;
943
+ status: 'running' | 'done' | 'error';
944
+ durationMs?: number;
945
+ } | {
946
+ type: 'done';
947
+ output: unknown;
948
+ success: boolean;
949
+ } | {
950
+ type: 'error';
951
+ message: string;
952
+ };
953
+ interface RunOptions {
954
+ /** An `execute`-scoped API key. It is visible to the browser: scope it to this agent only. */
955
+ apiKey: string;
956
+ /** Free-form or structured input for the agent's start block. */
957
+ input?: unknown;
958
+ /** Outputs to stream, as `blockId_path` or `Block name.path`. */
959
+ selectedOutputs?: string[];
960
+ }
961
+ declare function runAgent(client: AginiesClient, workflowId: string, options: RunOptions, signal?: AbortSignal): AsyncGenerator<RunEvent>;
962
+ /** Decodes an execute SSE body into run events. Exported for tests. */
963
+ declare function parseRunSSE(stream: ReadableStream<Uint8Array>): AsyncGenerator<RunEvent>;
964
+
965
+ export { ATTACHMENT_LIMITS, type ActivationConfig, type ActivationSession, type ActivationState, AgentRunner, type AgentRunnerProps, AginiesClient, type AginiesConfig, AginiesError, AginiesProvider, type AginiesProviderProps, ApprovalPanel, type ApprovalPanelProps, type ApprovalStatus, Button, type ButtonProps, type ChatAttachment, type ChatAuthRequired, type ChatConfig, type ChatFilePayload, type ChatMessage, type ChatStreamEvent, ChatWidget, type ChatWidgetProps, Chip, type CodeRequestResult, type CostBarItem, CostBars, type CostBarsProps, Eyebrow, Field, type HeatmapRow, Input, type Locale, Markdown, Panel, type PauseContext, type PausePoint, type PausedExecution, type ResumeField, type ResumeOutcome, type ResumeQueueEntry, type ResumeStatus, type RunEvent, type RunField, type RunOptions, type RunStatus, type RunStep, RunTimeline, type RunTimelineProps, type SendMessageInput, Spinner, Stat, type StatItem, StatTiles, type StructuredItem, type StructuredResponse, StructuredUI, SuccessHeatmap, type SuccessHeatmapProps, Tag, Textarea, type TimelineStep, buildSubmission, cx, fieldsOf, formatFieldValue, getClient, getPauseContext, getPausedExecution, init, initialValues, listPausedExecutions, outputOf, parseFieldValue, parseRunSSE, parseSSE, parseStructured, resumeExecution, runAgent, translator, useAgentRun, useAginies, useApproval, useChat, useModule };