@fiodos/web-core 0.1.9 → 0.1.11

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 (37) hide show
  1. package/dist/cjs/api/backendClient.js +20 -0
  2. package/dist/cjs/config/types.d.ts +18 -0
  3. package/dist/cjs/config/types.js +6 -1
  4. package/dist/cjs/controller/AgentController.d.ts +84 -1
  5. package/dist/cjs/controller/AgentController.js +515 -75
  6. package/dist/cjs/index.d.ts +3 -3
  7. package/dist/cjs/index.js +2 -1
  8. package/dist/cjs/orb/mountOrb.d.ts +6 -0
  9. package/dist/cjs/orb/mountOrb.js +307 -53
  10. package/dist/cjs/orb/orbView.d.ts +2 -0
  11. package/dist/cjs/orb/publishedConfig.d.ts +18 -0
  12. package/dist/cjs/orb/publishedConfig.js +6 -0
  13. package/dist/cjs/speech/bubbleDictation.d.ts +11 -0
  14. package/dist/cjs/speech/bubbleDictation.js +88 -0
  15. package/dist/cjs/ui/messages.d.ts +15 -0
  16. package/dist/cjs/ui/messages.js +12 -0
  17. package/dist/cjs/version.d.ts +1 -1
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/esm/api/backendClient.js +20 -0
  20. package/dist/esm/config/types.d.ts +18 -0
  21. package/dist/esm/config/types.js +5 -0
  22. package/dist/esm/controller/AgentController.d.ts +84 -1
  23. package/dist/esm/controller/AgentController.js +517 -77
  24. package/dist/esm/index.d.ts +3 -3
  25. package/dist/esm/index.js +1 -1
  26. package/dist/esm/orb/mountOrb.d.ts +6 -0
  27. package/dist/esm/orb/mountOrb.js +308 -54
  28. package/dist/esm/orb/orbView.d.ts +2 -0
  29. package/dist/esm/orb/publishedConfig.d.ts +18 -0
  30. package/dist/esm/orb/publishedConfig.js +6 -0
  31. package/dist/esm/speech/bubbleDictation.d.ts +11 -0
  32. package/dist/esm/speech/bubbleDictation.js +84 -0
  33. package/dist/esm/ui/messages.d.ts +15 -0
  34. package/dist/esm/ui/messages.js +12 -0
  35. package/dist/esm/version.d.ts +1 -1
  36. package/dist/esm/version.js +1 -1
  37. package/package.json +1 -1
