@robota-sdk/agent-provider 3.0.0-beta.65 → 3.0.0-beta.67
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/README.md +89 -0
- package/dist/browser/index.d.ts +5 -2
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +3 -3
- package/dist/browser/index.js.map +1 -1
- package/dist/loggers/index.d.ts.map +1 -1
- package/dist/loggers/index.js.map +1 -1
- package/dist/node/anthropic/index.d.ts +1 -1
- package/dist/node/anthropic/index.d.ts.map +1 -1
- package/dist/node/anthropic--1vgLC-e.js.map +1 -1
- package/dist/node/bytedance/index.d.ts.map +1 -1
- package/dist/node/bytedance-C_0sF_pJ.js.map +1 -1
- package/dist/node/deepseek-_8Ixx7rA.js.map +1 -1
- package/dist/node/gemini/index.d.ts.map +1 -1
- package/dist/node/gemini-Bh2U87MY.js.map +1 -1
- package/dist/node/gemma/index.cjs +1 -1
- package/dist/node/gemma/index.d.ts +1 -1
- package/dist/node/gemma/index.js +1 -1
- package/dist/node/{gemma-G-Pf_PnX.cjs → gemma-079LPvrN.cjs} +1 -1
- package/dist/node/gemma-BMFWnmXE.js +2 -0
- package/dist/node/gemma-BMFWnmXE.js.map +1 -0
- package/dist/node/google/index.d.ts.map +1 -1
- package/dist/node/google/index.js.map +1 -1
- package/dist/node/index-B6PnlDMd.d.ts.map +1 -1
- package/dist/node/index-B7UvPJcI.d.ts.map +1 -1
- package/dist/node/{index-C3beaqKO.d.ts → index-B9a2gTwI.d.ts} +3 -3
- package/dist/node/{index-BqixM_XD.d.ts.map → index-B9a2gTwI.d.ts.map} +1 -1
- package/dist/node/index-BLPOTNb5.d.ts.map +1 -1
- package/dist/node/{index-BqixM_XD.d.ts → index-CjPeNJ1G.d.ts} +3 -3
- package/dist/node/{index-C3beaqKO.d.ts.map → index-CjPeNJ1G.d.ts.map} +1 -1
- package/dist/node/index-Cp2XRh9G.d.ts.map +1 -1
- package/dist/node/index-DSv5xruI.d.ts.map +1 -1
- package/dist/node/index-w0bV1uaP.d.ts.map +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.d.ts +11 -5
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -1
- package/dist/node/index.js.map +1 -0
- package/dist/node/openai/index.cjs +1 -1
- package/dist/node/openai/index.d.ts +1 -1
- package/dist/node/openai/index.js +1 -1
- package/dist/node/openai--CyyQ-E4.js +2 -0
- package/dist/node/openai--CyyQ-E4.js.map +1 -0
- package/dist/node/{openai-xWC6pY7r.cjs → openai-CmuDu5k-.cjs} +1 -1
- package/dist/node/openai-compatible-Dm4Sof9e.js.map +1 -1
- package/dist/node/qwen/index.cjs +1 -1
- package/dist/node/qwen/index.d.ts +1 -1
- package/dist/node/qwen/index.js +1 -1
- package/dist/node/qwen-D8gtsbsC.js +2 -0
- package/dist/node/qwen-D8gtsbsC.js.map +1 -0
- package/dist/node/qwen-DxNnm7Le.cjs +1 -0
- package/package.json +4 -2
- package/src/anthropic/index.ts +1 -1
- package/src/anthropic/message-converter.ts +3 -2
- package/src/anthropic/model-catalog-refresh.ts +5 -4
- package/src/anthropic/parsers/response-parser.ts +5 -2
- package/src/anthropic/provider-definition.ts +2 -1
- package/src/anthropic/provider.ts +6 -3
- package/src/anthropic/streaming-handler.ts +4 -2
- package/src/anthropic/types.ts +1 -1
- package/src/bytedance/http-client.ts +1 -1
- package/src/bytedance/provider.spec.ts +1 -0
- package/src/bytedance/provider.ts +10 -9
- package/src/bytedance/status-mapper.ts +1 -1
- package/src/deepseek/model-catalog-refresh.ts +6 -5
- package/src/deepseek/model-catalog.ts +2 -1
- package/src/deepseek/provider-definition.ts +3 -2
- package/src/deepseek/provider.ts +11 -9
- package/src/deepseek/types.ts +1 -1
- package/src/default-provider-definitions.ts +19 -0
- package/src/gemini/execution-helpers.ts +14 -12
- package/src/gemini/image-operations.ts +2 -2
- package/src/gemini/message-converter.ts +1 -0
- package/src/gemini/model-catalog-refresh.ts +2 -1
- package/src/gemini/provider-definition.ts +2 -1
- package/src/gemini/provider.spec.ts +2 -0
- package/src/gemini/provider.ts +6 -3
- package/src/gemini/tool-schema-converter.ts +1 -0
- package/src/gemma/message-factory.ts +2 -1
- package/src/gemma/provider-definition.ts +3 -2
- package/src/gemma/provider-projection.ts +4 -3
- package/src/gemma/provider.ts +19 -17
- package/src/gemma/pseudo-command-envelope.ts +1 -0
- package/src/gemma/pseudo-tool-call-projector.ts +2 -1
- package/src/gemma/streaming-projection.ts +6 -4
- package/src/gemma/tool-call-projector.ts +4 -3
- package/src/gemma/types.ts +1 -1
- package/src/google/provider.ts +1 -0
- package/src/index.ts +2 -0
- package/src/openai/adapter.ts +1 -1
- package/src/openai/chat-completions-chat.ts +8 -7
- package/src/openai/loggers/console-payload-logger.ts +4 -2
- package/src/openai/loggers/file-payload-logger.ts +5 -2
- package/src/openai/message-converter.ts +3 -2
- package/src/openai/openai-request-format.ts +1 -1
- package/src/openai/parsers/response-parser.ts +3 -2
- package/src/openai/provider-definition.ts +3 -2
- package/src/openai/provider.ts +11 -9
- package/src/openai/responses-chat.ts +7 -5
- package/src/openai/responses-converter.ts +6 -6
- package/src/openai/responses-parser.ts +4 -2
- package/src/openai/responses-types.ts +1 -1
- package/src/openai/streaming/stream-handler.ts +6 -4
- package/src/openai/types.ts +1 -2
- package/src/qwen/model-catalog-refresh.ts +6 -5
- package/src/qwen/provider-capabilities.ts +1 -1
- package/src/qwen/provider-definition.ts +6 -5
- package/src/qwen/provider-streaming-assembly.ts +3 -2
- package/src/qwen/provider.ts +19 -12
- package/src/qwen/responses-chat.ts +8 -6
- package/src/qwen/responses-converter.ts +1 -1
- package/src/qwen/responses-parser.ts +4 -2
- package/src/qwen/types.ts +1 -1
- package/src/shared/openai-compatible/message-converter.ts +1 -1
- package/src/shared/openai-compatible/response-parser.ts +4 -2
- package/src/shared/openai-compatible/stream-assembler.ts +3 -2
- package/src/shared/openai-compatible/types.ts +1 -1
- package/dist/node/gemma-Dp_AfCUR.js +0 -2
- package/dist/node/gemma-Dp_AfCUR.js.map +0 -1
- package/dist/node/openai-CRQjg4xF.js +0 -2
- package/dist/node/openai-CRQjg4xF.js.map +0 -1
- package/dist/node/qwen-ChUZobTL.js +0 -2
- package/dist/node/qwen-ChUZobTL.js.map +0 -1
- package/dist/node/qwen-CjT71vSM.cjs +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-Bh2U87MY.js","names":[],"sources":["../../src/gemini/image-operations.ts","../../src/gemini/request-converter.ts","../../src/gemini/tool-schema-converter.ts","../../src/gemini/message-converter.ts","../../src/gemini/execution-helpers.ts","../../src/gemini/provider.ts","../../src/gemini/provider-definition.ts","../../src/gemini/model-catalog-refresh.ts"],"sourcesContent":["import type {\n TUniversalMessage,\n TUniversalMessagePart,\n IMediaOutputRef,\n IImageEditRequest,\n IImageComposeRequest,\n TProviderMediaResult,\n IChatOptions,\n} from '@robota-sdk/agent-core';\nimport type { GenerateContentParameters } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\n\n/** Checks whether the given parts contain an image part. */\nexport function hasImagePart(parts: TUniversalMessagePart[] | undefined): boolean {\n if (!parts) {\n return false;\n }\n return parts.some((part) => part.type === 'image_inline' || part.type === 'image_uri');\n}\n\n/** Extracts inline image parts from a message and converts them to media output references. */\nexport function mapInlineImagePartsToMediaOutputs(\n parts: TUniversalMessagePart[] | undefined,\n): IMediaOutputRef[] {\n if (!parts) {\n return [];\n }\n const outputs: IMediaOutputRef[] = [];\n for (const part of parts) {\n if (part.type !== 'image_inline') {\n continue;\n }\n outputs.push({\n kind: 'uri',\n uri: `data:${part.mimeType};base64,${part.data}`,\n mimeType: part.mimeType,\n });\n }\n return outputs;\n}\n\n/** Parses a data URI into its MIME type and base64 payload. */\nexport function parseDataUri(uri: string): { mimeType: string; data: string } | undefined {\n const commaIndex = uri.indexOf(',');\n if (commaIndex < 0) {\n return undefined;\n }\n const header = uri.slice(0, commaIndex);\n const payload = uri.slice(commaIndex + 1);\n if (!header.endsWith(';base64')) {\n return undefined;\n }\n const mimeType = header.replace('data:', '').replace(';base64', '').trim();\n if (mimeType.length === 0 || payload.trim().length === 0) {\n return undefined;\n }\n return {\n mimeType,\n data: payload,\n };\n}\n\n/** Maps an image input source (inline or URI) to a universal message part. */\nexport function mapImageInputSourceToPart(\n source: IImageEditRequest['image'] | IImageComposeRequest['images'][number],\n): TProviderMediaResult<TUniversalMessagePart> {\n if (source.kind === 'inline') {\n if (source.mimeType.trim().length === 0 || source.data.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Inline image source requires non-empty mimeType and data.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: source.mimeType,\n data: source.data,\n },\n };\n }\n if (!source.uri.startsWith('data:')) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Google image provider supports only inline or data URI input sources.',\n },\n };\n }\n const parsedResult = parseDataUri(source.uri);\n if (!parsedResult) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Data URI source must use base64 payload.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: parsedResult.mimeType,\n data: parsedResult.data,\n },\n };\n}\n\n/** Determines which response modalities to request from the Gemini API. */\nexport function buildResponseModalities(\n messages: TUniversalMessage[],\n defaultModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n optionModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n): Array<'TEXT' | 'IMAGE'> {\n if (optionModalities && optionModalities.length > 0) {\n return optionModalities;\n }\n const hasImageInput = messages.some((message) => hasImagePart(message.parts));\n if (hasImageInput) {\n return ['TEXT', 'IMAGE'];\n }\n if (defaultModalities && defaultModalities.length > 0) {\n return defaultModalities;\n }\n return ['TEXT'];\n}\n\n/** Checks whether the specified model is configured as image-capable. */\nexport function isImageCapableModel(\n model: string,\n configuredImageModels: string[] | undefined,\n): boolean {\n if (!configuredImageModels || configuredImageModels.length === 0) {\n return true;\n }\n return configuredImageModels.includes(model);\n}\n\n/** Builds the Gemini generation config including response modalities. */\nexport function buildGenerationConfig(\n messages: TUniversalMessage[],\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): NonNullable<GenerateContentParameters['config']> {\n assertCompatibleStructuredOutputOptions(providerOptions);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n validateImageCapableModel(options?.model, responseModalities, providerOptions);\n const config: NonNullable<GenerateContentParameters['config']> = { responseModalities };\n applyChatOptions(config, options);\n applySafetySettings(config, providerOptions, options);\n applyStructuredOutputOptions(config, providerOptions);\n applyProviderGenerationOptions(config, providerOptions);\n return config;\n}\n\nfunction validateImageCapableModel(\n model: string | undefined,\n responseModalities: Array<'TEXT' | 'IMAGE'>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (!model || !responseModalities.includes('IMAGE')) {\n return;\n }\n if (isImageCapableModel(model, providerOptions.imageCapableModels)) {\n return;\n }\n throw new Error(\n `Selected model \"${model}\" is not configured as image-capable for Google provider.`,\n );\n}\n\nfunction applyChatOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n options?: IChatOptions,\n): void {\n if (typeof options?.temperature === 'number') {\n config.temperature = options.temperature;\n }\n if (typeof options?.maxTokens === 'number') {\n config.maxOutputTokens = options.maxTokens;\n }\n if (typeof options?.google?.topP === 'number') {\n config.topP = options.google.topP;\n }\n if (typeof options?.google?.topK === 'number') {\n config.topK = options.google.topK;\n }\n if (typeof options?.google?.candidateCount === 'number') {\n config.candidateCount = options.google.candidateCount;\n }\n if (options?.google?.stopSequences && options.google.stopSequences.length > 0) {\n config.stopSequences = options.google.stopSequences;\n }\n if (options?.signal) {\n config.abortSignal = options.signal;\n }\n}\n\nfunction applySafetySettings(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): void {\n const safetySettings = options?.google?.safetySettings ?? providerOptions.safetySettings;\n if (safetySettings && safetySettings.length > 0) {\n config.safetySettings = safetySettings as NonNullable<\n GenerateContentParameters['config']\n >['safetySettings'];\n }\n}\n\nfunction applyStructuredOutputOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.responseMimeType) {\n config.responseMimeType = providerOptions.responseMimeType;\n }\n if (providerOptions.responseSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseSchema = providerOptions.responseSchema;\n }\n if (providerOptions.responseJsonSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseJsonSchema = providerOptions.responseJsonSchema;\n }\n}\n\nfunction applyProviderGenerationOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.thinkingConfig) {\n config.thinkingConfig = providerOptions.thinkingConfig as NonNullable<\n GenerateContentParameters['config']\n >['thinkingConfig'];\n }\n if (providerOptions.toolConfig) {\n config.toolConfig = providerOptions.toolConfig as NonNullable<\n GenerateContentParameters['config']\n >['toolConfig'];\n }\n}\n\nfunction assertCompatibleStructuredOutputOptions(providerOptions: IGeminiProviderOptions): void {\n if (providerOptions.responseSchema && providerOptions.responseJsonSchema) {\n throw new Error(\n 'Gemini structured output options responseSchema and responseJsonSchema are mutually exclusive.',\n );\n }\n}\n","import type { Content, Part } from '@google/genai';\nimport type {\n IAssistantMessage,\n ISystemMessage,\n IToolMessage,\n IUserMessage,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\ntype TGoogleJsonValue = string | number | boolean | null | TGoogleJsonValue[] | IGoogleJsonObject;\n\ninterface IGoogleJsonObject {\n readonly [key: string]: TGoogleJsonValue;\n}\n\nexport interface IGeminiMessageConversionResult {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/**\n * Maps universal message parts to Gemini-compatible parts.\n * Supports text and inline image parts; throws on unsupported part types.\n */\nexport function mapMessagePartsToGeminiParts(\n message: IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage,\n): Part[] {\n const parts: Part[] = [];\n const messageParts = message.parts ?? [];\n for (const part of messageParts) {\n if (part.type === 'text') {\n parts.push({ text: part.text });\n continue;\n }\n if (part.type === 'image_inline') {\n parts.push({\n inlineData: {\n mimeType: part.mimeType,\n data: part.data,\n },\n });\n continue;\n }\n throw new Error(`Google provider does not support image URI parts directly: ${part.uri}`);\n }\n if (parts.length === 0 && typeof message.content === 'string' && message.content.length > 0) {\n parts.push({ text: message.content });\n }\n return parts;\n}\n\n/**\n * Converts an array of universal messages to the Gemini Content format.\n *\n * IMPORTANT: Google Gemini allows content with function calls.\n * Content can be empty string or text, but NOT null.\n */\nexport function convertToGeminiFormat(messages: TUniversalMessage[]): Content[] {\n return convertToGeminiRequestFormat(messages).contents;\n}\n\n/**\n * Converts universal messages into Gemini request content plus request config\n * fields. Gemini system instructions are request-level config, not user turns.\n */\nexport function convertToGeminiRequestFormat(\n messages: TUniversalMessage[],\n): IGeminiMessageConversionResult {\n const contents: Content[] = [];\n const systemInstructionParts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n contents.push({\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n });\n continue;\n }\n if (msg.role === 'assistant') {\n contents.push(convertAssistantMessage(msg as IAssistantMessage));\n continue;\n }\n if (msg.role === 'tool') {\n contents.push(convertToolMessage(msg as IToolMessage));\n continue;\n }\n\n const systemInstruction = extractSystemInstructionText(msg as ISystemMessage);\n if (systemInstruction.length > 0) {\n systemInstructionParts.push(systemInstruction);\n }\n }\n\n return {\n contents,\n ...(systemInstructionParts.length > 0 && {\n systemInstruction: systemInstructionParts.join('\\n'),\n }),\n };\n}\n\n/**\n * Converts all messages to Gemini contents, including system instructions as\n * user content. This exists only for compatibility with callers that still need\n * a contents-only value.\n */\nexport function convertToGeminiFormatWithInlineSystem(messages: TUniversalMessage[]): Content[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n };\n }\n if (msg.role === 'assistant') {\n return convertAssistantMessage(msg as IAssistantMessage);\n }\n if (msg.role === 'tool') {\n const toolMessage = msg as IToolMessage;\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(toolMessage),\n };\n }\n const systemMessage = msg as ISystemMessage;\n const systemParts = mapMessagePartsToGeminiParts(systemMessage);\n if (systemParts.length === 0) {\n systemParts.push({ text: `System: ${systemMessage.content || ''}` });\n }\n return {\n role: 'user',\n parts: systemParts,\n };\n });\n}\n\nfunction convertAssistantMessage(assistantMsg: IAssistantMessage): Content {\n const parts: Part[] = [];\n const mappedAssistantParts = mapMessagePartsToGeminiParts(assistantMsg);\n for (const mappedPart of mappedAssistantParts) {\n parts.push(mappedPart);\n }\n if (parts.length === 0 && assistantMsg.content) {\n parts.push({ text: assistantMsg.content });\n }\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n assistantMsg.toolCalls.forEach((tc) => {\n parts.push({\n functionCall: {\n id: tc.id,\n name: tc.function.name,\n args: parseToolCallArguments(tc.function.arguments),\n },\n });\n });\n }\n return {\n role: 'model',\n parts,\n };\n}\n\nfunction convertToolMessage(toolMessage: IToolMessage): Content {\n const functionResponse = {\n id: toolMessage.toolCallId,\n name: requireToolMessageName(toolMessage),\n response: parseToolResponseContent(toolMessage.content),\n };\n return {\n role: 'user',\n parts: [{ functionResponse }],\n };\n}\n\nfunction extractSystemInstructionText(systemMessage: ISystemMessage): string {\n const parts = mapMessagePartsToGeminiParts(systemMessage);\n if (parts.length === 0) {\n return systemMessage.content;\n }\n const textParts: string[] = [];\n for (const part of parts) {\n if (typeof part.text === 'string') {\n textParts.push(part.text);\n continue;\n }\n throw new Error('Google provider system instructions support only text parts.');\n }\n return textParts.join('\\n');\n}\n\nfunction requireToolMessageName(toolMessage: IToolMessage): string {\n const toolName = toolMessage.name?.trim();\n if (!toolName) {\n throw new Error('Google provider tool message requires a function name.');\n }\n return toolName;\n}\n\nfunction parseToolCallArguments(serializedArguments: string): IGoogleJsonObject {\n const parsedArguments = JSON.parse(serializedArguments) as TGoogleJsonValue;\n if (!isJsonObject(parsedArguments)) {\n throw new Error('Google provider tool call arguments must be a JSON object.');\n }\n return parsedArguments;\n}\n\nfunction parseToolResponseContent(content: string): IGoogleJsonObject {\n const trimmedContent = content.trim();\n if (trimmedContent.length === 0) {\n return { output: null };\n }\n try {\n const parsedContent = JSON.parse(trimmedContent) as TGoogleJsonValue;\n if (isJsonObject(parsedContent)) {\n return parsedContent;\n }\n return { output: parsedContent };\n } catch {\n return { output: content };\n }\n}\n\nfunction isJsonObject(value: TGoogleJsonValue): value is IGoogleJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { Type } from '@google/genai';\nimport type { FunctionDeclaration, Schema } from '@google/genai';\nimport type { IParameterSchema, IToolSchema, TJSONSchemaKind } from '@robota-sdk/agent-core';\n\nconst GOOGLE_SCHEMA_TYPE_BY_JSON_KIND: Record<Exclude<TJSONSchemaKind, 'null'>, Type> = {\n string: Type.STRING,\n number: Type.NUMBER,\n integer: Type.INTEGER,\n boolean: Type.BOOLEAN,\n array: Type.ARRAY,\n object: Type.OBJECT,\n};\n\n/** Converts Robota tool schemas to Gemini function declarations. */\nexport function convertToolsToGeminiFormat(tools: IToolSchema[]): FunctionDeclaration[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: {\n type: Type.OBJECT,\n properties: convertParameterProperties(tool.parameters.properties),\n required: tool.parameters.required,\n },\n }));\n}\n\nfunction convertParameterProperties(\n properties: Record<string, IParameterSchema>,\n): Record<string, Schema> {\n const convertedProperties: Record<string, Schema> = {};\n for (const [key, value] of Object.entries(properties)) {\n convertedProperties[key] = convertParameterSchema(value);\n }\n return convertedProperties;\n}\n\nfunction convertParameterSchema(schema: IParameterSchema): Schema {\n const convertedSchema: Schema = {};\n const schemaType = convertSchemaKind(schema.type);\n if (schemaType) {\n convertedSchema.type = schemaType;\n }\n if (schema.description) {\n convertedSchema.description = schema.description;\n }\n if (schema.enum) {\n convertedSchema.enum = schema.enum.map(String);\n }\n if (schema.items) {\n convertedSchema.items = convertParameterSchema(schema.items);\n }\n if (schema.properties) {\n convertedSchema.properties = convertParameterProperties(schema.properties);\n }\n if (typeof schema.minimum === 'number') {\n convertedSchema.minimum = schema.minimum;\n }\n if (typeof schema.maximum === 'number') {\n convertedSchema.maximum = schema.maximum;\n }\n if (schema.pattern) {\n convertedSchema.pattern = schema.pattern;\n }\n if (schema.format) {\n convertedSchema.format = schema.format;\n }\n if (schema.default !== undefined) {\n convertedSchema.default = schema.default;\n }\n return convertedSchema;\n}\n\nfunction convertSchemaKind(kind: TJSONSchemaKind): Type | undefined {\n if (kind === 'null') {\n return undefined;\n }\n return GOOGLE_SCHEMA_TYPE_BY_JSON_KIND[kind];\n}\n","import { randomUUID } from 'node:crypto';\nimport type { Part, FunctionCall, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IAssistantMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nconst RANDOM_ID_RADIX = 36;\nconst RANDOM_ID_LENGTH = 9;\n\ninterface ICollectedGeminiParts {\n textValues: string[];\n messageParts: TUniversalMessagePart[];\n functionCalls: FunctionCall[];\n}\n\nexport {\n convertToGeminiFormat,\n convertToGeminiFormatWithInlineSystem,\n convertToGeminiRequestFormat,\n mapMessagePartsToGeminiParts,\n} from './request-converter';\nexport type { IGeminiMessageConversionResult } from './request-converter';\n\n/** Generates a unique call identifier for function call responses. */\nexport function generateCallId(): string {\n return `call_${Date.now()}_${Math.random().toString(RANDOM_ID_RADIX).substr(2, RANDOM_ID_LENGTH)}`;\n}\n\n/** Converts a Gemini API response into a universal message. */\nexport function convertFromGeminiResponse(response: GenerateContentResponse): TUniversalMessage {\n const candidate = response.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidate in Gemini response');\n }\n\n const content = candidate.content;\n if (!content || !content.parts || content.parts.length === 0) {\n throw new Error('No content in Gemini response');\n }\n\n const collectedParts = collectGeminiParts(content.parts);\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n state: 'complete' as const,\n role: 'assistant',\n content: collectedParts.textValues.length > 0 ? collectedParts.textValues.join('') : null,\n parts: collectedParts.messageParts,\n timestamp: new Date(),\n };\n\n if (collectedParts.functionCalls.length > 0) {\n const assistantResult = result as IAssistantMessage;\n assistantResult.toolCalls = collectedParts.functionCalls.map((fc) => ({\n id: fc.id ?? generateCallId(),\n type: 'function' as const,\n function: {\n name: requireFunctionCallName(fc),\n arguments: JSON.stringify(fc.args ?? {}),\n },\n }));\n }\n\n const usageMetadata = mapUsageMetadata(response);\n if (usageMetadata) {\n result.metadata = usageMetadata;\n }\n\n return result;\n}\n\nfunction collectGeminiParts(parts: Part[]): ICollectedGeminiParts {\n const textValues: string[] = [];\n const messageParts: TUniversalMessagePart[] = [];\n const functionCalls: FunctionCall[] = [];\n\n for (const part of parts) {\n collectTextPart(part, textValues, messageParts);\n collectInlineImagePart(part, messageParts);\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n\n return { textValues, messageParts, functionCalls };\n}\n\nfunction collectTextPart(\n part: Part,\n textValues: string[],\n messageParts: TUniversalMessagePart[],\n): void {\n if (typeof part.text !== 'string') {\n return;\n }\n textValues.push(part.text);\n messageParts.push({ type: 'text', text: part.text });\n}\n\nfunction collectInlineImagePart(part: Part, messageParts: TUniversalMessagePart[]): void {\n if (\n !part.inlineData ||\n typeof part.inlineData.data !== 'string' ||\n typeof part.inlineData.mimeType !== 'string'\n ) {\n return;\n }\n messageParts.push({\n type: 'image_inline',\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n });\n}\n\nfunction mapUsageMetadata(response: GenerateContentResponse): TUniversalMessage['metadata'] {\n if (\n !response.usageMetadata ||\n typeof response.usageMetadata.promptTokenCount !== 'number' ||\n typeof response.usageMetadata.candidatesTokenCount !== 'number' ||\n typeof response.usageMetadata.totalTokenCount !== 'number'\n ) {\n return undefined;\n }\n return {\n promptTokens: response.usageMetadata.promptTokenCount,\n completionTokens: response.usageMetadata.candidatesTokenCount,\n totalTokens: response.usageMetadata.totalTokenCount,\n };\n}\n\nexport { convertToolsToGeminiFormat } from './tool-schema-converter';\n\nfunction requireFunctionCallName(functionCall: FunctionCall): string {\n if (!functionCall.name || functionCall.name.trim().length === 0) {\n throw new Error('Gemini function call is missing a function name.');\n }\n return functionCall.name;\n}\n","import { randomUUID } from 'node:crypto';\nimport type { GoogleGenAI } from '@google/genai';\nimport type { Content, GenerateContentParameters, GenerateContentResponse } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\nimport {\n convertToGeminiRequestFormat,\n convertFromGeminiResponse,\n convertToolsToGeminiFormat,\n} from './message-converter';\nimport {\n hasImagePart,\n mapInlineImagePartsToMediaOutputs,\n buildResponseModalities,\n buildGenerationConfig,\n} from './image-operations';\n\n/**\n * Execute a direct (non-streaming) chat request against the Gemini API.\n */\nexport async function executeDirect(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n\n if (options?.onTextDelta && !responseModalities.includes('IMAGE')) {\n return assembleStreamingChatResponse(client, providerOptions, messages, options, providerName);\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const result = await client.models.generateContent(request);\n emitGeminiNativeRawPayload(options, providerName, 'response', result);\n\n const convertedResponse = convertFromGeminiResponse(result);\n if (responseModalities.includes('IMAGE') && !hasImagePart(convertedResponse.parts)) {\n throw new Error(\n 'Gemini response did not include an image part while IMAGE modality was requested.',\n );\n }\n return convertedResponse;\n}\n\n/**\n * Execute a streaming chat request against the Gemini API.\n */\nexport async function* executeDirectStream(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): AsyncIterable<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n if (responseModalities.includes('IMAGE')) {\n throw new Error('Google provider does not support streaming image modality responses.');\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const stream = await client.models.generateContentStream(request);\n\n let sequence = 0;\n for await (const chunk of stream) {\n emitGeminiNativeRawPayload(options, providerName, 'stream_event', chunk, sequence);\n sequence++;\n const text = extractStreamText(chunk);\n if (text) {\n options?.onTextDelta?.(text);\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n}\n\nfunction buildGenerateContentRequest(\n model: string,\n contents: Content[],\n generationOptions: GenerateContentParameters['config'],\n options?: IChatOptions,\n systemInstruction?: string,\n): GenerateContentParameters {\n const config: GenerateContentParameters['config'] = { ...generationOptions };\n if (options?.tools && options.tools.length > 0) {\n config.tools = [{ functionDeclarations: convertToolsToGeminiFormat(options.tools) }];\n }\n if (systemInstruction) {\n config.systemInstruction = systemInstruction;\n }\n return {\n model,\n contents,\n config,\n };\n}\n\nfunction resolveGeminiModel(\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): string {\n const model = options?.model ?? providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n return model;\n}\n\nasync function assembleStreamingChatResponse(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const textParts: string[] = [];\n for await (const chunk of executeDirectStream(\n client,\n providerOptions,\n messages,\n options,\n providerName,\n )) {\n if (typeof chunk.content === 'string') {\n textParts.push(chunk.content);\n }\n }\n const content = textParts.join('');\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n parts: content.length > 0 ? [{ type: 'text', text: content }] : [],\n state: 'complete',\n timestamp: new Date(),\n };\n}\n\nfunction emitGeminiNativeRawPayload(\n options: IChatOptions | undefined,\n providerName: string,\n payloadKind: 'request' | 'response' | 'stream_event',\n payload: object,\n sequence?: number,\n): void {\n options?.onProviderNativeRawPayload?.({\n provider: providerName,\n apiSurface: 'gemini-generate-content',\n payloadKind,\n ...(sequence !== undefined && { sequence }),\n payload,\n });\n}\n\nfunction extractStreamText(\n chunk: GenerateContentResponse | { readonly text?: () => string },\n): string | undefined {\n const textValue = chunk.text;\n return typeof textValue === 'function' ? textValue() : textValue;\n}\n\n/**\n * Run an image generation request through the chat API.\n */\nexport async function runImageRequest(\n chatFn: (messages: TUniversalMessage[], options?: IChatOptions) => Promise<TUniversalMessage>,\n messages: TUniversalMessage[],\n model: string,\n): Promise<TProviderMediaResult<IImageGenerationResult>> {\n try {\n const response = await chatFn(messages, {\n model,\n google: { responseModalities: ['TEXT', 'IMAGE'] },\n });\n const outputs = mapInlineImagePartsToMediaOutputs(response.parts);\n if (outputs.length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Google image response did not include image output parts.',\n },\n };\n }\n return { ok: true, value: { outputs, model } };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google image request failed.';\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message: errorMessage } };\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { GoogleGenAI } from '@google/genai';\nimport type { IGeminiProviderOptions } from './types';\nimport { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport type {\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n TUniversalMessagePart,\n IImageGenerationProvider,\n IImageGenerationRequest,\n IImageEditRequest,\n IImageComposeRequest,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\nimport { mapImageInputSourceToPart } from './image-operations';\nimport { executeDirect, executeDirectStream, runImageRequest } from './execution-helpers';\n\n/**\n * Gemini provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Google Gemini API:\n * - Function calls can have content (text) along with function calls\n * - Content can be empty string or actual text, NOT null\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class GeminiProvider extends AbstractAIProvider implements IImageGenerationProvider {\n override readonly name: string = 'gemini';\n override readonly version = '1.0.0';\n public onTextDelta?: TTextDeltaCallback;\n\n private readonly client?: GoogleGenAI;\n private readonly options: IGeminiProviderOptions;\n\n constructor(options: IGeminiProviderOptions) {\n super();\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n this.client = new GoogleGenAI({ apiKey: options.apiKey });\n }\n }\n\n /** Generate response using TUniversalMessage */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n return await executeDirect(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google chat failed: ${errorMessage}`);\n }\n }\n\n /** Generate streaming response using TUniversalMessage */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n yield* executeDirectStream(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google stream failed: ${errorMessage}`);\n }\n }\n\n /** Generate an image from a text prompt using the Gemini API. */\n public async generateImage(\n request: IImageGenerationRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty model.',\n },\n };\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [{ type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Edit an existing image based on a text prompt using the Gemini API. */\n public async editImage(\n request: IImageEditRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty model.',\n },\n };\n }\n\n const inputPartResult = mapImageInputSourceToPart(request.image);\n if (!inputPartResult.ok) {\n return inputPartResult;\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [inputPartResult.value, { type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Compose multiple images together based on a text prompt using the Gemini API. */\n public async composeImage(\n request: IImageComposeRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty model.',\n },\n };\n }\n if (request.images.length < 2) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires at least two input images.',\n },\n };\n }\n\n const messageParts: TUniversalMessagePart[] = [];\n for (const imageSource of request.images) {\n const mappedPartResult = mapImageInputSourceToPart(imageSource);\n if (!mappedPartResult.ok) {\n return mappedPartResult;\n }\n messageParts.push(mappedPartResult.value);\n }\n messageParts.push({ type: 'text', text: request.prompt });\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: messageParts,\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override validateConfig(): boolean {\n if (this.executor) {\n return this.executor.validateConfig();\n }\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Google client does not need explicit cleanup\n }\n\n private withProviderCallbacks(options?: IChatOptions): IChatOptions | undefined {\n const onTextDelta = options?.onTextDelta ?? this.onTextDelta;\n if (!onTextDelta) {\n return options;\n }\n return {\n ...options,\n onTextDelta,\n };\n }\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport { refreshGeminiModelCatalog } from './model-catalog-refresh';\nimport { GeminiProvider } from './provider';\n\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_ENV = 'GEMINI_API_KEY';\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_GEMINI_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_GEMINI_PROVIDER_MODEL = 'gemini-3-flash-preview';\nexport const GEMINI_MODEL_SOURCE_URL = 'https://ai.google.dev/api/models';\nexport const GEMINI_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMINI_API_KEY_URL = 'https://aistudio.google.com/apikey';\nconst GEMINI_SETUP_SOURCE_URL = 'https://ai.google.dev/gemini-api/docs/api-key';\nconst GEMINI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMINI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Google AI Studio API keys',\n url: GEMINI_API_KEY_URL,\n sourceUrl: GEMINI_SETUP_SOURCE_URL,\n lastVerifiedAt: GEMINI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createGeminiProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemini',\n aliases: ['google'],\n displayName: 'Gemini',\n description: 'Google Gemini API provider',\n defaults: {\n model: DEFAULT_GEMINI_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMINI_PROVIDER_MODEL,\n displayName: 'Gemini 3 Flash Preview',\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'preview',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n },\n ],\n },\n setupHelpLinks: GEMINI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'Gemini model',\n defaultValue: DEFAULT_GEMINI_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemini API key',\n defaultValue: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n refreshModelCatalog: ({ profile }) => refreshGeminiModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) =>\n new GeminiProvider({\n apiKey: requireApiKey(config.apiKey),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemini requires apiKey');\n }\n return apiKey;\n}\n","import type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\nimport { GEMINI_MODEL_LAST_VERIFIED_AT, GEMINI_MODEL_SOURCE_URL } from './provider-definition';\n\nconst GEMINI_API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models';\n\nexport interface IGeminiModelInfo {\n name?: string;\n displayName?: string;\n description?: string;\n inputTokenLimit?: number;\n outputTokenLimit?: number;\n supportedGenerationMethods?: string[];\n}\n\nexport interface IGeminiModelsResponse {\n models?: IGeminiModelInfo[];\n nextPageToken?: string;\n}\n\nexport interface IGeminiFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IGeminiFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IGeminiModelsResponse>;\n}\n\nexport type TGeminiFetch = (url: string, init?: IGeminiFetchInit) => Promise<IGeminiFetchResponse>;\n\nexport async function refreshGeminiModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TGeminiFetch = defaultGeminiFetch,\n): Promise<IProviderModelCatalog> {\n const url = profile.apiKey ? `${GEMINI_API_ENDPOINT}?key=${profile.apiKey}` : GEMINI_API_ENDPOINT;\n\n const response = await fetcher(url);\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n message: `Gemini model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.models ?? []).filter(supportsGenerateContent).map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: new Date().toISOString(),\n entries,\n message: `Fetched ${entries.length} Gemini models`,\n };\n}\n\nfunction supportsGenerateContent(model: IGeminiModelInfo): boolean {\n return model.supportedGenerationMethods?.includes('generateContent') === true;\n}\n\nfunction toModelCatalogEntry(model: IGeminiModelInfo): IProviderModelCatalogEntry {\n const rawName = model.name ?? '';\n const id = rawName.startsWith('models/') ? rawName.slice('models/'.length) : rawName;\n const lifecycle = rawName.includes('preview') ? 'preview' : 'active';\n\n return {\n id,\n displayName: model.displayName ?? id,\n lifecycle,\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nasync function defaultGeminiFetch(\n url: string,\n _init?: IGeminiFetchInit,\n): Promise<IGeminiFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IGeminiModelsResponse>,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gemini-Bh2U87MY.js","names":[],"sources":["../../src/gemini/image-operations.ts","../../src/gemini/request-converter.ts","../../src/gemini/tool-schema-converter.ts","../../src/gemini/message-converter.ts","../../src/gemini/execution-helpers.ts","../../src/gemini/provider.ts","../../src/gemini/provider-definition.ts","../../src/gemini/model-catalog-refresh.ts"],"sourcesContent":["import type { IGeminiProviderOptions } from './types';\nimport type { GenerateContentParameters } from '@google/genai';\nimport type {\n TUniversalMessage,\n TUniversalMessagePart,\n IMediaOutputRef,\n IImageEditRequest,\n IImageComposeRequest,\n TProviderMediaResult,\n IChatOptions,\n} from '@robota-sdk/agent-core';\n\n/** Checks whether the given parts contain an image part. */\nexport function hasImagePart(parts: TUniversalMessagePart[] | undefined): boolean {\n if (!parts) {\n return false;\n }\n return parts.some((part) => part.type === 'image_inline' || part.type === 'image_uri');\n}\n\n/** Extracts inline image parts from a message and converts them to media output references. */\nexport function mapInlineImagePartsToMediaOutputs(\n parts: TUniversalMessagePart[] | undefined,\n): IMediaOutputRef[] {\n if (!parts) {\n return [];\n }\n const outputs: IMediaOutputRef[] = [];\n for (const part of parts) {\n if (part.type !== 'image_inline') {\n continue;\n }\n outputs.push({\n kind: 'uri',\n uri: `data:${part.mimeType};base64,${part.data}`,\n mimeType: part.mimeType,\n });\n }\n return outputs;\n}\n\n/** Parses a data URI into its MIME type and base64 payload. */\nexport function parseDataUri(uri: string): { mimeType: string; data: string } | undefined {\n const commaIndex = uri.indexOf(',');\n if (commaIndex < 0) {\n return undefined;\n }\n const header = uri.slice(0, commaIndex);\n const payload = uri.slice(commaIndex + 1);\n if (!header.endsWith(';base64')) {\n return undefined;\n }\n const mimeType = header.replace('data:', '').replace(';base64', '').trim();\n if (mimeType.length === 0 || payload.trim().length === 0) {\n return undefined;\n }\n return {\n mimeType,\n data: payload,\n };\n}\n\n/** Maps an image input source (inline or URI) to a universal message part. */\nexport function mapImageInputSourceToPart(\n source: IImageEditRequest['image'] | IImageComposeRequest['images'][number],\n): TProviderMediaResult<TUniversalMessagePart> {\n if (source.kind === 'inline') {\n if (source.mimeType.trim().length === 0 || source.data.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Inline image source requires non-empty mimeType and data.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: source.mimeType,\n data: source.data,\n },\n };\n }\n if (!source.uri.startsWith('data:')) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Google image provider supports only inline or data URI input sources.',\n },\n };\n }\n const parsedResult = parseDataUri(source.uri);\n if (!parsedResult) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Data URI source must use base64 payload.',\n },\n };\n }\n return {\n ok: true,\n value: {\n type: 'image_inline',\n mimeType: parsedResult.mimeType,\n data: parsedResult.data,\n },\n };\n}\n\n/** Determines which response modalities to request from the Gemini API. */\nexport function buildResponseModalities(\n messages: TUniversalMessage[],\n defaultModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n optionModalities: Array<'TEXT' | 'IMAGE'> | undefined,\n): Array<'TEXT' | 'IMAGE'> {\n if (optionModalities && optionModalities.length > 0) {\n return optionModalities;\n }\n const hasImageInput = messages.some((message) => hasImagePart(message.parts));\n if (hasImageInput) {\n return ['TEXT', 'IMAGE'];\n }\n if (defaultModalities && defaultModalities.length > 0) {\n return defaultModalities;\n }\n return ['TEXT'];\n}\n\n/** Checks whether the specified model is configured as image-capable. */\nexport function isImageCapableModel(\n model: string,\n configuredImageModels: string[] | undefined,\n): boolean {\n if (!configuredImageModels || configuredImageModels.length === 0) {\n return true;\n }\n return configuredImageModels.includes(model);\n}\n\n/** Builds the Gemini generation config including response modalities. */\nexport function buildGenerationConfig(\n messages: TUniversalMessage[],\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): NonNullable<GenerateContentParameters['config']> {\n assertCompatibleStructuredOutputOptions(providerOptions);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n validateImageCapableModel(options?.model, responseModalities, providerOptions);\n const config: NonNullable<GenerateContentParameters['config']> = { responseModalities };\n applyChatOptions(config, options);\n applySafetySettings(config, providerOptions, options);\n applyStructuredOutputOptions(config, providerOptions);\n applyProviderGenerationOptions(config, providerOptions);\n return config;\n}\n\nfunction validateImageCapableModel(\n model: string | undefined,\n responseModalities: Array<'TEXT' | 'IMAGE'>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (!model || !responseModalities.includes('IMAGE')) {\n return;\n }\n if (isImageCapableModel(model, providerOptions.imageCapableModels)) {\n return;\n }\n throw new Error(\n `Selected model \"${model}\" is not configured as image-capable for Google provider.`,\n );\n}\n\nfunction applyChatOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n options?: IChatOptions,\n): void {\n if (typeof options?.temperature === 'number') {\n config.temperature = options.temperature;\n }\n if (typeof options?.maxTokens === 'number') {\n config.maxOutputTokens = options.maxTokens;\n }\n if (typeof options?.google?.topP === 'number') {\n config.topP = options.google.topP;\n }\n if (typeof options?.google?.topK === 'number') {\n config.topK = options.google.topK;\n }\n if (typeof options?.google?.candidateCount === 'number') {\n config.candidateCount = options.google.candidateCount;\n }\n if (options?.google?.stopSequences && options.google.stopSequences.length > 0) {\n config.stopSequences = options.google.stopSequences;\n }\n if (options?.signal) {\n config.abortSignal = options.signal;\n }\n}\n\nfunction applySafetySettings(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): void {\n const safetySettings = options?.google?.safetySettings ?? providerOptions.safetySettings;\n if (safetySettings && safetySettings.length > 0) {\n config.safetySettings = safetySettings as NonNullable<\n GenerateContentParameters['config']\n >['safetySettings'];\n }\n}\n\nfunction applyStructuredOutputOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.responseMimeType) {\n config.responseMimeType = providerOptions.responseMimeType;\n }\n if (providerOptions.responseSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseSchema = providerOptions.responseSchema;\n }\n if (providerOptions.responseJsonSchema) {\n config.responseMimeType = providerOptions.responseMimeType ?? 'application/json';\n config.responseJsonSchema = providerOptions.responseJsonSchema;\n }\n}\n\nfunction applyProviderGenerationOptions(\n config: NonNullable<GenerateContentParameters['config']>,\n providerOptions: IGeminiProviderOptions,\n): void {\n if (providerOptions.thinkingConfig) {\n config.thinkingConfig = providerOptions.thinkingConfig as NonNullable<\n GenerateContentParameters['config']\n >['thinkingConfig'];\n }\n if (providerOptions.toolConfig) {\n config.toolConfig = providerOptions.toolConfig as NonNullable<\n GenerateContentParameters['config']\n >['toolConfig'];\n }\n}\n\nfunction assertCompatibleStructuredOutputOptions(providerOptions: IGeminiProviderOptions): void {\n if (providerOptions.responseSchema && providerOptions.responseJsonSchema) {\n throw new Error(\n 'Gemini structured output options responseSchema and responseJsonSchema are mutually exclusive.',\n );\n }\n}\n","import type { Content, Part } from '@google/genai';\nimport type {\n IAssistantMessage,\n ISystemMessage,\n IToolMessage,\n IUserMessage,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\ntype TGoogleJsonValue = string | number | boolean | null | TGoogleJsonValue[] | IGoogleJsonObject;\n\ninterface IGoogleJsonObject {\n readonly [key: string]: TGoogleJsonValue;\n}\n\nexport interface IGeminiMessageConversionResult {\n contents: Content[];\n systemInstruction?: string;\n}\n\n/**\n * Maps universal message parts to Gemini-compatible parts.\n * Supports text and inline image parts; throws on unsupported part types.\n */\nexport function mapMessagePartsToGeminiParts(\n message: IUserMessage | IAssistantMessage | ISystemMessage | IToolMessage,\n): Part[] {\n const parts: Part[] = [];\n const messageParts = message.parts ?? [];\n for (const part of messageParts) {\n if (part.type === 'text') {\n parts.push({ text: part.text });\n continue;\n }\n if (part.type === 'image_inline') {\n parts.push({\n inlineData: {\n mimeType: part.mimeType,\n data: part.data,\n },\n });\n continue;\n }\n throw new Error(`Google provider does not support image URI parts directly: ${part.uri}`);\n }\n if (parts.length === 0 && typeof message.content === 'string' && message.content.length > 0) {\n parts.push({ text: message.content });\n }\n return parts;\n}\n\n/**\n * Converts an array of universal messages to the Gemini Content format.\n *\n * IMPORTANT: Google Gemini allows content with function calls.\n * Content can be empty string or text, but NOT null.\n */\nexport function convertToGeminiFormat(messages: TUniversalMessage[]): Content[] {\n return convertToGeminiRequestFormat(messages).contents;\n}\n\n/**\n * Converts universal messages into Gemini request content plus request config\n * fields. Gemini system instructions are request-level config, not user turns.\n */\nexport function convertToGeminiRequestFormat(\n messages: TUniversalMessage[],\n): IGeminiMessageConversionResult {\n const contents: Content[] = [];\n const systemInstructionParts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === 'user') {\n contents.push({\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n });\n continue;\n }\n if (msg.role === 'assistant') {\n contents.push(convertAssistantMessage(msg as IAssistantMessage));\n continue;\n }\n if (msg.role === 'tool') {\n contents.push(convertToolMessage(msg as IToolMessage));\n continue;\n }\n\n const systemInstruction = extractSystemInstructionText(msg as ISystemMessage);\n if (systemInstruction.length > 0) {\n systemInstructionParts.push(systemInstruction);\n }\n }\n\n return {\n contents,\n ...(systemInstructionParts.length > 0 && {\n systemInstruction: systemInstructionParts.join('\\n'),\n }),\n };\n}\n\n/**\n * Converts all messages to Gemini contents, including system instructions as\n * user content. This exists only for compatibility with callers that still need\n * a contents-only value.\n */\nexport function convertToGeminiFormatWithInlineSystem(messages: TUniversalMessage[]): Content[] {\n return messages.map((msg) => {\n if (msg.role === 'user') {\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(msg as IUserMessage),\n };\n }\n if (msg.role === 'assistant') {\n return convertAssistantMessage(msg as IAssistantMessage);\n }\n if (msg.role === 'tool') {\n const toolMessage = msg as IToolMessage;\n return {\n role: 'user',\n parts: mapMessagePartsToGeminiParts(toolMessage),\n };\n }\n const systemMessage = msg as ISystemMessage;\n const systemParts = mapMessagePartsToGeminiParts(systemMessage);\n if (systemParts.length === 0) {\n systemParts.push({ text: `System: ${systemMessage.content || ''}` });\n }\n return {\n role: 'user',\n parts: systemParts,\n };\n });\n}\n\nfunction convertAssistantMessage(assistantMsg: IAssistantMessage): Content {\n const parts: Part[] = [];\n const mappedAssistantParts = mapMessagePartsToGeminiParts(assistantMsg);\n for (const mappedPart of mappedAssistantParts) {\n parts.push(mappedPart);\n }\n if (parts.length === 0 && assistantMsg.content) {\n parts.push({ text: assistantMsg.content });\n }\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n assistantMsg.toolCalls.forEach((tc) => {\n parts.push({\n functionCall: {\n id: tc.id,\n name: tc.function.name,\n args: parseToolCallArguments(tc.function.arguments),\n },\n });\n });\n }\n return {\n role: 'model',\n parts,\n };\n}\n\nfunction convertToolMessage(toolMessage: IToolMessage): Content {\n const functionResponse = {\n id: toolMessage.toolCallId,\n name: requireToolMessageName(toolMessage),\n response: parseToolResponseContent(toolMessage.content),\n };\n return {\n role: 'user',\n parts: [{ functionResponse }],\n };\n}\n\nfunction extractSystemInstructionText(systemMessage: ISystemMessage): string {\n const parts = mapMessagePartsToGeminiParts(systemMessage);\n if (parts.length === 0) {\n return systemMessage.content;\n }\n const textParts: string[] = [];\n for (const part of parts) {\n if (typeof part.text === 'string') {\n textParts.push(part.text);\n continue;\n }\n throw new Error('Google provider system instructions support only text parts.');\n }\n return textParts.join('\\n');\n}\n\nfunction requireToolMessageName(toolMessage: IToolMessage): string {\n const toolName = toolMessage.name?.trim();\n if (!toolName) {\n throw new Error('Google provider tool message requires a function name.');\n }\n return toolName;\n}\n\nfunction parseToolCallArguments(serializedArguments: string): IGoogleJsonObject {\n const parsedArguments = JSON.parse(serializedArguments) as TGoogleJsonValue;\n if (!isJsonObject(parsedArguments)) {\n throw new Error('Google provider tool call arguments must be a JSON object.');\n }\n return parsedArguments;\n}\n\nfunction parseToolResponseContent(content: string): IGoogleJsonObject {\n const trimmedContent = content.trim();\n if (trimmedContent.length === 0) {\n return { output: null };\n }\n try {\n const parsedContent = JSON.parse(trimmedContent) as TGoogleJsonValue;\n if (isJsonObject(parsedContent)) {\n return parsedContent;\n }\n return { output: parsedContent };\n } catch {\n return { output: content };\n }\n}\n\nfunction isJsonObject(value: TGoogleJsonValue): value is IGoogleJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { Type } from '@google/genai';\n\nimport type { FunctionDeclaration, Schema } from '@google/genai';\nimport type { IParameterSchema, IToolSchema, TJSONSchemaKind } from '@robota-sdk/agent-core';\n\nconst GOOGLE_SCHEMA_TYPE_BY_JSON_KIND: Record<Exclude<TJSONSchemaKind, 'null'>, Type> = {\n string: Type.STRING,\n number: Type.NUMBER,\n integer: Type.INTEGER,\n boolean: Type.BOOLEAN,\n array: Type.ARRAY,\n object: Type.OBJECT,\n};\n\n/** Converts Robota tool schemas to Gemini function declarations. */\nexport function convertToolsToGeminiFormat(tools: IToolSchema[]): FunctionDeclaration[] {\n return tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: {\n type: Type.OBJECT,\n properties: convertParameterProperties(tool.parameters.properties),\n required: tool.parameters.required,\n },\n }));\n}\n\nfunction convertParameterProperties(\n properties: Record<string, IParameterSchema>,\n): Record<string, Schema> {\n const convertedProperties: Record<string, Schema> = {};\n for (const [key, value] of Object.entries(properties)) {\n convertedProperties[key] = convertParameterSchema(value);\n }\n return convertedProperties;\n}\n\nfunction convertParameterSchema(schema: IParameterSchema): Schema {\n const convertedSchema: Schema = {};\n const schemaType = convertSchemaKind(schema.type);\n if (schemaType) {\n convertedSchema.type = schemaType;\n }\n if (schema.description) {\n convertedSchema.description = schema.description;\n }\n if (schema.enum) {\n convertedSchema.enum = schema.enum.map(String);\n }\n if (schema.items) {\n convertedSchema.items = convertParameterSchema(schema.items);\n }\n if (schema.properties) {\n convertedSchema.properties = convertParameterProperties(schema.properties);\n }\n if (typeof schema.minimum === 'number') {\n convertedSchema.minimum = schema.minimum;\n }\n if (typeof schema.maximum === 'number') {\n convertedSchema.maximum = schema.maximum;\n }\n if (schema.pattern) {\n convertedSchema.pattern = schema.pattern;\n }\n if (schema.format) {\n convertedSchema.format = schema.format;\n }\n if (schema.default !== undefined) {\n convertedSchema.default = schema.default;\n }\n return convertedSchema;\n}\n\nfunction convertSchemaKind(kind: TJSONSchemaKind): Type | undefined {\n if (kind === 'null') {\n return undefined;\n }\n return GOOGLE_SCHEMA_TYPE_BY_JSON_KIND[kind];\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { Part, FunctionCall, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IAssistantMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nconst RANDOM_ID_RADIX = 36;\nconst RANDOM_ID_LENGTH = 9;\n\ninterface ICollectedGeminiParts {\n textValues: string[];\n messageParts: TUniversalMessagePart[];\n functionCalls: FunctionCall[];\n}\n\nexport {\n convertToGeminiFormat,\n convertToGeminiFormatWithInlineSystem,\n convertToGeminiRequestFormat,\n mapMessagePartsToGeminiParts,\n} from './request-converter';\nexport type { IGeminiMessageConversionResult } from './request-converter';\n\n/** Generates a unique call identifier for function call responses. */\nexport function generateCallId(): string {\n return `call_${Date.now()}_${Math.random().toString(RANDOM_ID_RADIX).substr(2, RANDOM_ID_LENGTH)}`;\n}\n\n/** Converts a Gemini API response into a universal message. */\nexport function convertFromGeminiResponse(response: GenerateContentResponse): TUniversalMessage {\n const candidate = response.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidate in Gemini response');\n }\n\n const content = candidate.content;\n if (!content || !content.parts || content.parts.length === 0) {\n throw new Error('No content in Gemini response');\n }\n\n const collectedParts = collectGeminiParts(content.parts);\n\n const result: TUniversalMessage = {\n id: randomUUID(),\n state: 'complete' as const,\n role: 'assistant',\n content: collectedParts.textValues.length > 0 ? collectedParts.textValues.join('') : null,\n parts: collectedParts.messageParts,\n timestamp: new Date(),\n };\n\n if (collectedParts.functionCalls.length > 0) {\n const assistantResult = result as IAssistantMessage;\n assistantResult.toolCalls = collectedParts.functionCalls.map((fc) => ({\n id: fc.id ?? generateCallId(),\n type: 'function' as const,\n function: {\n name: requireFunctionCallName(fc),\n arguments: JSON.stringify(fc.args ?? {}),\n },\n }));\n }\n\n const usageMetadata = mapUsageMetadata(response);\n if (usageMetadata) {\n result.metadata = usageMetadata;\n }\n\n return result;\n}\n\nfunction collectGeminiParts(parts: Part[]): ICollectedGeminiParts {\n const textValues: string[] = [];\n const messageParts: TUniversalMessagePart[] = [];\n const functionCalls: FunctionCall[] = [];\n\n for (const part of parts) {\n collectTextPart(part, textValues, messageParts);\n collectInlineImagePart(part, messageParts);\n if (part.functionCall) {\n functionCalls.push(part.functionCall);\n }\n }\n\n return { textValues, messageParts, functionCalls };\n}\n\nfunction collectTextPart(\n part: Part,\n textValues: string[],\n messageParts: TUniversalMessagePart[],\n): void {\n if (typeof part.text !== 'string') {\n return;\n }\n textValues.push(part.text);\n messageParts.push({ type: 'text', text: part.text });\n}\n\nfunction collectInlineImagePart(part: Part, messageParts: TUniversalMessagePart[]): void {\n if (\n !part.inlineData ||\n typeof part.inlineData.data !== 'string' ||\n typeof part.inlineData.mimeType !== 'string'\n ) {\n return;\n }\n messageParts.push({\n type: 'image_inline',\n data: part.inlineData.data,\n mimeType: part.inlineData.mimeType,\n });\n}\n\nfunction mapUsageMetadata(response: GenerateContentResponse): TUniversalMessage['metadata'] {\n if (\n !response.usageMetadata ||\n typeof response.usageMetadata.promptTokenCount !== 'number' ||\n typeof response.usageMetadata.candidatesTokenCount !== 'number' ||\n typeof response.usageMetadata.totalTokenCount !== 'number'\n ) {\n return undefined;\n }\n return {\n promptTokens: response.usageMetadata.promptTokenCount,\n completionTokens: response.usageMetadata.candidatesTokenCount,\n totalTokens: response.usageMetadata.totalTokenCount,\n };\n}\n\nexport { convertToolsToGeminiFormat } from './tool-schema-converter';\n\nfunction requireFunctionCallName(functionCall: FunctionCall): string {\n if (!functionCall.name || functionCall.name.trim().length === 0) {\n throw new Error('Gemini function call is missing a function name.');\n }\n return functionCall.name;\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n hasImagePart,\n mapInlineImagePartsToMediaOutputs,\n buildResponseModalities,\n buildGenerationConfig,\n} from './image-operations';\nimport {\n convertToGeminiRequestFormat,\n convertFromGeminiResponse,\n convertToolsToGeminiFormat,\n} from './message-converter';\n\nimport type { IGeminiProviderOptions } from './types';\nimport type { GoogleGenAI } from '@google/genai';\nimport type { Content, GenerateContentParameters, GenerateContentResponse } from '@google/genai';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\n\n/**\n * Execute a direct (non-streaming) chat request against the Gemini API.\n */\nexport async function executeDirect(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n\n if (options?.onTextDelta && !responseModalities.includes('IMAGE')) {\n return assembleStreamingChatResponse(client, providerOptions, messages, options, providerName);\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const result = await client.models.generateContent(request);\n emitGeminiNativeRawPayload(options, providerName, 'response', result);\n\n const convertedResponse = convertFromGeminiResponse(result);\n if (responseModalities.includes('IMAGE') && !hasImagePart(convertedResponse.parts)) {\n throw new Error(\n 'Gemini response did not include an image part while IMAGE modality was requested.',\n );\n }\n return convertedResponse;\n}\n\n/**\n * Execute a streaming chat request against the Gemini API.\n */\nexport async function* executeDirectStream(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options?: IChatOptions,\n providerName = 'gemini',\n): AsyncIterable<TUniversalMessage> {\n const model = resolveGeminiModel(providerOptions, options);\n const responseModalities = buildResponseModalities(\n messages,\n providerOptions.defaultResponseModalities,\n options?.google?.responseModalities,\n );\n if (responseModalities.includes('IMAGE')) {\n throw new Error('Google provider does not support streaming image modality responses.');\n }\n\n const requestFormat = convertToGeminiRequestFormat(messages);\n const genConfig = buildGenerationConfig(messages, providerOptions, { ...options, model });\n const request = buildGenerateContentRequest(\n model,\n requestFormat.contents,\n genConfig,\n options,\n requestFormat.systemInstruction,\n );\n\n emitGeminiNativeRawPayload(options, providerName, 'request', request);\n const stream = await client.models.generateContentStream(request);\n\n let sequence = 0;\n for await (const chunk of stream) {\n emitGeminiNativeRawPayload(options, providerName, 'stream_event', chunk, sequence);\n sequence++;\n const text = extractStreamText(chunk);\n if (text) {\n options?.onTextDelta?.(text);\n yield {\n id: randomUUID(),\n role: 'assistant',\n content: text,\n state: 'complete' as const,\n timestamp: new Date(),\n };\n }\n }\n}\n\nfunction buildGenerateContentRequest(\n model: string,\n contents: Content[],\n generationOptions: GenerateContentParameters['config'],\n options?: IChatOptions,\n systemInstruction?: string,\n): GenerateContentParameters {\n const config: GenerateContentParameters['config'] = { ...generationOptions };\n if (options?.tools && options.tools.length > 0) {\n config.tools = [{ functionDeclarations: convertToolsToGeminiFormat(options.tools) }];\n }\n if (systemInstruction) {\n config.systemInstruction = systemInstruction;\n }\n return {\n model,\n contents,\n config,\n };\n}\n\nfunction resolveGeminiModel(\n providerOptions: IGeminiProviderOptions,\n options?: IChatOptions,\n): string {\n const model = options?.model ?? providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n return model;\n}\n\nasync function assembleStreamingChatResponse(\n client: GoogleGenAI,\n providerOptions: IGeminiProviderOptions,\n messages: TUniversalMessage[],\n options: IChatOptions,\n providerName = 'gemini',\n): Promise<TUniversalMessage> {\n const textParts: string[] = [];\n for await (const chunk of executeDirectStream(\n client,\n providerOptions,\n messages,\n options,\n providerName,\n )) {\n if (typeof chunk.content === 'string') {\n textParts.push(chunk.content);\n }\n }\n const content = textParts.join('');\n return {\n id: randomUUID(),\n role: 'assistant',\n content,\n parts: content.length > 0 ? [{ type: 'text', text: content }] : [],\n state: 'complete',\n timestamp: new Date(),\n };\n}\n\nfunction emitGeminiNativeRawPayload(\n options: IChatOptions | undefined,\n providerName: string,\n payloadKind: 'request' | 'response' | 'stream_event',\n payload: object,\n sequence?: number,\n): void {\n options?.onProviderNativeRawPayload?.({\n provider: providerName,\n apiSurface: 'gemini-generate-content',\n payloadKind,\n ...(sequence !== undefined && { sequence }),\n payload,\n });\n}\n\nfunction extractStreamText(\n chunk: GenerateContentResponse | { readonly text?: () => string },\n): string | undefined {\n const textValue = chunk.text;\n return typeof textValue === 'function' ? textValue() : textValue;\n}\n\n/**\n * Run an image generation request through the chat API.\n */\nexport async function runImageRequest(\n chatFn: (messages: TUniversalMessage[], options?: IChatOptions) => Promise<TUniversalMessage>,\n messages: TUniversalMessage[],\n model: string,\n): Promise<TProviderMediaResult<IImageGenerationResult>> {\n try {\n const response = await chatFn(messages, {\n model,\n google: { responseModalities: ['TEXT', 'IMAGE'] },\n });\n const outputs = mapInlineImagePartsToMediaOutputs(response.parts);\n if (outputs.length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_UPSTREAM_ERROR',\n message: 'Google image response did not include image output parts.',\n },\n };\n }\n return { ok: true, value: { outputs, model } };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google image request failed.';\n return { ok: false, error: { code: 'PROVIDER_UPSTREAM_ERROR', message: errorMessage } };\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { GoogleGenAI } from '@google/genai';\nimport { AbstractAIProvider } from '@robota-sdk/agent-core';\n\nimport { executeDirect, executeDirectStream, runImageRequest } from './execution-helpers';\nimport { mapImageInputSourceToPart } from './image-operations';\n\nimport type { IGeminiProviderOptions } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n TTextDeltaCallback,\n TUniversalMessagePart,\n IImageGenerationProvider,\n IImageGenerationRequest,\n IImageEditRequest,\n IImageComposeRequest,\n IImageGenerationResult,\n TProviderMediaResult,\n} from '@robota-sdk/agent-core';\n\n/**\n * Gemini provider implementation for Robota\n *\n * IMPORTANT PROVIDER-SPECIFIC RULES:\n * 1. This provider MUST extend BaseAIProvider from @robota-sdk/agent-core\n * 2. Content handling for Google Gemini API:\n * - Function calls can have content (text) along with function calls\n * - Content can be empty string or actual text, NOT null\n * 3. Use override keyword for all methods inherited from BaseAIProvider\n * 4. Provider-specific API behavior should be documented here\n *\n * @public\n */\nexport class GeminiProvider extends AbstractAIProvider implements IImageGenerationProvider {\n override readonly name: string = 'gemini';\n override readonly version = '1.0.0';\n public onTextDelta?: TTextDeltaCallback;\n\n private readonly client?: GoogleGenAI;\n private readonly options: IGeminiProviderOptions;\n\n constructor(options: IGeminiProviderOptions) {\n super();\n this.options = options;\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n this.client = new GoogleGenAI({ apiKey: options.apiKey });\n }\n }\n\n /** Generate response using TUniversalMessage */\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n\n if (this.executor) {\n try {\n return await this.executeViaExecutorOrDirect(messages, options);\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n return await executeDirect(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google chat failed: ${errorMessage}`);\n }\n }\n\n /** Generate streaming response using TUniversalMessage */\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateMessages(messages);\n if (this.executor) {\n try {\n yield* this.executeStreamViaExecutorOrDirect(messages, options);\n return;\n } catch (error) {\n this.logger.error(\n 'Gemini Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (!this.client) {\n throw new Error('Google client not available. Either provide apiKey or use an executor.');\n }\n\n try {\n yield* executeDirectStream(\n this.client,\n this.options,\n messages,\n this.withProviderCallbacks(options),\n this.name,\n );\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Google API request failed';\n throw new Error(`Google stream failed: ${errorMessage}`);\n }\n }\n\n /** Generate an image from a text prompt using the Gemini API. */\n public async generateImage(\n request: IImageGenerationRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image generation requires a non-empty model.',\n },\n };\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [{ type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Edit an existing image based on a text prompt using the Gemini API. */\n public async editImage(\n request: IImageEditRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image edit requires a non-empty model.',\n },\n };\n }\n\n const inputPartResult = mapImageInputSourceToPart(request.image);\n if (!inputPartResult.ok) {\n return inputPartResult;\n }\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: [inputPartResult.value, { type: 'text', text: request.prompt }],\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n /** Compose multiple images together based on a text prompt using the Gemini API. */\n public async composeImage(\n request: IImageComposeRequest,\n ): Promise<TProviderMediaResult<IImageGenerationResult>> {\n if (request.prompt.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty prompt.',\n },\n };\n }\n if (request.model.trim().length === 0) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires a non-empty model.',\n },\n };\n }\n if (request.images.length < 2) {\n return {\n ok: false,\n error: {\n code: 'PROVIDER_INVALID_REQUEST',\n message: 'Image compose requires at least two input images.',\n },\n };\n }\n\n const messageParts: TUniversalMessagePart[] = [];\n for (const imageSource of request.images) {\n const mappedPartResult = mapImageInputSourceToPart(imageSource);\n if (!mappedPartResult.ok) {\n return mappedPartResult;\n }\n messageParts.push(mappedPartResult.value);\n }\n messageParts.push({ type: 'text', text: request.prompt });\n\n const message: TUniversalMessage = {\n id: randomUUID(),\n role: 'user',\n content: request.prompt,\n state: 'complete' as const,\n parts: messageParts,\n timestamp: new Date(),\n };\n return runImageRequest(this.chat.bind(this), [message], request.model);\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override validateConfig(): boolean {\n if (this.executor) {\n return this.executor.validateConfig();\n }\n return !!this.client && !!this.options && !!this.options.apiKey;\n }\n\n override async dispose(): Promise<void> {\n // Google client does not need explicit cleanup\n }\n\n private withProviderCallbacks(options?: IChatOptions): IChatOptions | undefined {\n const onTextDelta = options?.onTextDelta ?? this.onTextDelta;\n if (!onTextDelta) {\n return options;\n }\n return {\n ...options,\n onTextDelta,\n };\n }\n}\n","import { refreshGeminiModelCatalog } from './model-catalog-refresh';\nimport { GeminiProvider } from './provider';\n\nimport type { IProviderDefinition } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_ENV = 'GEMINI_API_KEY';\nexport const DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE = `$ENV:${DEFAULT_GEMINI_PROVIDER_API_KEY_ENV}`;\nexport const DEFAULT_GEMINI_PROVIDER_MODEL = 'gemini-3-flash-preview';\nexport const GEMINI_MODEL_SOURCE_URL = 'https://ai.google.dev/api/models';\nexport const GEMINI_MODEL_LAST_VERIFIED_AT = '2026-05-04';\nconst GEMINI_API_KEY_URL = 'https://aistudio.google.com/apikey';\nconst GEMINI_SETUP_SOURCE_URL = 'https://ai.google.dev/gemini-api/docs/api-key';\nconst GEMINI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst GEMINI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'Google AI Studio API keys',\n url: GEMINI_API_KEY_URL,\n sourceUrl: GEMINI_SETUP_SOURCE_URL,\n lastVerifiedAt: GEMINI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createGeminiProviderDefinition(): IProviderDefinition {\n return {\n type: 'gemini',\n aliases: ['google'],\n displayName: 'Gemini',\n description: 'Google Gemini API provider',\n defaults: {\n model: DEFAULT_GEMINI_PROVIDER_MODEL,\n apiKey: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n },\n modelCatalog: {\n status: 'fallback',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n entries: [\n {\n id: DEFAULT_GEMINI_PROVIDER_MODEL,\n displayName: 'Gemini 3 Flash Preview',\n capabilities: ['tools', 'vision', 'json_schema', 'reasoning', 'streaming'],\n lifecycle: 'preview',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n },\n ],\n },\n setupHelpLinks: GEMINI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'Gemini model',\n defaultValue: DEFAULT_GEMINI_PROVIDER_MODEL,\n },\n {\n key: 'apiKey',\n title: 'Gemini API key',\n defaultValue: DEFAULT_GEMINI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n refreshModelCatalog: ({ profile }) => refreshGeminiModelCatalog(profile),\n modelCatalogCacheTtlSeconds: 86400,\n createProvider: (config) =>\n new GeminiProvider({\n apiKey: requireApiKey(config.apiKey),\n defaultModel: config.model,\n }),\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider gemini requires apiKey');\n }\n return apiKey;\n}\n","import { GEMINI_MODEL_LAST_VERIFIED_AT, GEMINI_MODEL_SOURCE_URL } from './provider-definition';\n\nimport type {\n IProviderModelCatalog,\n IProviderModelCatalogEntry,\n IProviderProfileConfig,\n} from '@robota-sdk/agent-core';\n\nconst GEMINI_API_ENDPOINT = 'https://generativelanguage.googleapis.com/v1beta/models';\n\nexport interface IGeminiModelInfo {\n name?: string;\n displayName?: string;\n description?: string;\n inputTokenLimit?: number;\n outputTokenLimit?: number;\n supportedGenerationMethods?: string[];\n}\n\nexport interface IGeminiModelsResponse {\n models?: IGeminiModelInfo[];\n nextPageToken?: string;\n}\n\nexport interface IGeminiFetchInit {\n headers?: Record<string, string>;\n}\n\nexport interface IGeminiFetchResponse {\n ok: boolean;\n status: number;\n json: () => Promise<IGeminiModelsResponse>;\n}\n\nexport type TGeminiFetch = (url: string, init?: IGeminiFetchInit) => Promise<IGeminiFetchResponse>;\n\nexport async function refreshGeminiModelCatalog(\n profile: IProviderProfileConfig,\n fetcher: TGeminiFetch = defaultGeminiFetch,\n): Promise<IProviderModelCatalog> {\n const url = profile.apiKey ? `${GEMINI_API_ENDPOINT}?key=${profile.apiKey}` : GEMINI_API_ENDPOINT;\n\n const response = await fetcher(url);\n\n if (!response.ok) {\n return {\n status: 'unavailable',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n message: `Gemini model refresh failed: HTTP ${response.status}`,\n };\n }\n\n const body = await response.json();\n const entries = (body.models ?? []).filter(supportsGenerateContent).map(toModelCatalogEntry);\n\n return {\n status: 'live',\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: new Date().toISOString(),\n entries,\n message: `Fetched ${entries.length} Gemini models`,\n };\n}\n\nfunction supportsGenerateContent(model: IGeminiModelInfo): boolean {\n return model.supportedGenerationMethods?.includes('generateContent') === true;\n}\n\nfunction toModelCatalogEntry(model: IGeminiModelInfo): IProviderModelCatalogEntry {\n const rawName = model.name ?? '';\n const id = rawName.startsWith('models/') ? rawName.slice('models/'.length) : rawName;\n const lifecycle = rawName.includes('preview') ? 'preview' : 'active';\n\n return {\n id,\n displayName: model.displayName ?? id,\n lifecycle,\n sourceUrl: GEMINI_MODEL_SOURCE_URL,\n lastVerifiedAt: GEMINI_MODEL_LAST_VERIFIED_AT,\n };\n}\n\nasync function defaultGeminiFetch(\n url: string,\n _init?: IGeminiFetchInit,\n): Promise<IGeminiFetchResponse> {\n const response = await fetch(url);\n return {\n ok: response.ok,\n status: response.status,\n json: () => response.json() as Promise<IGeminiModelsResponse>,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../gemma-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../gemma-079LPvrN.cjs`);exports.DEFAULT_GEMMA_PROVIDER_API_KEY=e.t,exports.DEFAULT_GEMMA_PROVIDER_BASE_URL=e.n,exports.DEFAULT_GEMMA_PROVIDER_MODEL=e.r,exports.GemmaProvider=e.a,exports.GemmaReasoningProjector=e.l,exports.GemmaToolCallProjector=e.o,exports.createGemmaProviderDefinition=e.i,exports.createGemmaToolCallProjector=e.s,exports.projectGemmaReasoningText=e.u,exports.projectGemmaToolCallText=e.c;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as GemmaProvider, c as IGemmaToolCallProjectorOptions, d as GemmaReasoningProjector, f as IGemmaReasoningProjection, h as TGemmaProviderOptionValue, i as createGemmaProviderDefinition, l as createGemmaToolCallProjector, m as IGemmaProviderOptions, n as DEFAULT_GEMMA_PROVIDER_BASE_URL, o as GemmaToolCallProjector, p as projectGemmaReasoningText, r as DEFAULT_GEMMA_PROVIDER_MODEL, s as IGemmaToolCallProjection, t as DEFAULT_GEMMA_PROVIDER_API_KEY, u as projectGemmaToolCallText } from "../index-
|
|
1
|
+
import { a as GemmaProvider, c as IGemmaToolCallProjectorOptions, d as GemmaReasoningProjector, f as IGemmaReasoningProjection, h as TGemmaProviderOptionValue, i as createGemmaProviderDefinition, l as createGemmaToolCallProjector, m as IGemmaProviderOptions, n as DEFAULT_GEMMA_PROVIDER_BASE_URL, o as GemmaToolCallProjector, p as projectGemmaReasoningText, r as DEFAULT_GEMMA_PROVIDER_MODEL, s as IGemmaToolCallProjection, t as DEFAULT_GEMMA_PROVIDER_API_KEY, u as projectGemmaToolCallText } from "../index-DSv5xruI.js";
|
|
2
2
|
export { DEFAULT_GEMMA_PROVIDER_API_KEY, DEFAULT_GEMMA_PROVIDER_BASE_URL, DEFAULT_GEMMA_PROVIDER_MODEL, GemmaProvider, GemmaReasoningProjector, GemmaToolCallProjector, IGemmaProviderOptions, IGemmaReasoningProjection, IGemmaToolCallProjection, IGemmaToolCallProjectorOptions, TGemmaProviderOptionValue, createGemmaProviderDefinition, createGemmaToolCallProjector, projectGemmaReasoningText, projectGemmaToolCallText };
|
package/dist/node/gemma/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"../gemma-
|
|
1
|
+
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c,u as l}from"../gemma-BMFWnmXE.js";export{c as DEFAULT_GEMMA_PROVIDER_API_KEY,i as DEFAULT_GEMMA_PROVIDER_BASE_URL,o as DEFAULT_GEMMA_PROVIDER_MODEL,e as GemmaProvider,r as GemmaReasoningProjector,a as GemmaToolCallProjector,n as createGemmaProviderDefinition,s as createGemmaToolCallProjector,l as projectGemmaReasoningText,t as projectGemmaToolCallText};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./openai-compatible-BYfyY5lb.cjs`);let n=require(`node:crypto`),r=require(`@robota-sdk/agent-core`),i=require(`openai`);i=e.t(i,1);const a=`<|channel>`;function o(e){let t=c(e,{final:!0});return{rawText:e,visibleText:t.visibleParts.join(``),removedReasoning:t.removedReasoning}}var s=class{buffer=``;emittedVisibleText=``;hasRemovedReasoning=!1;get rawText(){return this.buffer}get removedReasoning(){return this.hasRemovedReasoning}project(e){return e.length===0?``:(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=c(this.buffer,e);this.hasRemovedReasoning=this.hasRemovedReasoning||t.removedReasoning;let n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length);return this.emittedVisibleText=n,r}};function c(e,t){let n={visibleParts:[],removedReasoning:!1},r=0;for(;r<e.length;){let i=e.indexOf(a,r);if(i===-1){l(n,e.slice(r),t);break}l(n,e.slice(r,i),t);let o=i+10,s=e.indexOf(`<channel|>`,o);if(s===-1){t.final&&(n.removedReasoning=!0);break}n.removedReasoning=!0,r=u(e,o,s)}return n}function l(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=d(t);e.visibleParts.push(t.slice(0,t.length-r))}function u(e,t,n){let r=e.slice(t,n),i=n+10;if(r.trim().length===0){let t=e.slice(i).match(/^thought(?:\r?\n)*/);return t&&(i+=t[0].length),i}return r.split(/\r?\n/,1)[0]?.trim(),i}function d(e){let t=Math.min(e.length,9);for(let n=t;n>0;--n)if(a.startsWith(e.slice(e.length-n)))return n;return 0}const f=`<|"|>`;var p=class{source;cursor=0;constructor(e){this.source=e}parse(){let e=this.parseObject();if(this.skipWhitespace(),this.cursor===this.source.length)return e}parseObject(){if(!this.consume(`{`))return;let e={};if(this.skipWhitespace(),this.consume(`}`))return e;for(;this.cursor<this.source.length;){let t=this.parseKey();if(!t||!this.consume(`:`))return;let n=this.parseValue();if(n===void 0)return;if(e[t]=n,this.skipWhitespace(),this.consume(`}`))return e;if(!this.consume(`,`))return}}parseArray(){if(!this.consume(`[`))return;let e=[];if(this.skipWhitespace(),this.consume(`]`))return e;for(;this.cursor<this.source.length;){let t=this.parseValue();if(t===void 0)return;if(e.push(t),this.skipWhitespace(),this.consume(`]`))return e;if(!this.consume(`,`))return}}parseValue(){return this.skipWhitespace(),this.source.startsWith(f,this.cursor)?this.parseString():this.source.startsWith(`{`,this.cursor)?this.parseObject():this.source.startsWith(`[`,this.cursor)?this.parseArray():this.consumeLiteral(`true`)?!0:this.consumeLiteral(`false`)?!1:this.consumeLiteral(`null`)?null:this.parseNumber()}parseKey(){if(this.skipWhitespace(),this.source.startsWith(f,this.cursor))return this.parseString();let e=/^[A-Za-z_][A-Za-z0-9_-]*/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),e[0]}parseString(){if(!this.consume(f))return;let e=this.source.indexOf(f,this.cursor);if(e===-1)return;let t=this.source.slice(this.cursor,e);return this.cursor=e+5,this.skipWhitespace(),t}parseNumber(){let e=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),Number(e[0])}consume(e){return this.skipWhitespace(),this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}consumeLiteral(e){return this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}skipWhitespace(){for(;/\s/.test(this.source[this.cursor]??``);)this.cursor+=1}};function ee(e){return[`<`]}function te(e,t,n){return e.indexOf(`<`,t)}function ne(e,t){return+!!e.endsWith(`<`)}function re(e,t){let n=e.indexOf(`>`,t+1);if(n===-1)return;let r=e.slice(t,n+1),i=r.match(/^<\s*([A-Za-z][\w:-]*)([\s/>][\s\S]*?|)>$/);if(!i)return;let a=i[1]??``;return{tagName:a,normalizedName:a.toLowerCase(),rawOpenTag:r,attributes:_(i[2]??``),openEnd:n+1,selfClosing:/\/\s*>$/.test(r)}}function m(e,t,n){if(t.selfClosing)return{innerText:``,end:t.openEnd,complete:!0};let r=y(e,t.tagName,t.openEnd);if(r===-1)return{innerText:e.slice(t.openEnd),end:n.final?e.length:t.openEnd-t.rawOpenTag.length,complete:!1};let i=e.indexOf(`>`,r);return{innerText:e.slice(t.openEnd,r),end:i===-1?e.length:i+1,complete:!0}}function h(e,t){if(t.selfClosing)return{rawText:t.rawOpenTag,end:t.openEnd};let n=y(e,t.tagName,t.openEnd);if(n===-1)return{rawText:t.rawOpenTag,end:t.openEnd};let r=e.indexOf(`>`,n),i=r===-1?e.length:r+1;return{rawText:e.slice(t.openEnd-t.rawOpenTag.length,i),end:i}}function g(e,t){let n=b(e);return t.find(e=>b(e)===n)}function _(e){let t={},n=/([A-Za-z_][\w:-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/g,r=n.exec(e);for(;r;){let i=r[1]??``;t[i]=ie(v(r[2]??r[3]??``)),r=n.exec(e)}return t}function ie(e){return e===`true`?!0:e===`false`?!1:e===`null`?null:/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e)?Number(e):e}function v(e){return e.replace(/"/g,`"`).replace(/'/g,`'`).replace(/</g,`<`).replace(/>/g,`>`).replace(/&/g,`&`)}function y(e,t,n){return e.toLowerCase().indexOf(`</${t.toLowerCase()}>`,n)}function b(e){return e.replace(/[^a-z0-9]/gi,``).toLowerCase()}function x(e,t){let n=S(e,t);return n?[n]:[]}function S(e,t){let n=e.indexOf(`>`),r=e.lastIndexOf(`</`);if(n===-1||r===-1||r<=n)return;let i=C(e.slice(n+1,r).trim());if(!w(i))return;let a=i.command,o=i.args;if(typeof a!=`string`||!w(o))return;let s=g(a,t);if(s)return{toolName:s,args:o}}function C(e){try{return JSON.parse(e)}catch{return}}function w(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function T(e,t,n){let r=A(),i=ee(t.toolNames),a=0;for(;a<e.length;){let o=te(e,a,i);if(o===-1){O(r,e.slice(a),n,i);break}O(r,e.slice(a,o),n,i);let s=E(e,o,r,t,n);if(!s.completed)break;a=s.cursor}return{visibleText:r.visibleParts.join(``),toolCalls:r.toolCalls,rawToolCallTextParts:r.rawToolCallTextParts,removedToolCallText:r.removedToolCallText}}function E(e,t,n,r,i){let a=re(e,t);if(!a)return D(e,t,n,i);let o=g(a.tagName,r.toolNames);return o?se(e,a,o,n,r):ae(e,t,a,n,r,i)}function D(e,t,n,r){return r.final?(n.visibleParts.push(e[t]??``),{cursor:t+1,completed:!0}):{cursor:t,completed:!1}}function ae(e,t,n,r,i,a){let o=m(e,n,a);if(!o.complete&&!a.final)return{cursor:t,completed:!1};let s=e.slice(t,o.end),c=r.rawToolCallTextParts.length;return r.removedToolCallText=!0,le(r,s,i),j(r,oe(o,r,i)),r.rawToolCallTextParts.length===c&&r.rawToolCallTextParts.push(s),{cursor:o.end,completed:!0}}function oe(e,t,n){return T(e.innerText,{...n,startCallIndex:M(t,n)},{final:!0})}function se(e,t,n,r,i){let a=h(e,t);return ce(r,n,t.attributes,a.rawText,i),{cursor:a.end,completed:!0}}function O(e,t,n,r){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let i=ne(t,r);e.visibleParts.push(t.slice(0,t.length-i))}function ce(e,t,n,r,i){Object.keys(n).length!==0&&(e.toolCalls.push(k(t,n,i,e)),e.rawToolCallTextParts.push(r),e.removedToolCallText=!0)}function le(e,t,n){let r=x(t,n.toolNames);for(let i of r)e.toolCalls.push(k(i.toolName,i.args,n,e)),e.rawToolCallTextParts.push(t)}function k(e,t,n,r){return{id:`${n.callIdPrefix??`gemma_call`}_${M(r,n)}`,type:`function`,function:{name:e,arguments:JSON.stringify(t)}}}function A(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function j(e,t){e.toolCalls.push(...t.toolCalls),e.rawToolCallTextParts.push(...t.rawToolCallTextParts),e.removedToolCallText=e.removedToolCallText||t.removedToolCallText}function M(e,t){return(t.startCallIndex??0)+e.toolCalls.length}const N=`<|tool_call>`,P=`gemma_call`;function F(e){if(!(!e||e.length===0))return new L({toolNames:e.map(e=>e.name)})}function I(e,t){return ue(e,R(e,t,{final:!0}))}var L=class{options;buffer=``;emittedVisibleText=``;emittedRawToolCallText=``;emittedToolCallIds=new Set;constructor(e){this.options=e}project(e){return e.length===0?de():(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=R(this.buffer,this.options,e),n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length),i=t.rawToolCallTextParts.join(``),a=i.slice(this.emittedRawToolCallText.length);return this.emittedVisibleText=n,this.emittedRawToolCallText=i,{visibleText:r,toolCalls:t.toolCalls.filter(e=>this.emittedToolCallIds.has(e.id)?!1:(this.emittedToolCallIds.add(e.id),!0)),removedToolCallText:a.length>0,...a.length>0&&{rawToolCallText:a}}}};function R(e,t,n){let r=z(e,t,n),i=T(r.visibleParts.join(``),{toolNames:t.toolNames,callIdPrefix:t.callIdPrefix??P,startCallIndex:r.toolCalls.length},n);return{visibleParts:[i.visibleText],toolCalls:[...r.toolCalls,...i.toolCalls],rawToolCallTextParts:[...r.rawToolCallTextParts,...i.rawToolCallTextParts],removedToolCallText:r.removedToolCallText||i.removedToolCallText}}function z(e,t,n){let r=V(),i=new Set(t.toolNames),a=0,o=0;for(;a<e.length;){let s=e.indexOf(N,a);if(s===-1){H(r,e.slice(a),n);break}H(r,e.slice(a,s),n);let c=s+12,l=e.indexOf(`<tool_call|>`,c);if(l===-1){n.final&&r.visibleParts.push(e.slice(s));break}let u=e.slice(s,l+12),d=B(e.slice(c,l),i,t,o);d?(r.toolCalls.push(d),r.rawToolCallTextParts.push(u),r.removedToolCallText=!0,o+=1):r.visibleParts.push(u),a=l+12}return r}function B(e,t,n,r){let i=e.trim();if(!i.startsWith(`call:`))return;let a=i.slice(5).trimStart(),o=a.indexOf(`{`);if(o<=0)return;let s=a.slice(0,o).trim();if(!t.has(s))return;let c=new p(a.slice(o)).parse();if(c)return{id:`${n.callIdPrefix??P}_${r}`,type:`function`,function:{name:s,arguments:JSON.stringify(c)}}}function V(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function H(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=U(t);e.visibleParts.push(t.slice(0,t.length-r))}function U(e){let t=Math.min(e.length,11);for(let n=t;n>0;--n)if(N.startsWith(e.slice(e.length-n)))return n;return 0}function ue(e,t){return{rawText:e,visibleText:t.visibleParts.join(``),toolCalls:t.toolCalls,removedToolCallText:t.removedToolCallText,...t.rawToolCallTextParts.length>0&&{rawToolCallText:t.rawToolCallTextParts.join(``)}}}function de(){return{visibleText:``,toolCalls:[],removedToolCallText:!1}}function fe(e,n,r){let i=e.choices?.[0]?.message.content||``,a=new t.i({logger:n,...r?.tools&&{toolCallTextProjector:F(r.tools)}}).parseResponse(e),s=o(a.content??``);return W({...a,content:s.visibleText},i,s.removedReasoning)}function W(e,t,n){return n?{...e,metadata:{...e.metadata??{},gemmaReasoningFiltered:!0,gemmaRawContent:t}}:e}function G(e,t){return{id:(0,n.randomUUID)(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function pe(e,t){return{id:(0,n.randomUUID)(),role:`assistant`,content:``,toolCalls:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function me(e,n){return{reasoningProjector:new s,responseParser:new t.i({logger:e}),...n&&{toolCallProjector:F(n)}}}function he(e,t){let n=e.choices?.[0];if(!n)return[];let i=t.responseParser.parseStreamingChunk(e);return i&&(0,r.isAssistantMessage)(i)&&i.toolCalls?.length?[i]:K(n.delta.content||``,n.finish_reason,t)}function ge(e){let t=K(``,null,e,!0),n=e.reasoningProjector.flush();return n.length>0&&t.push(G(n,null)),t}function K(e,t,n,r=!1){let i=r?n.toolCallProjector?.flush():n.toolCallProjector?.project(e),a=[];i?.toolCalls.length&&a.push(pe(i.toolCalls,t));let o=i?.visibleText??e,s=n.reasoningProjector.project(o);return s.length>0&&a.push(G(s,t)),a}var q=class extends r.AbstractAIProvider{name=`gemma`;version=`1.0.0`;client;options;onTextDelta;constructor(e){if(super(e.logger||r.SilentLogger),this.options=e,e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new i.default({apiKey:e.apiKey,...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout}});else throw Error(`Either Gemma client, apiKey, or executor is required`)}async chat(e,t){if(this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(e,t)}catch(e){throw this.logger.error(`Gemma Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let n=this.buildRequestParams(e,t),r=t?.onTextDelta??this.onTextDelta;if(r)return await this.chatWithStreamingAssembly({...n,stream:!0},{...t,onTextDelta:r});t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let i=await this.client.chat.completions.create(n);return t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),fe(i,this.logger,t)}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma chat failed: ${t}`)}}async*chatStream(e,n){if(this.validateMessages(e),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(e,n);return}catch(e){throw this.logger.error(`Gemma Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let r=this.buildStreamingRequestParams(e,n);n?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:r});let i=await this.client.chat.completions.create(r),a=me(this.logger,n?.tools),o=t.n(i,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n?.onProviderNativeRawPayload});for await(let e of this.streamWithAbort(o,n?.signal))for(let t of he(e,a))yield t;for(let e of ge(a))yield e}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma stream failed: ${t}`)}}supportsTools(){return!0}getCapabilities(){return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web search.`},webFetch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web fetch.`}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}buildRequestParams(e,n){let r=n?.model??this.options.defaultModel;if(!r)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);return{model:r,messages:t.a(e),...n?.temperature!==void 0&&{temperature:n.temperature},...n?.maxTokens!==void 0&&{max_tokens:n.maxTokens},...n?.tools&&{tools:t.o(n.tools),tool_choice:`auto`}}}buildStreamingRequestParams(e,t){return{...this.buildRequestParams(e,t),stream:!0}}async chatWithStreamingAssembly(e,n){if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{n.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:e});let r=await this.client.chat.completions.create(e,n.signal?{signal:n.signal}:void 0),i=new s;return W(await t.r({stream:t.n(r,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n.onProviderNativeRawPayload}),onTextDelta:n.onTextDelta,signal:n.signal,textProjector:e=>i.project(e),textProjectorFlush:()=>i.flush(),toolCallTextProjector:F(n.tools)}),i.rawText,i.removedReasoning)}catch(e){let t=e.message||`Gemma streaming request failed`;throw Error(`Gemma stream failed: ${t}`)}}};const J=`supergemma4-26b-uncensored-v2`,Y=`lm-studio`,X=`http://localhost:1234/v1`,Z=`https://ai.google.dev/gemma`,Q=`2026-05-04`,$=`https://lmstudio.ai/docs/developer`,_e=[{kind:`official`,label:`LM Studio local API documentation`,url:$,sourceUrl:$,lastVerifiedAt:`2026-05-08`}],ve={status:`fallback`,sourceUrl:Z,lastVerifiedAt:Q,entries:[{id:J,displayName:`SuperGemma 4 26B`,capabilities:[`tools`,`streaming`],lifecycle:`active`,sourceUrl:Z,lastVerifiedAt:Q}]};function ye(){return{type:`gemma`,displayName:`Gemma`,description:`Gemma-family local models through an OpenAI-compatible endpoint`,defaults:{model:J,apiKey:Y,baseURL:X},modelCatalog:ve,setupHelpLinks:_e,setupSteps:[{key:`baseURL`,title:`Gemma OpenAI-compatible base URL`,defaultValue:X},{key:`model`,title:`Gemma model`,defaultValue:J},{key:`apiKey`,title:`Gemma OpenAI-compatible API key`,defaultValue:Y,masked:!0}],requiresApiKey:!0,probeProfile:t.t,createProvider:e=>new q({apiKey:be(e.apiKey),...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout},defaultModel:e.model})}}function be(e){if(!e)throw Error(`Provider gemma requires apiKey`);return e}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return o}});
|
|
1
|
+
const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./openai-compatible-BYfyY5lb.cjs`);let n=require(`node:crypto`),r=require(`@robota-sdk/agent-core`),i=require(`openai`);i=e.t(i,1);const a=`<|channel>`;function o(e){let t=c(e,{final:!0});return{rawText:e,visibleText:t.visibleParts.join(``),removedReasoning:t.removedReasoning}}var s=class{buffer=``;emittedVisibleText=``;hasRemovedReasoning=!1;get rawText(){return this.buffer}get removedReasoning(){return this.hasRemovedReasoning}project(e){return e.length===0?``:(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=c(this.buffer,e);this.hasRemovedReasoning=this.hasRemovedReasoning||t.removedReasoning;let n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length);return this.emittedVisibleText=n,r}};function c(e,t){let n={visibleParts:[],removedReasoning:!1},r=0;for(;r<e.length;){let i=e.indexOf(a,r);if(i===-1){l(n,e.slice(r),t);break}l(n,e.slice(r,i),t);let o=i+10,s=e.indexOf(`<channel|>`,o);if(s===-1){t.final&&(n.removedReasoning=!0);break}n.removedReasoning=!0,r=u(e,o,s)}return n}function l(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=d(t);e.visibleParts.push(t.slice(0,t.length-r))}function u(e,t,n){let r=e.slice(t,n),i=n+10;if(r.trim().length===0){let t=e.slice(i).match(/^thought(?:\r?\n)*/);return t&&(i+=t[0].length),i}return r.split(/\r?\n/,1)[0]?.trim(),i}function d(e){let t=Math.min(e.length,9);for(let n=t;n>0;--n)if(a.startsWith(e.slice(e.length-n)))return n;return 0}function f(e){return[`<`]}function p(e,t,n){return e.indexOf(`<`,t)}function ee(e,t){return+!!e.endsWith(`<`)}function te(e,t){let n=e.indexOf(`>`,t+1);if(n===-1)return;let r=e.slice(t,n+1),i=r.match(/^<\s*([A-Za-z][\w:-]*)([\s/>][\s\S]*?|)>$/);if(!i)return;let a=i[1]??``;return{tagName:a,normalizedName:a.toLowerCase(),rawOpenTag:r,attributes:g(i[2]??``),openEnd:n+1,selfClosing:/\/\s*>$/.test(r)}}function m(e,t,n){if(t.selfClosing)return{innerText:``,end:t.openEnd,complete:!0};let r=y(e,t.tagName,t.openEnd);if(r===-1)return{innerText:e.slice(t.openEnd),end:n.final?e.length:t.openEnd-t.rawOpenTag.length,complete:!1};let i=e.indexOf(`>`,r);return{innerText:e.slice(t.openEnd,r),end:i===-1?e.length:i+1,complete:!0}}function ne(e,t){if(t.selfClosing)return{rawText:t.rawOpenTag,end:t.openEnd};let n=y(e,t.tagName,t.openEnd);if(n===-1)return{rawText:t.rawOpenTag,end:t.openEnd};let r=e.indexOf(`>`,n),i=r===-1?e.length:r+1;return{rawText:e.slice(t.openEnd-t.rawOpenTag.length,i),end:i}}function h(e,t){let n=b(e);return t.find(e=>b(e)===n)}function g(e){let t={},n=/([A-Za-z_][\w:-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/g,r=n.exec(e);for(;r;){let i=r[1]??``;t[i]=_(v(r[2]??r[3]??``)),r=n.exec(e)}return t}function _(e){return e===`true`?!0:e===`false`?!1:e===`null`?null:/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e)?Number(e):e}function v(e){return e.replace(/"/g,`"`).replace(/'/g,`'`).replace(/</g,`<`).replace(/>/g,`>`).replace(/&/g,`&`)}function y(e,t,n){return e.toLowerCase().indexOf(`</${t.toLowerCase()}>`,n)}function b(e){return e.replace(/[^a-z0-9]/gi,``).toLowerCase()}function re(e,t){let n=ie(e,t);return n?[n]:[]}function ie(e,t){let n=e.indexOf(`>`),r=e.lastIndexOf(`</`);if(n===-1||r===-1||r<=n)return;let i=x(e.slice(n+1,r).trim());if(!S(i))return;let a=i.command,o=i.args;if(typeof a!=`string`||!S(o))return;let s=h(a,t);if(s)return{toolName:s,args:o}}function x(e){try{return JSON.parse(e)}catch{return}}function S(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function C(e,t,n){let r=le(),i=f(t.toolNames),a=0;for(;a<e.length;){let o=p(e,a,i);if(o===-1){D(r,e.slice(a),n,i);break}D(r,e.slice(a,o),n,i);let s=w(e,o,r,t,n);if(!s.completed)break;a=s.cursor}return{visibleText:r.visibleParts.join(``),toolCalls:r.toolCalls,rawToolCallTextParts:r.rawToolCallTextParts,removedToolCallText:r.removedToolCallText}}function w(e,t,n,r,i){let a=te(e,t);if(!a)return T(e,t,n,i);let o=h(a.tagName,r.toolNames);return o?oe(e,a,o,n,r):E(e,t,a,n,r,i)}function T(e,t,n,r){return r.final?(n.visibleParts.push(e[t]??``),{cursor:t+1,completed:!0}):{cursor:t,completed:!1}}function E(e,t,n,r,i,a){let o=m(e,n,a);if(!o.complete&&!a.final)return{cursor:t,completed:!1};let s=e.slice(t,o.end),c=r.rawToolCallTextParts.length;return r.removedToolCallText=!0,ce(r,s,i),k(r,ae(o,r,i)),r.rawToolCallTextParts.length===c&&r.rawToolCallTextParts.push(s),{cursor:o.end,completed:!0}}function ae(e,t,n){return C(e.innerText,{...n,startCallIndex:A(t,n)},{final:!0})}function oe(e,t,n,r,i){let a=ne(e,t);return se(r,n,t.attributes,a.rawText,i),{cursor:a.end,completed:!0}}function D(e,t,n,r){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let i=ee(t,r);e.visibleParts.push(t.slice(0,t.length-i))}function se(e,t,n,r,i){Object.keys(n).length!==0&&(e.toolCalls.push(O(t,n,i,e)),e.rawToolCallTextParts.push(r),e.removedToolCallText=!0)}function ce(e,t,n){let r=re(t,n.toolNames);for(let i of r)e.toolCalls.push(O(i.toolName,i.args,n,e)),e.rawToolCallTextParts.push(t)}function O(e,t,n,r){return{id:`${n.callIdPrefix??`gemma_call`}_${A(r,n)}`,type:`function`,function:{name:e,arguments:JSON.stringify(t)}}}function le(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function k(e,t){e.toolCalls.push(...t.toolCalls),e.rawToolCallTextParts.push(...t.rawToolCallTextParts),e.removedToolCallText=e.removedToolCallText||t.removedToolCallText}function A(e,t){return(t.startCallIndex??0)+e.toolCalls.length}const j=`<|"|>`;var M=class{source;cursor=0;constructor(e){this.source=e}parse(){let e=this.parseObject();if(this.skipWhitespace(),this.cursor===this.source.length)return e}parseObject(){if(!this.consume(`{`))return;let e={};if(this.skipWhitespace(),this.consume(`}`))return e;for(;this.cursor<this.source.length;){let t=this.parseKey();if(!t||!this.consume(`:`))return;let n=this.parseValue();if(n===void 0)return;if(e[t]=n,this.skipWhitespace(),this.consume(`}`))return e;if(!this.consume(`,`))return}}parseArray(){if(!this.consume(`[`))return;let e=[];if(this.skipWhitespace(),this.consume(`]`))return e;for(;this.cursor<this.source.length;){let t=this.parseValue();if(t===void 0)return;if(e.push(t),this.skipWhitespace(),this.consume(`]`))return e;if(!this.consume(`,`))return}}parseValue(){return this.skipWhitespace(),this.source.startsWith(j,this.cursor)?this.parseString():this.source.startsWith(`{`,this.cursor)?this.parseObject():this.source.startsWith(`[`,this.cursor)?this.parseArray():this.consumeLiteral(`true`)?!0:this.consumeLiteral(`false`)?!1:this.consumeLiteral(`null`)?null:this.parseNumber()}parseKey(){if(this.skipWhitespace(),this.source.startsWith(j,this.cursor))return this.parseString();let e=/^[A-Za-z_][A-Za-z0-9_-]*/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),e[0]}parseString(){if(!this.consume(j))return;let e=this.source.indexOf(j,this.cursor);if(e===-1)return;let t=this.source.slice(this.cursor,e);return this.cursor=e+5,this.skipWhitespace(),t}parseNumber(){let e=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),Number(e[0])}consume(e){return this.skipWhitespace(),this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}consumeLiteral(e){return this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}skipWhitespace(){for(;/\s/.test(this.source[this.cursor]??``);)this.cursor+=1}};const N=`<|tool_call>`,P=`gemma_call`;function F(e){if(!(!e||e.length===0))return new L({toolNames:e.map(e=>e.name)})}function I(e,t){return ue(e,R(e,t,{final:!0}))}var L=class{options;buffer=``;emittedVisibleText=``;emittedRawToolCallText=``;emittedToolCallIds=new Set;constructor(e){this.options=e}project(e){return e.length===0?de():(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=R(this.buffer,this.options,e),n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length),i=t.rawToolCallTextParts.join(``),a=i.slice(this.emittedRawToolCallText.length);return this.emittedVisibleText=n,this.emittedRawToolCallText=i,{visibleText:r,toolCalls:t.toolCalls.filter(e=>this.emittedToolCallIds.has(e.id)?!1:(this.emittedToolCallIds.add(e.id),!0)),removedToolCallText:a.length>0,...a.length>0&&{rawToolCallText:a}}}};function R(e,t,n){let r=z(e,t,n),i=C(r.visibleParts.join(``),{toolNames:t.toolNames,callIdPrefix:t.callIdPrefix??P,startCallIndex:r.toolCalls.length},n);return{visibleParts:[i.visibleText],toolCalls:[...r.toolCalls,...i.toolCalls],rawToolCallTextParts:[...r.rawToolCallTextParts,...i.rawToolCallTextParts],removedToolCallText:r.removedToolCallText||i.removedToolCallText}}function z(e,t,n){let r=V(),i=new Set(t.toolNames),a=0,o=0;for(;a<e.length;){let s=e.indexOf(N,a);if(s===-1){H(r,e.slice(a),n);break}H(r,e.slice(a,s),n);let c=s+12,l=e.indexOf(`<tool_call|>`,c);if(l===-1){n.final&&r.visibleParts.push(e.slice(s));break}let u=e.slice(s,l+12),d=B(e.slice(c,l),i,t,o);d?(r.toolCalls.push(d),r.rawToolCallTextParts.push(u),r.removedToolCallText=!0,o+=1):r.visibleParts.push(u),a=l+12}return r}function B(e,t,n,r){let i=e.trim();if(!i.startsWith(`call:`))return;let a=i.slice(5).trimStart(),o=a.indexOf(`{`);if(o<=0)return;let s=a.slice(0,o).trim();if(!t.has(s))return;let c=new M(a.slice(o)).parse();if(c)return{id:`${n.callIdPrefix??P}_${r}`,type:`function`,function:{name:s,arguments:JSON.stringify(c)}}}function V(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function H(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=U(t);e.visibleParts.push(t.slice(0,t.length-r))}function U(e){let t=Math.min(e.length,11);for(let n=t;n>0;--n)if(N.startsWith(e.slice(e.length-n)))return n;return 0}function ue(e,t){return{rawText:e,visibleText:t.visibleParts.join(``),toolCalls:t.toolCalls,removedToolCallText:t.removedToolCallText,...t.rawToolCallTextParts.length>0&&{rawToolCallText:t.rawToolCallTextParts.join(``)}}}function de(){return{visibleText:``,toolCalls:[],removedToolCallText:!1}}function fe(e,n,r){let i=e.choices?.[0]?.message.content||``,a=new t.i({logger:n,...r?.tools&&{toolCallTextProjector:F(r.tools)}}).parseResponse(e),s=o(a.content??``);return W({...a,content:s.visibleText},i,s.removedReasoning)}function W(e,t,n){return n?{...e,metadata:{...e.metadata??{},gemmaReasoningFiltered:!0,gemmaRawContent:t}}:e}function G(e,t){return{id:(0,n.randomUUID)(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function pe(e,t){return{id:(0,n.randomUUID)(),role:`assistant`,content:``,toolCalls:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function me(e,n){return{reasoningProjector:new s,responseParser:new t.i({logger:e}),...n&&{toolCallProjector:F(n)}}}function he(e,t){let n=e.choices?.[0];if(!n)return[];let i=t.responseParser.parseStreamingChunk(e);return i&&(0,r.isAssistantMessage)(i)&&i.toolCalls?.length?[i]:K(n.delta.content||``,n.finish_reason,t)}function ge(e){let t=K(``,null,e,!0),n=e.reasoningProjector.flush();return n.length>0&&t.push(G(n,null)),t}function K(e,t,n,r=!1){let i=r?n.toolCallProjector?.flush():n.toolCallProjector?.project(e),a=[];i?.toolCalls.length&&a.push(pe(i.toolCalls,t));let o=i?.visibleText??e,s=n.reasoningProjector.project(o);return s.length>0&&a.push(G(s,t)),a}var q=class extends r.AbstractAIProvider{name=`gemma`;version=`1.0.0`;client;options;onTextDelta;constructor(e){if(super(e.logger||r.SilentLogger),this.options=e,e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new i.default({apiKey:e.apiKey,...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout}});else throw Error(`Either Gemma client, apiKey, or executor is required`)}async chat(e,t){if(this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(e,t)}catch(e){throw this.logger.error(`Gemma Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let n=this.buildRequestParams(e,t),r=t?.onTextDelta??this.onTextDelta;if(r)return await this.chatWithStreamingAssembly({...n,stream:!0},{...t,onTextDelta:r});t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let i=await this.client.chat.completions.create(n);return t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),fe(i,this.logger,t)}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma chat failed: ${t}`)}}async*chatStream(e,n){if(this.validateMessages(e),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(e,n);return}catch(e){throw this.logger.error(`Gemma Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let r=this.buildStreamingRequestParams(e,n);n?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:r});let i=await this.client.chat.completions.create(r),a=me(this.logger,n?.tools),o=t.n(i,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n?.onProviderNativeRawPayload});for await(let e of this.streamWithAbort(o,n?.signal))for(let t of he(e,a))yield t;for(let e of ge(a))yield e}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma stream failed: ${t}`)}}supportsTools(){return!0}getCapabilities(){return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web search.`},webFetch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web fetch.`}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}buildRequestParams(e,n){let r=n?.model??this.options.defaultModel;if(!r)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);return{model:r,messages:t.a(e),...n?.temperature!==void 0&&{temperature:n.temperature},...n?.maxTokens!==void 0&&{max_tokens:n.maxTokens},...n?.tools&&{tools:t.o(n.tools),tool_choice:`auto`}}}buildStreamingRequestParams(e,t){return{...this.buildRequestParams(e,t),stream:!0}}async chatWithStreamingAssembly(e,n){if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{n.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:e});let r=await this.client.chat.completions.create(e,n.signal?{signal:n.signal}:void 0),i=new s;return W(await t.r({stream:t.n(r,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n.onProviderNativeRawPayload}),onTextDelta:n.onTextDelta,signal:n.signal,textProjector:e=>i.project(e),textProjectorFlush:()=>i.flush(),toolCallTextProjector:F(n.tools)}),i.rawText,i.removedReasoning)}catch(e){let t=e.message||`Gemma streaming request failed`;throw Error(`Gemma stream failed: ${t}`)}}};const J=`supergemma4-26b-uncensored-v2`,Y=`lm-studio`,X=`http://localhost:1234/v1`,Z=`https://ai.google.dev/gemma`,Q=`2026-05-04`,$=`https://lmstudio.ai/docs/developer`,_e=[{kind:`official`,label:`LM Studio local API documentation`,url:$,sourceUrl:$,lastVerifiedAt:`2026-05-08`}],ve={status:`fallback`,sourceUrl:Z,lastVerifiedAt:Q,entries:[{id:J,displayName:`SuperGemma 4 26B`,capabilities:[`tools`,`streaming`],lifecycle:`active`,sourceUrl:Z,lastVerifiedAt:Q}]};function ye(){return{type:`gemma`,displayName:`Gemma`,description:`Gemma-family local models through an OpenAI-compatible endpoint`,defaults:{model:J,apiKey:Y,baseURL:X},modelCatalog:ve,setupHelpLinks:_e,setupSteps:[{key:`baseURL`,title:`Gemma OpenAI-compatible base URL`,defaultValue:X},{key:`model`,title:`Gemma model`,defaultValue:J},{key:`apiKey`,title:`Gemma OpenAI-compatible API key`,defaultValue:Y,masked:!0}],requiresApiKey:!0,probeProfile:t.t,createProvider:e=>new q({apiKey:be(e.apiKey),...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout},defaultModel:e.model})}}function be(e){if(!e)throw Error(`Provider gemma requires apiKey`);return e}Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return o}});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e,i as t,n,o as r,r as i,t as a}from"./openai-compatible-Dm4Sof9e.js";import{randomUUID as o}from"node:crypto";import{AbstractAIProvider as s,SilentLogger as c,isAssistantMessage as l}from"@robota-sdk/agent-core";import u from"openai";const d=`<|channel>`;function f(e){let t=m(e,{final:!0});return{rawText:e,visibleText:t.visibleParts.join(``),removedReasoning:t.removedReasoning}}var p=class{buffer=``;emittedVisibleText=``;hasRemovedReasoning=!1;get rawText(){return this.buffer}get removedReasoning(){return this.hasRemovedReasoning}project(e){return e.length===0?``:(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=m(this.buffer,e);this.hasRemovedReasoning=this.hasRemovedReasoning||t.removedReasoning;let n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length);return this.emittedVisibleText=n,r}};function m(e,t){let n={visibleParts:[],removedReasoning:!1},r=0;for(;r<e.length;){let i=e.indexOf(d,r);if(i===-1){h(n,e.slice(r),t);break}h(n,e.slice(r,i),t);let a=i+10,o=e.indexOf(`<channel|>`,a);if(o===-1){t.final&&(n.removedReasoning=!0);break}n.removedReasoning=!0,r=ee(e,a,o)}return n}function h(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=te(t);e.visibleParts.push(t.slice(0,t.length-r))}function ee(e,t,n){let r=e.slice(t,n),i=n+10;if(r.trim().length===0){let t=e.slice(i).match(/^thought(?:\r?\n)*/);return t&&(i+=t[0].length),i}return r.split(/\r?\n/,1)[0]?.trim(),i}function te(e){let t=Math.min(e.length,9);for(let n=t;n>0;--n)if(d.startsWith(e.slice(e.length-n)))return n;return 0}function ne(e){return[`<`]}function re(e,t,n){return e.indexOf(`<`,t)}function ie(e,t){return+!!e.endsWith(`<`)}function g(e,t){let n=e.indexOf(`>`,t+1);if(n===-1)return;let r=e.slice(t,n+1),i=r.match(/^<\s*([A-Za-z][\w:-]*)([\s/>][\s\S]*?|)>$/);if(!i)return;let a=i[1]??``;return{tagName:a,normalizedName:a.toLowerCase(),rawOpenTag:r,attributes:b(i[2]??``),openEnd:n+1,selfClosing:/\/\s*>$/.test(r)}}function _(e,t,n){if(t.selfClosing)return{innerText:``,end:t.openEnd,complete:!0};let r=S(e,t.tagName,t.openEnd);if(r===-1)return{innerText:e.slice(t.openEnd),end:n.final?e.length:t.openEnd-t.rawOpenTag.length,complete:!1};let i=e.indexOf(`>`,r);return{innerText:e.slice(t.openEnd,r),end:i===-1?e.length:i+1,complete:!0}}function v(e,t){if(t.selfClosing)return{rawText:t.rawOpenTag,end:t.openEnd};let n=S(e,t.tagName,t.openEnd);if(n===-1)return{rawText:t.rawOpenTag,end:t.openEnd};let r=e.indexOf(`>`,n),i=r===-1?e.length:r+1;return{rawText:e.slice(t.openEnd-t.rawOpenTag.length,i),end:i}}function y(e,t){let n=C(e);return t.find(e=>C(e)===n)}function b(e){let t={},n=/([A-Za-z_][\w:-]*)\s*=\s*(?:"([^"]*)"|'([^']*)')/g,r=n.exec(e);for(;r;){let i=r[1]??``;t[i]=ae(x(r[2]??r[3]??``)),r=n.exec(e)}return t}function ae(e){return e===`true`?!0:e===`false`?!1:e===`null`?null:/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e)?Number(e):e}function x(e){return e.replace(/"/g,`"`).replace(/'/g,`'`).replace(/</g,`<`).replace(/>/g,`>`).replace(/&/g,`&`)}function S(e,t,n){return e.toLowerCase().indexOf(`</${t.toLowerCase()}>`,n)}function C(e){return e.replace(/[^a-z0-9]/gi,``).toLowerCase()}function w(e,t){let n=T(e,t);return n?[n]:[]}function T(e,t){let n=e.indexOf(`>`),r=e.lastIndexOf(`</`);if(n===-1||r===-1||r<=n)return;let i=E(e.slice(n+1,r).trim());if(!D(i))return;let a=i.command,o=i.args;if(typeof a!=`string`||!D(o))return;let s=y(a,t);if(s)return{toolName:s,args:o}}function E(e){try{return JSON.parse(e)}catch{return}}function D(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function O(e,t,n){let r=j(),i=ne(t.toolNames),a=0;for(;a<e.length;){let o=re(e,a,i);if(o===-1){k(r,e.slice(a),n,i);break}k(r,e.slice(a,o),n,i);let s=oe(e,o,r,t,n);if(!s.completed)break;a=s.cursor}return{visibleText:r.visibleParts.join(``),toolCalls:r.toolCalls,rawToolCallTextParts:r.rawToolCallTextParts,removedToolCallText:r.removedToolCallText}}function oe(e,t,n,r,i){let a=g(e,t);if(!a)return se(e,t,n,i);let o=y(a.tagName,r.toolNames);return o?ue(e,a,o,n,r):ce(e,t,a,n,r,i)}function se(e,t,n,r){return r.final?(n.visibleParts.push(e[t]??``),{cursor:t+1,completed:!0}):{cursor:t,completed:!1}}function ce(e,t,n,r,i,a){let o=_(e,n,a);if(!o.complete&&!a.final)return{cursor:t,completed:!1};let s=e.slice(t,o.end),c=r.rawToolCallTextParts.length;return r.removedToolCallText=!0,fe(r,s,i),M(r,le(o,r,i)),r.rawToolCallTextParts.length===c&&r.rawToolCallTextParts.push(s),{cursor:o.end,completed:!0}}function le(e,t,n){return O(e.innerText,{...n,startCallIndex:N(t,n)},{final:!0})}function ue(e,t,n,r,i){let a=v(e,t);return de(r,n,t.attributes,a.rawText,i),{cursor:a.end,completed:!0}}function k(e,t,n,r){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let i=ie(t,r);e.visibleParts.push(t.slice(0,t.length-i))}function de(e,t,n,r,i){Object.keys(n).length!==0&&(e.toolCalls.push(A(t,n,i,e)),e.rawToolCallTextParts.push(r),e.removedToolCallText=!0)}function fe(e,t,n){let r=w(t,n.toolNames);for(let i of r)e.toolCalls.push(A(i.toolName,i.args,n,e)),e.rawToolCallTextParts.push(t)}function A(e,t,n,r){return{id:`${n.callIdPrefix??`gemma_call`}_${N(r,n)}`,type:`function`,function:{name:e,arguments:JSON.stringify(t)}}}function j(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function M(e,t){e.toolCalls.push(...t.toolCalls),e.rawToolCallTextParts.push(...t.rawToolCallTextParts),e.removedToolCallText=e.removedToolCallText||t.removedToolCallText}function N(e,t){return(t.startCallIndex??0)+e.toolCalls.length}const P=`<|"|>`;var F=class{source;cursor=0;constructor(e){this.source=e}parse(){let e=this.parseObject();if(this.skipWhitespace(),this.cursor===this.source.length)return e}parseObject(){if(!this.consume(`{`))return;let e={};if(this.skipWhitespace(),this.consume(`}`))return e;for(;this.cursor<this.source.length;){let t=this.parseKey();if(!t||!this.consume(`:`))return;let n=this.parseValue();if(n===void 0)return;if(e[t]=n,this.skipWhitespace(),this.consume(`}`))return e;if(!this.consume(`,`))return}}parseArray(){if(!this.consume(`[`))return;let e=[];if(this.skipWhitespace(),this.consume(`]`))return e;for(;this.cursor<this.source.length;){let t=this.parseValue();if(t===void 0)return;if(e.push(t),this.skipWhitespace(),this.consume(`]`))return e;if(!this.consume(`,`))return}}parseValue(){return this.skipWhitespace(),this.source.startsWith(P,this.cursor)?this.parseString():this.source.startsWith(`{`,this.cursor)?this.parseObject():this.source.startsWith(`[`,this.cursor)?this.parseArray():this.consumeLiteral(`true`)?!0:this.consumeLiteral(`false`)?!1:this.consumeLiteral(`null`)?null:this.parseNumber()}parseKey(){if(this.skipWhitespace(),this.source.startsWith(P,this.cursor))return this.parseString();let e=/^[A-Za-z_][A-Za-z0-9_-]*/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),e[0]}parseString(){if(!this.consume(P))return;let e=this.source.indexOf(P,this.cursor);if(e===-1)return;let t=this.source.slice(this.cursor,e);return this.cursor=e+5,this.skipWhitespace(),t}parseNumber(){let e=/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/.exec(this.source.slice(this.cursor));if(e)return this.cursor+=e[0].length,this.skipWhitespace(),Number(e[0])}consume(e){return this.skipWhitespace(),this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}consumeLiteral(e){return this.source.startsWith(e,this.cursor)?(this.cursor+=e.length,this.skipWhitespace(),!0):!1}skipWhitespace(){for(;/\s/.test(this.source[this.cursor]??``);)this.cursor+=1}};const I=`<|tool_call>`,L=`gemma_call`;function R(e){if(!(!e||e.length===0))return new B({toolNames:e.map(e=>e.name)})}function z(e,t){return _e(e,V(e,t,{final:!0}))}var B=class{options;buffer=``;emittedVisibleText=``;emittedRawToolCallText=``;emittedToolCallIds=new Set;constructor(e){this.options=e}project(e){return e.length===0?ve():(this.buffer+=e,this.projectVisibleText({final:!1}))}flush(){return this.projectVisibleText({final:!0})}projectVisibleText(e){let t=V(this.buffer,this.options,e),n=t.visibleParts.join(``),r=n.slice(this.emittedVisibleText.length),i=t.rawToolCallTextParts.join(``),a=i.slice(this.emittedRawToolCallText.length);return this.emittedVisibleText=n,this.emittedRawToolCallText=i,{visibleText:r,toolCalls:t.toolCalls.filter(e=>this.emittedToolCallIds.has(e.id)?!1:(this.emittedToolCallIds.add(e.id),!0)),removedToolCallText:a.length>0,...a.length>0&&{rawToolCallText:a}}}};function V(e,t,n){let r=pe(e,t,n),i=O(r.visibleParts.join(``),{toolNames:t.toolNames,callIdPrefix:t.callIdPrefix??L,startCallIndex:r.toolCalls.length},n);return{visibleParts:[i.visibleText],toolCalls:[...r.toolCalls,...i.toolCalls],rawToolCallTextParts:[...r.rawToolCallTextParts,...i.rawToolCallTextParts],removedToolCallText:r.removedToolCallText||i.removedToolCallText}}function pe(e,t,n){let r=he(),i=new Set(t.toolNames),a=0,o=0;for(;a<e.length;){let s=e.indexOf(I,a);if(s===-1){H(r,e.slice(a),n);break}H(r,e.slice(a,s),n);let c=s+12,l=e.indexOf(`<tool_call|>`,c);if(l===-1){n.final&&r.visibleParts.push(e.slice(s));break}let u=e.slice(s,l+12),d=me(e.slice(c,l),i,t,o);d?(r.toolCalls.push(d),r.rawToolCallTextParts.push(u),r.removedToolCallText=!0,o+=1):r.visibleParts.push(u),a=l+12}return r}function me(e,t,n,r){let i=e.trim();if(!i.startsWith(`call:`))return;let a=i.slice(5).trimStart(),o=a.indexOf(`{`);if(o<=0)return;let s=a.slice(0,o).trim();if(!t.has(s))return;let c=new F(a.slice(o)).parse();if(c)return{id:`${n.callIdPrefix??L}_${r}`,type:`function`,function:{name:s,arguments:JSON.stringify(c)}}}function he(){return{visibleParts:[],toolCalls:[],rawToolCallTextParts:[],removedToolCallText:!1}}function H(e,t,n){if(t.length===0)return;if(n.final){e.visibleParts.push(t);return}let r=ge(t);e.visibleParts.push(t.slice(0,t.length-r))}function ge(e){let t=Math.min(e.length,11);for(let n=t;n>0;--n)if(I.startsWith(e.slice(e.length-n)))return n;return 0}function _e(e,t){return{rawText:e,visibleText:t.visibleParts.join(``),toolCalls:t.toolCalls,removedToolCallText:t.removedToolCallText,...t.rawToolCallTextParts.length>0&&{rawToolCallText:t.rawToolCallTextParts.join(``)}}}function ve(){return{visibleText:``,toolCalls:[],removedToolCallText:!1}}function ye(e,n,r){let i=e.choices?.[0]?.message.content||``,a=new t({logger:n,...r?.tools&&{toolCallTextProjector:R(r.tools)}}).parseResponse(e),o=f(a.content??``);return U({...a,content:o.visibleText},i,o.removedReasoning)}function U(e,t,n){return n?{...e,metadata:{...e.metadata??{},gemmaReasoningFiltered:!0,gemmaRawContent:t}}:e}function W(e,t){return{id:o(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function be(e,t){return{id:o(),role:`assistant`,content:``,toolCalls:e,state:`complete`,timestamp:new Date,metadata:{isStreamChunk:!0,isComplete:t===`stop`||t===`tool_calls`}}}function xe(e,n){return{reasoningProjector:new p,responseParser:new t({logger:e}),...n&&{toolCallProjector:R(n)}}}function Se(e,t){let n=e.choices?.[0];if(!n)return[];let r=t.responseParser.parseStreamingChunk(e);return r&&l(r)&&r.toolCalls?.length?[r]:K(n.delta.content||``,n.finish_reason,t)}function G(e){let t=K(``,null,e,!0),n=e.reasoningProjector.flush();return n.length>0&&t.push(W(n,null)),t}function K(e,t,n,r=!1){let i=r?n.toolCallProjector?.flush():n.toolCallProjector?.project(e),a=[];i?.toolCalls.length&&a.push(be(i.toolCalls,t));let o=i?.visibleText??e,s=n.reasoningProjector.project(o);return s.length>0&&a.push(W(s,t)),a}var q=class extends s{name=`gemma`;version=`1.0.0`;client;options;onTextDelta;constructor(e){if(super(e.logger||c),this.options=e,e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new u({apiKey:e.apiKey,...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout}});else throw Error(`Either Gemma client, apiKey, or executor is required`)}async chat(e,t){if(this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(e,t)}catch(e){throw this.logger.error(`Gemma Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let n=this.buildRequestParams(e,t),r=t?.onTextDelta??this.onTextDelta;if(r)return await this.chatWithStreamingAssembly({...n,stream:!0},{...t,onTextDelta:r});t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let i=await this.client.chat.completions.create(n);return t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),ye(i,this.logger,t)}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma chat failed: ${t}`)}}async*chatStream(e,t){if(this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(e,t);return}catch(e){throw this.logger.error(`Gemma Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{let r=this.buildStreamingRequestParams(e,t);t?.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:r});let i=await this.client.chat.completions.create(r),a=xe(this.logger,t?.tools),o=n(i,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:t?.onProviderNativeRawPayload});for await(let e of this.streamWithAbort(o,t?.signal))for(let t of Se(e,a))yield t;for(let e of G(a))yield e}catch(e){let t=e.message||`Gemma API request failed`;throw Error(`Gemma stream failed: ${t}`)}}supportsTools(){return!0}getCapabilities(){return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web search.`},webFetch:{supported:!1,enabled:!1,source:`openai-compatible-chat-completions`,reason:`Gemma OpenAI-compatible endpoints support declared function tools, not provider-native web fetch.`}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}buildRequestParams(t,n){let i=n?.model??this.options.defaultModel;if(!i)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);return{model:i,messages:e(t),...n?.temperature!==void 0&&{temperature:n.temperature},...n?.maxTokens!==void 0&&{max_tokens:n.maxTokens},...n?.tools&&{tools:r(n.tools),tool_choice:`auto`}}}buildStreamingRequestParams(e,t){return{...this.buildRequestParams(e,t),stream:!0}}async chatWithStreamingAssembly(e,t){if(!this.client)throw Error(`Gemma client not available. Either provide a client/apiKey or use an executor.`);try{t.onProviderNativeRawPayload?.({provider:`gemma`,apiSurface:`chat-completions`,payloadKind:`request`,payload:e});let r=await this.client.chat.completions.create(e,t.signal?{signal:t.signal}:void 0),a=new p;return U(await i({stream:n(r,{provider:`gemma`,apiSurface:`chat-completions`,onProviderNativeRawPayload:t.onProviderNativeRawPayload}),onTextDelta:t.onTextDelta,signal:t.signal,textProjector:e=>a.project(e),textProjectorFlush:()=>a.flush(),toolCallTextProjector:R(t.tools)}),a.rawText,a.removedReasoning)}catch(e){let t=e.message||`Gemma streaming request failed`;throw Error(`Gemma stream failed: ${t}`)}}};const J=`supergemma4-26b-uncensored-v2`,Y=`lm-studio`,X=`http://localhost:1234/v1`,Z=`https://ai.google.dev/gemma`,Q=`2026-05-04`,$=`https://lmstudio.ai/docs/developer`,Ce=[{kind:`official`,label:`LM Studio local API documentation`,url:$,sourceUrl:$,lastVerifiedAt:`2026-05-08`}],we={status:`fallback`,sourceUrl:Z,lastVerifiedAt:Q,entries:[{id:J,displayName:`SuperGemma 4 26B`,capabilities:[`tools`,`streaming`],lifecycle:`active`,sourceUrl:Z,lastVerifiedAt:Q}]};function Te(){return{type:`gemma`,displayName:`Gemma`,description:`Gemma-family local models through an OpenAI-compatible endpoint`,defaults:{model:J,apiKey:Y,baseURL:X},modelCatalog:we,setupHelpLinks:Ce,setupSteps:[{key:`baseURL`,title:`Gemma OpenAI-compatible base URL`,defaultValue:X},{key:`model`,title:`Gemma model`,defaultValue:J},{key:`apiKey`,title:`Gemma OpenAI-compatible API key`,defaultValue:Y,masked:!0}],requiresApiKey:!0,probeProfile:a,createProvider:e=>new q({apiKey:Ee(e.apiKey),...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout},defaultModel:e.model})}}function Ee(e){if(!e)throw Error(`Provider gemma requires apiKey`);return e}export{q as a,z as c,Te as i,p as l,X as n,B as o,J as r,R as s,Y as t,f as u};
|
|
2
|
+
//# sourceMappingURL=gemma-BMFWnmXE.js.map
|