@terminai/core 0.21.0 → 0.25.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/dist/docs/assets/image.png +0 -0
- package/dist/src/audit/redaction.js +24 -0
- package/dist/src/audit/redaction.js.map +1 -1
- package/dist/src/audit/redaction.test.d.ts +7 -0
- package/dist/src/audit/redaction.test.js +45 -0
- package/dist/src/audit/redaction.test.js.map +1 -0
- package/dist/src/auth/geminiAuthStatus.js +1 -1
- package/dist/src/auth/geminiAuthStatus.js.map +1 -1
- package/dist/src/auth/geminiAuthStatus.test.js +1 -1
- package/dist/src/auth/geminiAuthStatus.test.js.map +1 -1
- package/dist/src/auth/providerRegistry.js +20 -0
- package/dist/src/auth/providerRegistry.js.map +1 -1
- package/dist/src/auth/wizardSettings.d.ts +5 -0
- package/dist/src/auth/wizardSettings.js +48 -1
- package/dist/src/auth/wizardSettings.js.map +1 -1
- package/dist/src/auth/wizardSettings.test.js +30 -2
- package/dist/src/auth/wizardSettings.test.js.map +1 -1
- package/dist/src/auth/wizardState.d.ts +1 -1
- package/dist/src/auth/wizardState.js +6 -0
- package/dist/src/auth/wizardState.js.map +1 -1
- package/dist/src/auth/wizardState.test.js +23 -0
- package/dist/src/auth/wizardState.test.js.map +1 -1
- package/dist/src/availability/policyHelpers.test.js +4 -4
- package/dist/src/availability/policyHelpers.test.js.map +1 -1
- package/dist/src/brain/__tests__/environmentDetector.test.js +2 -1
- package/dist/src/brain/__tests__/environmentDetector.test.js.map +1 -1
- package/dist/src/brain/__tests__/orchestratorFlag.test.d.ts +7 -0
- package/dist/src/brain/__tests__/orchestratorFlag.test.js +47 -0
- package/dist/src/brain/__tests__/orchestratorFlag.test.js.map +1 -0
- package/dist/src/brain/__tests__/orchestratorRecovery.test.d.ts +7 -0
- package/dist/src/brain/__tests__/orchestratorRecovery.test.js +85 -0
- package/dist/src/brain/__tests__/orchestratorRecovery.test.js.map +1 -0
- package/dist/src/brain/__tests__/thinkingOrchestrator.test.js +1 -0
- package/dist/src/brain/__tests__/thinkingOrchestrator.test.js.map +1 -1
- package/dist/src/brain/__tests__/toolIntegration.test.d.ts +7 -0
- package/dist/src/brain/__tests__/toolIntegration.test.js +154 -0
- package/dist/src/brain/__tests__/toolIntegration.test.js.map +1 -0
- package/dist/src/brain/advisors/codeGenerator.js +3 -2
- package/dist/src/brain/advisors/codeGenerator.js.map +1 -1
- package/dist/src/brain/advisors/depScanner.js +3 -2
- package/dist/src/brain/advisors/depScanner.js.map +1 -1
- package/dist/src/brain/advisors/enumerator.js +3 -2
- package/dist/src/brain/advisors/enumerator.js.map +1 -1
- package/dist/src/brain/advisors/fallbackChain.js +3 -2
- package/dist/src/brain/advisors/fallbackChain.js.map +1 -1
- package/dist/src/brain/advisors/patternMatcher.js +3 -2
- package/dist/src/brain/advisors/patternMatcher.js.map +1 -1
- package/dist/src/brain/consensus.js +2 -1
- package/dist/src/brain/consensus.js.map +1 -1
- package/dist/src/brain/environmentDetector.d.ts +1 -0
- package/dist/src/brain/environmentDetector.js +35 -20
- package/dist/src/brain/environmentDetector.js.map +1 -1
- package/dist/src/brain/pacLoop.js +2 -1
- package/dist/src/brain/pacLoop.js.map +1 -1
- package/dist/src/brain/riskAssessor.d.ts +6 -2
- package/dist/src/brain/riskAssessor.js +7 -4
- package/dist/src/brain/riskAssessor.js.map +1 -1
- package/dist/src/brain/stepBackEvaluator.js +2 -1
- package/dist/src/brain/stepBackEvaluator.js.map +1 -1
- package/dist/src/brain/thinkingOrchestrator.d.ts +9 -1
- package/dist/src/brain/thinkingOrchestrator.js +47 -1
- package/dist/src/brain/thinkingOrchestrator.js.map +1 -1
- package/dist/src/brain/toolIntegration.d.ts +51 -0
- package/dist/src/brain/toolIntegration.js +202 -0
- package/dist/src/brain/toolIntegration.js.map +1 -0
- package/dist/src/code_assist/oauth2.begin.test.js +4 -1
- package/dist/src/code_assist/oauth2.begin.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +1 -1
- package/dist/src/code_assist/oauth2.js +9 -13
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +69 -41
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/commands/init.js +5 -0
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/computer/PersistentShell.d.ts +5 -0
- package/dist/src/computer/PersistentShell.js +21 -2
- package/dist/src/computer/PersistentShell.js.map +1 -1
- package/dist/src/computer/PersistentShell.test.js +23 -11
- package/dist/src/computer/PersistentShell.test.js.map +1 -1
- package/dist/src/config/builder.js +78 -5
- package/dist/src/config/builder.js.map +1 -1
- package/dist/src/config/config.d.ts +12 -1
- package/dist/src/config/config.js +64 -0
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +39 -0
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/models.d.ts +2 -2
- package/dist/src/config/models.js +2 -2
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/models.test.js +1 -1
- package/dist/src/config/settings/schema.d.ts +78 -4
- package/dist/src/config/settings/schema.js +76 -4
- package/dist/src/config/settings/schema.js.map +1 -1
- package/dist/src/core/chatGptCodexContentGenerator.d.ts +35 -0
- package/dist/src/core/chatGptCodexContentGenerator.js +605 -0
- package/dist/src/core/chatGptCodexContentGenerator.js.map +1 -0
- package/dist/src/core/chatGptCodexContentGenerator.test.d.ts +7 -0
- package/dist/src/core/chatGptCodexContentGenerator.test.js +250 -0
- package/dist/src/core/chatGptCodexContentGenerator.test.js.map +1 -0
- package/dist/src/core/contentGenerator.d.ts +2 -1
- package/dist/src/core/contentGenerator.js +10 -0
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +36 -0
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +1 -0
- package/dist/src/core/loggingContentGenerator.js +30 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.js +62 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
- package/dist/src/core/openaiContentGenerator.d.ts +16 -0
- package/dist/src/core/openaiContentGenerator.js +252 -53
- package/dist/src/core/openaiContentGenerator.js.map +1 -1
- package/dist/src/core/openaiContentGenerator.test.js +176 -7
- package/dist/src/core/openaiContentGenerator.test.js.map +1 -1
- package/dist/src/core/providerTypes.d.ts +17 -1
- package/dist/src/core/providerTypes.js +10 -0
- package/dist/src/core/providerTypes.js.map +1 -1
- package/dist/src/core/providerTypes.test.js +11 -0
- package/dist/src/core/providerTypes.test.js.map +1 -1
- package/dist/src/core/turn.js +1 -1
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +1 -1
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/fallback/handler.test.js +14 -14
- package/dist/src/fallback/handler.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/gui/drivers/__tests__/sidecarContract.test.d.ts +2 -2
- package/dist/src/gui/drivers/__tests__/sidecarContract.test.js +3 -4
- package/dist/src/gui/drivers/__tests__/sidecarContract.test.js.map +1 -1
- package/dist/src/gui/drivers/linuxAtspiDriver.js +11 -4
- package/dist/src/gui/drivers/linuxAtspiDriver.js.map +1 -1
- package/dist/src/gui/drivers/windowsUiaDriver.js +2 -2
- package/dist/src/gui/drivers/windowsUiaDriver.js.map +1 -1
- package/dist/src/gui/selectors/__tests__/selectors.test.js +5 -2
- package/dist/src/gui/selectors/__tests__/selectors.test.js.map +1 -1
- package/dist/src/gui/selectors/parser.d.ts +1 -1
- package/dist/src/gui/selectors/parser.js +1 -1
- package/dist/src/gui/selectors/parser.js.map +1 -1
- package/dist/src/gui/service/DesktopAutomationService.d.ts +1 -1
- package/dist/src/gui/service/DesktopAutomationService.js +8 -9
- package/dist/src/gui/service/DesktopAutomationService.js.map +1 -1
- package/dist/src/gui/service/__tests__/capabilities.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/capabilities.test.js +32 -4
- package/dist/src/gui/service/__tests__/capabilities.test.js.map +1 -1
- package/dist/src/gui/service/__tests__/diagnose.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/diagnose.test.js +6 -0
- package/dist/src/gui/service/__tests__/diagnose.test.js.map +1 -1
- package/dist/src/gui/service/__tests__/progressive.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/progressive.test.js +30 -3
- package/dist/src/gui/service/__tests__/progressive.test.js.map +1 -1
- package/dist/src/gui/service/__tests__/redaction.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/redaction.test.js +27 -1
- package/dist/src/gui/service/__tests__/redaction.test.js.map +1 -1
- package/dist/src/gui/service/__tests__/selectorError.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/selectorError.test.js +6 -0
- package/dist/src/gui/service/__tests__/selectorError.test.js.map +1 -1
- package/dist/src/gui/service/__tests__/wait.test.d.ts +6 -0
- package/dist/src/gui/service/__tests__/wait.test.js +29 -2
- package/dist/src/gui/service/__tests__/wait.test.js.map +1 -1
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/openai_chatgpt/constants.d.ts +23 -0
- package/dist/src/openai_chatgpt/constants.js +35 -0
- package/dist/src/openai_chatgpt/constants.js.map +1 -0
- package/dist/src/openai_chatgpt/credentialStorage.d.ts +18 -0
- package/dist/src/openai_chatgpt/credentialStorage.js +116 -0
- package/dist/src/openai_chatgpt/credentialStorage.js.map +1 -0
- package/dist/src/openai_chatgpt/credentialStorage.test.d.ts +7 -0
- package/dist/src/openai_chatgpt/credentialStorage.test.js +73 -0
- package/dist/src/openai_chatgpt/credentialStorage.test.js.map +1 -0
- package/dist/src/openai_chatgpt/imports.d.ts +10 -0
- package/dist/src/openai_chatgpt/imports.js +164 -0
- package/dist/src/openai_chatgpt/imports.js.map +1 -0
- package/dist/src/openai_chatgpt/imports.test.d.ts +7 -0
- package/dist/src/openai_chatgpt/imports.test.js +82 -0
- package/dist/src/openai_chatgpt/imports.test.js.map +1 -0
- package/dist/src/openai_chatgpt/jwt.d.ts +7 -0
- package/dist/src/openai_chatgpt/jwt.js +31 -0
- package/dist/src/openai_chatgpt/jwt.js.map +1 -0
- package/dist/src/openai_chatgpt/jwt.test.d.ts +7 -0
- package/dist/src/openai_chatgpt/jwt.test.js +23 -0
- package/dist/src/openai_chatgpt/jwt.test.js.map +1 -0
- package/dist/src/openai_chatgpt/oauthClient.d.ts +52 -0
- package/dist/src/openai_chatgpt/oauthClient.js +196 -0
- package/dist/src/openai_chatgpt/oauthClient.js.map +1 -0
- package/dist/src/openai_chatgpt/oauthClient.test.d.ts +7 -0
- package/dist/src/openai_chatgpt/oauthClient.test.js +138 -0
- package/dist/src/openai_chatgpt/oauthClient.test.js.map +1 -0
- package/dist/src/openai_chatgpt/types.d.ts +34 -0
- package/dist/src/openai_chatgpt/types.js +8 -0
- package/dist/src/openai_chatgpt/types.js.map +1 -0
- package/dist/src/policy/shell-safety.test.js +2 -1
- package/dist/src/policy/shell-safety.test.js.map +1 -1
- package/dist/src/safety/approval-ladder/__tests__/buildShellActionProfile.test.js +2 -1
- package/dist/src/safety/approval-ladder/__tests__/buildShellActionProfile.test.js.map +1 -1
- package/dist/src/safety/built-in.test.js +4 -2
- package/dist/src/safety/built-in.test.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +95 -75
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/tools/__tests__/edit.risk.test.d.ts +7 -0
- package/dist/src/tools/__tests__/edit.risk.test.js +138 -0
- package/dist/src/tools/__tests__/edit.risk.test.js.map +1 -0
- package/dist/src/tools/__tests__/memoryToolDedupe.test.d.ts +7 -0
- package/dist/src/tools/__tests__/memoryToolDedupe.test.js +53 -0
- package/dist/src/tools/__tests__/memoryToolDedupe.test.js.map +1 -0
- package/dist/src/tools/__tests__/shell.pin.test.js +2 -1
- package/dist/src/tools/__tests__/shell.pin.test.js.map +1 -1
- package/dist/src/tools/__tests__/shell.provenance.test.js +14 -4
- package/dist/src/tools/__tests__/shell.provenance.test.js.map +1 -1
- package/dist/src/tools/__tests__/ui-diagnose.test.d.ts +6 -0
- package/dist/src/tools/__tests__/ui-diagnose.test.js +11 -8
- package/dist/src/tools/__tests__/ui-diagnose.test.js.map +1 -1
- package/dist/src/tools/__tests__/ui-health.test.d.ts +6 -0
- package/dist/src/tools/__tests__/ui-health.test.js +37 -37
- package/dist/src/tools/__tests__/ui-health.test.js.map +1 -1
- package/dist/src/tools/agent-control.js +6 -18
- package/dist/src/tools/agent-control.js.map +1 -1
- package/dist/src/tools/agent-control.test.js +2 -28
- package/dist/src/tools/agent-control.test.js.map +1 -1
- package/dist/src/tools/edit.js +49 -9
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +1 -19
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/file-ops.js +9 -10
- package/dist/src/tools/file-ops.js.map +1 -1
- package/dist/src/tools/file-ops.test.js +0 -7
- package/dist/src/tools/file-ops.test.js.map +1 -1
- package/dist/src/tools/glob.js +4 -16
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +0 -29
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.js +4 -10
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.d.ts +1 -1
- package/dist/src/tools/ls.js +8 -7
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +0 -7
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.js +8 -6
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +0 -10
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/memoryTool.js +10 -0
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/process-manager.js +6 -5
- package/dist/src/tools/process-manager.js.map +1 -1
- package/dist/src/tools/process-manager.test.js +2 -1
- package/dist/src/tools/process-manager.test.js.map +1 -1
- package/dist/src/tools/read-file.js +8 -10
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +0 -12
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.js +2 -7
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/repl.js +10 -45
- package/dist/src/tools/repl.js.map +1 -1
- package/dist/src/tools/ripGrep.js +2 -5
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +1 -1
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +2 -11
- package/dist/src/tools/shell.js +31 -191
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +2 -1
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/smart-edit.js +2 -5
- package/dist/src/tools/smart-edit.js.map +1 -1
- package/dist/src/tools/smart-edit.test.js +0 -9
- package/dist/src/tools/smart-edit.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +5 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/ui-click.js +69 -3
- package/dist/src/tools/ui-click.js.map +1 -1
- package/dist/src/tools/write-file.js +34 -8
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +1 -15
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/errorReporting.js +1 -1
- package/dist/src/utils/errorReporting.js.map +1 -1
- package/dist/src/utils/errorReporting.test.js +1 -1
- package/dist/src/utils/errorReporting.test.js.map +1 -1
- package/dist/src/utils/events.d.ts +11 -0
- package/dist/src/utils/events.js +1 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/fileUtils.js +2 -7
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/processUtils.d.ts +43 -0
- package/dist/src/utils/processUtils.js +134 -0
- package/dist/src/utils/processUtils.js.map +1 -0
- package/dist/src/utils/shell-permissions.d.ts +1 -0
- package/dist/src/utils/shell-permissions.js +3 -3
- package/dist/src/utils/shell-permissions.js.map +1 -1
- package/dist/src/utils/shell-permissions.test.js +11 -5
- package/dist/src/utils/shell-permissions.test.js.map +1 -1
- package/dist/src/utils/shell-utils.js +6 -3
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +6 -2
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
|
@@ -19,6 +19,7 @@ vi.mock('../telemetry/trace.js', () => ({
|
|
|
19
19
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
20
20
|
import { LoggingContentGenerator } from './loggingContentGenerator.js';
|
|
21
21
|
import { ApiRequestEvent } from '../telemetry/types.js';
|
|
22
|
+
import { LlmProviderId } from './providerTypes.js';
|
|
22
23
|
describe('LoggingContentGenerator', () => {
|
|
23
24
|
let wrapped;
|
|
24
25
|
let config;
|
|
@@ -33,6 +34,9 @@ describe('LoggingContentGenerator', () => {
|
|
|
33
34
|
config = {
|
|
34
35
|
getGoogleAIConfig: vi.fn(),
|
|
35
36
|
getVertexAIConfig: vi.fn(),
|
|
37
|
+
getProviderConfig: vi
|
|
38
|
+
.fn()
|
|
39
|
+
.mockReturnValue({ provider: LlmProviderId.GEMINI }),
|
|
36
40
|
getContentGeneratorConfig: vi.fn().mockReturnValue({
|
|
37
41
|
authType: 'API_KEY',
|
|
38
42
|
}),
|
|
@@ -75,6 +79,35 @@ describe('LoggingContentGenerator', () => {
|
|
|
75
79
|
const responseEvent = vi.mocked(logApiResponse).mock.calls[0][1];
|
|
76
80
|
expect(responseEvent.duration_ms).toBe(1000);
|
|
77
81
|
});
|
|
82
|
+
it('should attribute server details for OpenAI-compatible providers', async () => {
|
|
83
|
+
vi.mocked(config.getProviderConfig).mockReturnValue({
|
|
84
|
+
provider: LlmProviderId.OPENAI_COMPATIBLE,
|
|
85
|
+
baseUrl: 'https://openrouter.ai/api/v1',
|
|
86
|
+
model: 'gpt-4o-mini',
|
|
87
|
+
});
|
|
88
|
+
const req = {
|
|
89
|
+
contents: [{ role: 'user', parts: [{ text: 'hello' }] }],
|
|
90
|
+
model: 'gpt-4o-mini',
|
|
91
|
+
};
|
|
92
|
+
const userPromptId = 'prompt-123';
|
|
93
|
+
const response = {
|
|
94
|
+
candidates: [],
|
|
95
|
+
usageMetadata: undefined,
|
|
96
|
+
text: undefined,
|
|
97
|
+
functionCalls: undefined,
|
|
98
|
+
executableCode: undefined,
|
|
99
|
+
codeExecutionResult: undefined,
|
|
100
|
+
data: undefined,
|
|
101
|
+
};
|
|
102
|
+
vi.mocked(wrapped.generateContent).mockResolvedValue(response);
|
|
103
|
+
await loggingContentGenerator.generateContent(req, userPromptId);
|
|
104
|
+
const requestEvent = vi.mocked(logApiRequest).mock.calls[0][1];
|
|
105
|
+
expect(requestEvent).toBeInstanceOf(ApiRequestEvent);
|
|
106
|
+
expect(requestEvent.prompt.server).toEqual({
|
|
107
|
+
address: 'openrouter.ai',
|
|
108
|
+
port: 443,
|
|
109
|
+
});
|
|
110
|
+
});
|
|
78
111
|
it('should log error on failure', async () => {
|
|
79
112
|
const req = {
|
|
80
113
|
contents: [{ role: 'user', parts: [{ text: 'hello' }] }],
|
|
@@ -124,6 +157,35 @@ describe('LoggingContentGenerator', () => {
|
|
|
124
157
|
const responseEvent = vi.mocked(logApiResponse).mock.calls[0][1];
|
|
125
158
|
expect(responseEvent.duration_ms).toBe(1000);
|
|
126
159
|
});
|
|
160
|
+
it('should attribute server details for OpenAI-compatible streaming calls', async () => {
|
|
161
|
+
vi.mocked(config.getProviderConfig).mockReturnValue({
|
|
162
|
+
provider: LlmProviderId.OPENAI_COMPATIBLE,
|
|
163
|
+
baseUrl: 'http://localhost:1234/v1',
|
|
164
|
+
model: 'gpt-4o-mini',
|
|
165
|
+
});
|
|
166
|
+
const req = {
|
|
167
|
+
contents: [{ role: 'user', parts: [{ text: 'hello' }] }],
|
|
168
|
+
model: 'gpt-4o-mini',
|
|
169
|
+
};
|
|
170
|
+
const userPromptId = 'prompt-123';
|
|
171
|
+
const response = {
|
|
172
|
+
candidates: [],
|
|
173
|
+
usageMetadata: undefined,
|
|
174
|
+
};
|
|
175
|
+
async function* createAsyncGenerator() {
|
|
176
|
+
yield response;
|
|
177
|
+
}
|
|
178
|
+
vi.mocked(wrapped.generateContentStream).mockResolvedValue(createAsyncGenerator());
|
|
179
|
+
const stream = await loggingContentGenerator.generateContentStream(req, userPromptId);
|
|
180
|
+
for await (const _ of stream) {
|
|
181
|
+
// consume stream
|
|
182
|
+
}
|
|
183
|
+
const requestEvent = vi.mocked(logApiRequest).mock.calls[0][1];
|
|
184
|
+
expect(requestEvent.prompt.server).toEqual({
|
|
185
|
+
address: 'localhost',
|
|
186
|
+
port: 1234,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
127
189
|
it('should log error on failure', async () => {
|
|
128
190
|
const req = {
|
|
129
191
|
contents: [{ role: 'user', parts: [{ text: 'hello' }] }],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loggingContentGenerator.test.js","sourceRoot":"","sources":["../../../src/core/loggingContentGenerator.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAChD,MAAM,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AACjD,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAE9C,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,aAAa;IACb,cAAc;IACd,WAAW;CACZ,CAAC,CAAC,CAAC;AAEJ,MAAM,iBAAiB,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CACxC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAClE,CAAC;AAEF,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,iBAAiB;CAClB,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAMzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"loggingContentGenerator.test.js","sourceRoot":"","sources":["../../../src/core/loggingContentGenerator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,13 @@ import type { Config } from '../config/config.js';
|
|
|
11
11
|
export declare class OpenAIContentGenerator implements ContentGenerator {
|
|
12
12
|
private readonly config;
|
|
13
13
|
private readonly globalConfig;
|
|
14
|
+
private toolNameMap;
|
|
14
15
|
constructor(config: OpenAICompatibleConfig, globalConfig: Config);
|
|
15
16
|
private hasUnsupportedModalities;
|
|
16
17
|
private partUnionToText;
|
|
18
|
+
private isPlainObject;
|
|
19
|
+
private getParametersJsonSchema;
|
|
20
|
+
private parseToolArguments;
|
|
17
21
|
private contentUnionToText;
|
|
18
22
|
private normalizeTools;
|
|
19
23
|
generateContent(request: GenerateContentParameters, _userPromptId: string): Promise<GenerateContentResponse>;
|
|
@@ -22,6 +26,18 @@ export declare class OpenAIContentGenerator implements ContentGenerator {
|
|
|
22
26
|
embedContent(_request: EmbedContentParameters): Promise<EmbedContentResponse>;
|
|
23
27
|
private fetchOpenAI;
|
|
24
28
|
private convertTools;
|
|
29
|
+
/**
|
|
30
|
+
* Sanitizes tool names for OpenAI function calling compatibility.
|
|
31
|
+
* OpenAI spec only allows: ^[a-zA-Z0-9_-]+$ (no dots, must not start with number)
|
|
32
|
+
* This converts names like "ui.click" → "ui_click" at the adapter level,
|
|
33
|
+
* keeping Gemini tool names unchanged in the core codebase.
|
|
34
|
+
* Records the mapping so we can reverse it when parsing model responses.
|
|
35
|
+
*/
|
|
36
|
+
private sanitizeToolName;
|
|
37
|
+
/**
|
|
38
|
+
* Reverses tool name sanitization to get original Gemini name.
|
|
39
|
+
*/
|
|
40
|
+
private unsanitizeToolName;
|
|
25
41
|
private convertSchemaToOpenAI;
|
|
26
42
|
private convertContentsToOpenAIMessages;
|
|
27
43
|
private convertOpenAIResponseToGemini;
|
|
@@ -11,6 +11,9 @@ import { estimateTokenCountSync } from '../utils/tokenCalculation.js';
|
|
|
11
11
|
export class OpenAIContentGenerator {
|
|
12
12
|
config;
|
|
13
13
|
globalConfig;
|
|
14
|
+
// Maps sanitized OpenAI tool names back to original Gemini names
|
|
15
|
+
// e.g., "ui_click" → "ui.click"
|
|
16
|
+
toolNameMap = new Map();
|
|
14
17
|
constructor(config, globalConfig) {
|
|
15
18
|
this.config = config;
|
|
16
19
|
this.globalConfig = globalConfig;
|
|
@@ -41,6 +44,32 @@ export class OpenAIContentGenerator {
|
|
|
41
44
|
}
|
|
42
45
|
return '';
|
|
43
46
|
}
|
|
47
|
+
isPlainObject(value) {
|
|
48
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
49
|
+
}
|
|
50
|
+
getParametersJsonSchema(fn) {
|
|
51
|
+
if (!this.isPlainObject(fn)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const parametersJsonSchema = fn['parametersJsonSchema'];
|
|
55
|
+
return this.isPlainObject(parametersJsonSchema)
|
|
56
|
+
? parametersJsonSchema
|
|
57
|
+
: null;
|
|
58
|
+
}
|
|
59
|
+
parseToolArguments(value) {
|
|
60
|
+
if (value === undefined || value === null) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (typeof value === 'string') {
|
|
64
|
+
const trimmed = value.trim();
|
|
65
|
+
if (!trimmed) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const parsed = JSON.parse(trimmed);
|
|
69
|
+
return this.isPlainObject(parsed) ? parsed : {};
|
|
70
|
+
}
|
|
71
|
+
return this.isPlainObject(value) ? value : null;
|
|
72
|
+
}
|
|
44
73
|
contentUnionToText(content) {
|
|
45
74
|
if (!content) {
|
|
46
75
|
return '';
|
|
@@ -69,7 +98,7 @@ export class OpenAIContentGenerator {
|
|
|
69
98
|
async generateContent(request, _userPromptId) {
|
|
70
99
|
const contents = toContents(request.contents);
|
|
71
100
|
if (this.hasUnsupportedModalities(contents)) {
|
|
72
|
-
throw new Error('
|
|
101
|
+
throw new Error('The OpenAI provider currently only supports text. To use images or other files, please switch to the Gemini provider.');
|
|
73
102
|
}
|
|
74
103
|
const messages = this.convertContentsToOpenAIMessages(contents);
|
|
75
104
|
const systemText = this.contentUnionToText(request.config?.systemInstruction);
|
|
@@ -92,6 +121,21 @@ export class OpenAIContentGenerator {
|
|
|
92
121
|
if (request.config?.temperature !== undefined) {
|
|
93
122
|
body['temperature'] = request.config.temperature;
|
|
94
123
|
}
|
|
124
|
+
if (request.config?.topP !== undefined) {
|
|
125
|
+
body['top_p'] = request.config.topP;
|
|
126
|
+
}
|
|
127
|
+
if (request.config?.presencePenalty !== undefined) {
|
|
128
|
+
body['presence_penalty'] = request.config.presencePenalty;
|
|
129
|
+
}
|
|
130
|
+
if (request.config?.frequencyPenalty !== undefined) {
|
|
131
|
+
body['frequency_penalty'] = request.config.frequencyPenalty;
|
|
132
|
+
}
|
|
133
|
+
if (request.config?.seed !== undefined) {
|
|
134
|
+
body['seed'] = request.config.seed;
|
|
135
|
+
}
|
|
136
|
+
if (request.config?.stopSequences) {
|
|
137
|
+
body['stop'] = request.config.stopSequences;
|
|
138
|
+
}
|
|
95
139
|
const response = await this.fetchOpenAI('/chat/completions', body, request.config?.abortSignal);
|
|
96
140
|
const data = (await response.json());
|
|
97
141
|
return this.convertOpenAIResponseToGemini(data);
|
|
@@ -99,7 +143,7 @@ export class OpenAIContentGenerator {
|
|
|
99
143
|
async generateContentStream(request, _userPromptId) {
|
|
100
144
|
const contents = toContents(request.contents);
|
|
101
145
|
if (this.hasUnsupportedModalities(contents)) {
|
|
102
|
-
throw new Error('
|
|
146
|
+
throw new Error('The OpenAI provider currently only supports text. To use images or other files, please switch to the Gemini provider.');
|
|
103
147
|
}
|
|
104
148
|
const messages = this.convertContentsToOpenAIMessages(contents);
|
|
105
149
|
const systemText = this.contentUnionToText(request.config?.systemInstruction);
|
|
@@ -121,15 +165,30 @@ export class OpenAIContentGenerator {
|
|
|
121
165
|
body['max_tokens'] = request.config.maxOutputTokens;
|
|
122
166
|
if (request.config?.temperature !== undefined)
|
|
123
167
|
body['temperature'] = request.config.temperature;
|
|
168
|
+
if (request.config?.topP !== undefined)
|
|
169
|
+
body['top_p'] = request.config.topP;
|
|
170
|
+
if (request.config?.presencePenalty !== undefined)
|
|
171
|
+
body['presence_penalty'] = request.config.presencePenalty;
|
|
172
|
+
if (request.config?.frequencyPenalty !== undefined)
|
|
173
|
+
body['frequency_penalty'] = request.config.frequencyPenalty;
|
|
174
|
+
if (request.config?.seed !== undefined)
|
|
175
|
+
body['seed'] = request.config.seed;
|
|
176
|
+
if (request.config?.stopSequences)
|
|
177
|
+
body['stop'] = request.config.stopSequences;
|
|
178
|
+
// Request usage implementation for streaming
|
|
179
|
+
body['stream_options'] = { include_usage: true };
|
|
124
180
|
const response = await this.fetchOpenAI('/chat/completions', body, request.config?.abortSignal);
|
|
125
181
|
if (!response.body) {
|
|
126
182
|
throw new Error('No response body from OpenAI stream');
|
|
127
183
|
}
|
|
128
184
|
const debugMode = this.globalConfig.getDebugMode();
|
|
185
|
+
const toolNameMap = this.toolNameMap;
|
|
186
|
+
const parseToolArguments = (value) => this.parseToolArguments(value);
|
|
129
187
|
return (async function* () {
|
|
130
188
|
const reader = response.body.getReader();
|
|
131
189
|
const decoder = new TextDecoder();
|
|
132
190
|
let buffer = '';
|
|
191
|
+
let hasYieldedAnyText = false;
|
|
133
192
|
// Buffer for streaming tool calls
|
|
134
193
|
const pendingToolCalls = {};
|
|
135
194
|
try {
|
|
@@ -147,20 +206,23 @@ export class OpenAIContentGenerator {
|
|
|
147
206
|
if (trimmed.startsWith('data: ')) {
|
|
148
207
|
try {
|
|
149
208
|
const data = JSON.parse(trimmed.slice(6));
|
|
150
|
-
const
|
|
151
|
-
const
|
|
209
|
+
const choice = data.choices?.[0];
|
|
210
|
+
const delta = choice?.delta;
|
|
211
|
+
const message = choice?.message;
|
|
212
|
+
const finishReason = choice?.finish_reason?.toUpperCase();
|
|
152
213
|
// 1. Handle Text Content
|
|
153
214
|
if (delta?.content) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
},
|
|
215
|
+
hasYieldedAnyText = true;
|
|
216
|
+
const resp = new GenerateContentResponse();
|
|
217
|
+
resp.candidates = [
|
|
218
|
+
{
|
|
219
|
+
content: {
|
|
220
|
+
role: 'model',
|
|
221
|
+
parts: [{ text: delta.content }],
|
|
161
222
|
},
|
|
162
|
-
|
|
163
|
-
|
|
223
|
+
},
|
|
224
|
+
];
|
|
225
|
+
yield resp;
|
|
164
226
|
}
|
|
165
227
|
// 2. Accumulate Tool Calls
|
|
166
228
|
if (delta?.tool_calls) {
|
|
@@ -172,14 +234,21 @@ export class OpenAIContentGenerator {
|
|
|
172
234
|
type: 'function',
|
|
173
235
|
function: {
|
|
174
236
|
name: tc.function?.name || '',
|
|
175
|
-
arguments: tc.function?.arguments
|
|
237
|
+
arguments: typeof tc.function?.arguments === 'string'
|
|
238
|
+
? tc.function.arguments
|
|
239
|
+
: '',
|
|
176
240
|
},
|
|
177
241
|
};
|
|
178
242
|
}
|
|
179
243
|
else {
|
|
244
|
+
if (tc.id && !pendingToolCalls[index].id) {
|
|
245
|
+
pendingToolCalls[index].id = tc.id;
|
|
246
|
+
}
|
|
180
247
|
if (tc.function?.arguments) {
|
|
181
|
-
|
|
182
|
-
|
|
248
|
+
if (typeof tc.function.arguments === 'string') {
|
|
249
|
+
pendingToolCalls[index].function.arguments +=
|
|
250
|
+
tc.function.arguments;
|
|
251
|
+
}
|
|
183
252
|
}
|
|
184
253
|
if (tc.function?.name) {
|
|
185
254
|
pendingToolCalls[index].function.name +=
|
|
@@ -188,10 +257,28 @@ export class OpenAIContentGenerator {
|
|
|
188
257
|
}
|
|
189
258
|
}
|
|
190
259
|
}
|
|
191
|
-
// 3. Handle
|
|
260
|
+
// 3. Handle Usage Metadata (streaming)
|
|
261
|
+
if (data.usage) {
|
|
262
|
+
const usage = data.usage;
|
|
263
|
+
const resp = new GenerateContentResponse();
|
|
264
|
+
resp.usageMetadata = {
|
|
265
|
+
promptTokenCount: usage.prompt_tokens,
|
|
266
|
+
candidatesTokenCount: usage.completion_tokens,
|
|
267
|
+
totalTokenCount: usage.total_tokens,
|
|
268
|
+
};
|
|
269
|
+
// If usage comes in a separate chunk without content, we must yield it
|
|
270
|
+
// Often it's the last chunk.
|
|
271
|
+
yield resp;
|
|
272
|
+
}
|
|
273
|
+
// 4. Handle Finish
|
|
192
274
|
if (finishReason) {
|
|
193
275
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
194
276
|
const parts = [];
|
|
277
|
+
if (!hasYieldedAnyText &&
|
|
278
|
+
typeof message?.content === 'string') {
|
|
279
|
+
parts.push({ text: message.content });
|
|
280
|
+
}
|
|
281
|
+
let hasEmittedToolCall = false;
|
|
195
282
|
// If we have buffered tool calls, finalize them now
|
|
196
283
|
const toolIndices = Object.keys(pendingToolCalls)
|
|
197
284
|
.map(Number)
|
|
@@ -199,13 +286,18 @@ export class OpenAIContentGenerator {
|
|
|
199
286
|
for (const index of toolIndices) {
|
|
200
287
|
const tc = pendingToolCalls[index];
|
|
201
288
|
try {
|
|
202
|
-
const
|
|
289
|
+
const parsedArgs = parseToolArguments(tc.function.arguments);
|
|
290
|
+
const args = parsedArgs ?? {};
|
|
291
|
+
// Unsanitize tool name back to original Gemini format
|
|
292
|
+
const originalName = toolNameMap.get(tc.function.name) || tc.function.name;
|
|
203
293
|
parts.push({
|
|
204
294
|
functionCall: {
|
|
205
|
-
|
|
295
|
+
...(tc.id ? { id: tc.id } : {}),
|
|
296
|
+
name: originalName,
|
|
206
297
|
args,
|
|
207
298
|
},
|
|
208
299
|
});
|
|
300
|
+
hasEmittedToolCall = true;
|
|
209
301
|
}
|
|
210
302
|
catch (e) {
|
|
211
303
|
if (debugMode) {
|
|
@@ -213,17 +305,39 @@ export class OpenAIContentGenerator {
|
|
|
213
305
|
}
|
|
214
306
|
}
|
|
215
307
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
308
|
+
if (!hasEmittedToolCall && message?.tool_calls) {
|
|
309
|
+
for (const tc of message.tool_calls) {
|
|
310
|
+
try {
|
|
311
|
+
const parsedArgs = parseToolArguments(tc.function.arguments);
|
|
312
|
+
const args = parsedArgs ?? {};
|
|
313
|
+
parts.push({
|
|
314
|
+
functionCall: {
|
|
315
|
+
...(tc.id ? { id: tc.id } : {}),
|
|
316
|
+
name: toolNameMap.get(tc.function.name || '') ||
|
|
317
|
+
tc.function.name ||
|
|
318
|
+
'',
|
|
319
|
+
args,
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
catch (e) {
|
|
324
|
+
if (debugMode) {
|
|
325
|
+
console.error('[OpenAI Provider] Failed to parse message tool arguments:', e);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const resp = new GenerateContentResponse();
|
|
331
|
+
resp.candidates = [
|
|
332
|
+
{
|
|
333
|
+
content: {
|
|
334
|
+
role: 'model',
|
|
335
|
+
parts,
|
|
224
336
|
},
|
|
225
|
-
|
|
226
|
-
|
|
337
|
+
finishReason: finishReason,
|
|
338
|
+
},
|
|
339
|
+
];
|
|
340
|
+
yield resp;
|
|
227
341
|
}
|
|
228
342
|
}
|
|
229
343
|
catch (e) {
|
|
@@ -258,7 +372,14 @@ export class OpenAIContentGenerator {
|
|
|
258
372
|
throw new Error('Embeddings not supported for OpenAI-compatible provider yet.');
|
|
259
373
|
}
|
|
260
374
|
async fetchOpenAI(endpoint, body, signal) {
|
|
261
|
-
const
|
|
375
|
+
const baseUrl = this.config.baseUrl.trim();
|
|
376
|
+
if (baseUrl.length === 0) {
|
|
377
|
+
throw new Error('OpenAI-compatible baseUrl is missing. Set llm.openaiCompatible.baseUrl (or run /auth wizard) and try again.');
|
|
378
|
+
}
|
|
379
|
+
if (!/^https?:\/\//i.test(baseUrl)) {
|
|
380
|
+
throw new Error(`OpenAI-compatible baseUrl must start with http:// or https:// (got "${this.config.baseUrl}").`);
|
|
381
|
+
}
|
|
382
|
+
const url = `${baseUrl.replace(/\/+$/, '')}${endpoint}`;
|
|
262
383
|
const headers = {
|
|
263
384
|
'Content-Type': 'application/json',
|
|
264
385
|
...this.config.headers,
|
|
@@ -287,26 +408,55 @@ export class OpenAIContentGenerator {
|
|
|
287
408
|
if (proxy) {
|
|
288
409
|
options.dispatcher = new ProxyAgent(proxy);
|
|
289
410
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
411
|
+
let attempt = 0;
|
|
412
|
+
while (true) {
|
|
413
|
+
attempt++;
|
|
414
|
+
try {
|
|
415
|
+
const response = await fetch(url, options);
|
|
416
|
+
if (response.ok) {
|
|
417
|
+
return response;
|
|
418
|
+
}
|
|
419
|
+
// Check for retryable errors (429, 503)
|
|
420
|
+
if (attempt < 3 &&
|
|
421
|
+
(response.status === 429 || response.status >= 500)) {
|
|
422
|
+
const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;
|
|
423
|
+
if (this.globalConfig.getDebugMode()) {
|
|
424
|
+
console.warn(`[OpenAI] Request failed with ${response.status}. Retrying in ${Math.round(delay)}ms (attempt ${attempt}/3)`);
|
|
425
|
+
}
|
|
426
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
const text = await response.text().catch(() => '');
|
|
430
|
+
throw new Error(`OpenAI compatible backend error (${response.status}): ${text}`);
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
if (attempt < 3) {
|
|
434
|
+
const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;
|
|
435
|
+
if (this.globalConfig.getDebugMode()) {
|
|
436
|
+
console.warn(`[OpenAI] Network error. Retrying in ${Math.round(delay)}ms (attempt ${attempt}/3)`, error);
|
|
437
|
+
}
|
|
438
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
throw error;
|
|
442
|
+
}
|
|
294
443
|
}
|
|
295
|
-
return response;
|
|
296
444
|
}
|
|
297
445
|
convertTools(tools) {
|
|
298
446
|
const openAITools = [];
|
|
299
447
|
for (const tool of tools) {
|
|
300
448
|
if (tool.functionDeclarations) {
|
|
301
449
|
for (const fn of tool.functionDeclarations) {
|
|
450
|
+
const parametersFromJsonSchema = this.getParametersJsonSchema(fn);
|
|
302
451
|
openAITools.push({
|
|
303
452
|
type: 'function',
|
|
304
453
|
function: {
|
|
305
|
-
name: fn.name || 'unknown_tool',
|
|
454
|
+
name: this.sanitizeToolName(fn.name || 'unknown_tool'),
|
|
306
455
|
description: fn.description,
|
|
307
|
-
parameters:
|
|
308
|
-
|
|
309
|
-
|
|
456
|
+
parameters: parametersFromJsonSchema ??
|
|
457
|
+
(fn.parameters
|
|
458
|
+
? this.convertSchemaToOpenAI(fn.parameters)
|
|
459
|
+
: undefined),
|
|
310
460
|
},
|
|
311
461
|
});
|
|
312
462
|
}
|
|
@@ -314,6 +464,32 @@ export class OpenAIContentGenerator {
|
|
|
314
464
|
}
|
|
315
465
|
return openAITools;
|
|
316
466
|
}
|
|
467
|
+
/**
|
|
468
|
+
* Sanitizes tool names for OpenAI function calling compatibility.
|
|
469
|
+
* OpenAI spec only allows: ^[a-zA-Z0-9_-]+$ (no dots, must not start with number)
|
|
470
|
+
* This converts names like "ui.click" → "ui_click" at the adapter level,
|
|
471
|
+
* keeping Gemini tool names unchanged in the core codebase.
|
|
472
|
+
* Records the mapping so we can reverse it when parsing model responses.
|
|
473
|
+
*/
|
|
474
|
+
sanitizeToolName(name) {
|
|
475
|
+
// Replace dots and other invalid characters with underscores
|
|
476
|
+
let sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
477
|
+
// Ensure name doesn't start with a number
|
|
478
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
479
|
+
sanitized = '_' + sanitized;
|
|
480
|
+
}
|
|
481
|
+
// Record mapping for reverse lookup
|
|
482
|
+
if (sanitized !== name) {
|
|
483
|
+
this.toolNameMap.set(sanitized, name);
|
|
484
|
+
}
|
|
485
|
+
return sanitized;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Reverses tool name sanitization to get original Gemini name.
|
|
489
|
+
*/
|
|
490
|
+
unsanitizeToolName(sanitizedName) {
|
|
491
|
+
return this.toolNameMap.get(sanitizedName) || sanitizedName;
|
|
492
|
+
}
|
|
317
493
|
convertSchemaToOpenAI(schema) {
|
|
318
494
|
// Convert Gemini Schema to JSON Schema format
|
|
319
495
|
// Gemini uses Type enum (OBJECT, STRING, etc.) while JSON Schema uses lowercase strings
|
|
@@ -424,9 +600,10 @@ export class OpenAIContentGenerator {
|
|
|
424
600
|
if (part.functionCall) {
|
|
425
601
|
const name = part.functionCall.name;
|
|
426
602
|
if (name) {
|
|
427
|
-
const id =
|
|
428
|
-
.
|
|
429
|
-
|
|
603
|
+
const id = part.functionCall.id ||
|
|
604
|
+
`call_${name}_${Date.now()}_${Math.random()
|
|
605
|
+
.toString(36)
|
|
606
|
+
.slice(2, 7)}`;
|
|
430
607
|
if (!toolCallIdStack[name])
|
|
431
608
|
toolCallIdStack[name] = [];
|
|
432
609
|
toolCallIdStack[name].push(id);
|
|
@@ -434,7 +611,7 @@ export class OpenAIContentGenerator {
|
|
|
434
611
|
id,
|
|
435
612
|
type: 'function',
|
|
436
613
|
function: {
|
|
437
|
-
name,
|
|
614
|
+
name: this.sanitizeToolName(name),
|
|
438
615
|
arguments: JSON.stringify(part.functionCall.args),
|
|
439
616
|
},
|
|
440
617
|
});
|
|
@@ -452,8 +629,15 @@ export class OpenAIContentGenerator {
|
|
|
452
629
|
}
|
|
453
630
|
// Standard text message
|
|
454
631
|
const textParts = (content.parts || [])
|
|
455
|
-
.
|
|
456
|
-
|
|
632
|
+
.map((p) => {
|
|
633
|
+
if ('thought' in p && p.thought) {
|
|
634
|
+
return `[Thought: ${p.thought}]\n`;
|
|
635
|
+
}
|
|
636
|
+
if ('text' in p && p.text) {
|
|
637
|
+
return p.text;
|
|
638
|
+
}
|
|
639
|
+
return '';
|
|
640
|
+
})
|
|
457
641
|
.join('');
|
|
458
642
|
messages.push({
|
|
459
643
|
role,
|
|
@@ -473,21 +657,29 @@ export class OpenAIContentGenerator {
|
|
|
473
657
|
if (message?.tool_calls) {
|
|
474
658
|
for (const toolCall of message.tool_calls) {
|
|
475
659
|
if (toolCall.type === 'function') {
|
|
476
|
-
let args = {};
|
|
477
660
|
try {
|
|
478
|
-
|
|
661
|
+
const parsedArgs = this.parseToolArguments(toolCall.function.arguments);
|
|
662
|
+
const args = parsedArgs ?? {};
|
|
663
|
+
parts.push({
|
|
664
|
+
functionCall: {
|
|
665
|
+
id: toolCall.id,
|
|
666
|
+
name: this.unsanitizeToolName(toolCall.function.name || ''),
|
|
667
|
+
args,
|
|
668
|
+
},
|
|
669
|
+
});
|
|
479
670
|
}
|
|
480
671
|
catch (e) {
|
|
481
672
|
if (this.globalConfig.getDebugMode()) {
|
|
482
673
|
console.error('[OpenAI Provider] Failed to parse function arguments:', e);
|
|
483
674
|
}
|
|
675
|
+
parts.push({
|
|
676
|
+
functionCall: {
|
|
677
|
+
id: toolCall.id,
|
|
678
|
+
name: this.unsanitizeToolName(toolCall.function.name || ''),
|
|
679
|
+
args: {},
|
|
680
|
+
},
|
|
681
|
+
});
|
|
484
682
|
}
|
|
485
|
-
parts.push({
|
|
486
|
-
functionCall: {
|
|
487
|
-
name: toolCall.function.name || '',
|
|
488
|
-
args,
|
|
489
|
-
},
|
|
490
|
-
});
|
|
491
683
|
}
|
|
492
684
|
}
|
|
493
685
|
}
|
|
@@ -501,6 +693,13 @@ export class OpenAIContentGenerator {
|
|
|
501
693
|
};
|
|
502
694
|
const response = new GenerateContentResponse();
|
|
503
695
|
response.candidates = [candidate];
|
|
696
|
+
if (data.usage) {
|
|
697
|
+
response.usageMetadata = {
|
|
698
|
+
promptTokenCount: data.usage.prompt_tokens,
|
|
699
|
+
candidatesTokenCount: data.usage.completion_tokens,
|
|
700
|
+
totalTokenCount: data.usage.total_tokens,
|
|
701
|
+
};
|
|
702
|
+
}
|
|
504
703
|
return response;
|
|
505
704
|
}
|
|
506
705
|
}
|