@useago/sdk 0.4.4 → 0.4.6

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/widget.d.cts CHANGED
@@ -516,11 +516,14 @@ export declare interface CreateFormCollectorOptions<V = Record<string, unknown>>
516
516
  declare type DynamicContextProvider = () => ContextEntry | null | undefined;
517
517
 
518
518
  /**
519
- * JSON-schema shape of a form's fields — identical to a client function's
520
- * `parameters`, so one schema feeds the store, the update function, and the
521
- * dynamic context with no second type.
519
+ * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
520
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
522
521
  */
523
- declare type FormCollectorSchema = ClientFunctionSchema["parameters"];
522
+ declare interface FormCollectorSchema {
523
+ type: "object";
524
+ properties: Record<string, FormFieldSchema>;
525
+ required?: string[];
526
+ }
524
527
 
525
528
  declare interface FormField {
526
529
  type: "string" | "number" | "boolean" | "array";
@@ -530,6 +533,43 @@ declare interface FormField {
530
533
  default?: unknown;
531
534
  }
532
535
 
536
+ /**
537
+ * A field's conditional-requiredness rule. The field becomes required exactly
538
+ * when the controlling `property` matches `value` against the answers collected
539
+ * so far:
540
+ * - a single `value`, no `op` — equality (compared as strings);
541
+ * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
542
+ * - an array `value`, no `op` — "one of": matches when the property equals any
543
+ * listed value.
544
+ *
545
+ * SDK-only — it is stripped from the schema before it reaches the LLM tool
546
+ */
547
+ declare interface FormFieldCondition {
548
+ /** The controlling field whose value the rule tests. */
549
+ property: string;
550
+ /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
551
+ op?: ">=" | "<=" | ">" | "<";
552
+ /**
553
+ * The value(s) to test the controlling field against. A single value is an
554
+ * equality (or, with `op`, a numeric comparison); an array is an "is one of"
555
+ * membership test, e.g. `value: ["1", "2", "3"]`.
556
+ */
557
+ value: string | number | Array<string | number>;
558
+ }
559
+
560
+ /** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
561
+ declare interface FormFieldSchema {
562
+ type: string;
563
+ description?: string;
564
+ enum?: string[];
565
+ default?: unknown;
566
+ /**
567
+ * Makes the field required only while this condition holds. Drives the dynamic
568
+ * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
569
+ */
570
+ requiredWhen?: FormFieldCondition;
571
+ }
572
+
533
573
  /**
534
574
  * Form schema for tool calls requiring user input
535
575
  */
@@ -546,8 +586,9 @@ declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCEL
546
586
  * Vue, or Angular required. Mirrors the React `<ChatWidget>`: it streams replies,
547
587
  * renders clickable suggested replies, and installs conversational form collectors.
548
588
  *
549
- * Message content is rendered as plain text (no markdown) to stay dependency-free;
550
- * use the React `<Message>` component if you need GitHub-flavored markdown.
589
+ * Message content is rendered as GitHub-flavored markdown by a tiny built-in
590
+ * parser (no dependencies); all message text is HTML-escaped first (see
591
+ * {@link renderMarkdown}).
551
592
  *
