@pillar-ai/sdk 0.1.14 → 0.1.16

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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -12
  3. package/dist/actions/types.d.ts +30 -0
  4. package/dist/api/client.d.ts +63 -32
  5. package/dist/api/mcp-client.d.ts +46 -23
  6. package/dist/cli/sync.js +2 -0
  7. package/dist/components/Button/EdgeTrigger.d.ts +18 -0
  8. package/dist/components/Cards/ConfirmActionCard.d.ts +0 -4
  9. package/dist/components/Cards/index.d.ts +1 -1
  10. package/dist/components/DevTools/index.d.ts +1 -1
  11. package/dist/components/PagePilot/PagePilotBanner.d.ts +7 -0
  12. package/dist/components/PagePilot/PagePilotManager.d.ts +42 -0
  13. package/dist/components/PagePilot/index.d.ts +6 -0
  14. package/dist/components/PagePilot/styles.d.ts +6 -0
  15. package/dist/components/Panel/Header.d.ts +4 -5
  16. package/dist/components/Panel/Panel.d.ts +10 -4
  17. package/dist/components/Panel/PanelContent.d.ts +1 -2
  18. package/dist/components/Panel/TaskButton.d.ts +0 -4
  19. package/dist/components/Panel/UnifiedChatInput.d.ts +7 -3
  20. package/dist/components/Panel/WorkflowChecklist.d.ts +0 -1
  21. package/dist/components/Panel/index.d.ts +2 -3
  22. package/dist/components/Panel/styles.d.ts +2 -2
  23. package/dist/components/Progress/ProgressGroup.d.ts +20 -0
  24. package/dist/components/Progress/ProgressRow.d.ts +9 -5
  25. package/dist/components/Progress/ProgressStack.d.ts +14 -5
  26. package/dist/components/Progress/ReasoningDisclosure.d.ts +6 -10
  27. package/dist/components/Progress/index.d.ts +1 -1
  28. package/dist/components/TextSelection/index.d.ts +0 -1
  29. package/dist/components/index.d.ts +2 -1
  30. package/dist/core/Pillar.d.ts +27 -6
  31. package/dist/core/config.d.ts +15 -3
  32. package/dist/index.d.ts +2 -2
  33. package/dist/pillar.esm.js +1 -1
  34. package/dist/store/chat.d.ts +103 -16
  35. package/dist/store/index.d.ts +1 -0
  36. package/dist/store/pagePilot.d.ts +56 -0
  37. package/dist/store/panel.d.ts +9 -0
  38. package/dist/store/suggestions.d.ts +2 -2
  39. package/dist/styles/panel-styles.d.ts +6 -0
  40. package/dist/styles/theme.d.ts +13 -0
  41. package/dist/types/dom-scanner.d.ts +23 -0
  42. package/dist/utils/dom-scanner.d.ts +41 -2
  43. package/dist/utils/markdown-components.d.ts +0 -1
  44. package/dist/utils/preact-markdown.d.ts +0 -1
  45. package/package.json +10 -7
  46. package/src/actions/types.ts +33 -0
@@ -2,39 +2,86 @@
2
2
  * Chat Store
3
3
  * Signal-based state for chat messages and interaction
4
4
  */
5
- import type { ArticleSummary, ChatMessage } from '../api/client';
6
- import type { ChatImage } from '../api/mcp-client';
7
- import type { TaskButtonData } from '../components/Panel/TaskButton';
8
- import type { UserContextItem } from '../types/user-context';
9
- export type { ChatImage } from '../api/mcp-client';
5
+ import type { ArticleSummary, ChatMessage, ConversationSummary, HistoryMessage, DisplayStep } from "../api/client";
6
+ import type { ChatImage } from "../api/mcp-client";
7
+ import type { TaskButtonData } from "../components/Panel/TaskButton";
8
+ import type { UserContextItem } from "../types/user-context";
9
+ export type { ChatImage } from "../api/mcp-client";
10
10
  export interface ActionStatus {
11
- status: 'pending' | 'success' | 'failed';
11
+ status: "pending" | "success" | "failed";
12
12
  completedAt?: number;
13
13
  errorMessage?: string;
14
14
  }
