@genesislcap/foundation-ai 14.407.0-workspaces.4 → 14.408.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.
Files changed (128) hide show
  1. package/dist/dts/ai-provider.d.ts +18 -2
  2. package/dist/dts/ai-provider.d.ts.map +1 -1
  3. package/dist/dts/index.d.ts +5 -1
  4. package/dist/dts/index.d.ts.map +1 -1
  5. package/dist/dts/interactions/criteria-interpretation.d.ts +11 -0
  6. package/dist/dts/interactions/criteria-interpretation.d.ts.map +1 -1
  7. package/dist/dts/providers/gemini-provider.d.ts +25 -0
  8. package/dist/dts/providers/gemini-provider.d.ts.map +1 -0
  9. package/dist/dts/transports/gemini-transport.d.ts +66 -0
  10. package/dist/dts/transports/gemini-transport.d.ts.map +1 -0
  11. package/dist/dts/types/chat-transport.types.d.ts +16 -0
  12. package/dist/dts/types/chat-transport.types.d.ts.map +1 -0
  13. package/dist/dts/types/chat.types.d.ts +157 -0
  14. package/dist/dts/types/chat.types.d.ts.map +1 -0
  15. package/dist/dts/types/config.types.d.ts +16 -2
  16. package/dist/dts/types/config.types.d.ts.map +1 -1
  17. package/dist/dts/types/criteria-types.d.ts +10 -0
  18. package/dist/dts/types/criteria-types.d.ts.map +1 -1
  19. package/dist/dts/types/index.d.ts +2 -0
  20. package/dist/dts/types/index.d.ts.map +1 -1
  21. package/dist/dts/utils/speech-to-text.d.ts +11 -0
  22. package/dist/dts/utils/speech-to-text.d.ts.map +1 -1
  23. package/dist/esm/ai-provider.js +18 -0
  24. package/dist/esm/index.js +2 -0
  25. package/dist/esm/providers/gemini-provider.js +59 -0
  26. package/dist/esm/transports/gemini-transport.js +249 -0
  27. package/dist/esm/types/chat-transport.types.js +1 -0
  28. package/dist/esm/types/chat.types.js +1 -0
  29. package/dist/esm/types/index.js +2 -0
  30. package/dist/esm/utils/speech-to-text.js +11 -0
  31. package/dist/foundation-ai.api.json +2937 -240
  32. package/dist/foundation-ai.d.ts +357 -4
  33. package/docs/api/foundation-ai.aiconfig.md +2 -2
  34. package/docs/api/foundation-ai.aiprovider.chat.md +85 -0
  35. package/docs/api/foundation-ai.aiprovider.md +22 -0
  36. package/docs/api/foundation-ai.aiprovider.streamchat.md +85 -0
  37. package/docs/api/foundation-ai.aiprovidertype.md +1 -1
  38. package/docs/api/foundation-ai.chatanimationsconfig.enabled.md +16 -0
  39. package/docs/api/foundation-ai.chatanimationsconfig.md +80 -0
  40. package/docs/api/foundation-ai.chatanimationsconfig.userconfigurable.md +16 -0
  41. package/docs/api/foundation-ai.chatattachment.content.md +14 -0
  42. package/docs/api/foundation-ai.chatattachment.md +99 -0
  43. package/docs/api/foundation-ai.chatattachment.mimetype.md +14 -0
  44. package/docs/api/foundation-ai.chatattachment.name.md +14 -0
  45. package/docs/api/foundation-ai.chatconfig.acceptedfiles.md +16 -0
  46. package/docs/api/foundation-ai.chatconfig.allowdebugdownload.md +16 -0
  47. package/docs/api/foundation-ai.chatconfig.animations.md +16 -0
  48. package/docs/api/foundation-ai.chatconfig.loadingdelay.md +16 -0
  49. package/docs/api/foundation-ai.chatconfig.maxtooliterations.md +16 -0
  50. package/docs/api/foundation-ai.chatconfig.md +177 -0
  51. package/docs/api/foundation-ai.chatconfig.showthinkingsteps.md +16 -0
  52. package/docs/api/foundation-ai.chatconfig.showtoolcalls.md +16 -0
  53. package/docs/api/foundation-ai.chatinteraction.componentname.md +14 -0
  54. package/docs/api/foundation-ai.chatinteraction.data.md +14 -0
  55. package/docs/api/foundation-ai.chatinteraction.interactionid.md +14 -0
  56. package/docs/api/foundation-ai.chatinteraction.md +118 -0
  57. package/docs/api/foundation-ai.chatinteraction.resolved.md +16 -0
  58. package/docs/api/foundation-ai.chatmessage.attachments.md +14 -0
  59. package/docs/api/foundation-ai.chatmessage.content.md +14 -0
  60. package/docs/api/foundation-ai.chatmessage.interaction.md +14 -0
  61. package/docs/api/foundation-ai.chatmessage.md +175 -0
  62. package/docs/api/foundation-ai.chatmessage.role.md +14 -0
  63. package/docs/api/foundation-ai.chatmessage.thinking.md +14 -0
  64. package/docs/api/foundation-ai.chatmessage.toolcalls.md +14 -0
  65. package/docs/api/foundation-ai.chatmessage.toolresult.md +14 -0
  66. package/docs/api/foundation-ai.chatrequestoptions.attachments.md +14 -0
  67. package/docs/api/foundation-ai.chatrequestoptions.md +118 -0
  68. package/docs/api/foundation-ai.chatrequestoptions.signal.md +14 -0
  69. package/docs/api/foundation-ai.chatrequestoptions.systemprompt.md +14 -0
  70. package/docs/api/foundation-ai.chatrequestoptions.tools.md +14 -0
  71. package/docs/api/foundation-ai.chatrole.md +16 -0
  72. package/docs/api/foundation-ai.chatstreamchunk.delta.md +14 -0
  73. package/docs/api/foundation-ai.chatstreamchunk.done.md +14 -0
  74. package/docs/api/foundation-ai.chatstreamchunk.md +99 -0
  75. package/docs/api/foundation-ai.chatstreamchunk.toolcalls.md +14 -0
  76. package/docs/api/foundation-ai.chattoolcall.args.md +14 -0
  77. package/docs/api/foundation-ai.chattoolcall.id.md +14 -0
  78. package/docs/api/foundation-ai.chattoolcall.md +99 -0
  79. package/docs/api/foundation-ai.chattoolcall.name.md +14 -0
  80. package/docs/api/foundation-ai.chattooldefinition.description.md +14 -0
  81. package/docs/api/foundation-ai.chattooldefinition.md +99 -0
  82. package/docs/api/foundation-ai.chattooldefinition.name.md +14 -0
  83. package/docs/api/foundation-ai.chattooldefinition.parameters.md +14 -0
  84. package/docs/api/foundation-ai.chattoolhandlers.md +18 -0
  85. package/docs/api/foundation-ai.chattoolresult.content.md +14 -0
  86. package/docs/api/foundation-ai.chattoolresult.md +80 -0
  87. package/docs/api/foundation-ai.chattoolresult.toolcallid.md +14 -0
  88. package/docs/api/foundation-ai.chattransport.md +58 -0
  89. package/docs/api/foundation-ai.chattransport.sendchatmessage.md +83 -0
  90. package/docs/api/foundation-ai.chattransport.streamchatmessage.md +83 -0
  91. package/docs/api/foundation-ai.criteriagroupresult.clauses.md +3 -0
  92. package/docs/api/foundation-ai.criteriagroupresult.logic.md +3 -0
  93. package/docs/api/foundation-ai.criteriagroupresult.md +10 -1
  94. package/docs/api/foundation-ai.criteriagroupresult.negated.md +3 -0
  95. package/docs/api/foundation-ai.criteriainterpretationresult.groups.md +3 -0
  96. package/docs/api/foundation-ai.criteriainterpretationresult.md +7 -0
  97. package/docs/api/foundation-ai.criteriainterpretcontext.fields.md +3 -0
  98. package/docs/api/foundation-ai.criteriainterpretcontext.md +6 -1
  99. package/docs/api/foundation-ai.fieldlike.md +5 -0
  100. package/docs/api/foundation-ai.geminiaiconfig.apikey.md +14 -0
  101. package/docs/api/foundation-ai.geminiaiconfig.md +123 -0
  102. package/docs/api/foundation-ai.geminiaiconfig.model.md +14 -0
  103. package/docs/api/foundation-ai.geminiaiconfig.providertype.md +14 -0
  104. package/docs/api/foundation-ai.geminiaiconfig.serverendpoint.md +14 -0
  105. package/docs/api/foundation-ai.geminiprovider._constructor_.md +65 -0
  106. package/docs/api/foundation-ai.geminiprovider.chat.md +83 -0
  107. package/docs/api/foundation-ai.geminiprovider.getstatus.md +18 -0
  108. package/docs/api/foundation-ai.geminiprovider.interpretcriteria.md +67 -0
  109. package/docs/api/foundation-ai.geminiprovider.md +128 -0
  110. package/docs/api/foundation-ai.geminiprovider.streamchat.md +83 -0
  111. package/docs/api/foundation-ai.geminitransport._constructor_.md +53 -0
  112. package/docs/api/foundation-ai.geminitransport.getconfig.md +21 -0
  113. package/docs/api/foundation-ai.geminitransport.md +116 -0
  114. package/docs/api/foundation-ai.geminitransport.sendchatmessage.md +83 -0
  115. package/docs/api/foundation-ai.geminitransport.sendstructuredprompt.md +53 -0
  116. package/docs/api/foundation-ai.interactionresult.md +20 -0
  117. package/docs/api/foundation-ai.isspeechrecognitionavailable.md +1 -1
  118. package/docs/api/foundation-ai.malformedfunctioncallerror._constructor_.md +53 -0
  119. package/docs/api/foundation-ai.malformedfunctioncallerror.finishmessage.md +14 -0
  120. package/docs/api/foundation-ai.malformedfunctioncallerror.md +98 -0
  121. package/docs/api/foundation-ai.md +230 -1
  122. package/docs/api/foundation-ai.resolveaiconfigoptions.md +9 -4
  123. package/docs/api/foundation-ai.resolveaiconfigoptions.model.md +3 -0
  124. package/docs/api/foundation-ai.resolveaiconfigoptions.preferchrome.md +3 -0
  125. package/docs/api/foundation-ai.resolveaiconfigoptions.provider.md +5 -2
  126. package/docs/api/foundation-ai.startspeechrecognition.md +5 -0
  127. package/docs/api-report.md.api.md +192 -11
  128. package/package.json +11 -11
