@agent-native/toolkit 0.221.0-same-host-mcp-20261027-20261027081850 → 0.221.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.
- package/agent-native.eject.json +16 -1
- package/dist/app/agentkit/react/components.d.ts +5 -3
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +103 -42
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +93 -65
- package/dist/app/agentkit/react/voice-transcripts.d.ts +22 -1
- package/dist/app/agentkit/react/voice-transcripts.d.ts.map +1 -1
- package/dist/app/agentkit/react/voice-transcripts.js +209 -8
- package/dist/app/agentkit/react/voice-transcripts.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +55 -40
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +1 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +18 -6
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/index.js +1 -1
- package/dist/app/chat/agentkit-chat/index.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +5 -1
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/reply-connection-suggestion.d.ts +29 -0
- package/dist/app/chat/reply-connection-suggestion.d.ts.map +1 -0
- package/dist/app/chat/reply-connection-suggestion.js +42 -0
- package/dist/app/chat/reply-connection-suggestion.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +7 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +7 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +7 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +7 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +7 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +7 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +7 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +7 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +7 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +7 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +7 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +7 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/mcp-approval/McpApprovalReview.d.ts +25 -0
- package/dist/app/mcp-approval/McpApprovalReview.d.ts.map +1 -0
- package/dist/app/mcp-approval/McpApprovalReview.js +342 -0
- package/dist/app/mcp-approval/McpApprovalReview.js.map +1 -0
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +299 -71
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/GettingStartedCard.js +1 -1
- package/dist/app/onboarding/GettingStartedCard.js.map +1 -1
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts +2 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts.map +1 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js +8 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js.map +1 -0
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +14 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.d.ts +2 -4
- package/dist/app/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.js +59 -36
- package/dist/app/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.d.ts.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.js +14 -1
- package/dist/app/settings/account/PreferencesSettings.js.map +1 -1
- package/dist/app/settings/account/ThemeFamilySettings.js +2 -2
- package/dist/app/settings/account/ThemeFamilySettings.js.map +1 -1
- package/dist/app/settings/account/search-entries.d.ts +1 -0
- package/dist/app/settings/account/search-entries.d.ts.map +1 -1
- package/dist/app/settings/account/search-entries.js +5 -0
- package/dist/app/settings/account/search-entries.js.map +1 -1
- package/dist/app/settings/shell/SettingsShell.d.ts.map +1 -1
- package/dist/app/settings/shell/SettingsShell.js +26 -2
- package/dist/app/settings/shell/SettingsShell.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +4 -10
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/app/shared/EnvironmentBadge.d.ts +2 -1
- package/dist/app/shared/EnvironmentBadge.d.ts.map +1 -1
- package/dist/app/shared/EnvironmentBadge.js +2 -3
- package/dist/app/shared/EnvironmentBadge.js.map +1 -1
- package/dist/app/shared/is-builder-io-employee.d.ts +8 -0
- package/dist/app/shared/is-builder-io-employee.d.ts.map +1 -0
- package/dist/app/shared/is-builder-io-employee.js +10 -0
- package/dist/app/shared/is-builder-io-employee.js.map +1 -0
- package/dist/app/styles/agent-conversation.css +30 -17
- package/dist/app/styles/theme-families.css +22 -5
- package/dist/app/styles/tokens/agent-kit.css +3 -3
- package/dist/composer/PromptComposer.d.ts +15 -3
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +74 -16
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/RealtimeVoiceMode.d.ts +7 -0
- package/dist/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/RealtimeVoiceMode.js +9 -2
- package/dist/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +7 -0
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +12 -4
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts +2 -0
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +5 -4
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/index.d.ts +2 -2
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -1
- package/dist/composer/index.js.map +1 -1
- package/dist/composer/prompt-attachments.d.ts +20 -0
- package/dist/composer/prompt-attachments.d.ts.map +1 -1
- package/dist/composer/prompt-attachments.js +188 -11
- package/dist/composer/prompt-attachments.js.map +1 -1
- package/dist/composer/realtime-voice-transcript.d.ts +27 -0
- package/dist/composer/realtime-voice-transcript.d.ts.map +1 -1
- package/dist/composer/realtime-voice-transcript.js +34 -1
- package/dist/composer/realtime-voice-transcript.js.map +1 -1
- package/dist/composer/realtime-voice-turn-metrics.d.ts +43 -0
- package/dist/composer/realtime-voice-turn-metrics.d.ts.map +1 -0
- package/dist/composer/realtime-voice-turn-metrics.js +132 -0
- package/dist/composer/realtime-voice-turn-metrics.js.map +1 -0
- package/dist/composer/runtime-adapters.d.ts +4 -1
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.d.ts +61 -9
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.js +536 -99
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/composer/voice-chat-icon.d.ts +7 -0
- package/dist/composer/voice-chat-icon.d.ts.map +1 -0
- package/dist/composer/voice-chat-icon.js +14 -0
- package/dist/composer/voice-chat-icon.js.map +1 -0
- package/dist/editor/DragHandle.d.ts +12 -1
- package/dist/editor/DragHandle.d.ts.map +1 -1
- package/dist/editor/DragHandle.js +165 -41
- package/dist/editor/DragHandle.js.map +1 -1
- package/dist/editor/RegistryBlockNode.d.ts +20 -0
- package/dist/editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/editor/RegistryBlockNode.js +58 -13
- package/dist/editor/RegistryBlockNode.js.map +1 -1
- package/dist/editor/index.d.ts +2 -2
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/editor/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +5 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +14 -4
- package/src/app/agentkit/react/components.regenerate-readiness.spec.tsx +3 -1
- package/src/app/agentkit/react/components.spec.tsx +24 -4
- package/src/app/agentkit/react/components.tsx +174 -44
- package/src/app/agentkit/react/composer-context.spec.tsx +3 -0
- package/src/app/agentkit/react/disclosures.spec.tsx +124 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +8 -2
- package/src/app/agentkit/react/message-actions.spec.tsx +161 -5
- package/src/app/agentkit/react/saved-reply-reload.spec.tsx +206 -0
- package/src/app/agentkit/react/styles.css +93 -65
- package/src/app/agentkit/react/voice-transcripts.spec.tsx +239 -4
- package/src/app/agentkit/react/voice-transcripts.ts +245 -8
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +59 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +74 -62
- package/src/app/chat/agentkit-chat/guided-answers-context.spec.ts +9 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +17 -7
- package/src/app/chat/agentkit-chat/index.ts +1 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +45 -0
- package/src/app/chat/chat/run-recovery.tsx +6 -1
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/reply-connection-suggestion.spec.ts +121 -0
- package/src/app/chat/reply-connection-suggestion.ts +76 -0
- package/src/app/i18n/catalogs/ar-SA.ts +10 -0
- package/src/app/i18n/catalogs/de-DE.ts +10 -0
- package/src/app/i18n/catalogs/en-US.ts +10 -0
- package/src/app/i18n/catalogs/es-ES.ts +10 -0
- package/src/app/i18n/catalogs/fr-FR.ts +10 -0
- package/src/app/i18n/catalogs/hi-IN.ts +10 -0
- package/src/app/i18n/catalogs/ja-JP.ts +10 -0
- package/src/app/i18n/catalogs/ko-KR.ts +10 -0
- package/src/app/i18n/catalogs/pt-BR.ts +10 -0
- package/src/app/i18n/catalogs/zh-CN.ts +10 -0
- package/src/app/i18n/catalogs/zh-TW.ts +10 -0
- package/src/app/mcp-approval/McpApprovalReview.spec.tsx +687 -0
- package/src/app/mcp-approval/McpApprovalReview.tsx +913 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +736 -26
- package/src/app/onboarding/FirstRunOnboarding.tsx +473 -145
- package/src/app/onboarding/GettingStartedCard.tsx +1 -1
- package/src/app/onboarding/first-run-builder-credits-flag.spec.ts +13 -0
- package/src/app/onboarding/first-run-builder-credits-flag.ts +9 -0
- package/src/app/providers/AppProviders.spec.tsx +109 -0
- package/src/app/providers/AppProviders.tsx +53 -1
- package/src/app/resources/McpConnectionSuggestion.spec.ts +77 -12
- package/src/app/resources/McpConnectionSuggestion.tsx +69 -51
- package/src/app/settings/VoiceChatSettings.spec.tsx +6 -1
- package/src/app/settings/account/PreferencesSettings.spec.tsx +73 -0
- package/src/app/settings/account/PreferencesSettings.tsx +24 -7
- package/src/app/settings/account/ThemeFamilySettings.tsx +2 -2
- package/src/app/settings/account/search-entries.spec.ts +14 -0
- package/src/app/settings/account/search-entries.ts +9 -0
- package/src/app/settings/shell/SettingsShell.tsx +29 -2
- package/src/app/shared/AppShellSkeleton.spec.tsx +2 -2
- package/src/app/shared/AppShellSkeleton.tsx +3 -16
- package/src/app/shared/EnvironmentBadge.tsx +3 -4
- package/src/app/shared/is-builder-io-employee.ts +17 -0
- package/src/app/styles/agent-conversation.css +30 -17
- package/src/app/styles/theme-families.css +22 -5
- package/src/app/styles/theme-families.spec.ts +73 -0
- package/src/app/styles/tokens/agent-kit.css +3 -3
- package/src/composer/AgentSuggestionBar.overflow.spec.tsx +1 -1
- package/src/composer/AttachmentChip.spec.tsx +87 -0
- package/src/composer/PromptComposer.context.spec.tsx +8 -4
- package/src/composer/PromptComposer.setup-card.spec.tsx +170 -0
- package/src/composer/PromptComposer.tsx +125 -14
- package/src/composer/RealtimeVoiceMode.spec.tsx +48 -0
- package/src/composer/RealtimeVoiceMode.tsx +45 -2
- package/src/composer/TiptapComposer.tsx +25 -0
- package/src/composer/TiptapComposer.voice-toolbar.spec.tsx +4 -1
- package/src/composer/VoiceButton.tsx +8 -3
- package/src/composer/index.ts +4 -0
- package/src/composer/prompt-attachments.spec.ts +160 -8
- package/src/composer/prompt-attachments.ts +221 -12
- package/src/composer/realtime-voice-transcript.spec.ts +36 -0
- package/src/composer/realtime-voice-transcript.ts +56 -1
- package/src/composer/realtime-voice-turn-metrics.spec.ts +175 -0
- package/src/composer/realtime-voice-turn-metrics.ts +192 -0
- package/src/composer/runtime-adapters.tsx +5 -1
- package/src/composer/useRealtimeVoiceMode.session.spec.tsx +487 -2
- package/src/composer/useRealtimeVoiceMode.spec.ts +267 -65
- package/src/composer/useRealtimeVoiceMode.tsx +716 -139
- package/src/composer/voice-chat-icon.tsx +19 -0
- package/src/editor/DragHandle.spec.ts +217 -0
- package/src/editor/DragHandle.ts +214 -55
- package/src/editor/RegistryBlockNode.spec.ts +172 -2
- package/src/editor/RegistryBlockNode.tsx +91 -13
- package/src/editor/index.ts +4 -0
- package/src/styles.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -88,14 +88,24 @@ describe("Realtime voice client transport", () => {
|
|
|
88
88
|
intelligence: "deep",
|
|
89
89
|
voice: "cedar",
|
|
90
90
|
}),
|
|
91
|
-
).toEqual({
|
|
91
|
+
).toEqual({
|
|
92
|
+
language: "en",
|
|
93
|
+
intelligence: "deep",
|
|
94
|
+
voice: "cedar",
|
|
95
|
+
intelligenceChosen: true,
|
|
96
|
+
});
|
|
92
97
|
expect(
|
|
93
98
|
normalizeRealtimeVoicePreferences({
|
|
94
99
|
language: "xx",
|
|
95
100
|
intelligence: "maximum",
|
|
96
101
|
voice: "unknown",
|
|
97
102
|
}),
|
|
98
|
-
).toEqual({
|
|
103
|
+
).toEqual({
|
|
104
|
+
language: "auto",
|
|
105
|
+
intelligence: "instant",
|
|
106
|
+
voice: "marin",
|
|
107
|
+
intelligenceChosen: false,
|
|
108
|
+
});
|
|
99
109
|
expect(resolveRealtimeVoiceLanguage("auto", ["en-US", "fr"])).toBe("en");
|
|
100
110
|
expect(resolveRealtimeVoiceLanguage("auto", ["nl-NL"])).toBe("en");
|
|
101
111
|
});
|
|
@@ -137,12 +147,44 @@ describe("Realtime voice client transport", () => {
|
|
|
137
147
|
type: "session.update",
|
|
138
148
|
session: {
|
|
139
149
|
delegation: {
|
|
140
|
-
responses: { reasoning: { effort: "
|
|
150
|
+
responses: { reasoning: { effort: "high" } },
|
|
141
151
|
},
|
|
142
152
|
},
|
|
143
153
|
});
|
|
144
154
|
});
|
|
145
155
|
|
|
156
|
+
it("gives each intelligence level its own GPT-Live reasoning effort", () => {
|
|
157
|
+
expect(realtimeVoiceReasoningEffort("instant", "live")).toBe("low");
|
|
158
|
+
expect(realtimeVoiceReasoningEffort("balanced", "live")).toBe("medium");
|
|
159
|
+
expect(realtimeVoiceReasoningEffort("deep", "live")).toBe("high");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("treats an old save's default level as not picked, and keeps a new pick and the app's default", () => {
|
|
163
|
+
expect(
|
|
164
|
+
normalizeRealtimeVoicePreferences({
|
|
165
|
+
language: "en",
|
|
166
|
+
intelligence: "instant",
|
|
167
|
+
voice: "cedar",
|
|
168
|
+
}).intelligenceChosen,
|
|
169
|
+
).toBe(false);
|
|
170
|
+
expect(
|
|
171
|
+
normalizeRealtimeVoicePreferences({
|
|
172
|
+
language: "en",
|
|
173
|
+
intelligence: "instant",
|
|
174
|
+
voice: "cedar",
|
|
175
|
+
intelligenceChosen: true,
|
|
176
|
+
}),
|
|
177
|
+
).toMatchObject({ intelligence: "instant", intelligenceChosen: true });
|
|
178
|
+
expect(
|
|
179
|
+
normalizeRealtimeVoicePreferences({
|
|
180
|
+
language: "en",
|
|
181
|
+
intelligence: "balanced",
|
|
182
|
+
voice: "cedar",
|
|
183
|
+
intelligenceChosen: false,
|
|
184
|
+
}),
|
|
185
|
+
).toMatchObject({ intelligence: "balanced", intelligenceChosen: false });
|
|
186
|
+
});
|
|
187
|
+
|
|
146
188
|
it("maps instant intelligence to a supported GPT-Live reasoning effort", () => {
|
|
147
189
|
expect(
|
|
148
190
|
createRealtimeVoicePreferenceUpdate(
|
|
@@ -341,6 +383,7 @@ describe("Realtime voice client transport", () => {
|
|
|
341
383
|
language: "auto",
|
|
342
384
|
intelligence: "instant",
|
|
343
385
|
voice: "marin",
|
|
386
|
+
intelligenceChosen: true,
|
|
344
387
|
},
|
|
345
388
|
browserLanguages: ["en-US"],
|
|
346
389
|
}),
|
|
@@ -373,6 +416,61 @@ describe("Realtime voice client transport", () => {
|
|
|
373
416
|
);
|
|
374
417
|
});
|
|
375
418
|
|
|
419
|
+
it("lets the app default apply until the user picks a level", async () => {
|
|
420
|
+
const fetchMock = vi.fn(
|
|
421
|
+
async () =>
|
|
422
|
+
new Response("answer-sdp", {
|
|
423
|
+
status: 200,
|
|
424
|
+
headers: {
|
|
425
|
+
"X-Agent-Native-Realtime-Protocol": "live",
|
|
426
|
+
"X-Agent-Native-Realtime-Intelligence": "balanced",
|
|
427
|
+
"X-Agent-Native-Realtime-Priority-Tools":
|
|
428
|
+
"edit-design, bad name,update-slide",
|
|
429
|
+
},
|
|
430
|
+
}),
|
|
431
|
+
);
|
|
432
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
433
|
+
|
|
434
|
+
await expect(
|
|
435
|
+
createRealtimeVoiceSessionWithCapability("offer-sdp", {
|
|
436
|
+
preferences: {
|
|
437
|
+
language: "en",
|
|
438
|
+
intelligence: "instant",
|
|
439
|
+
voice: "marin",
|
|
440
|
+
intelligenceChosen: false,
|
|
441
|
+
},
|
|
442
|
+
}),
|
|
443
|
+
).resolves.toEqual({
|
|
444
|
+
sdp: "answer-sdp",
|
|
445
|
+
protocol: "live",
|
|
446
|
+
intelligence: "balanced",
|
|
447
|
+
priorityToolNames: ["edit-design", "update-slide"],
|
|
448
|
+
});
|
|
449
|
+
const [, init] = fetchMock.mock.calls[0] as unknown as [
|
|
450
|
+
string,
|
|
451
|
+
RequestInit,
|
|
452
|
+
];
|
|
453
|
+
expect(init.headers).not.toHaveProperty(
|
|
454
|
+
"X-Agent-Native-Realtime-Intelligence",
|
|
455
|
+
);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it("sends the level of preferences that do not say whether it was chosen", async () => {
|
|
459
|
+
const fetchMock = vi.fn(async () => new Response("answer-sdp"));
|
|
460
|
+
vi.stubGlobal("fetch", fetchMock);
|
|
461
|
+
|
|
462
|
+
await createRealtimeVoiceSessionWithCapability("offer-sdp", {
|
|
463
|
+
preferences: { language: "en", intelligence: "deep", voice: "marin" },
|
|
464
|
+
});
|
|
465
|
+
const [, init] = fetchMock.mock.calls[0] as unknown as [
|
|
466
|
+
string,
|
|
467
|
+
RequestInit,
|
|
468
|
+
];
|
|
469
|
+
expect(init.headers).toMatchObject({
|
|
470
|
+
"X-Agent-Native-Realtime-Intelligence": "deep",
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
|
|
376
474
|
it("sends function calls to the authenticated Agent-Native tool bridge", async () => {
|
|
377
475
|
const signal = new AbortController().signal;
|
|
378
476
|
const fetchMock = vi.fn(async () =>
|
|
@@ -475,6 +573,66 @@ describe("Realtime voice dynamic tool manifests", () => {
|
|
|
475
573
|
expect(names).not.toContain("old-26");
|
|
476
574
|
});
|
|
477
575
|
|
|
576
|
+
it("keeps the app's edit tools when a discovery fills the manifest", () => {
|
|
577
|
+
const current = [
|
|
578
|
+
...Array.from({ length: 31 }, (_, index) => realtimeTool(`old-${index}`)),
|
|
579
|
+
realtimeTool("edit-design"),
|
|
580
|
+
];
|
|
581
|
+
const discoveries = Array.from({ length: 8 }, (_, index) =>
|
|
582
|
+
realtimeTool(`found-${index}`),
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
expect(
|
|
586
|
+
mergeRealtimeVoiceToolManifest(current, discoveries).map(
|
|
587
|
+
(tool) => tool.name,
|
|
588
|
+
),
|
|
589
|
+
).not.toContain("edit-design");
|
|
590
|
+
const merged = mergeRealtimeVoiceToolManifest(
|
|
591
|
+
current,
|
|
592
|
+
discoveries,
|
|
593
|
+
"live",
|
|
594
|
+
["edit-design"],
|
|
595
|
+
).map((tool) => tool.name);
|
|
596
|
+
expect(merged[0]).toBe("edit-design");
|
|
597
|
+
expect(merged).toContain("found-7");
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it("keeps the session's app edit tools through a coordinator expansion", () => {
|
|
601
|
+
const sent: Record<string, unknown>[] = [];
|
|
602
|
+
const coordinator = createRealtimeVoiceToolManifestCoordinator((event) =>
|
|
603
|
+
sent.push(event),
|
|
604
|
+
);
|
|
605
|
+
coordinator.setProtocol("live");
|
|
606
|
+
coordinator.setPriorityToolNames(["update-slide"]);
|
|
607
|
+
coordinator.setSessionTools([
|
|
608
|
+
...Array.from({ length: 31 }, (_, index) => realtimeTool(`old-${index}`)),
|
|
609
|
+
realtimeTool("update-slide"),
|
|
610
|
+
]);
|
|
611
|
+
coordinator.enqueue({
|
|
612
|
+
callId: "call-search",
|
|
613
|
+
status: "completed",
|
|
614
|
+
output: "{}",
|
|
615
|
+
expandedTools: [realtimeTool("web-search")],
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
const update = sent[0] as {
|
|
619
|
+
session: { delegation: { responses: { tools: { name: string }[] } } };
|
|
620
|
+
};
|
|
621
|
+
const names = update.session.delegation.responses.tools.map(
|
|
622
|
+
(tool) => tool.name,
|
|
623
|
+
);
|
|
624
|
+
expect(names.slice(0, 2)).toEqual(["web-search", "update-slide"]);
|
|
625
|
+
expect(names).toHaveLength(32);
|
|
626
|
+
// A strict schema would make the delegated model fill every optional field.
|
|
627
|
+
expect(
|
|
628
|
+
new Set(
|
|
629
|
+
update.session.delegation.responses.tools.map(
|
|
630
|
+
(tool) => (tool as { strict?: unknown }).strict,
|
|
631
|
+
),
|
|
632
|
+
),
|
|
633
|
+
).toEqual(new Set([false]));
|
|
634
|
+
});
|
|
635
|
+
|
|
478
636
|
it("packs dynamic schemas within the realtime session byte budget", () => {
|
|
479
637
|
const largeTool = (name: string): RealtimeVoiceFunctionTool => ({
|
|
480
638
|
...realtimeTool(name),
|
|
@@ -1153,79 +1311,120 @@ describe("Realtime voice startup and transcript ordering", () => {
|
|
|
1153
1311
|
]);
|
|
1154
1312
|
});
|
|
1155
1313
|
|
|
1156
|
-
|
|
1314
|
+
// GPT-Live transcript deltas carry an id and their place on the session
|
|
1315
|
+
// timeline; the SDK's grouper turns them into speaker turns.
|
|
1316
|
+
let liveEventId = 0;
|
|
1317
|
+
const liveDelta = (
|
|
1318
|
+
role: "user" | "assistant",
|
|
1319
|
+
delta: string,
|
|
1320
|
+
start_ms: number,
|
|
1321
|
+
end_ms: number,
|
|
1322
|
+
) => ({
|
|
1323
|
+
type:
|
|
1324
|
+
role === "user"
|
|
1325
|
+
? "session.input_transcript.delta"
|
|
1326
|
+
: "session.output_transcript.delta",
|
|
1327
|
+
event_id: `live-event-${++liveEventId}`,
|
|
1328
|
+
delta,
|
|
1329
|
+
start_ms,
|
|
1330
|
+
end_ms,
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
it("orders GPT-Live turns by speaker", () => {
|
|
1157
1334
|
const published: Array<{ role: string; text: string }> = [];
|
|
1158
1335
|
const sequencer = createRealtimeVoiceTranscriptSequencer((transcript) => {
|
|
1159
1336
|
published.push(transcript);
|
|
1160
1337
|
});
|
|
1161
1338
|
|
|
1162
|
-
sequencer.handle(
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
});
|
|
1168
|
-
sequencer.handle({
|
|
1169
|
-
type: "session.input_transcript.delta",
|
|
1170
|
-
delta: "me?",
|
|
1171
|
-
start_ms: 400,
|
|
1172
|
-
end_ms: 500,
|
|
1173
|
-
});
|
|
1174
|
-
sequencer.handle({
|
|
1175
|
-
type: "session.output_transcript.delta",
|
|
1176
|
-
delta: "Absolutely.",
|
|
1177
|
-
start_ms: 300,
|
|
1178
|
-
end_ms: 900,
|
|
1179
|
-
});
|
|
1180
|
-
expect(published).toEqual([]);
|
|
1181
|
-
|
|
1182
|
-
sequencer.handle({
|
|
1183
|
-
type: "response.event",
|
|
1184
|
-
event: { type: "response.completed" },
|
|
1185
|
-
});
|
|
1186
|
-
expect(published).toEqual([]);
|
|
1339
|
+
sequencer.handle(liveDelta("user", "Can you help ", 0, 400));
|
|
1340
|
+
sequencer.handle(liveDelta("user", "me?", 400, 500));
|
|
1341
|
+
sequencer.handle(liveDelta("assistant", "Absolutely.", 1_100, 1_900));
|
|
1342
|
+
sequencer.handle(liveDelta("user", "Next question.", 3_000, 3_400));
|
|
1343
|
+
sequencer.handle(liveDelta("assistant", "Next answer.", 4_000, 4_500));
|
|
1344
|
+
sequencer.handle({ type: "session.closed" });
|
|
1187
1345
|
|
|
1188
|
-
sequencer.handle({
|
|
1189
|
-
type: "session.input_transcript.delta",
|
|
1190
|
-
delta: "Next question.",
|
|
1191
|
-
start_ms: 2_000,
|
|
1192
|
-
end_ms: 2_200,
|
|
1193
|
-
});
|
|
1194
|
-
sequencer.handle({
|
|
1195
|
-
type: "session.output_transcript.delta",
|
|
1196
|
-
delta: "Next answer.",
|
|
1197
|
-
start_ms: 2_300,
|
|
1198
|
-
end_ms: 2_500,
|
|
1199
|
-
});
|
|
1200
1346
|
expect(published).toEqual([
|
|
1201
1347
|
{ role: "user", text: "Can you help me?" },
|
|
1202
1348
|
{ role: "assistant", text: "Absolutely." },
|
|
1349
|
+
{ role: "user", text: "Next question." },
|
|
1350
|
+
{ role: "assistant", text: "Next answer." },
|
|
1203
1351
|
]);
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
it("keeps a GPT-Live reply spoken with pauses as one message", () => {
|
|
1355
|
+
const published: Array<{ role: string; text: string }> = [];
|
|
1356
|
+
const sequencer = createRealtimeVoiceTranscriptSequencer((transcript) => {
|
|
1357
|
+
published.push(transcript);
|
|
1358
|
+
});
|
|
1204
1359
|
|
|
1360
|
+
sequencer.handle(
|
|
1361
|
+
liveDelta("assistant", "I found a solid overview. ", 0, 1_000),
|
|
1362
|
+
);
|
|
1363
|
+
sequencer.handle(
|
|
1364
|
+
liveDelta(
|
|
1365
|
+
"assistant",
|
|
1366
|
+
"They explain the meaning of life, ",
|
|
1367
|
+
2_000,
|
|
1368
|
+
3_000,
|
|
1369
|
+
),
|
|
1370
|
+
);
|
|
1371
|
+
sequencer.handle(
|
|
1372
|
+
liveDelta("assistant", "and meaning in life.", 4_500, 5_500),
|
|
1373
|
+
);
|
|
1205
1374
|
sequencer.handle({ type: "session.closed" });
|
|
1375
|
+
|
|
1206
1376
|
expect(published).toEqual([
|
|
1207
|
-
{
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1377
|
+
{
|
|
1378
|
+
role: "assistant",
|
|
1379
|
+
text: "I found a solid overview. They explain the meaning of life, and meaning in life.",
|
|
1380
|
+
},
|
|
1211
1381
|
]);
|
|
1212
1382
|
});
|
|
1213
1383
|
|
|
1214
|
-
it("
|
|
1384
|
+
it("starts a new GPT-Live message after the assistant goes quiet", () => {
|
|
1215
1385
|
const published: Array<{ role: string; text: string }> = [];
|
|
1216
1386
|
const sequencer = createRealtimeVoiceTranscriptSequencer((transcript) => {
|
|
1217
1387
|
published.push(transcript);
|
|
1218
1388
|
});
|
|
1219
1389
|
|
|
1220
|
-
sequencer.handle(
|
|
1221
|
-
|
|
1222
|
-
|
|
1390
|
+
sequencer.handle(liveDelta("assistant", "On it, looking it ", 0, 400));
|
|
1391
|
+
sequencer.handle(liveDelta("assistant", "up.", 400, 600));
|
|
1392
|
+
// A tool runs in the silence before the answer.
|
|
1393
|
+
sequencer.handle(
|
|
1394
|
+
liveDelta("assistant", "Here is what I found.", 6_000, 7_000),
|
|
1395
|
+
);
|
|
1396
|
+
sequencer.handle({ type: "session.closed" });
|
|
1397
|
+
|
|
1398
|
+
expect(published).toEqual([
|
|
1399
|
+
{ role: "assistant", text: "On it, looking it up." },
|
|
1400
|
+
{ role: "assistant", text: "Here is what I found." },
|
|
1401
|
+
]);
|
|
1402
|
+
});
|
|
1403
|
+
|
|
1404
|
+
it("discards unconfirmed GPT-Live transcripts on reset", () => {
|
|
1405
|
+
const published: Array<{ role: string; text: string }> = [];
|
|
1406
|
+
const sequencer = createRealtimeVoiceTranscriptSequencer((transcript) => {
|
|
1407
|
+
published.push(transcript);
|
|
1223
1408
|
});
|
|
1409
|
+
|
|
1410
|
+
sequencer.handle(liveDelta("assistant", "Possibly incomplete.", 0, 500));
|
|
1224
1411
|
sequencer.reset();
|
|
1225
1412
|
sequencer.flush();
|
|
1226
1413
|
|
|
1227
1414
|
expect(published).toEqual([]);
|
|
1228
1415
|
});
|
|
1416
|
+
|
|
1417
|
+
it("rejects a GPT-Live transcript delta without its timing", () => {
|
|
1418
|
+
const sequencer = createRealtimeVoiceTranscriptSequencer(() => undefined);
|
|
1419
|
+
|
|
1420
|
+
expect(() =>
|
|
1421
|
+
sequencer.handle({
|
|
1422
|
+
type: "session.output_transcript.delta",
|
|
1423
|
+
event_id: "untimed",
|
|
1424
|
+
delta: "Hello",
|
|
1425
|
+
}),
|
|
1426
|
+
).toThrow(/timing/);
|
|
1427
|
+
});
|
|
1229
1428
|
});
|
|
1230
1429
|
|
|
1231
1430
|
describe("Realtime voice transcript streaming", () => {
|
|
@@ -1310,28 +1509,31 @@ describe("Realtime voice transcript streaming", () => {
|
|
|
1310
1509
|
]);
|
|
1311
1510
|
});
|
|
1312
1511
|
|
|
1313
|
-
it("streams GPT-Live turns under
|
|
1512
|
+
it("streams GPT-Live turns under the id their final transcript keeps", () => {
|
|
1314
1513
|
const { sequencer, streamed, published } = streamingSequencer();
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1514
|
+
for (const [index, [delta, start_ms, end_ms]] of (
|
|
1515
|
+
[
|
|
1516
|
+
["Hello ", 0, 200],
|
|
1517
|
+
["there", 200, 400],
|
|
1518
|
+
] as const
|
|
1519
|
+
).entries()) {
|
|
1520
|
+
sequencer.handle({
|
|
1521
|
+
type: "session.input_transcript.delta",
|
|
1522
|
+
event_id: `stream-${index}`,
|
|
1523
|
+
delta,
|
|
1524
|
+
start_ms,
|
|
1525
|
+
end_ms,
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1327
1528
|
sequencer.handle({ type: "session.closed" });
|
|
1328
1529
|
|
|
1530
|
+
const [id] = published.map(({ providerId }) => providerId);
|
|
1329
1531
|
expect(streamed).toEqual([
|
|
1330
|
-
{ role: "user", text: "Hello", providerId:
|
|
1331
|
-
{ role: "user", text: "Hello there", providerId:
|
|
1532
|
+
{ role: "user", text: "Hello", providerId: id },
|
|
1533
|
+
{ role: "user", text: "Hello there", providerId: id },
|
|
1332
1534
|
]);
|
|
1333
1535
|
expect(published).toEqual([
|
|
1334
|
-
{ role: "user", text: "Hello there", providerId:
|
|
1536
|
+
{ role: "user", text: "Hello there", providerId: id },
|
|
1335
1537
|
]);
|
|
1336
1538
|
});
|
|
1337
1539
|
});
|