552
593
  * ```ts
553
594
  * import { mountChatWidget } from "@useago/sdk/widget";
@@ -638,6 +679,34 @@ export declare interface MountChatWidgetOptions {
638
679
  }) => void;
639
680
  }
640
681
 
682
+ /**
683
+ * Tiny, dependency-free markdown → DOM renderer for the vanilla chat widget.
684
+ *
685
+ * The React widget renders GitHub-flavored markdown via `react-markdown` +
686
+ * `remark-gfm`; bundling those into the framework-agnostic widget would defeat
687
+ * its "no dependencies" promise, so this is a hand-rolled subset that mirrors
688
+ * the visible styling of `react/components/Markdown.tsx`.
689
+ *
690
+ * Supported: paragraphs (single newline → `<br>`), ATX headings, **bold**,
691
+ * *italic*, ~~strikethrough~~, `inline code`, fenced code blocks, links,
692
+ * images, ordered/unordered (and nested) lists, blockquotes, horizontal rules,
693
+ * and GFM tables.
694
+ *
695
+ * ## Security
696
+ *
697
+ * The widget is embedded into third-party pages, so the agent's message content
698
+ * is untrusted. Every span of message text is HTML-escaped before it reaches the
699
+ * DOM; only a fixed set of safe tags is ever emitted, and `href`/`src` URLs are
700
+ * scheme-validated (see {@link safeUrl}) so `javascript:`/`data:` payloads can't
701
+ * slip through. Callers should append the returned fragment — never feed raw
702
+ * message content to `innerHTML` directly.
703
+ */
704
+ /**
705
+ * Parse a markdown string into a {@link DocumentFragment} of safely-built block
706
+ * elements. Append it to the message bubble; do not stringify it back to HTML.
707
+ */
708
+ export declare function renderMarkdown(source: string): DocumentFragment;
709
+
641
710
  /**
642
711
  * Options for sending a message
643
712
  */
package/dist/widget.d.ts CHANGED
@@ -516,11 +516,14 @@ export declare interface CreateFormCollectorOptions<V = Record<string, unknown>>
516
516
  declare type DynamicContextProvider = () => ContextEntry | null | undefined;
517
517
 
518
518
  /**
519
- * JSON-schema shape of a form's fields — identical to a client function's
520
- * `parameters`, so one schema feeds the store, the update function, and the
521
- * dynamic context with no second type.
519
+ * Shape of a form's fields. Mirrors a client function's `parameters` (so the same
520
+ * object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
522
521
  */
523
- declare type FormCollectorSchema = ClientFunctionSchema["parameters"];
522
+ declare interface FormCollectorSchema {
523
+ type: "object";
524
+ properties: Record<string, FormFieldSchema>;
525
+ required?: string[];
526
+ }
524
527
 
525
528
  declare interface FormField {
526
529
  type: "string" | "number" | "boolean" | "array";
@@ -530,6 +533,43 @@ declare interface FormField {
530
533
  default?: unknown;
531
534
  }
532
535
 
536
+ /**
537
+ * A field's conditional-requiredness rule. The field becomes required exactly
538
+ * when the controlling `property` matches `value` against the answers collected
539
+ * so far:
540
+ * - a single `value`, no `op` — equality (compared as strings);
541
+ * - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
542
+ * - an array `value`, no `op` — "one of": matches when the property equals any
543
+ * listed value.
544
+ *
545
+ * SDK-only — it is stripped from the schema before it reaches the LLM tool
546
+ */
547
+ declare interface FormFieldCondition {
548
+ /** The controlling field whose value the rule tests. */
549
+ property: string;
550
+ /** Comparison operator; omitted means equality. Ignored when `value` is an array. */
551
+ op?: ">=" | "<=" | ">" | "<";
552
+ /**
553
+ * The value(s) to test the controlling field against. A single value is an
554
+ * equality (or, with `op`, a numeric comparison); an array is an "is one of"
555
+ * membership test, e.g. `value: ["1", "2", "3"]`.
556
+ */
557
+ value: string | number | Array<string | number>;
558
+ }
559
+
560
+ /** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
561
+ declare interface FormFieldSchema {
562
+ type: string;
563
+ description?: string;
564
+ enum?: string[];
565
+ default?: unknown;
566
+ /**
567
+ * Makes the field required only while this condition holds. Drives the dynamic
568
+ * `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
569
+ */
570
+ requiredWhen?: FormFieldCondition;
571
+ }
572
+
533
573
  /**
534
574
  * Form schema for tool calls requiring user input
535
575
  */
@@ -546,8 +586,9 @@ declare type MessageStatus = "IN_PROGRESS" | "DONE" | "ERROR" | "TODO" | "CANCEL
546
586
  * Vue, or Angular required. Mirrors the React `<ChatWidget>`: it streams replies,
547
587
  * renders clickable suggested replies, and installs conversational form collectors.
548
588
  *
549
- * Message content is rendered as plain text (no markdown) to stay dependency-free;
550
- * use the React `<Message>` component if you need GitHub-flavored markdown.
589
+ * Message content is rendered as GitHub-flavored markdown by a tiny built-in
590
+ * parser (no dependencies); all message text is HTML-escaped first (see
591
+ * {@link renderMarkdown}).
551
592
  *
552
593
  * ```ts
553
594
  * import { mountChatWidget } from "@useago/sdk/widget";
@@ -638,6 +679,34 @@ export declare interface MountChatWidgetOptions {
638
679
  }) => void;
639
680
  }
640
681
 
682
+ /**
683
+ * Tiny, dependency-free markdown → DOM renderer for the vanilla chat widget.
684
+ *
685
+ * The React widget renders GitHub-flavored markdown via `react-markdown` +
686
+ * `remark-gfm`; bundling those into the framework-agnostic widget would defeat
687
+ * its "no dependencies" promise, so this is a hand-rolled subset that mirrors
688
+ * the visible styling of `react/components/Markdown.tsx`.
689
+ *
690
+ * Supported: paragraphs (single newline → `<br>`), ATX headings, **bold**,
691
+ * *italic*, ~~strikethrough~~, `inline code`, fenced code blocks, links,
692
+ * images, ordered/unordered (and nested) lists, blockquotes, horizontal rules,
693
+ * and GFM tables.
694
+ *
695
+ * ## Security
696
+ *
697
+ * The widget is embedded into third-party pages, so the agent's message content
698
+ * is untrusted. Every span of message text is HTML-escaped before it reaches the
699
+ * DOM; only a fixed set of safe tags is ever emitted, and `href`/`src` URLs are
700
+ * scheme-validated (see {@link safeUrl}) so `javascript:`/`data:` payloads can't
701
+ * slip through. Callers should append the returned fragment — never feed raw
702
+ * message content to `innerHTML` directly.
703
+ */
704
+ /**
705
+ * Parse a markdown string into a {@link DocumentFragment} of safely-built block
706
+ * elements. Append it to the message bubble; do not stringify it back to HTML.
707
+ */
708
+ export declare function renderMarkdown(source: string): DocumentFragment;
709
+
641
710
  /**
642
711
  * Options for sending a message
643
712
  */