15
+ /**
16
+ * A segment in an assistant message's timeline.
17
+ * Segments maintain chronological order so text and tool blocks interleave correctly.
18
+ *
19
+ * - "text": Model-generated content tokens (narration or final response)
20
+ * - "progress": A group of progress events (thinking, search, tool calls)
21
+ */
22
+ export type MessageSegment = {
23
+ type: "text";
24
+ content: string;
25
+ } | {
26
+ type: "progress";
27
+ events: ProgressEvent[];
28
+ };
15
29
  export interface StoredChatMessage extends ChatMessage {
16
30
  id?: string;
17
- feedback?: 'up' | 'down' | null;
31
+ feedback?: "up" | "down" | null;
18
32
  actions?: TaskButtonData[];
19
33
  sources?: ArticleSummary[];
20
34
  actionStatus?: Record<string, ActionStatus>;
21
35
  userContext?: UserContextItem[];
22
36
  images?: ChatImage[];
23
37
  progressEvents?: ProgressEvent[];
38
+ segments?: MessageSegment[];
24
39
  }
25
40
  export declare const messages: import("@preact/signals-core").Signal<StoredChatMessage[]>;
26
41
  export declare const conversationId: import("@preact/signals-core").Signal<string | null>;
27
42
  export declare const registeredActions: import("@preact/signals-core").Signal<Record<string, unknown>[]>;
28
43
  export declare const historyInvalidationCounter: import("@preact/signals-core").Signal<number>;
44
+ export declare const optimisticConversations: import("@preact/signals-core").Signal<ConversationSummary[]>;
45
+ /**
46
+ * Read the persisted conversation ID from localStorage (e.g. for restore on refresh).
47
+ */
48
+ export declare function getStoredConversationId(): string | null;
29
49
  export declare const isLoading: import("@preact/signals-core").Signal<boolean>;
50
+ export declare const activeRequestId: import("@preact/signals-core").Signal<number | null>;
51
+ export declare const setActiveRequestId: (id: number | null) => void;
52
+ export declare const isLoadingHistory: import("@preact/signals-core").Signal<boolean>;
30
53
  export interface InterruptedSession {
31
54
  conversationId: string;
32
55
  userMessage: string;
33
56
  partialResponse: string;
34
- summary: string;
57
+ displayTrace: DisplayStep[];
35
58
  elapsedMs: number;
36
59
  }
37
60
  export declare const interruptedSession: import("@preact/signals-core").Signal<InterruptedSession | null>;