@@ -119,6 +119,21 @@ function createFiodosBackendClient(options) {
119
119
  if (request.sessionId?.trim()) {
120
120
  body.session_id = request.sessionId.trim();
121
121
  }
122
+ // Autonomous-chain continuation metadata (backward compatible: absent on a
123
+ // normal turn; an old backend simply ignores these fields).
124
+ if (request.isContinuation) {
125
+ body.is_continuation = true;
126
+ if (typeof request.chainStep === 'number')
127
+ body.chain_step = request.chainStep;
128
+ if (request.lastStep) {
129
+ body.last_step = {
130
+ type: request.lastStep.type,
131
+ intent: request.lastStep.intent,
132
+ ...(request.lastStep.label ? { label: request.lastStep.label } : {}),
133
+ success: request.lastStep.success,
134
+ };
135
+ }
136
+ }
122
137
  const res = await fetchWithTimeout(`${baseUrl}/assistant/chat`, { method: 'POST', headers: buildHeaders(), body: JSON.stringify(body) }, turnTimeoutMs, opts?.signal);
123
138
  if (!res.ok)
124
139
  throw await errorFromResponse(res);
@@ -129,11 +144,16 @@ function createFiodosBackendClient(options) {
129
144
  catch {
130
145
  throw new errors_1.AgentApiError('invalid_response');
131
146
  }
147
+ // Chain-continuation signal. Default to 'complete' so an old backend that
148
+ // never sends it keeps the one-action-per-turn behaviour (no chaining).
149
+ const rawStatus = typeof data.task_status === 'string' ? data.task_status : '';
150
+ const taskStatus = rawStatus === 'in_progress' || rawStatus === 'blocked' ? rawStatus : 'complete';
132
151
  return {
133
152
  reply: (data.reply ?? '').trim(),
134
153
  audioBase64: data.audio_base64 ?? null,
135
154
  action: (0, core_1.parseAgentAction)(data.action),
136
155
  wasTruncated: data.was_truncated === true,
156
+ taskStatus,
137
157
  };
138
158
  },
139
159
  async previewTts(voice, text) {
@@ -17,6 +17,22 @@ export interface AgentTimings {
17
17
  minTranscriptChars: number;
18
18
  }
19
19
  export declare const DEFAULT_AGENT_TIMINGS: AgentTimings;
20
+ /**
21
+ * Autonomous multi-step chaining. OFF by default: with `enabled: false` the orb
22
+ * behaves exactly as before (one action per turn). When ON, after a successful
23
+ * navigate/execute whose backend `task_status` is "in_progress", the orb takes
24
+ * the next step on its own — capped at `maxSteps` and guarded by no-progress
25
+ * detection and sensitive-confirmation pauses (which always require the human).
26
+ */
27
+ export interface AgentChaining {
28
+ /** Master switch. Default false (retrocompatible, one action per turn). */
29
+ enabled: boolean;
30
+ /** Hard cap on steps per user request (safety). Default 6. */
31
+ maxSteps: number;
32
+ /** Pause between chained steps so the user can see each screen (ms). */
33
+ dwellMs: number;
34
+ }
35
+ export declare const DEFAULT_AGENT_CHAINING: AgentChaining;
20
36
  export type TurnGateVerdict = {
21
37
  ok: true;
22
38
  } | {
@@ -59,5 +75,7 @@ export interface FiodosWebAgentConfig {
59
75
  ttsVoice?: string | (() => string | undefined);
60
76
  consentVersion?: number;
61
77
  timings?: Partial<AgentTimings>;
78
+ /** Autonomous multi-step chaining. OFF unless explicitly enabled. */
79
+ chaining?: Partial<AgentChaining>;
62
80
  }
63
81
  export type { WebUiMessages };
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_AGENT_TIMINGS = void 0;
3
+ exports.DEFAULT_AGENT_CHAINING = exports.DEFAULT_AGENT_TIMINGS = void 0;
4
4
  exports.DEFAULT_AGENT_TIMINGS = {
5
5
  thinkingWatchdogMs: 25000,
6
6
  maxListeningSeconds: 60,
7
7
  confirmationVoiceWindowMs: 8000,
8
8
  minTranscriptChars: 2,
9
9
  };
10
+ exports.DEFAULT_AGENT_CHAINING = {
11
+ enabled: false,
12
+ maxSteps: 6,
13
+ dwellMs: 450,
14
+ };
@@ -23,6 +23,19 @@ export interface AgentExchange {
23
23
  userText: string;
24
24
  replyText: string;
25
25
  }
26
+ /**
27
+ * REAL live activity for the chat panel — what the agent is actually doing
28
+ * right now, not a canned walk-through. Emitted at true lifecycle moments:
29
+ * request in flight ('thinking'), a navigate/execute action that really ran
30
+ * ('navigating'/'executing' with the manifest label), or a sensitive action
31
+ * waiting for the human ('waiting_confirmation'). Cleared when the final
32
+ * reply lands, so the panel narrative disappears exactly like before.
33
+ */
34
+ export interface AgentActivity {
35
+ kind: 'thinking' | 'navigating' | 'executing' | 'waiting_confirmation';
36
+ /** Manifest label (route/action) for navigating/executing steps. */
37
+ label?: string;
38
+ }
26
39
  /** The reactive snapshot every framework binding renders. */
27
40
  export interface AgentState {
28
41
  phase: AgentPhase;
@@ -33,6 +46,12 @@ export interface AgentState {
33
46
  isBusy: boolean;
34
47
  isListening: boolean;
35
48
  lastExchange: AgentExchange | null;
49
+ /** Paged window of recent user+reply pairs while session memory is active. */
50
+ recentExchanges: AgentExchange[];
51
+ /** Older messages exist beyond the mounted window (scroll up to load them). */
52
+ hasOlderExchanges: boolean;
53
+ /** An older page is being loaded (show the loading row at the top). */
54
+ loadingOlderExchanges: boolean;
36
55
  /** Confirmation question to show in the modal, or null. */
37
56
  confirmationMessage: string | null;
38
57
  /** Visible-only hint for strict actions (the exact phrase), or null. */
@@ -40,6 +59,10 @@ export interface AgentState {
40
59
  consentModalVisible: boolean;
41
60
  /** Mic denied/unusable: the orb should fall back to the keyboard channel. */
42
61
  voiceBlocked: boolean;
62
+ /** Current REAL agent activity for the panel's live row (null when idle). */
63
+ liveActivity: AgentActivity | null;
64
+ /** An autonomous chain is running steps (keeps the live row visible between turns). */
65
+ chainActive: boolean;
43
66
  }
44
67
  export declare class AgentController {
45
68
  readonly config: FiodosWebAgentConfig;
@@ -52,6 +75,7 @@ export declare class AgentController {
52
75
  private readonly consent;
53
76
  private readonly executor;
54
77
  private readonly timings;
78
+ private readonly chaining;
55
79
  private readonly ttsLocale;
56
80
  private readonly speech;
57
81
  private readonly notifyError;
@@ -77,10 +101,32 @@ export declare class AgentController {
77
101
  private speakTimer;
78
102
  private serverTtsUnavailable;
79
103
  private pendingConsentIntent;
104
+ /** Parked chain state (set when a chain pauses on a sensitive action). */
105
+ private chainState;
106
+ /** REAL live activity for the panel (replaces the old canned walk-through). */
107
+ private liveActivity;
108
+ private chainActive;
109
+ /** How many exchanges the bubble currently mounts (grows one page at a time). */
110
+ private bubbleWindowSize;
111
+ /** Idle retention from the dashboard (undefined = 30-minute default). */
112
+ private conversationOptions;
113
+ /** Raw dashboard retention (minutes; 0 = never; null = default). Persisted
114
+ * with the session so a restore applies the same expiry rule. */
115
+ private conversationRetentionMinutes;
116
+ /** Persistence scope: internal orbs keep their memory under a separate key
117
+ * so a public orb sharing the same appId can never read it. */
118
+ private conversationScope;
119
+ private loadingOlderExchanges;
120
+ private loadOlderTimer;
80
121
  private readonly listeners;
81
122
  private unsubscribeSpeech;
82
123
  constructor(config: FiodosWebAgentConfig);
124
+ private restorePersistedConversation;
125
+ private persistConversation;
83
126
  getState(): AgentState;
127
+ /** Update the REAL live activity and re-render (no-op when unchanged). */
128
+ private setActivity;
129
+ private setChainActive;
84
130
  /** Whether speech recognition can actually run (API present AND mic not denied). */
85
131
  get voiceAvailable(): boolean;
86
132
  /** Unlock audio playback inside a user gesture (orb tap) so the spoken reply
@@ -90,6 +136,22 @@ export declare class AgentController {
90
136
  /** Flag the mic as denied/unusable (called on a permission error or upfront
91
137
  * permission detection) so the orb routes taps to the keyboard instead. */
92
138
  markVoiceBlocked(blocked: boolean): void;
139
+ /**
140
+ * Page one more block of older session messages into the bubble (scroll-to-top).
141
+ * The mount is deferred behind a short loading state so old messages stream in
142
+ * on demand instead of all rendering at once (keeps the open bubble light).
143
+ */
144
+ loadOlderExchanges(): void;
145
+ /**
146
+ * Apply the dashboard's context-retention setting (minutes; 0 = never clear,
147
+ * null/undefined = the 30-minute default). Called when the published config
148
+ * arrives/refreshes, so the developer's choice is live without a reload.
149
+ * `expandedMemory` = INTERNAL orb profile: use the expanded conversation
150
+ * memory window (more literal turns + longer rolling summary per request).
151
+ */
152
+ setConversationRetention(minutes?: number | null, expandedMemory?: boolean): void;
153
+ /** Collapse the bubble history back to the initial page (bubble closed). */
154
+ resetBubbleWindow(): void;
93
155
  subscribe(listener: (state: AgentState) => void): () => void;
94
156
  private emit;
95
157
  setEnabled(value: boolean): void;
@@ -109,6 +171,22 @@ export declare class AgentController {
109
171
  confirmPendingAction(): Promise<void>;
110
172
  cancelPendingAction(): void;
111
173
  private handleConfirmationTranscript;
174
+ private routeLabel;
175
+ private actionLabel;
176
+ /**
177
+ * Resolve ONE backend turn into user-facing reply/audio: run its action (or
178
+ * stage its confirmation), emit telemetry, and report whether the autonomous
179
+ * chain may take another step. Shared by the first turn and every
180
+ * continuation so both follow the exact same security path — disabled
181
+ * capabilities, confidentiality and sensitive confirmations apply per step.
182
+ */
183
+ private applyOutcome;
184
+ /**
185
+ * The autonomous continuation loop. Extracted so confirmPendingAction can
186
+ * RESUME the SAME chain after a sensitive step is confirmed. Capped at
187
+ * maxSteps, with no-progress detection and sensitive-confirmation pauses.
188
+ */
189
+ private runChainLoop;
112
190
  private handleTranscript;
113
191
  private onTranscript;
114
192
  private onSpeechError;
@@ -119,7 +197,12 @@ export declare class AgentController {
119
197
  }): Promise<void>;
120
198
  acceptConsent(): Promise<void>;
121
199
  declineConsent(): void;
122
- cancelAll(): void;
200
+ /**
201
+ * Cancel everything in flight. If a first turn was still awaiting its reply,
202
+ * its message is removed from the panel and returned here so the UI can put
203
+ * it back into the input for editing; null otherwise.
204
+ */
205
+ cancelAll(): string | null;
123
206
  /** Best-effort backend warm-up (cold-start mitigation). */
124
207
  warmUp(): void;
125
208
  dispose(): void;