@@ -0,0 +1,249 @@
1
+ import { __awaiter } from "tslib";
2
+ const GEMINI_DIRECT_URL = (model) => `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
3
+ const DEFAULT_MODEL = 'gemini-2.0-flash';
4
+ const DEFAULT_TIMEOUT = 180000; // 3 minutes
5
+ /**
6
+ * Thrown when Gemini returns a `MALFORMED_FUNCTION_CALL` finish reason,
7
+ * typically because the model tried to batch multiple tool calls using
8
+ * Python-style syntax instead of the proper API format.
9
+ *
10
+ * @beta
11
+ */
12
+ export class MalformedFunctionCallError extends Error {
13
+ constructor(finishMessage) {
14
+ super('Gemini returned MALFORMED_FUNCTION_CALL');
15
+ this.finishMessage = finishMessage;
16
+ this.name = 'MalformedFunctionCallError';
17
+ }
18
+ }
19
+ /**
20
+ * Transport for Gemini. Calls the Gemini REST API directly when `apiKey` is
21
+ * provided, otherwise falls back to a server-proxy endpoint (if `serverEndpoint`
22
+ * is configured).
23
+ *
24
+ * Implements `AITransport` (structured prompt) and `ChatTransport` (multi-turn chat).
25
+ *
26
+ * @beta
27
+ */
28
+ export class GeminiTransport {
29
+ constructor(config = {}) {
30
+ var _a, _b;
31
+ this.model = (_a = config.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL;
32
+ this.timeout = (_b = config.timeout) !== null && _b !== void 0 ? _b : DEFAULT_TIMEOUT;
33
+ this.apiKey = config.apiKey;
34
+ this.serverEndpoint = config.serverEndpoint;
35
+ }
36
+ getConfig() {
37
+ return { provider: 'gemini', model: this.model };
38
+ }
39
+ // ── AITransport (structured prompt) ────────────────────────────────────
40
+ sendStructuredPrompt(options) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ var _a;
43
+ const { systemPrompt, userPrompt, responseSchema } = options;
44
+ const contents = [];
45
+ if (systemPrompt) {
46
+ contents.push({ role: 'user', parts: [{ text: systemPrompt }] });
47
+ contents.push({ role: 'model', parts: [{ text: 'Understood.' }] });
48
+ }
49
+ contents.push({ role: 'user', parts: [{ text: userPrompt }] });
50
+ const response = yield this.post({ model: this.model, contents, responseSchema });
51
+ return (_a = response === null || response === void 0 ? void 0 : response.content) !== null && _a !== void 0 ? _a : '';
52
+ });
53
+ }
54
+ // ── ChatTransport (multi-turn chat) ────────────────────────────────────
55
+ sendChatMessage(history, userMessage, options) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ var _a;
58
+ const contents = this.toGeminiContents(history, userMessage, options === null || options === void 0 ? void 0 : options.attachments);
59
+ const tools = ((_a = options === null || options === void 0 ? void 0 : options.tools) === null || _a === void 0 ? void 0 : _a.length)
60
+ ? [
61
+ {
62
+ functionDeclarations: options.tools.map((t) => ({
63
+ name: t.name,
64
+ description: t.description,
65
+ parameters: t.parameters,
66
+ })),
67
+ },
68
+ ]
69
+ : undefined;
70
+ const systemInstruction = (options === null || options === void 0 ? void 0 : options.systemPrompt)
71
+ ? { role: 'system', parts: [{ text: options.systemPrompt }] }
72
+ : undefined;
73
+ const response = yield this.post({ model: this.model, contents, tools, systemInstruction }, options === null || options === void 0 ? void 0 : options.signal);
74
+ return this.fromGeminiResponse(response);
75
+ });
76
+ }
77
+ logTokenUsage(promptTokens, candidateTokens) {
78
+ const promptCost = (promptTokens / GeminiTransport.TOKENS_PER_MILLION) * GeminiTransport.PROMPT_COST_PER_MILLION;
79
+ const candidateCost = (candidateTokens / GeminiTransport.TOKENS_PER_MILLION) *
80
+ GeminiTransport.CANDIDATE_COST_PER_MILLION;
81
+ const totalCost = promptCost + candidateCost;
82
+ console.log('--- Gemini Token Usage ---');
83
+ console.log(`Prompt Tokens: ${promptTokens} ($${promptCost.toFixed(GeminiTransport.COST_DECIMAL_PLACES)})`);
84
+ console.log(`Candidate Tokens: ${candidateTokens} ($${candidateCost.toFixed(GeminiTransport.COST_DECIMAL_PLACES)})`);
85
+ console.log(`Total Cost: $${totalCost.toFixed(GeminiTransport.COST_DECIMAL_PLACES)}`);
86
+ console.log('--------------------------');
87
+ }
88
+ toGeminiContents(history, userMessage, attachments) {
89
+ var _a, _b;
90
+ const contents = [];
91
+ for (const msg of history) {
92
+ if (msg.role === 'system' || msg.thinking)
93
+ continue;
94
+ const role = msg.role === 'user' ? 'user' : 'model';
95
+ if (msg.toolResult) {
96
+ contents.push({
97
+ role: 'user',
98
+ parts: [
99
+ {
100
+ functionResponse: {
101
+ name: msg.toolResult.toolCallId,
102
+ response: { content: msg.toolResult.content },
103
+ },
104
+ },
105
+ ],
106
+ });
107
+ }
108
+ else if ((_a = msg.toolCalls) === null || _a === void 0 ? void 0 : _a.length) {
109
+ contents.push({
110
+ role: 'model',
111
+ parts: msg.toolCalls.map((tc) => ({
112
+ functionCall: { name: tc.name, args: tc.args },
113
+ })),
114
+ });
115
+ }
116
+ else if (role === 'user' && ((_b = msg.attachments) === null || _b === void 0 ? void 0 : _b.length)) {
117
+ const msgAttachmentParts = msg.attachments.map((att) => ({
118
+ text: `[File: ${att.name}]\n${att.content}`,
119
+ }));
120
+ contents.push({ role: 'user', parts: [{ text: msg.content }, ...msgAttachmentParts] });
121
+ }
122
+ else {
123
+ contents.push({ role, parts: [{ text: msg.content }] });
124
+ }
125
+ }
126
+ const attachmentParts = (attachments !== null && attachments !== void 0 ? attachments : []).map((att) => ({
127
+ text: `[File: ${att.name}]\n${att.content}`,
128
+ }));
129
+ if (userMessage || attachmentParts.length) {
130
+ contents.push({ role: 'user', parts: [{ text: userMessage }, ...attachmentParts] });
131
+ }
132
+ return contents;
133
+ }
134
+ fromGeminiResponse(response) {
135
+ var _a, _b, _c, _d, _e;
136
+ if (response.usageMetadata) {
137
+ const usage = response.usageMetadata;
138
+ this.logTokenUsage((_a = usage.promptTokenCount) !== null && _a !== void 0 ? _a : 0, (_b = usage.candidatesTokenCount) !== null && _b !== void 0 ? _b : 0);
139
+ }
140
+ const candidates = response === null || response === void 0 ? void 0 : response.candidates;
141
+ const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];
142
+ if ((firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.finishReason) === 'MALFORMED_FUNCTION_CALL') {
143
+ throw new MalformedFunctionCallError(firstCandidate.finishMessage);
144
+ }
145
+ const parts = (_d = (_c = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _c === void 0 ? void 0 : _c.parts) !== null && _d !== void 0 ? _d : [];
146
+ const toolCalls = [];
147
+ const thoughtParts = [];
148
+ const textParts = [];
149
+ for (const part of parts) {
150
+ if (part.functionCall) {
151
+ toolCalls.push({
152
+ id: part.functionCall.name,
153
+ name: part.functionCall.name,
154
+ args: (_e = part.functionCall.args) !== null && _e !== void 0 ? _e : {},
155
+ });
156
+ }
157
+ else if (part.thought && part.text) {
158
+ thoughtParts.push(part.text);
159
+ }
160
+ else if (part.text) {
161
+ textParts.push(part.text);
162
+ }
163
+ }
164
+ // For tool-call responses, surface thought parts as `content` so the UI can
165
+ // render them as a collapsible thinking block. Fall back to text narration
166
+ // (textParts) for models that don't emit native thought parts (e.g. gemini-2.0-flash)
167
+ // but do narrate alongside tool calls when prompted to do so.
168
+ // For final answers, surface only the response text.
169
+ return toolCalls.length > 0
170
+ ? { role: 'assistant', content: thoughtParts.join('') || textParts.join(''), toolCalls }
171
+ : { role: 'assistant', content: textParts.join('') };
172
+ }
173
+ buildEndpoint(body) {
174
+ if (this.apiKey) {
175
+ return {
176
+ url: `${GEMINI_DIRECT_URL(this.model)}?key=${this.apiKey}`,
177
+ payload: this.toDirectPayload(body),
178
+ credentials: 'omit',
179
+ };
180
+ }
181
+ if (this.serverEndpoint) {
182
+ return {
183
+ url: this.serverEndpoint,
184
+ payload: body,
185
+ credentials: 'include',
186
+ };
187
+ }
188
+ throw new Error('GeminiTransport: no API key or server endpoint configured. ' +
189
+ 'Set GEMINI_API_KEY in your .env or pass apiKey/serverEndpoint in GeminiAIConfig.');
190
+ }
191
+ post(body, signal) {
192
+ return __awaiter(this, void 0, void 0, function* () {
193
+ const { url, payload, credentials } = this.buildEndpoint(body);
194
+ // Sequential retries are intentional — each attempt depends on the previous response.
195
+ /* eslint-disable no-await-in-loop */
196
+ for (let attempt = 0; attempt <= GeminiTransport.MAX_RETRIES; attempt += 1) {
197
+ const controller = new AbortController();
198
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
199
+ let response;
200
+ try {
201
+ response = yield fetch(url, {
202
+ method: 'POST',
203
+ headers: { 'Content-Type': 'application/json' },
204
+ body: JSON.stringify(payload),
205
+ signal: signal !== null && signal !== void 0 ? signal : controller.signal,
206
+ credentials,
207
+ });
208
+ }
209
+ catch (e) {
210
+ clearTimeout(timeoutId);
211
+ throw e;
212
+ }
213
+ clearTimeout(timeoutId);
214
+ if (response.status === GeminiTransport.RATE_LIMIT_STATUS &&
215
+ attempt < GeminiTransport.MAX_RETRIES) {
216
+ // Exponential backoff: 1s, 2s, 4s, 8s, 16s
217
+ yield new Promise((resolve) => {
218
+ setTimeout(resolve, GeminiTransport.BACKOFF_BASE_MS * (1 << attempt));
219
+ });
220
+ continue;
221
+ }
222
+ if (!response.ok) {
223
+ const err = yield response.text();
224
+ throw new Error(`Gemini request error ${response.status}: ${err}`);
225
+ }
226
+ return (yield response.json());
227
+ }
228
+ /* eslint-enable no-await-in-loop */
229
+ throw new Error('Gemini request failed: max retries exceeded');
230
+ });
231
+ }
232
+ toDirectPayload(body) {
233
+ const payload = Object.assign({}, body);
234
+ delete payload.model;
235
+ if (payload.responseSchema) {
236
+ payload.generationConfig = Object.assign(Object.assign({}, payload.generationConfig), { responseMimeType: 'application/json', responseSchema: payload.responseSchema });
237
+ delete payload.responseSchema;
238
+ }
239
+ return payload;
240
+ }
241
+ }
242
+ // ── Private helpers ────────────────────────────────────────────────────
243
+ GeminiTransport.TOKENS_PER_MILLION = 1000000;
244
+ GeminiTransport.PROMPT_COST_PER_MILLION = 0.1;
245
+ GeminiTransport.CANDIDATE_COST_PER_MILLION = 0.4;
246
+ GeminiTransport.COST_DECIMAL_PLACES = 6;
247
+ GeminiTransport.MAX_RETRIES = 5;
248
+ GeminiTransport.RATE_LIMIT_STATUS = 429;
249
+ GeminiTransport.BACKOFF_BASE_MS = 1000;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,5 @@
1
+ export * from './chat-transport.types';
2
+ export * from './chat.types';
1
3
  export * from './config.types';
2
4
  export * from './criteria-types';
3
5
  export * from './status.types';
@@ -4,10 +4,21 @@
4
4
  *
5
5
  * @beta
6
6
  */
7
+ /**
8
+ * Returns true if the Web Speech API is available in the current environment.
9
+ *
10
+ * @beta
11
+ */
7
12
  export function isSpeechRecognitionAvailable() {
8
13
  return (typeof window !== 'undefined' &&
9
14
  ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window));
10
15
  }
16
+ /**
17
+ * Starts continuous speech recognition, calling `onResult` with each transcript update.
18
+ * Returns a stop function, or null if speech recognition is unavailable.
19
+ *
20
+ * @beta
21
+ */
11
22
  export function startSpeechRecognition(onResult, onError) {
12
23
  if (!isSpeechRecognitionAvailable()) {
13
24
  return null;