61
+ export interface TokenUsageState {
62
+ /** Input tokens for the latest iteration */
63
+ promptTokens: number;
64
+ /** Output tokens for the latest iteration */
65
+ completionTokens: number;
66
+ /** Cumulative prompt tokens across all iterations */
67
+ totalPromptTokens: number;
68
+ /** Cumulative completion tokens across all iterations */
69
+ totalCompletionTokens: number;
70
+ /** Current total tokens in context */
71
+ totalUsed: number;
72
+ /** Maximum context window for the model */
73
+ contextWindow: number;
74
+ /** Current context occupancy percentage (0-100) */
75
+ occupancyPct: number;
76
+ /** Name of the model in use */
77
+ modelName: string;
78
+ /** Current iteration number (0-indexed) */
79
+ iteration: number;
80
+ }
81
+ /** Current token usage for the active streaming response */
82
+ export declare const tokenUsage: import("@preact/signals-core").Signal<TokenUsageState | null>;
83
+ export declare const updateTokenUsage: (usage: TokenUsageState) => void;
84
+ export declare const clearTokenUsage: () => void;
38
85
  export interface ProgressStatus {
39
86
  kind: string | null;
40
87
  message?: string;
@@ -59,7 +106,7 @@ export interface ProgressEvent {
59
106
  kind: string;
60
107
  id?: string;
61
108
  label?: string;
62
- status?: 'active' | 'done' | 'error';
109
+ status?: "active" | "done" | "error";
63
110
  text?: string;
64
111
  children?: ProgressChild[];
65
112
  metadata?: Record<string, unknown>;
@@ -85,6 +132,12 @@ export declare const progressEvents: import("@preact/signals-core").Signal<Progr
85
132
  * This prevents multiple rows from appearing for the same event.
86
133
  */
87
134
  export declare const addProgressEventToLastMessage: (event: ProgressEvent) => void;
135
+ /**
136
+ * Append a content token to the last assistant message's segments array.
137
+ * Creates a new text segment or appends to an existing one, while also
138
+ * updating `content` for backward compat (history persistence, feedback, etc.).
139
+ */
140
+ export declare const appendTokenToSegments: (token: string) => void;
88
141
  export declare const isExpanded: import("@preact/signals-core").Signal<boolean>;
89
142
  /**
90
143
  * @deprecated Sources are now stored per-message on `StoredChatMessage.sources`. Will be removed in v2.0.
@@ -104,7 +157,8 @@ export declare const submitPendingTrigger: import("@preact/signals-core").Signal
104
157
  export declare const focusInputTrigger: import("@preact/signals-core").Signal<number>;
105
158
  export declare const userContext: import("@preact/signals-core").Signal<UserContextItem[]>;
106
159
  export declare const pendingUserContext: import("@preact/signals-core").Signal<UserContextItem[]>;
107
- export type ImageUploadStatus = 'uploading' | 'ready' | 'error';
160
+ export declare const pendingImagesForNavigation: import("@preact/signals-core").Signal<ChatImage[]>;
161
+ export type ImageUploadStatus = "uploading" | "ready" | "error";
108
162
  export interface PendingImage {
109
163
  id: string;
110
164
  file: File;
@@ -112,12 +166,13 @@ export interface PendingImage {
112
166
  status: ImageUploadStatus;
113
167
  url?: string;
114
168
  error?: string;
169
+ path?: string;
115
170
  }
116
171
  export declare const pendingImages: import("@preact/signals-core").Signal<PendingImage[]>;
117
172
  export declare const isUploadingImages: import("@preact/signals-core").ReadonlySignal<boolean>;
118
173
  export declare const getReadyImages: () => ChatImage[];
119
174
  export declare const addPendingImage: (image: PendingImage) => void;
120
- export declare const updateImageStatus: (id: string, status: ImageUploadStatus, url?: string, error?: string) => void;
175
+ export declare const updateImageStatus: (id: string, status: ImageUploadStatus, url?: string, error?: string, path?: string) => void;
121
176
  export declare const removePendingImage: (id: string) => void;
122
177
  export declare const clearPendingImages: () => void;
123
178
  export declare const hasMessages: import("@preact/signals-core").ReadonlySignal<boolean>;
@@ -154,10 +209,24 @@ export declare const clearActions: () => void;
154
209
  export declare const setLoading: (loading: boolean) => void;
155
210
  export declare const setProgressStatus: (status: ProgressStatus) => void;
156
211
  export declare const clearProgressStatus: () => void;
212
+ /**
213
+ * Mark all active progress events on the last assistant message as "done".
214
+ * Called when the user cancels/stops streaming so thinking timers stop.
215
+ */
216
+ export declare const finalizeActiveProgressEvents: () => void;
157
217
  export declare const addProgressEvent: (event: ProgressEvent) => void;
158
218
  export declare const clearProgressEvents: () => void;
159
219
  export declare const setInterruptedSession: (session: InterruptedSession | null) => void;
160
220
  export declare const clearInterruptedSession: () => void;
221
+ /**
222
+ * Remove the last assistant message if it has no content AND no progress events.
223
+ * Used after Stop / AbortError to clean up the empty placeholder
224
+ * that was added before streaming started.
225
+ *
226
+ * If the model was thinking (progress events exist), the message is kept
227
+ * so the user can still see the thinking text that was streamed.
228
+ */
229
+ export declare const removeLastEmptyAssistantMessage: () => void;
161
230
  export declare const expandChat: () => void;
162
231
  export declare const collapseChat: () => void;
163
232
  export declare const setPrefillText: (text: string) => void;
@@ -171,13 +240,31 @@ export declare const removeUserContext: (id: string) => void;
171
240
  export declare const clearUserContext: () => void;
172
241
  export declare const setPendingUserContext: (items: UserContextItem[]) => void;
173
242
  export declare const clearPendingUserContext: () => void;
243
+ export declare const setPendingImagesForNavigation: (images: ChatImage[]) => void;
244
+ export declare const clearPendingImagesForNavigation: () => void;
174
245
  export declare const resetChat: () => void;
246
+ /**
247
+ * Start loading a conversation from history.
248
+ * Shows loading state immediately for better UX.
249
+ */
250
+ export declare const startLoadingHistory: () => void;
175
251
  /**
176
252
  * Load a conversation from history.
177
253
  * Populates the chat with messages from a previous conversation.
178
254
  */
179
- export declare const loadConversation: (id: string, historyMessages: Array<{
180
- role: "user" | "assistant";
181
- content: string;
182
- id?: string;
183
- }>) => void;
255
+ export declare const loadConversation: (id: string, historyMessages: HistoryMessage[]) => void;
256
+ /**
257
+ * Stop loading history (on error or cancellation).
258
+ */
259
+ export declare const stopLoadingHistory: () => void;
260
+ /**
261
+ * Optimistically add a new conversation to the history list.
262
+ * The conversation appears immediately in the dropdown without
263
+ * waiting for the server to confirm via listConversations.
264
+ */
265
+ export declare const addOptimisticConversation: (id: string, title: string) => void;
266
+ /**
267
+ * Select and load a conversation by ID (fetch from API, navigate to chat, load messages).
268
+ * Use from history dropdown or anywhere else in the SDK that needs to open a past conversation.
269
+ */
270
+ export declare const selectConversationById: (conversationId: string) => Promise<void>;
@@ -8,3 +8,4 @@ export * as chatStore from './chat';
8
8
  export * as contextStore from './context';
9
9
  export * as workflowStore from './workflow';
10
10
  export * as suggestionsStore from './suggestions';
11
+ export * as pagePilotStore from './pagePilot';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Page Pilot Store
3
+ * Signal-based state for tracking when the AI agent is piloting the page
4
+ * (executing interact_with_page actions like click, type, select, etc.)
5
+ */
6
+ /** Current piloting operation type */
7
+ export type PilotOperation = 'click' | 'type' | 'select' | 'focus' | 'toggle' | null;
8
+ /** Whether page interaction is currently in progress */
9
+ export declare const isPiloting: import("@preact/signals-core").Signal<boolean>;
10
+ /** Current operation type being performed */
11
+ export declare const pilotOperation: import("@preact/signals-core").Signal<PilotOperation>;
12
+ /** Flag to indicate cancellation was requested */
13
+ export declare const isCancelled: import("@preact/signals-core").Signal<boolean>;
14
+ /** Tool call ID of the current action (for sending cancellation result) */
15
+ export declare const currentToolCallId: import("@preact/signals-core").Signal<string | null>;
16
+ /**
17
+ * Start piloting mode - called when an interact_with_page action begins
18
+ */
19
+ export declare function startPiloting(operation: PilotOperation, toolCallId?: string): void;
20
+ /**
21
+ * Stop piloting mode - called when an interact_with_page action completes
22
+ */
23
+ export declare function stopPiloting(): void;
24
+ /**
25
+ * Cancel the current piloting action - called when user clicks Stop
26
+ */
27
+ export declare function cancelPiloting(): void;
28
+ /**
29
+ * Reset cancellation flag after it's been handled
30
+ */
31
+ export declare function resetCancellation(): void;
32
+ /**
33
+ * Check if cancellation was requested
34
+ */
35
+ export declare function wasCancelled(): boolean;
36
+ /** Whether a destructive action is awaiting user confirmation */
37
+ export declare const needsConfirmation: import("@preact/signals-core").Signal<boolean>;
38
+ /** Human-readable description of the action pending confirmation */
39
+ export declare const confirmationLabel: import("@preact/signals-core").Signal<string | null>;
40
+ /** Resolver function for the confirmation promise */
41
+ export declare const confirmationResolver: import("@preact/signals-core").Signal<((confirmed: boolean) => void) | null>;
42
+ /**
43
+ * Request user confirmation for a destructive action.
44
+ * Shows a confirmation UI and returns a Promise that resolves when the user responds.
45
+ *
46
+ * @param label - Description of the action (e.g., 'Agent wants to click "Delete Account"')
47
+ * @returns Promise<boolean> - true if user confirmed, false if denied
48
+ */
49
+ export declare function requestConfirmation(label: string): Promise<boolean>;
50
+ /**
51
+ * Resolve the pending confirmation request.
52
+ * Called by the UI when the user clicks Allow or Deny.
53
+ *
54
+ * @param confirmed - Whether the user confirmed the action
55
+ */
56
+ export declare function resolveConfirmation(confirmed: boolean): void;
@@ -3,6 +3,15 @@
3
3
  * Signal-based state for panel open/close and configuration
4
4
  */
5
5
  import type { PanelPosition, PanelMode } from '../core/config';
6
+ /**
7
+ * Load panel width from localStorage.
8
+ * Returns null if not set or on error.
9
+ */
10
+ export declare function loadPanelWidth(): number | null;
11
+ /**
12
+ * Save panel width to localStorage.
13
+ */
14
+ export declare function savePanelWidth(w: number): void;
6
15
  export declare const isOpen: import("@preact/signals-core").Signal<boolean>;
7
16
  export declare const activeTab: import("@preact/signals-core").Signal<string>;
8
17
  export declare const position: import("@preact/signals-core").Signal<PanelPosition>;
@@ -2,12 +2,12 @@
2
2
  * Suggestions Store
3
3
  * Signal-based state for page-aware suggested questions
4
4
  *
5
- * The backend generates a pool of 15-20 diverse suggestions.
5
+ * The backend generates a small set of suggested questions.
6
6
  * This store sorts them client-side based on page relevance
7
7
  * for instant page-aware suggestions without additional LLM calls.
8
8
  */
9
9
  import type { SuggestedQuestion } from '../api/client';
10
- /** Base suggestion pool from backend (15-20 suggestions) */
10
+ /** Base suggestion pool from backend */
11
11
  export declare const suggestionPool: import("@preact/signals-core").Signal<SuggestedQuestion[]>;
12
12
  /** Currently displayed suggestions (sorted by page relevance) */
13
13
  export declare const suggestions: import("@preact/signals-core").Signal<SuggestedQuestion[]>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Panel Styles Aggregator
3
+ * Imports all CSS files that are injected into the Panel (Shadow DOM or head)
4
+ * and exports them as a single concatenated string.
5
+ */
6
+ export declare const ALL_PANEL_STYLES: string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Theme CSS Generation
3
+ * Runtime functions for generating CSS variable overrides from theme config.
4
+ */
5
+ import type { ResolvedThemeConfig, ThemeColors } from "../core/config";
6
+ /**
7
+ * Generate CSS variable overrides from theme colors
8
+ */
9
+ export declare function generateThemeVariables(colors: ThemeColors, prefix?: string): string;
10
+ /**
11
+ * Generate custom theme CSS from config
12
+ */
13
+ export declare function generateThemeCSS(theme: ResolvedThemeConfig): string;
@@ -20,6 +20,10 @@ export interface ScanOptions {
20
20
  minTextLength?: number;
21
21
  /** Maximum text length before truncation (default: 500) */
22
22
  maxTextLength?: number;
23
+ /** Maximum total output length in characters (default: 50000) */
24
+ maxTotalLength?: number;
25
+ /** Maximum label length for interactable elements (default: 100) */
26
+ maxLabelLength?: number;
23
27
  /** Include element positions/coordinates (default: false) */
24
28
  includePositions?: boolean;
25
29
  }
@@ -38,6 +42,25 @@ export interface CompactScanResult {
38
42
  /** Title of the page */
39
43
  title: string;
40
44
  }
45
+ /** Result of a delta scan showing only changes since the last scan */
46
+ export interface DeltaScanResult {
47
+ /** Formatted delta string for LLM context, or null if no changes */
48
+ content: string | null;
49
+ /** Ref IDs of elements no longer on the page */
50
+ removedRefs: string[];
51
+ /** Number of new interactable elements found */
52
+ newInteractableCount: number;
53
+ /** Total interactable elements currently on the page */
54
+ totalInteractableCount: number;
55
+ /** Whether any changes were detected */
56
+ hasChanges: boolean;
57
+ /** Timestamp when scan was performed */
58
+ timestamp: number;
59
+ /** URL of the page that was scanned */
60
+ url: string;
61
+ /** Title of the page */
62
+ title: string;
63
+ }
41
64
  /** HTML tags that are inherently interactable */
42
65
  export declare const INTERACTABLE_TAGS: Set<string>;
43
66
  /** ARIA roles that indicate interactability */
@@ -2,12 +2,28 @@
2
2
  * DOM Scanner Utilities
3
3
  * Scans the DOM and outputs compact text representation for LLM context
4
4
  */
5
- import { type CompactScanResult, type InteractionType, type ScanOptions } from "../types/dom-scanner";
5
+ import { type CompactScanResult, type DeltaScanResult, type InteractionType, type ScanOptions } from "../types/dom-scanner";
6
6
  /**
7
7
  * Clear all pillar refs from the DOM.
8
- * Called before scanning to remove stale refs.
8
+ * Called before full scans to remove stale refs and reset counter.
9
9
  */
10
10
  export declare function clearPillarRefs(): void;
11
+ /**
12
+ * Check if an element or any of its ancestors is marked for redaction.
13
+ * Elements with `data-pillar-redact` or password inputs are redacted.
14
+ * Their text content is replaced with [REDACTED] in scan output.
15
+ */
16
+ export declare function isRedacted(el: Element): boolean;
17
+ /**
18
+ * Check if an element represents a destructive action.
19
+ * Used to gate interactions behind user confirmation.
20
+ *
21
+ * Returns true if:
22
+ * - The element has `data-pillar-destructive` attribute (explicit opt-in)
23
+ * - The element's label or text content contains destructive keywords
24
+ * - The element is a reset/submit button on a form with "delete" in its action URL
25
+ */
26
+ export declare function isDestructiveElement(el: Element): boolean;
11
27
  /**
12
28
  * Check if an element is interactable
13
29
  */
@@ -16,12 +32,22 @@ export declare function isInteractable(el: Element): boolean;
16
32
  * Determine the interaction type for an element
17
33
  */
18
34
  export declare function getInteractionType(el: Element): InteractionType;
35
+ /**
36
+ * Validate that a ref string matches the expected pillar ref format.
37
+ * Prevents CSS selector injection from malformed/malicious ref values.
38
+ *
39
+ * @param ref - Ref string to validate
40
+ * @returns true if the ref matches the expected format
41
+ */
42
+ export declare function isValidPillarRef(ref: string): boolean;
19
43
  /**
20
44
  * Build full selector from short ref ID.
21
45
  * Converts "pr-abc" to '[data-pillar-ref="pr-abc"]'
46
+ * Throws if the ref format is invalid to prevent CSS selector injection.
22
47
  *
23
48
  * @param shortRef - Short ref ID (e.g., "pr-abc")
24
49
  * @returns Full CSS selector for querySelector
50
+ * @throws Error if the ref format is invalid
25
51
  */
26
52
  export declare function buildSelectorFromRef(shortRef: string): string;
27
53
  /**
@@ -42,3 +68,16 @@ export declare function buildSelectorFromRef(shortRef: string): string;
42
68
  * ```
43
69
  */
44
70
  export declare function scanPageDirect(options?: ScanOptions): CompactScanResult;
71
+ /**
72
+ * Delta DOM scanner that only returns changes since the last scan.
73
+ * Reuses existing refs on elements, assigns new refs only to new elements.
74
+ * Compares output lines against the previous scan to find new content.
75
+ *
76
+ * Must be called after an initial `scanPageDirect()` which establishes
77
+ * the baseline. If called without a prior scan, behaves like a full scan
78
+ * but without the header/footer framing.
79
+ *
80
+ * @param options - Scan options
81
+ * @returns Delta scan result with only new lines and removed ref IDs
82
+ */
83
+ export declare function scanPageDelta(options?: ScanOptions): DeltaScanResult;
@@ -50,4 +50,3 @@ export interface ProgressIndicatorProps {
50
50
  isActive?: boolean;
51
51
  }
52
52
  export declare function ProgressIndicator({ message, isActive, }: ProgressIndicatorProps): VNode;
53
- export declare const MARKDOWN_COMPONENT_STYLES = "\n/* Collapsible Section */\n._pillar-collapsible {\n margin: 2px 0;\n}\n\n._pillar-collapsible-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n color: var(--pillar-text-secondary, #6b7280);\n font-family: inherit;\n width: 100%;\n text-align: left;\n transition: background-color 0.15s ease;\n}\n\n._pillar-collapsible-header:hover {\n background: var(--pillar-bg-hover, rgba(0, 0, 0, 0.05));\n}\n\n._pillar-collapsible-icon {\n font-size: 10px;\n color: var(--pillar-text-muted, #9ca3af);\n}\n\n._pillar-collapsible-title {\n flex: 1;\n}\n\n._pillar-collapsible-content-wrapper {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows 0.2s ease;\n}\n\n._pillar-collapsible-content-wrapper--expanded {\n grid-template-rows: 1fr;\n}\n\n._pillar-collapsible-content {\n overflow: hidden;\n padding-left: 18px;\n font-size: 13px;\n color: var(--pillar-text-secondary, #6b7280);\n line-height: 1.4;\n}\n\n._pillar-collapsible-content-wrapper--expanded ._pillar-collapsible-content {\n padding-top: 2px;\n padding-bottom: 4px;\n}\n\n/* Source List */\n._pillar-source-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin: 4px 0;\n}\n\n._pillar-source-item {\n display: block;\n padding: 4px 8px;\n font-size: 12px;\n color: var(--pillar-primary, #2563eb);\n text-decoration: none;\n border-radius: 4px;\n transition: background-color 0.15s ease;\n}\n\n._pillar-source-item:hover {\n background: var(--pillar-bg-hover, rgba(0, 0, 0, 0.05));\n text-decoration: underline;\n}\n\n/* Task List */\n._pillar-task-list {\n list-style: none;\n padding: 0;\n margin: 8px 0;\n}\n\n._pillar-task-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n font-size: 13px;\n}\n\n._pillar-task-item--completed ._pillar-task-text {\n text-decoration: line-through;\n color: var(--pillar-text-placeholder, #9ca3af);\n}\n\n._pillar-task-checkbox {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n/* Code Block */\n._pillar-code-block {\n margin: 8px 0;\n border-radius: 8px;\n overflow: hidden;\n background: var(--pillar-bg-code, #1e1e1e);\n}\n\n._pillar-code-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n background: var(--pillar-bg-code-header, #2d2d2d);\n border-bottom: 1px solid var(--pillar-border-code, #404040);\n}\n\n._pillar-code-language {\n font-size: 11px;\n font-weight: 500;\n color: var(--pillar-text-code-header, #a0a0a0);\n text-transform: uppercase;\n}\n\n._pillar-code-copy {\n padding: 4px 8px;\n font-size: 11px;\n font-family: inherit;\n background: transparent;\n border: 1px solid var(--pillar-border-code, #404040);\n border-radius: 4px;\n color: var(--pillar-text-code-header, #a0a0a0);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n._pillar-code-copy:hover {\n background: var(--pillar-bg-code-hover, #404040);\n color: #fff;\n}\n\n._pillar-code-pre {\n margin: 0;\n padding: 12px;\n overflow-x: auto;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;\n font-size: 13px;\n line-height: 1.5;\n}\n\n._pillar-code-content {\n color: var(--pillar-text-code, #e0e0e0);\n}\n\n/* Action Buttons */\n._pillar-action-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n margin: 8px 0;\n}\n\n._pillar-action-button {\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n background: var(--pillar-primary, #2563eb);\n color: #fff;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n._pillar-action-button:hover {\n background: var(--pillar-primary-hover, #1d4ed8);\n}\n\n/* Progress Indicator */\n._pillar-progress-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n font-size: 13px;\n color: var(--pillar-text-secondary, #6b7280);\n}\n\n._pillar-progress-indicator--active ._pillar-loading-spinner {\n display: inline-block;\n}\n\n/* Streaming Thinking Content */\n._pillar-progress-row--streaming {\n margin: 2px 0;\n}\n\n._pillar-thinking-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 0;\n font-size: 13px;\n font-weight: 500;\n color: var(--pillar-text-secondary, #6b7280);\n}\n\n._pillar-thinking-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n\n._pillar-spinner {\n width: 12px;\n height: 12px;\n border: 2px solid var(--pillar-border, #e5e7eb);\n border-top-color: var(--pillar-primary, #2563eb);\n border-radius: 50%;\n animation: pillar-spin 0.8s linear infinite;\n}\n\n@keyframes pillar-spin {\n to { transform: rotate(360deg); }\n}\n\n._pillar-thinking-label {\n flex: 1;\n}\n\n._pillar-thinking-content {\n padding: 6px 10px;\n font-size: 13px;\n line-height: 1.4;\n color: var(--pillar-text-secondary, #6b7280);\n background: var(--pillar-bg-tertiary, #f9fafb);\n border-radius: 4px;\n margin-top: 2px;\n max-height: 150px;\n overflow-y: auto;\n}\n";
@@ -14,4 +14,3 @@ export interface PreactMarkdownProps {
14
14
  * Supports custom component markers in code blocks and HTML-like syntax.
15
15
  */
16
16
  export declare function PreactMarkdown({ content, class: className }: PreactMarkdownProps): VNode;
17
- export declare const PREACT_MARKDOWN_STYLES = "\n/* Base markdown container */\n._pillar-markdown {\n font-size: 14px;\n line-height: 1.6;\n color: var(--pillar-text, #1a1a1a);\n}\n\n/* Headings */\n._pillar-md-heading {\n margin: 16px 0 8px 0;\n font-weight: 600;\n line-height: 1.3;\n}\n\n._pillar-md-h1 { font-size: 1.5em; }\n._pillar-md-h2 { font-size: 1.3em; }\n._pillar-md-h3 { font-size: 1.15em; }\n._pillar-md-h4 { font-size: 1em; }\n._pillar-md-h5 { font-size: 0.95em; }\n._pillar-md-h6 { font-size: 0.9em; }\n\n/* Paragraphs */\n._pillar-md-paragraph {\n margin: 8px 0;\n}\n\n/* Links */\n._pillar-md-link {\n color: var(--pillar-primary, #2563eb);\n text-decoration: none;\n}\n\n._pillar-md-link:hover {\n text-decoration: underline;\n}\n\n/* Inline code */\n._pillar-md-code-inline {\n padding: 2px 6px;\n font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;\n font-size: 0.9em;\n background: var(--pillar-bg-code-inline, #f3f4f6);\n border-radius: 4px;\n}\n\n/* Lists */\n._pillar-md-list {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n._pillar-md-list-item {\n margin: 4px 0;\n}\n\n/* Task list items */\n._pillar-md-task-item {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n list-style: none;\n margin-left: -24px;\n}\n\n._pillar-md-task-checkbox {\n margin-top: 4px;\n}\n\n._pillar-md-task-text--checked {\n text-decoration: line-through;\n color: var(--pillar-text-placeholder, #9ca3af);\n}\n\n/* Blockquote */\n._pillar-md-blockquote {\n margin: 8px 0;\n padding: 8px 16px;\n border-left: 3px solid var(--pillar-border, #e5e7eb);\n color: var(--pillar-text-muted, #6b7280);\n background: var(--pillar-bg-secondary, #f9fafb);\n}\n\n/* Horizontal rule */\n._pillar-md-hr {\n margin: 16px 0;\n border: none;\n border-top: 1px solid var(--pillar-border, #e5e7eb);\n}\n\n/* Tables */\n._pillar-md-table-wrapper {\n overflow-x: auto;\n margin: 8px 0;\n}\n\n._pillar-md-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n._pillar-md-th,\n._pillar-md-td {\n padding: 8px 12px;\n border: 1px solid var(--pillar-border, #e5e7eb);\n text-align: left;\n}\n\n._pillar-md-th {\n background: var(--pillar-bg-secondary, #f9fafb);\n font-weight: 600;\n}\n\n/* Images */\n._pillar-md-image {\n max-width: 100%;\n height: auto;\n border-radius: 8px;\n margin: 8px 0;\n}\n";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pillar-ai/sdk",
3
- "version": "0.1.14",
4
- "description": "Pillar Embedded Help SDK - Add contextual help and AI chat to your application",
3
+ "version": "0.1.16",
4
+ "description": "Product copilot SDK for SaaS and web apps AI assistant that executes tasks, not just answers questions",
5
5
  "type": "module",
6
6
  "main": "./dist/pillar.esm.js",
7
7
  "module": "./dist/pillar.esm.js",
@@ -32,12 +32,15 @@
32
32
  "prepublishOnly": "npm run build"
33
33
  },
34
34
  "keywords": [
35
- "help",
36
- "documentation",
37
- "support",
38
- "chat",
35
+ "copilot",
36
+ "assistant",
39
37
  "ai",
40
- "embedded"
38
+ "sdk",
39
+ "saas",
40
+ "embedded",
41
+ "agent",
42
+ "support",
43
+ "chat"
41
44
  ],
42
45
  "author": "Pillar Team",
43
46
  "license": "MIT",
@@ -182,6 +182,19 @@ export interface ActionDefinition<TData = Record<string, unknown>> {
182
182
  */
183
183
  returns?: boolean;
184
184
 
185
+ /**
186
+ * Concrete examples of valid parameter objects for the AI to reference.
187
+ *
188
+ * Each example should have a `description` explaining the scenario
189
+ * and a `parameters` object matching the `dataSchema`.
190
+ * Useful for complex schemas where the AI benefits from seeing
191
+ * what a correct call looks like.
192
+ */
193
+ parameterExamples?: Array<{
194
+ description: string;
195
+ parameters: Record<string, unknown>;
196
+ }>;
197
+
185
198
  /**
186
199
  * Handler function executed when the action is triggered.
187
200
  *
@@ -216,6 +229,10 @@ export interface ActionManifestEntry {
216
229
  data_schema?: ActionDataSchema;
217
230
  default_data?: Record<string, unknown>;
218
231
  required_context?: Record<string, unknown>;
232
+ parameter_examples?: Array<{
233
+ description: string;
234
+ parameters: Record<string, unknown>;
235
+ }>;
219
236
  }
220
237
 
221
238
  /**
@@ -248,6 +265,12 @@ export interface ActionManifest {
248
265
  * Action definitions (without handlers).
249
266
  */
250
267
  actions: ActionManifestEntry[];
268
+
269
+ /**
270
+ * Custom agent guidance synced alongside actions.
271
+ * Injected into the AI agent's prompt as product_guidance.
272
+ */
273
+ agentGuidance?: string;
251
274
  }
252
275
 
253
276
  /**
@@ -314,6 +337,16 @@ export interface SyncActionDefinition<TData = Record<string, unknown>> {
314
337
  * If true, the handler's return value is sent back to the agent.
315
338
  */
316
339
  returns?: boolean;
340
+
341
+ /**
342
+ * Concrete examples of valid parameter objects for the AI to reference.
343
+ * Each example should have a `description` and a `parameters` object
344
+ * matching the `dataSchema`.
345
+ */
346
+ parameterExamples?: Array<{
347
+ description: string;
348
+ parameters: Record<string, unknown>;
349
+ }>;
317
350
  }
318
351
 
319
352
  /**