@fgv/ts-extras 5.1.0-48 → 5.1.0-49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/dist/packlets/ai-assist/completionClient.js +435 -0
  2. package/dist/packlets/ai-assist/completionClient.js.map +1 -0
  3. package/dist/packlets/ai-assist/embeddingClient.js +2 -2
  4. package/dist/packlets/ai-assist/embeddingClient.js.map +1 -1
  5. package/dist/packlets/ai-assist/endpoint.js +29 -0
  6. package/dist/packlets/ai-assist/endpoint.js.map +1 -1
  7. package/dist/packlets/ai-assist/http.js +48 -19
  8. package/dist/packlets/ai-assist/http.js.map +1 -1
  9. package/dist/packlets/ai-assist/imageGenerationClient.js +454 -0
  10. package/dist/packlets/ai-assist/imageGenerationClient.js.map +1 -0
  11. package/dist/packlets/ai-assist/index.js +3 -1
  12. package/dist/packlets/ai-assist/index.js.map +1 -1
  13. package/dist/packlets/ai-assist/jsonCompletion.js +1 -1
  14. package/dist/packlets/ai-assist/jsonCompletion.js.map +1 -1
  15. package/dist/packlets/ai-assist/listModelsClient.js +294 -0
  16. package/dist/packlets/ai-assist/listModelsClient.js.map +1 -0
  17. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js +2 -5
  18. package/dist/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -1
  19. package/dist/packlets/ai-assist/streamingAdapters/gemini.js +2 -1
  20. package/dist/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -1
  21. package/dist/packlets/crypto-utils/encryptedFile.js +37 -0
  22. package/dist/packlets/crypto-utils/encryptedFile.js.map +1 -1
  23. package/dist/packlets/crypto-utils/index.js +1 -1
  24. package/dist/packlets/crypto-utils/index.js.map +1 -1
  25. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js +32 -0
  26. package/dist/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -1
  27. package/dist/ts-extras.d.ts +59 -4
  28. package/lib/packlets/ai-assist/completionClient.d.ts +74 -0
  29. package/lib/packlets/ai-assist/completionClient.d.ts.map +1 -0
  30. package/lib/packlets/ai-assist/completionClient.js +439 -0
  31. package/lib/packlets/ai-assist/completionClient.js.map +1 -0
  32. package/lib/packlets/ai-assist/embeddingClient.js +1 -1
  33. package/lib/packlets/ai-assist/embeddingClient.js.map +1 -1
  34. package/lib/packlets/ai-assist/endpoint.d.ts +21 -0
  35. package/lib/packlets/ai-assist/endpoint.d.ts.map +1 -1
  36. package/lib/packlets/ai-assist/endpoint.js +31 -0
  37. package/lib/packlets/ai-assist/endpoint.js.map +1 -1
  38. package/lib/packlets/ai-assist/http.d.ts +12 -2
  39. package/lib/packlets/ai-assist/http.d.ts.map +1 -1
  40. package/lib/packlets/ai-assist/http.js +49 -18
  41. package/lib/packlets/ai-assist/http.js.map +1 -1
  42. package/lib/packlets/ai-assist/imageGenerationClient.d.ts +46 -0
  43. package/lib/packlets/ai-assist/imageGenerationClient.d.ts.map +1 -0
  44. package/lib/packlets/ai-assist/imageGenerationClient.js +458 -0
  45. package/lib/packlets/ai-assist/imageGenerationClient.js.map +1 -0
  46. package/lib/packlets/ai-assist/index.d.ts +3 -1
  47. package/lib/packlets/ai-assist/index.d.ts.map +1 -1
  48. package/lib/packlets/ai-assist/index.js +9 -7
  49. package/lib/packlets/ai-assist/index.js.map +1 -1
  50. package/lib/packlets/ai-assist/jsonCompletion.d.ts +1 -1
  51. package/lib/packlets/ai-assist/jsonCompletion.d.ts.map +1 -1
  52. package/lib/packlets/ai-assist/jsonCompletion.js +2 -2
  53. package/lib/packlets/ai-assist/jsonCompletion.js.map +1 -1
  54. package/lib/packlets/ai-assist/listModelsClient.d.ts +46 -0
  55. package/lib/packlets/ai-assist/listModelsClient.d.ts.map +1 -0
  56. package/lib/packlets/ai-assist/listModelsClient.js +298 -0
  57. package/lib/packlets/ai-assist/listModelsClient.js.map +1 -0
  58. package/lib/packlets/ai-assist/streamingAdapters/anthropic.d.ts.map +1 -1
  59. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js +2 -5
  60. package/lib/packlets/ai-assist/streamingAdapters/anthropic.js.map +1 -1
  61. package/lib/packlets/ai-assist/streamingAdapters/gemini.d.ts.map +1 -1
  62. package/lib/packlets/ai-assist/streamingAdapters/gemini.js +2 -1
  63. package/lib/packlets/ai-assist/streamingAdapters/gemini.js.map +1 -1
  64. package/lib/packlets/crypto-utils/encryptedFile.d.ts +25 -0
  65. package/lib/packlets/crypto-utils/encryptedFile.d.ts.map +1 -1
  66. package/lib/packlets/crypto-utils/encryptedFile.js +38 -0
  67. package/lib/packlets/crypto-utils/encryptedFile.js.map +1 -1
  68. package/lib/packlets/crypto-utils/index.d.ts +1 -1
  69. package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
  70. package/lib/packlets/crypto-utils/index.js +2 -1
  71. package/lib/packlets/crypto-utils/index.js.map +1 -1
  72. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts +30 -2
  73. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.d.ts.map +1 -1
  74. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js +32 -0
  75. package/lib/packlets/zip-file-tree/zipFileTreeAccessors.js.map +1 -1
  76. package/package.json +7 -7
  77. package/dist/packlets/ai-assist/apiClient.js +0 -1236
  78. package/dist/packlets/ai-assist/apiClient.js.map +0 -1
  79. package/lib/packlets/ai-assist/apiClient.d.ts +0 -152
  80. package/lib/packlets/ai-assist/apiClient.d.ts.map +0 -1
  81. package/lib/packlets/ai-assist/apiClient.js +0 -1244
  82. package/lib/packlets/ai-assist/apiClient.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,iCAiGiB;AAhGf,iGAAA,QAAQ,OAAA;AAER,6GAAA,oBAAoB,OAAA;AAcpB,qHAAA,4BAA4B,OAAA;AAe5B,0GAAA,iBAAiB,OAAA;AAEjB,iHAAA,wBAAwB,OAAA;AAoCxB,yGAAA,gBAAgB,OAAA;AAChB,4GAAA,mBAAmB,OAAA;AACnB,qGAAA,YAAY,OAAA;AAEZ,0GAAA,iBAAiB,OAAA;AACjB,0GAAA,iBAAiB,OAAA;AACjB,6GAAA,oBAAoB,OAAA;AACpB,6GAAA,oBAAoB,OAAA;AACpB,gHAAA,uBAAuB,OAAA;AACvB,qHAAA,4BAA4B,OAAA;AAC5B,kGAAA,SAAS,OAAA;AAmBX,+DAIgC;AAF9B,2HAAA,mBAAmB,OAAA;AACnB,+HAAA,uBAAuB,OAAA;AAGzB,uCASoB;AARlB,0GAAA,cAAc,OAAA;AACd,kHAAA,sBAAsB,OAAA;AACtB,iHAAA,qBAAqB,OAAA;AACrB,kHAAA,sBAAsB,OAAA;AACtB,mHAAA,uBAAuB,OAAA;AACvB,sHAAA,0BAA0B,OAAA;AAC1B,6GAAA,iBAAiB,OAAA;AACjB,2HAAA,+BAA+B,OAAA;AAGjC,yCAUqB;AATnB,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AACrB,wHAAA,2BAA2B,OAAA;AAC3B,uHAAA,0BAA0B,OAAA;AAC1B,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AAMvB,qDAI2B;AAHzB,wHAAA,qBAAqB,OAAA;AACrB,uHAAA,oBAAoB,OAAA;AAItB,qDAQ2B;AAPzB,+HAAA,4BAA4B,OAAA;AAC5B,8HAAA,2BAA2B,OAAA;AAE3B,wHAAA,qBAAqB,OAAA;AAMvB,2CAYsB;AAXpB,0GAAA,YAAY,OAAA;AACZ,8GAAA,gBAAgB,OAAA;AAChB,mHAAA,qBAAqB,OAAA;AACrB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,gHAAA,kBAAkB,OAAA;AAClB,8GAAA,gBAAgB,OAAA;AAChB,oHAAA,sBAAsB,OAAA;AACtB,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,uGAAA,SAAS,OAAA;AAGX,6CAAsD;AAA7C,oHAAA,qBAAqB,OAAA;AAE9B,+CAQwB;AAPtB,wHAAA,wBAAwB,OAAA;AACxB,+GAAA,eAAe,OAAA;AACf,qHAAA,qBAAqB,OAAA;AAOvB,mDAM0B;AALxB,wHAAA,sBAAsB,OAAA;AACtB,wHAAA,sBAAsB,OAAA;AAMxB,qEAAwG;AAA/F,wIAAA,6BAA6B,OAAA","sourcesContent":["/**\n * AI assist packlet - provider registry, prompt class, settings, and API client.\n * @packageDocumentation\n */\n\nexport {\n AiPrompt,\n type AiModelCapability,\n allModelCapabilities,\n type AiProviderId,\n type AiServerToolType,\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiWebSearchToolConfig,\n type IAiClientToolConfig,\n type IAiToolAnnotations,\n type IAiClientTool,\n type IAiClientToolCallSummary,\n type IAiClientToolContinuation,\n type IAiClientToolTurnResult,\n type IAiToolEnablement,\n type IAiCompletionResponse,\n DEFAULT_ANTHROPIC_MAX_TOKENS,\n type IChatMessage,\n type IChatRequest,\n type AiApiFormat,\n type AiImageApiFormat,\n type AiEmbeddingApiFormat,\n type AiEmbeddingTaskType,\n type IAiEmbeddingModelCapability,\n type IAiEmbeddingParams,\n type IAiEmbeddingUsage,\n type IAiEmbeddingResult,\n type IAiImageModelCapability,\n type IAiProviderDescriptor,\n type IAiAssistProviderConfig,\n type IAiAssistSettings,\n DEFAULT_AI_ASSIST,\n type IAiAssistKeyStore,\n providerApiKeySecretName,\n type IAiImageAttachment,\n type IAiImageData,\n type AiImageSize,\n type AiImageQuality,\n type GptImageSize,\n type GptImageQuality,\n type GptImageModelNames,\n type GrokImagineModelNames,\n type GeminiFlashImageModelNames,\n type IGptImageGenerationConfig,\n type IGrokImagineImageGenerationConfig,\n type IGeminiFlashImageGenerationConfig,\n type IGptImageModelOptions,\n type IGrokImagineModelOptions,\n type IGeminiFlashImageModelOptions,\n type IOtherModelOptions,\n type IModelFamilyConfig,\n type IAiImageGenerationOptions,\n type IAiImageGenerationParams,\n type IAiGeneratedImage,\n type IAiImageGenerationResponse,\n type IAiModelCapabilityRule,\n type IAiModelCapabilityConfig,\n type IAiModelInfo,\n type IAiStreamEvent,\n type IAiStreamTextDelta,\n type IAiStreamToolEvent,\n type IAiStreamToolUseStart,\n type IAiStreamToolUseDelta,\n type IAiStreamToolUseComplete,\n type IAiStreamDone,\n type IAiStreamError,\n type ModelSpec,\n type ModelSpecKey,\n type IModelSpecMap,\n allModelSpecKeys,\n MODEL_SPEC_BASE_KEY,\n resolveModel,\n type IModelAliasMap,\n MODEL_ALIAS_SIGIL,\n resolveModelAlias,\n resolveProviderModel,\n isResponsesOnlyModel,\n isAdaptiveThinkingModel,\n usesMaxCompletionTokensField,\n toDataUrl,\n type AiThinkingMode,\n type IThinkingConfig,\n type IThinkingProviderConfig,\n type IAnthropicThinkingOptions,\n type IOpenAiThinkingOptions,\n type IGeminiThinkingOptions,\n type IXAiThinkingOptions,\n type IOtherThinkingOptions,\n type IAnthropicThinkingConfig,\n type IOpenAiThinkingConfig,\n type IGeminiThinkingConfig,\n type IXAiThinkingConfig,\n type AnthropicThinkingModelNames,\n type OpenAiThinkingModelNames,\n type GeminiThinkingModelNames,\n type XAiThinkingModelNames\n} from './model';\n\nexport {\n type IResolvedImageOptions,\n resolveImageOptions,\n validateResolvedOptions\n} from './imageOptionsResolver';\n\nexport {\n allProviderIds,\n getProviderDescriptors,\n getProviderDescriptor,\n resolveImageCapability,\n supportsImageGeneration,\n resolveEmbeddingCapability,\n supportsEmbedding,\n DEFAULT_MODEL_CAPABILITY_CONFIG\n} from './registry';\n\nexport {\n callProviderCompletion,\n callProxiedCompletion,\n callProviderImageGeneration,\n callProxiedImageGeneration,\n callProviderListModels,\n callProxiedListModels,\n type IProviderCompletionParams,\n type IProviderImageGenerationParams,\n type IProviderListModelsParams\n} from './apiClient';\n\nexport {\n callProviderEmbedding,\n callProxiedEmbedding,\n type IProviderEmbeddingParams\n} from './embeddingClient';\n\nexport {\n callProviderCompletionStream,\n callProxiedCompletionStream,\n type IProviderCompletionStreamParams,\n executeClientToolTurn,\n type IExecuteClientToolTurnParams,\n type IExecuteClientToolTurnResult,\n type IToolExecutionDecision\n} from './streamingClient';\n\nexport {\n aiProviderId,\n aiServerToolType,\n aiWebSearchToolConfig,\n aiServerToolConfig,\n aiToolAnnotations,\n aiClientToolConfig,\n aiToolEnablement,\n aiAssistProviderConfig,\n aiAssistSettings,\n modelSpecKey,\n modelSpec\n} from './converters';\n\nexport { resolveEffectiveTools } from './toolFormats';\n\nexport {\n classifyJsonParseFailure,\n extractJsonText,\n fencedStringifiedJson,\n type IFencedStringifiedJsonExtractorOptions,\n type IFencedStringifiedJsonOptions,\n type JsonParseFailureReason,\n type JsonTextExtractor\n} from './jsonResponse';\n\nexport {\n generateJsonCompletion,\n SMART_JSON_PROMPT_HINT,\n type IGenerateJsonCompletionParams,\n type IGenerateJsonCompletionResult,\n type JsonPromptHint\n} from './jsonCompletion';\n\nexport { anthropicEffortToBudgetTokens, type IResolvedThinkingConfig } from './thinkingOptionsResolver';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,iCAiGiB;AAhGf,iGAAA,QAAQ,OAAA;AAER,6GAAA,oBAAoB,OAAA;AAcpB,qHAAA,4BAA4B,OAAA;AAe5B,0GAAA,iBAAiB,OAAA;AAEjB,iHAAA,wBAAwB,OAAA;AAoCxB,yGAAA,gBAAgB,OAAA;AAChB,4GAAA,mBAAmB,OAAA;AACnB,qGAAA,YAAY,OAAA;AAEZ,0GAAA,iBAAiB,OAAA;AACjB,0GAAA,iBAAiB,OAAA;AACjB,6GAAA,oBAAoB,OAAA;AACpB,6GAAA,oBAAoB,OAAA;AACpB,gHAAA,uBAAuB,OAAA;AACvB,qHAAA,4BAA4B,OAAA;AAC5B,kGAAA,SAAS,OAAA;AAmBX,+DAIgC;AAF9B,2HAAA,mBAAmB,OAAA;AACnB,+HAAA,uBAAuB,OAAA;AAGzB,uCASoB;AARlB,0GAAA,cAAc,OAAA;AACd,kHAAA,sBAAsB,OAAA;AACtB,iHAAA,qBAAqB,OAAA;AACrB,kHAAA,sBAAsB,OAAA;AACtB,mHAAA,uBAAuB,OAAA;AACvB,sHAAA,0BAA0B,OAAA;AAC1B,6GAAA,iBAAiB,OAAA;AACjB,2HAAA,+BAA+B,OAAA;AAGjC,uDAI4B;AAH1B,0HAAA,sBAAsB,OAAA;AACtB,yHAAA,qBAAqB,OAAA;AAIvB,iEAIiC;AAH/B,oIAAA,2BAA2B,OAAA;AAC3B,mIAAA,0BAA0B,OAAA;AAI5B,uDAI4B;AAH1B,0HAAA,sBAAsB,OAAA;AACtB,yHAAA,qBAAqB,OAAA;AAIvB,qDAI2B;AAHzB,wHAAA,qBAAqB,OAAA;AACrB,uHAAA,oBAAoB,OAAA;AAItB,qDAQ2B;AAPzB,+HAAA,4BAA4B,OAAA;AAC5B,8HAAA,2BAA2B,OAAA;AAE3B,wHAAA,qBAAqB,OAAA;AAMvB,2CAYsB;AAXpB,0GAAA,YAAY,OAAA;AACZ,8GAAA,gBAAgB,OAAA;AAChB,mHAAA,qBAAqB,OAAA;AACrB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,gHAAA,kBAAkB,OAAA;AAClB,8GAAA,gBAAgB,OAAA;AAChB,oHAAA,sBAAsB,OAAA;AACtB,8GAAA,gBAAgB,OAAA;AAChB,0GAAA,YAAY,OAAA;AACZ,uGAAA,SAAS,OAAA;AAGX,6CAAsD;AAA7C,oHAAA,qBAAqB,OAAA;AAE9B,+CAQwB;AAPtB,wHAAA,wBAAwB,OAAA;AACxB,+GAAA,eAAe,OAAA;AACf,qHAAA,qBAAqB,OAAA;AAOvB,mDAM0B;AALxB,wHAAA,sBAAsB,OAAA;AACtB,wHAAA,sBAAsB,OAAA;AAMxB,qEAAwG;AAA/F,wIAAA,6BAA6B,OAAA","sourcesContent":["/**\n * AI assist packlet - provider registry, prompt class, settings, and API client.\n * @packageDocumentation\n */\n\nexport {\n AiPrompt,\n type AiModelCapability,\n allModelCapabilities,\n type AiProviderId,\n type AiServerToolType,\n type AiServerToolConfig,\n type AiToolConfig,\n type IAiWebSearchToolConfig,\n type IAiClientToolConfig,\n type IAiToolAnnotations,\n type IAiClientTool,\n type IAiClientToolCallSummary,\n type IAiClientToolContinuation,\n type IAiClientToolTurnResult,\n type IAiToolEnablement,\n type IAiCompletionResponse,\n DEFAULT_ANTHROPIC_MAX_TOKENS,\n type IChatMessage,\n type IChatRequest,\n type AiApiFormat,\n type AiImageApiFormat,\n type AiEmbeddingApiFormat,\n type AiEmbeddingTaskType,\n type IAiEmbeddingModelCapability,\n type IAiEmbeddingParams,\n type IAiEmbeddingUsage,\n type IAiEmbeddingResult,\n type IAiImageModelCapability,\n type IAiProviderDescriptor,\n type IAiAssistProviderConfig,\n type IAiAssistSettings,\n DEFAULT_AI_ASSIST,\n type IAiAssistKeyStore,\n providerApiKeySecretName,\n type IAiImageAttachment,\n type IAiImageData,\n type AiImageSize,\n type AiImageQuality,\n type GptImageSize,\n type GptImageQuality,\n type GptImageModelNames,\n type GrokImagineModelNames,\n type GeminiFlashImageModelNames,\n type IGptImageGenerationConfig,\n type IGrokImagineImageGenerationConfig,\n type IGeminiFlashImageGenerationConfig,\n type IGptImageModelOptions,\n type IGrokImagineModelOptions,\n type IGeminiFlashImageModelOptions,\n type IOtherModelOptions,\n type IModelFamilyConfig,\n type IAiImageGenerationOptions,\n type IAiImageGenerationParams,\n type IAiGeneratedImage,\n type IAiImageGenerationResponse,\n type IAiModelCapabilityRule,\n type IAiModelCapabilityConfig,\n type IAiModelInfo,\n type IAiStreamEvent,\n type IAiStreamTextDelta,\n type IAiStreamToolEvent,\n type IAiStreamToolUseStart,\n type IAiStreamToolUseDelta,\n type IAiStreamToolUseComplete,\n type IAiStreamDone,\n type IAiStreamError,\n type ModelSpec,\n type ModelSpecKey,\n type IModelSpecMap,\n allModelSpecKeys,\n MODEL_SPEC_BASE_KEY,\n resolveModel,\n type IModelAliasMap,\n MODEL_ALIAS_SIGIL,\n resolveModelAlias,\n resolveProviderModel,\n isResponsesOnlyModel,\n isAdaptiveThinkingModel,\n usesMaxCompletionTokensField,\n toDataUrl,\n type AiThinkingMode,\n type IThinkingConfig,\n type IThinkingProviderConfig,\n type IAnthropicThinkingOptions,\n type IOpenAiThinkingOptions,\n type IGeminiThinkingOptions,\n type IXAiThinkingOptions,\n type IOtherThinkingOptions,\n type IAnthropicThinkingConfig,\n type IOpenAiThinkingConfig,\n type IGeminiThinkingConfig,\n type IXAiThinkingConfig,\n type AnthropicThinkingModelNames,\n type OpenAiThinkingModelNames,\n type GeminiThinkingModelNames,\n type XAiThinkingModelNames\n} from './model';\n\nexport {\n type IResolvedImageOptions,\n resolveImageOptions,\n validateResolvedOptions\n} from './imageOptionsResolver';\n\nexport {\n allProviderIds,\n getProviderDescriptors,\n getProviderDescriptor,\n resolveImageCapability,\n supportsImageGeneration,\n resolveEmbeddingCapability,\n supportsEmbedding,\n DEFAULT_MODEL_CAPABILITY_CONFIG\n} from './registry';\n\nexport {\n callProviderCompletion,\n callProxiedCompletion,\n type IProviderCompletionParams\n} from './completionClient';\n\nexport {\n callProviderImageGeneration,\n callProxiedImageGeneration,\n type IProviderImageGenerationParams\n} from './imageGenerationClient';\n\nexport {\n callProviderListModels,\n callProxiedListModels,\n type IProviderListModelsParams\n} from './listModelsClient';\n\nexport {\n callProviderEmbedding,\n callProxiedEmbedding,\n type IProviderEmbeddingParams\n} from './embeddingClient';\n\nexport {\n callProviderCompletionStream,\n callProxiedCompletionStream,\n type IProviderCompletionStreamParams,\n executeClientToolTurn,\n type IExecuteClientToolTurnParams,\n type IExecuteClientToolTurnResult,\n type IToolExecutionDecision\n} from './streamingClient';\n\nexport {\n aiProviderId,\n aiServerToolType,\n aiWebSearchToolConfig,\n aiServerToolConfig,\n aiToolAnnotations,\n aiClientToolConfig,\n aiToolEnablement,\n aiAssistProviderConfig,\n aiAssistSettings,\n modelSpecKey,\n modelSpec\n} from './converters';\n\nexport { resolveEffectiveTools } from './toolFormats';\n\nexport {\n classifyJsonParseFailure,\n extractJsonText,\n fencedStringifiedJson,\n type IFencedStringifiedJsonExtractorOptions,\n type IFencedStringifiedJsonOptions,\n type JsonParseFailureReason,\n type JsonTextExtractor\n} from './jsonResponse';\n\nexport {\n generateJsonCompletion,\n SMART_JSON_PROMPT_HINT,\n type IGenerateJsonCompletionParams,\n type IGenerateJsonCompletionResult,\n type JsonPromptHint\n} from './jsonCompletion';\n\nexport { anthropicEffortToBudgetTokens, type IResolvedThinkingConfig } from './thinkingOptionsResolver';\n"]}
@@ -7,7 +7,7 @@
7
7
  * @packageDocumentation
8
8
  */
9
9
  import { type Converter, Result, type Validator } from '@fgv/ts-utils';
10
- import { type IProviderCompletionParams } from './apiClient';
10
+ import { type IProviderCompletionParams } from './completionClient';
11
11
  import { type IAiCompletionResponse } from './model';
12
12
  /**
13
13
  * Default system-prompt suffix appended when {@link AiAssist.IGenerateJsonCompletionParams.promptHint}
@@ -1 +1 @@
1
- {"version":3,"file":"jsonCompletion.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/jsonCompletion.ts"],"names":[],"mappings":"AAoBA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtF,OAAO,EAA0B,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAErF,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAE2C,CAAC;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,6BAA6B,CAAC,CAAC,CAAE,SAAQ,yBAAyB;IACjF;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAEtC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,6BAA6B,CAAC,CAAC;IAC9C,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;CAC1C;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,MAAM,EAAE,6BAA6B,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAoBnD"}
1
+ {"version":3,"file":"jsonCompletion.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/jsonCompletion.ts"],"names":[],"mappings":"AAoBA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAQ,MAAM,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtF,OAAO,EAA0B,KAAK,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAE2C,CAAC;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,6BAA6B,CAAC,CAAC,CAAE,SAAQ,yBAAyB;IACjF;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAEtC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,6BAA6B,CAAC,CAAC;IAC9C,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;CAC1C;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,MAAM,EAAE,6BAA6B,CAAC,CAAC,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAoBnD"}
@@ -41,7 +41,7 @@ exports.generateJsonCompletion = generateJsonCompletion;
41
41
  * @packageDocumentation
42
42
  */
43
43
  const ts_utils_1 = require("@fgv/ts-utils");
44
- const apiClient_1 = require("./apiClient");
44
+ const completionClient_1 = require("./completionClient");
45
45
  const jsonResponse_1 = require("./jsonResponse");
46
46
  /**
47
47
  * Default system-prompt suffix appended when {@link AiAssist.IGenerateJsonCompletionParams.promptHint}
@@ -84,7 +84,7 @@ async function generateJsonCompletion(params) {
84
84
  }
85
85
  const pipeline = jsonConverter !== null && jsonConverter !== void 0 ? jsonConverter : (0, jsonResponse_1.fencedStringifiedJson)({ inner: converter });
86
86
  const augmentedSystem = applyPromptHint(system, promptHint);
87
- const response = await (0, apiClient_1.callProviderCompletion)(Object.assign(Object.assign({}, rest), { system: augmentedSystem }));
87
+ const response = await (0, completionClient_1.callProviderCompletion)(Object.assign(Object.assign({}, rest), { system: augmentedSystem }));
88
88
  if (response.isFailure()) {
89
89
  return (0, ts_utils_1.fail)(response.message);
90
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"jsonCompletion.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/jsonCompletion.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;AAiHZ,wDAsBC;AArID;;;;;;;GAOG;AAEH,4CAAsF;AAEtF,2CAAqF;AACrF,iDAAuD;AAGvD;;;;;GAKG;AACU,QAAA,sBAAsB,GACjC,8EAA8E;IAC9E,8EAA8E,CAAC;AA6DjF,SAAS,eAAe,CAAC,MAA0B,EAAE,IAAoB;IACvE,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,8BAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACI,KAAK,UAAU,sBAAsB,CAC1C,MAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,GAAG,OAAO,EAAE,MAAM,KAAc,MAAM,EAAf,IAAI,UAAK,MAAM,EAA5E,sDAAmE,CAAS,CAAC;IAEnF,IAAI,aAAa,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,IAAA,eAAI,EAAC,6EAA6E,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,QAAQ,GAAiB,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,IAAA,oCAAqB,EAAI,EAAE,KAAK,EAAE,SAAU,EAAE,CAAC,CAAC;IAChG,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAsB,kCAAM,IAAI,KAAE,MAAM,EAAE,eAAe,IAAG,CAAC;IACpF,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;QACzB,OAAO,IAAA,eAAI,EAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC;IAElC,OAAO,QAAQ;SACZ,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;SAC3B,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,2BAA2B,GAAG,EAAE,CAAC;SAC1D,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * `generateJsonCompletion<T>` — request a JSON-shaped completion from any\n * provider supported by AiAssist and validate it against a caller-supplied\n * `Converter<T>` or `Validator<T>`. Wraps fence/preamble tolerance + parsing +\n * validation into a single call so consumers don't reinvent the pipeline.\n *\n * @packageDocumentation\n */\n\nimport { type Converter, fail, Result, succeed, type Validator } from '@fgv/ts-utils';\n\nimport { callProviderCompletion, type IProviderCompletionParams } from './apiClient';\nimport { fencedStringifiedJson } from './jsonResponse';\nimport { type IAiCompletionResponse } from './model';\n\n/**\n * Default system-prompt suffix appended when {@link AiAssist.IGenerateJsonCompletionParams.promptHint}\n * is `'smart'` (the default). Designed to discourage code fences and prose in\n * the model's response while still tolerating them via the read-side extractor.\n * @public\n */\nexport const SMART_JSON_PROMPT_HINT: string =\n 'Respond with raw JSON only — no Markdown code fences, no explanatory prose, ' +\n 'no preamble or trailing commentary. The response must parse with JSON.parse.';\n\n/**\n * Controls the optional system-prompt augmentation applied by\n * {@link AiAssist.generateJsonCompletion}.\n *\n * - `'smart'` (default): append {@link AiAssist.SMART_JSON_PROMPT_HINT}.\n * - `'none'`: do not modify the prompt.\n * - A string: append the supplied text verbatim.\n *\n * @remarks\n * The `string & {}` branch is the standard TypeScript trick that prevents\n * the literal members from being widened away — callers still get\n * autocomplete for `'smart'` and `'none'` while accepting any string.\n *\n * @public\n */\nexport type JsonPromptHint = 'smart' | 'none' | (string & {});\n\n/**\n * Parameters for {@link AiAssist.generateJsonCompletion}. Extends\n * {@link AiAssist.IProviderCompletionParams} with JSON-validation knobs.\n * @public\n */\nexport interface IGenerateJsonCompletionParams<T> extends IProviderCompletionParams {\n /**\n * Caller-supplied `Converter<T>` or `Validator<T>` applied to the parsed\n * JSON value. Wrapped internally in {@link AiAssist.fencedStringifiedJson}\n * unless {@link AiAssist.IGenerateJsonCompletionParams.jsonConverter} is\n * provided.\n */\n readonly converter?: Converter<T> | Validator<T>;\n\n /**\n * Full string-to-`T` pipeline override. When supplied, takes precedence over\n * {@link AiAssist.IGenerateJsonCompletionParams.converter} and lets the\n * caller plug in a custom extractor or skip the default fence tolerance\n * entirely.\n */\n readonly jsonConverter?: Converter<T>;\n\n /**\n * Controls the optional system-prompt augmentation. Defaults to `'smart'`.\n * Pass `'none'` to disable, or a string to append custom guidance.\n */\n readonly promptHint?: JsonPromptHint;\n}\n\n/**\n * Successful result of {@link AiAssist.generateJsonCompletion}.\n * @public\n */\nexport interface IGenerateJsonCompletionResult<T> {\n /** The validated JSON value. */\n readonly value: T;\n /** The raw response text returned by the provider. */\n readonly raw: string;\n /** The full underlying completion response. */\n readonly response: IAiCompletionResponse;\n}\n\nfunction applyPromptHint(system: string | undefined, hint: JsonPromptHint): string | undefined {\n if (hint === 'none') {\n return system;\n }\n const suffix = hint === 'smart' ? SMART_JSON_PROMPT_HINT : hint;\n return system !== undefined && system.length > 0 ? `${system}\\n\\n${suffix}` : suffix;\n}\n\n/**\n * Calls {@link AiAssist.callProviderCompletion}, then runs the response text\n * through a tolerant JSON converter (default:\n * {@link AiAssist.fencedStringifiedJson}) and the caller's\n * `converter`/`validator`. Returns the validated value plus the raw text and\n * underlying completion response for diagnostics.\n *\n * @remarks\n * The default smart prompt hint asks the model to emit raw JSON. The read-side\n * extractor still tolerates fences and prose, so models that ignore the hint\n * are still handled.\n *\n * Either `converter` or `jsonConverter` must be provided; passing both lets\n * `jsonConverter` win.\n *\n * @param params - Provider parameters plus JSON validation options.\n * @returns The validated value, the raw text, and the underlying response.\n * @public\n */\nexport async function generateJsonCompletion<T>(\n params: IGenerateJsonCompletionParams<T>\n): Promise<Result<IGenerateJsonCompletionResult<T>>> {\n const { converter, jsonConverter, promptHint = 'smart', system, ...rest } = params;\n\n if (jsonConverter === undefined && converter === undefined) {\n return fail('generateJsonCompletion: either converter or jsonConverter must be provided.');\n }\n\n const pipeline: Converter<T> = jsonConverter ?? fencedStringifiedJson<T>({ inner: converter! });\n const augmentedSystem = applyPromptHint(system, promptHint);\n\n const response = await callProviderCompletion({ ...rest, system: augmentedSystem });\n if (response.isFailure()) {\n return fail(response.message);\n }\n const completion = response.value;\n\n return pipeline\n .convert(completion.content)\n .withErrorFormat((msg) => `generateJsonCompletion: ${msg}`)\n .onSuccess((value) => succeed({ value, raw: completion.content, response: completion }));\n}\n"]}
1
+ {"version":3,"file":"jsonCompletion.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/jsonCompletion.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;AAiHZ,wDAsBC;AArID;;;;;;;GAOG;AAEH,4CAAsF;AAEtF,yDAA4F;AAC5F,iDAAuD;AAGvD;;;;;GAKG;AACU,QAAA,sBAAsB,GACjC,8EAA8E;IAC9E,8EAA8E,CAAC;AA6DjF,SAAS,eAAe,CAAC,MAA0B,EAAE,IAAoB;IACvE,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,8BAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACI,KAAK,UAAU,sBAAsB,CAC1C,MAAwC;IAExC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,GAAG,OAAO,EAAE,MAAM,KAAc,MAAM,EAAf,IAAI,UAAK,MAAM,EAA5E,sDAAmE,CAAS,CAAC;IAEnF,IAAI,aAAa,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,IAAA,eAAI,EAAC,6EAA6E,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,QAAQ,GAAiB,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,IAAA,oCAAqB,EAAI,EAAE,KAAK,EAAE,SAAU,EAAE,CAAC,CAAC;IAChG,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAE5D,MAAM,QAAQ,GAAG,MAAM,IAAA,yCAAsB,kCAAM,IAAI,KAAE,MAAM,EAAE,eAAe,IAAG,CAAC;IACpF,IAAI,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;QACzB,OAAO,IAAA,eAAI,EAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC;IAElC,OAAO,QAAQ;SACZ,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;SAC3B,eAAe,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,2BAA2B,GAAG,EAAE,CAAC;SAC1D,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * `generateJsonCompletion<T>` — request a JSON-shaped completion from any\n * provider supported by AiAssist and validate it against a caller-supplied\n * `Converter<T>` or `Validator<T>`. Wraps fence/preamble tolerance + parsing +\n * validation into a single call so consumers don't reinvent the pipeline.\n *\n * @packageDocumentation\n */\n\nimport { type Converter, fail, Result, succeed, type Validator } from '@fgv/ts-utils';\n\nimport { callProviderCompletion, type IProviderCompletionParams } from './completionClient';\nimport { fencedStringifiedJson } from './jsonResponse';\nimport { type IAiCompletionResponse } from './model';\n\n/**\n * Default system-prompt suffix appended when {@link AiAssist.IGenerateJsonCompletionParams.promptHint}\n * is `'smart'` (the default). Designed to discourage code fences and prose in\n * the model's response while still tolerating them via the read-side extractor.\n * @public\n */\nexport const SMART_JSON_PROMPT_HINT: string =\n 'Respond with raw JSON only — no Markdown code fences, no explanatory prose, ' +\n 'no preamble or trailing commentary. The response must parse with JSON.parse.';\n\n/**\n * Controls the optional system-prompt augmentation applied by\n * {@link AiAssist.generateJsonCompletion}.\n *\n * - `'smart'` (default): append {@link AiAssist.SMART_JSON_PROMPT_HINT}.\n * - `'none'`: do not modify the prompt.\n * - A string: append the supplied text verbatim.\n *\n * @remarks\n * The `string & {}` branch is the standard TypeScript trick that prevents\n * the literal members from being widened away — callers still get\n * autocomplete for `'smart'` and `'none'` while accepting any string.\n *\n * @public\n */\nexport type JsonPromptHint = 'smart' | 'none' | (string & {});\n\n/**\n * Parameters for {@link AiAssist.generateJsonCompletion}. Extends\n * {@link AiAssist.IProviderCompletionParams} with JSON-validation knobs.\n * @public\n */\nexport interface IGenerateJsonCompletionParams<T> extends IProviderCompletionParams {\n /**\n * Caller-supplied `Converter<T>` or `Validator<T>` applied to the parsed\n * JSON value. Wrapped internally in {@link AiAssist.fencedStringifiedJson}\n * unless {@link AiAssist.IGenerateJsonCompletionParams.jsonConverter} is\n * provided.\n */\n readonly converter?: Converter<T> | Validator<T>;\n\n /**\n * Full string-to-`T` pipeline override. When supplied, takes precedence over\n * {@link AiAssist.IGenerateJsonCompletionParams.converter} and lets the\n * caller plug in a custom extractor or skip the default fence tolerance\n * entirely.\n */\n readonly jsonConverter?: Converter<T>;\n\n /**\n * Controls the optional system-prompt augmentation. Defaults to `'smart'`.\n * Pass `'none'` to disable, or a string to append custom guidance.\n */\n readonly promptHint?: JsonPromptHint;\n}\n\n/**\n * Successful result of {@link AiAssist.generateJsonCompletion}.\n * @public\n */\nexport interface IGenerateJsonCompletionResult<T> {\n /** The validated JSON value. */\n readonly value: T;\n /** The raw response text returned by the provider. */\n readonly raw: string;\n /** The full underlying completion response. */\n readonly response: IAiCompletionResponse;\n}\n\nfunction applyPromptHint(system: string | undefined, hint: JsonPromptHint): string | undefined {\n if (hint === 'none') {\n return system;\n }\n const suffix = hint === 'smart' ? SMART_JSON_PROMPT_HINT : hint;\n return system !== undefined && system.length > 0 ? `${system}\\n\\n${suffix}` : suffix;\n}\n\n/**\n * Calls {@link AiAssist.callProviderCompletion}, then runs the response text\n * through a tolerant JSON converter (default:\n * {@link AiAssist.fencedStringifiedJson}) and the caller's\n * `converter`/`validator`. Returns the validated value plus the raw text and\n * underlying completion response for diagnostics.\n *\n * @remarks\n * The default smart prompt hint asks the model to emit raw JSON. The read-side\n * extractor still tolerates fences and prose, so models that ignore the hint\n * are still handled.\n *\n * Either `converter` or `jsonConverter` must be provided; passing both lets\n * `jsonConverter` win.\n *\n * @param params - Provider parameters plus JSON validation options.\n * @returns The validated value, the raw text, and the underlying response.\n * @public\n */\nexport async function generateJsonCompletion<T>(\n params: IGenerateJsonCompletionParams<T>\n): Promise<Result<IGenerateJsonCompletionResult<T>>> {\n const { converter, jsonConverter, promptHint = 'smart', system, ...rest } = params;\n\n if (jsonConverter === undefined && converter === undefined) {\n return fail('generateJsonCompletion: either converter or jsonConverter must be provided.');\n }\n\n const pipeline: Converter<T> = jsonConverter ?? fencedStringifiedJson<T>({ inner: converter! });\n const augmentedSystem = applyPromptHint(system, promptHint);\n\n const response = await callProviderCompletion({ ...rest, system: augmentedSystem });\n if (response.isFailure()) {\n return fail(response.message);\n }\n const completion = response.value;\n\n return pipeline\n .convert(completion.content)\n .withErrorFormat((msg) => `generateJsonCompletion: ${msg}`)\n .onSuccess((value) => succeed({ value, raw: completion.content, response: completion }));\n}\n"]}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Model-listing clients for AI assist. One provider dispatcher over
3
+ * `IAiProviderDescriptor.apiFormat`, its adapters and response validators, the
4
+ * capability-resolution helpers that turn a raw model id into an
5
+ * `IAiModelInfo`, and the proxied variant.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { type Logging, Result } from '@fgv/ts-utils';
10
+ import { type AiModelCapability, type IAiModelCapabilityConfig, type IAiModelInfo, type IAiProviderDescriptor } from './model';
11
+ /**
12
+ * Parameters for a list-models request.
13
+ * @public
14
+ */
15
+ export interface IProviderListModelsParams {
16
+ /** The provider descriptor */
17
+ readonly descriptor: IAiProviderDescriptor;
18
+ /** API key for authentication */
19
+ readonly apiKey: string;
20
+ /** Optional capability filter; when set, only models declaring this capability are returned. */
21
+ readonly capability?: AiModelCapability;
22
+ /** Optional capability config override (defaults to {@link DEFAULT_MODEL_CAPABILITY_CONFIG}). */
23
+ readonly capabilityConfig?: IAiModelCapabilityConfig;
24
+ /** Optional logger for request/response observability. */
25
+ readonly logger?: Logging.ILogger;
26
+ /** Optional abort signal for cancelling the in-flight request. */
27
+ readonly signal?: AbortSignal;
28
+ /** Optional override of the descriptor's base URL; per-format `/models` route is appended unchanged. */
29
+ readonly endpoint?: string;
30
+ }
31
+ /**
32
+ * Lists models available from a provider, routing by `descriptor.apiFormat`.
33
+ * Capabilities are resolved from native provider info and a configurable rule set.
34
+ * @param params - Request parameters (descriptor, API key, optional capability filter)
35
+ * @public
36
+ */
37
+ export declare function callProviderListModels(params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
38
+ /**
39
+ * Calls the model-listing endpoint on a proxy server. Endpoint:
40
+ * `POST ${proxyUrl}/api/ai/list-models`. Capability config is not forwarded;
41
+ * `capabilities` is serialized as a string array. Error body `{error: string}`
42
+ * is surfaced as `proxy: ${error}`.
43
+ * @public
44
+ */
45
+ export declare function callProxiedListModels(proxyUrl: string, params: IProviderListModelsParams): Promise<Result<ReadonlyArray<IAiModelInfo>>>;
46
+ //# sourceMappingURL=listModelsClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listModelsClient.d.ts","sourceRoot":"","sources":["../../../src/packlets/ai-assist/listModelsClient.ts"],"names":[],"mappings":"AAoBA;;;;;;;GAOG;AAEH,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAEhG,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAE7B,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC3B,MAAM,SAAS,CAAC;AA4CjB;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IACxC,iGAAiG;IACjG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IACrD,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,wGAAwG;IACxG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAuQD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAwC9C;AAMD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAoC9C"}
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ // Copyright (c) 2026 Erik Fortune
3
+ //
4
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ // of this software and associated documentation files (the "Software"), to deal
6
+ // in the Software without restriction, including without limitation the rights
7
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ // copies of the Software, and to permit persons to whom the Software is
9
+ // furnished to do so, subject to the following conditions:
10
+ //
11
+ // The above copyright notice and this permission notice shall be included in all
12
+ // copies or substantial portions of the Software.
13
+ //
14
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ // SOFTWARE.
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.callProviderListModels = callProviderListModels;
23
+ exports.callProxiedListModels = callProxiedListModels;
24
+ /**
25
+ * Model-listing clients for AI assist. One provider dispatcher over
26
+ * `IAiProviderDescriptor.apiFormat`, its adapters and response validators, the
27
+ * capability-resolution helpers that turn a raw model id into an
28
+ * `IAiModelInfo`, and the proxied variant.
29
+ *
30
+ * @packageDocumentation
31
+ */
32
+ const ts_utils_1 = require("@fgv/ts-utils");
33
+ const model_1 = require("./model");
34
+ const endpoint_1 = require("./endpoint");
35
+ const http_1 = require("./http");
36
+ const registry_1 = require("./registry");
37
+ const proxiedListModelsEntry = ts_utils_1.Validators.object({
38
+ id: ts_utils_1.Validators.string,
39
+ capabilities: ts_utils_1.Validators.arrayOf(ts_utils_1.Validators.enumeratedValue(model_1.allModelCapabilities)),
40
+ displayName: ts_utils_1.Validators.string.optional()
41
+ });
42
+ const proxiedListModelsResponse = ts_utils_1.Validators.object({
43
+ models: ts_utils_1.Validators.arrayOf(proxiedListModelsEntry)
44
+ });
45
+ const openAiListEntry = ts_utils_1.Validators.object({
46
+ id: ts_utils_1.Validators.string
47
+ });
48
+ const openAiListResponse = ts_utils_1.Validators.object({
49
+ data: ts_utils_1.Validators.arrayOf(openAiListEntry)
50
+ });
51
+ const anthropicListEntry = ts_utils_1.Validators.object({
52
+ id: ts_utils_1.Validators.string,
53
+ display_name: ts_utils_1.Validators.string.optional()
54
+ });
55
+ const anthropicListResponse = ts_utils_1.Validators.object({
56
+ data: ts_utils_1.Validators.arrayOf(anthropicListEntry)
57
+ });
58
+ const geminiListEntry = ts_utils_1.Validators.object({
59
+ name: ts_utils_1.Validators.string,
60
+ displayName: ts_utils_1.Validators.string.optional(),
61
+ supportedGenerationMethods: ts_utils_1.Validators.arrayOf(ts_utils_1.Validators.string).optional()
62
+ });
63
+ const geminiListResponse = ts_utils_1.Validators.object({
64
+ models: ts_utils_1.Validators.arrayOf(geminiListEntry)
65
+ });
66
+ // ============================================================================
67
+ // List models — capability resolution
68
+ // ============================================================================
69
+ /**
70
+ * Translates Gemini's `supportedGenerationMethods` strings into our abstract
71
+ * capability vocabulary. Methods without a mapping are ignored.
72
+ * @internal
73
+ */
74
+ function geminiMethodsToCapabilities(methods) {
75
+ const out = [];
76
+ for (const m of methods) {
77
+ if (m === 'generateContent') {
78
+ out.push('chat');
79
+ }
80
+ else if (m === 'predict') {
81
+ out.push('image-generation');
82
+ }
83
+ }
84
+ return out;
85
+ }
86
+ /**
87
+ * Strips the `models/` prefix Gemini includes on listed model names.
88
+ * @internal
89
+ */
90
+ function geminiBareId(name) {
91
+ /* c8 ignore next 1 - defensive: Gemini API always returns names prefixed with 'models/' */
92
+ return name.startsWith('models/') ? name.substring('models/'.length) : name;
93
+ }
94
+ /**
95
+ * Applies a capability config to a model id. Walks per-provider rules then
96
+ * global rules; unions all matching rules' capabilities. Returns the union
97
+ * and the first matching `displayName` (if any).
98
+ * @internal
99
+ */
100
+ function applyCapabilityConfig(config, providerId, modelId) {
101
+ var _a, _b, _c;
102
+ const caps = new Set();
103
+ let displayName;
104
+ const rulesets = [
105
+ (_b = (_a = config.perProvider) === null || _a === void 0 ? void 0 : _a[providerId]) !== null && _b !== void 0 ? _b : [],
106
+ (_c = config.global) !== null && _c !== void 0 ? _c : []
107
+ ];
108
+ for (const rules of rulesets) {
109
+ for (const rule of rules) {
110
+ rule.idPattern.lastIndex = 0;
111
+ if (rule.idPattern.test(modelId)) {
112
+ for (const cap of rule.capabilities) {
113
+ caps.add(cap);
114
+ }
115
+ if (displayName === undefined && rule.displayName !== undefined) {
116
+ displayName = typeof rule.displayName === 'function' ? rule.displayName(modelId) : rule.displayName;
117
+ }
118
+ }
119
+ }
120
+ }
121
+ return { capabilities: Array.from(caps), displayName };
122
+ }
123
+ /**
124
+ * Combines provider-native capability info (when supplied) and config-derived
125
+ * capability info into a final {@link IAiModelInfo}.
126
+ * @internal
127
+ */
128
+ function buildModelInfo(providerId, id, nativeCapabilities, nativeDisplayName, config) {
129
+ const fromConfig = applyCapabilityConfig(config, providerId, id);
130
+ const all = new Set([...nativeCapabilities, ...fromConfig.capabilities]);
131
+ return Object.assign({ id, capabilities: all }, (nativeDisplayName !== undefined
132
+ ? { displayName: nativeDisplayName }
133
+ : fromConfig.displayName !== undefined
134
+ ? { displayName: fromConfig.displayName }
135
+ : {}));
136
+ }
137
+ // ============================================================================
138
+ // List models — adapters
139
+ // ============================================================================
140
+ /**
141
+ * Calls the OpenAI-style `GET /models` endpoint. Used by openai, xai-grok,
142
+ * groq, and mistral. Provider supplies no capability info — capabilities are
143
+ * derived entirely from the config.
144
+ * @internal
145
+ */
146
+ async function callOpenAiListModels(config, providerId, capabilityConfig, logger, signal) {
147
+ const url = `${config.baseUrl}/models`;
148
+ const headers = (0, endpoint_1.bearerAuthHeader)(config.apiKey);
149
+ /* c8 ignore next 1 - optional logger */
150
+ logger === null || logger === void 0 ? void 0 : logger.info(`List models: provider=${providerId}, format=openai`);
151
+ const jsonResult = await (0, http_1.fetchGetJson)(url, headers, logger, signal);
152
+ if (jsonResult.isFailure()) {
153
+ return (0, ts_utils_1.fail)(jsonResult.message);
154
+ }
155
+ return openAiListResponse
156
+ .validate(jsonResult.value)
157
+ .withErrorFormat((msg) => `OpenAI models API response: ${msg}`)
158
+ .onSuccess((response) => {
159
+ const models = response.data.map((entry) => buildModelInfo(providerId, entry.id, [], undefined, capabilityConfig));
160
+ return (0, ts_utils_1.succeed)(models);
161
+ });
162
+ }
163
+ /**
164
+ * Calls the Anthropic `GET /models` endpoint. Provider supplies a
165
+ * `display_name` but no native capability info.
166
+ * @internal
167
+ */
168
+ async function callAnthropicListModels(config, providerId, capabilityConfig, logger, signal) {
169
+ const url = `${config.baseUrl}/models`;
170
+ const headers = (0, endpoint_1.anthropicAuthHeaders)(config.apiKey);
171
+ /* c8 ignore next 1 - optional logger */
172
+ logger === null || logger === void 0 ? void 0 : logger.info(`List models: provider=${providerId}, format=anthropic`);
173
+ const jsonResult = await (0, http_1.fetchGetJson)(url, headers, logger, signal);
174
+ if (jsonResult.isFailure()) {
175
+ return (0, ts_utils_1.fail)(jsonResult.message);
176
+ }
177
+ return anthropicListResponse
178
+ .validate(jsonResult.value)
179
+ .withErrorFormat((msg) => `Anthropic models API response: ${msg}`)
180
+ .onSuccess((response) => {
181
+ const models = response.data.map((entry) => buildModelInfo(providerId, entry.id, [], entry.display_name, capabilityConfig));
182
+ return (0, ts_utils_1.succeed)(models);
183
+ });
184
+ }
185
+ /**
186
+ * Calls the Gemini `GET /models` endpoint. Provider supplies both a
187
+ * `displayName` and `supportedGenerationMethods` — translated to native
188
+ * capabilities and unioned with config-derived capabilities.
189
+ * @internal
190
+ */
191
+ async function callGeminiListModels(config, providerId, capabilityConfig, logger, signal) {
192
+ const url = `${config.baseUrl}/models`;
193
+ const headers = (0, endpoint_1.geminiAuthHeader)(config.apiKey);
194
+ /* c8 ignore next 1 - optional logger */
195
+ logger === null || logger === void 0 ? void 0 : logger.info(`List models: provider=${providerId}, format=gemini`);
196
+ const jsonResult = await (0, http_1.fetchGetJson)(url, headers, logger, signal);
197
+ if (jsonResult.isFailure()) {
198
+ return (0, ts_utils_1.fail)(jsonResult.message);
199
+ }
200
+ return geminiListResponse
201
+ .validate(jsonResult.value)
202
+ .withErrorFormat((msg) => `Gemini models API response: ${msg}`)
203
+ .onSuccess((response) => {
204
+ const models = response.models.map((entry) => {
205
+ const id = geminiBareId(entry.name);
206
+ const native = entry.supportedGenerationMethods
207
+ ? geminiMethodsToCapabilities(entry.supportedGenerationMethods)
208
+ : [];
209
+ return buildModelInfo(providerId, id, native, entry.displayName, capabilityConfig);
210
+ });
211
+ return (0, ts_utils_1.succeed)(models);
212
+ });
213
+ }
214
+ // ============================================================================
215
+ // List models — dispatcher
216
+ // ============================================================================
217
+ /**
218
+ * Lists models available from a provider, routing by `descriptor.apiFormat`.
219
+ * Capabilities are resolved from native provider info and a configurable rule set.
220
+ * @param params - Request parameters (descriptor, API key, optional capability filter)
221
+ * @public
222
+ */
223
+ async function callProviderListModels(params) {
224
+ const { descriptor, apiKey, capability, capabilityConfig, logger, signal, endpoint } = params;
225
+ const baseUrlResult = (0, endpoint_1.resolveEffectiveBaseUrl)(descriptor, endpoint);
226
+ if (baseUrlResult.isFailure()) {
227
+ return (0, ts_utils_1.fail)(baseUrlResult.message);
228
+ }
229
+ const config = {
230
+ baseUrl: baseUrlResult.value,
231
+ apiKey,
232
+ model: '' // unused by listing
233
+ };
234
+ const effectiveConfig = capabilityConfig !== null && capabilityConfig !== void 0 ? capabilityConfig : registry_1.DEFAULT_MODEL_CAPABILITY_CONFIG;
235
+ let listResult;
236
+ switch (descriptor.apiFormat) {
237
+ case 'openai':
238
+ listResult = await callOpenAiListModels(config, descriptor.id, effectiveConfig, logger, signal);
239
+ break;
240
+ case 'anthropic':
241
+ listResult = await callAnthropicListModels(config, descriptor.id, effectiveConfig, logger, signal);
242
+ break;
243
+ case 'gemini':
244
+ listResult = await callGeminiListModels(config, descriptor.id, effectiveConfig, logger, signal);
245
+ break;
246
+ /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */
247
+ default: {
248
+ const _exhaustive = descriptor.apiFormat;
249
+ return (0, ts_utils_1.fail)(`unsupported API format: ${String(_exhaustive)}`);
250
+ }
251
+ }
252
+ if (listResult.isFailure()) {
253
+ return listResult;
254
+ }
255
+ if (capability === undefined) {
256
+ return listResult;
257
+ }
258
+ return (0, ts_utils_1.succeed)(listResult.value.filter((m) => m.capabilities.has(capability)));
259
+ }
260
+ // ============================================================================
261
+ // Proxied list models
262
+ // ============================================================================
263
+ /**
264
+ * Calls the model-listing endpoint on a proxy server. Endpoint:
265
+ * `POST ${proxyUrl}/api/ai/list-models`. Capability config is not forwarded;
266
+ * `capabilities` is serialized as a string array. Error body `{error: string}`
267
+ * is surfaced as `proxy: ${error}`.
268
+ * @public
269
+ */
270
+ async function callProxiedListModels(proxyUrl, params) {
271
+ const { descriptor, apiKey, capability, logger, signal } = params;
272
+ const body = {
273
+ providerId: descriptor.id,
274
+ apiKey
275
+ };
276
+ if (capability !== undefined) {
277
+ body.capability = capability;
278
+ }
279
+ /* c8 ignore next 1 - optional logger */
280
+ logger === null || logger === void 0 ? void 0 : logger.info(`AI list-models proxy request: provider=${descriptor.id}, proxy=${proxyUrl}`);
281
+ const url = `${proxyUrl}/api/ai/list-models`;
282
+ const jsonResult = await (0, http_1.fetchJson)(url, {}, body, logger, signal);
283
+ if (jsonResult.isFailure()) {
284
+ return (0, ts_utils_1.fail)(jsonResult.message);
285
+ }
286
+ const response = jsonResult.value;
287
+ if (typeof response.error === 'string') {
288
+ return (0, ts_utils_1.fail)(`proxy: ${response.error}`);
289
+ }
290
+ return proxiedListModelsResponse
291
+ .validate(response)
292
+ .withErrorFormat((msg) => `proxy returned invalid response: ${msg}`)
293
+ .onSuccess((parsed) => {
294
+ const models = parsed.models.map((m) => (Object.assign({ id: m.id, capabilities: new Set(m.capabilities) }, (m.displayName !== undefined ? { displayName: m.displayName } : {}))));
295
+ return (0, ts_utils_1.succeed)(models);
296
+ });
297
+ }
298
+ //# sourceMappingURL=listModelsClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listModelsClient.js","sourceRoot":"","sources":["../../../src/packlets/ai-assist/listModelsClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Model-listing clients for AI assist. One provider dispatcher over\n * `IAiProviderDescriptor.apiFormat`, its adapters and response validators, the\n * capability-resolution helpers that turn a raw model id into an\n * `IAiModelInfo`, and the proxied variant.\n *\n * @packageDocumentation\n */\n\nimport { fail, type Logging, Result, succeed, type Validator, Validators } from '@fgv/ts-utils';\n\nimport {\n type AiModelCapability,\n allModelCapabilities,\n type IAiModelCapabilityConfig,\n type IAiModelCapabilityRule,\n type IAiModelInfo,\n type IAiProviderDescriptor\n} from './model';\nimport {\n anthropicAuthHeaders,\n bearerAuthHeader,\n geminiAuthHeader,\n resolveEffectiveBaseUrl\n} from './endpoint';\nimport { type IAiApiConfig, fetchGetJson, fetchJson } from './http';\nimport { DEFAULT_MODEL_CAPABILITY_CONFIG } from './registry';\n\n// ---- Proxied list-models response ----\n\n/**\n * Wire shape for proxy list-models responses. `capabilities` arrives as an\n * array (Sets don't survive JSON), then gets reassembled into a `Set` in\n * {@link callProxiedListModels}.\n * @internal\n */\ninterface IProxiedListModelsEntry {\n id: string;\n capabilities: AiModelCapability[];\n displayName?: string;\n}\n/** @internal */\ninterface IProxiedListModelsBody {\n models: IProxiedListModelsEntry[];\n}\n\nconst proxiedListModelsEntry: Validator<IProxiedListModelsEntry> = Validators.object<IProxiedListModelsEntry>(\n {\n id: Validators.string,\n capabilities: Validators.arrayOf(Validators.enumeratedValue<AiModelCapability>(allModelCapabilities)),\n displayName: Validators.string.optional()\n }\n);\nconst proxiedListModelsResponse: Validator<IProxiedListModelsBody> =\n Validators.object<IProxiedListModelsBody>({\n models: Validators.arrayOf(proxiedListModelsEntry)\n });\n\n// ============================================================================\n// List models — request types\n// ============================================================================\n\n/**\n * Parameters for a list-models request.\n * @public\n */\nexport interface IProviderListModelsParams {\n /** The provider descriptor */\n readonly descriptor: IAiProviderDescriptor;\n /** API key for authentication */\n readonly apiKey: string;\n /** Optional capability filter; when set, only models declaring this capability are returned. */\n readonly capability?: AiModelCapability;\n /** Optional capability config override (defaults to {@link DEFAULT_MODEL_CAPABILITY_CONFIG}). */\n readonly capabilityConfig?: IAiModelCapabilityConfig;\n /** Optional logger for request/response observability. */\n readonly logger?: Logging.ILogger;\n /** Optional abort signal for cancelling the in-flight request. */\n readonly signal?: AbortSignal;\n /** Optional override of the descriptor's base URL; per-format `/models` route is appended unchanged. */\n readonly endpoint?: string;\n}\n\n// ============================================================================\n// List models — response validators\n// ============================================================================\n\n// ---- OpenAI / xAI / Groq / Mistral list format ----\n\n/** @internal */\ninterface IOpenAiListEntry {\n id: string;\n}\n/** @internal */\ninterface IOpenAiListResponse {\n data: IOpenAiListEntry[];\n}\n\nconst openAiListEntry: Validator<IOpenAiListEntry> = Validators.object<IOpenAiListEntry>({\n id: Validators.string\n});\nconst openAiListResponse: Validator<IOpenAiListResponse> = Validators.object<IOpenAiListResponse>({\n data: Validators.arrayOf(openAiListEntry)\n});\n\n// ---- Anthropic list format ----\n\n/** @internal */\ninterface IAnthropicListEntry {\n id: string;\n display_name?: string;\n}\n/** @internal */\ninterface IAnthropicListResponse {\n data: IAnthropicListEntry[];\n}\n\nconst anthropicListEntry: Validator<IAnthropicListEntry> = Validators.object<IAnthropicListEntry>({\n id: Validators.string,\n display_name: Validators.string.optional()\n});\nconst anthropicListResponse: Validator<IAnthropicListResponse> = Validators.object<IAnthropicListResponse>({\n data: Validators.arrayOf(anthropicListEntry)\n});\n\n// ---- Gemini list format ----\n\n/** @internal */\ninterface IGeminiListEntry {\n name: string;\n displayName?: string;\n supportedGenerationMethods?: string[];\n}\n/** @internal */\ninterface IGeminiListResponse {\n models: IGeminiListEntry[];\n}\n\nconst geminiListEntry: Validator<IGeminiListEntry> = Validators.object<IGeminiListEntry>({\n name: Validators.string,\n displayName: Validators.string.optional(),\n supportedGenerationMethods: Validators.arrayOf(Validators.string).optional()\n});\nconst geminiListResponse: Validator<IGeminiListResponse> = Validators.object<IGeminiListResponse>({\n models: Validators.arrayOf(geminiListEntry)\n});\n\n// ============================================================================\n// List models — capability resolution\n// ============================================================================\n\n/**\n * Translates Gemini's `supportedGenerationMethods` strings into our abstract\n * capability vocabulary. Methods without a mapping are ignored.\n * @internal\n */\nfunction geminiMethodsToCapabilities(methods: ReadonlyArray<string>): ReadonlyArray<AiModelCapability> {\n const out: AiModelCapability[] = [];\n for (const m of methods) {\n if (m === 'generateContent') {\n out.push('chat');\n } else if (m === 'predict') {\n out.push('image-generation');\n }\n }\n return out;\n}\n\n/**\n * Strips the `models/` prefix Gemini includes on listed model names.\n * @internal\n */\nfunction geminiBareId(name: string): string {\n /* c8 ignore next 1 - defensive: Gemini API always returns names prefixed with 'models/' */\n return name.startsWith('models/') ? name.substring('models/'.length) : name;\n}\n\n/**\n * Applies a capability config to a model id. Walks per-provider rules then\n * global rules; unions all matching rules' capabilities. Returns the union\n * and the first matching `displayName` (if any).\n * @internal\n */\nfunction applyCapabilityConfig(\n config: IAiModelCapabilityConfig,\n providerId: string,\n modelId: string\n): { capabilities: AiModelCapability[]; displayName: string | undefined } {\n const caps = new Set<AiModelCapability>();\n let displayName: string | undefined;\n\n const rulesets: ReadonlyArray<ReadonlyArray<IAiModelCapabilityRule>> = [\n config.perProvider?.[providerId as keyof typeof config.perProvider] ?? [],\n config.global ?? []\n ];\n\n for (const rules of rulesets) {\n for (const rule of rules) {\n rule.idPattern.lastIndex = 0;\n if (rule.idPattern.test(modelId)) {\n for (const cap of rule.capabilities) {\n caps.add(cap);\n }\n if (displayName === undefined && rule.displayName !== undefined) {\n displayName = typeof rule.displayName === 'function' ? rule.displayName(modelId) : rule.displayName;\n }\n }\n }\n }\n return { capabilities: Array.from(caps), displayName };\n}\n\n/**\n * Combines provider-native capability info (when supplied) and config-derived\n * capability info into a final {@link IAiModelInfo}.\n * @internal\n */\nfunction buildModelInfo(\n providerId: string,\n id: string,\n nativeCapabilities: ReadonlyArray<AiModelCapability>,\n nativeDisplayName: string | undefined,\n config: IAiModelCapabilityConfig\n): IAiModelInfo {\n const fromConfig = applyCapabilityConfig(config, providerId, id);\n const all = new Set<AiModelCapability>([...nativeCapabilities, ...fromConfig.capabilities]);\n return {\n id,\n capabilities: all,\n ...(nativeDisplayName !== undefined\n ? { displayName: nativeDisplayName }\n : fromConfig.displayName !== undefined\n ? { displayName: fromConfig.displayName }\n : {})\n };\n}\n\n// ============================================================================\n// List models — adapters\n// ============================================================================\n\n/**\n * Calls the OpenAI-style `GET /models` endpoint. Used by openai, xai-grok,\n * groq, and mistral. Provider supplies no capability info — capabilities are\n * derived entirely from the config.\n * @internal\n */\nasync function callOpenAiListModels(\n config: IAiApiConfig,\n providerId: string,\n capabilityConfig: IAiModelCapabilityConfig,\n logger?: Logging.ILogger,\n signal?: AbortSignal\n): Promise<Result<ReadonlyArray<IAiModelInfo>>> {\n const url = `${config.baseUrl}/models`;\n const headers: Record<string, string> = bearerAuthHeader(config.apiKey);\n /* c8 ignore next 1 - optional logger */\n logger?.info(`List models: provider=${providerId}, format=openai`);\n const jsonResult = await fetchGetJson(url, headers, logger, signal);\n if (jsonResult.isFailure()) {\n return fail(jsonResult.message);\n }\n return openAiListResponse\n .validate(jsonResult.value)\n .withErrorFormat((msg) => `OpenAI models API response: ${msg}`)\n .onSuccess((response) => {\n const models = response.data.map((entry) =>\n buildModelInfo(providerId, entry.id, [], undefined, capabilityConfig)\n );\n return succeed(models);\n });\n}\n\n/**\n * Calls the Anthropic `GET /models` endpoint. Provider supplies a\n * `display_name` but no native capability info.\n * @internal\n */\nasync function callAnthropicListModels(\n config: IAiApiConfig,\n providerId: string,\n capabilityConfig: IAiModelCapabilityConfig,\n logger?: Logging.ILogger,\n signal?: AbortSignal\n): Promise<Result<ReadonlyArray<IAiModelInfo>>> {\n const url = `${config.baseUrl}/models`;\n const headers: Record<string, string> = anthropicAuthHeaders(config.apiKey);\n /* c8 ignore next 1 - optional logger */\n logger?.info(`List models: provider=${providerId}, format=anthropic`);\n const jsonResult = await fetchGetJson(url, headers, logger, signal);\n if (jsonResult.isFailure()) {\n return fail(jsonResult.message);\n }\n return anthropicListResponse\n .validate(jsonResult.value)\n .withErrorFormat((msg) => `Anthropic models API response: ${msg}`)\n .onSuccess((response) => {\n const models = response.data.map((entry) =>\n buildModelInfo(providerId, entry.id, [], entry.display_name, capabilityConfig)\n );\n return succeed(models);\n });\n}\n\n/**\n * Calls the Gemini `GET /models` endpoint. Provider supplies both a\n * `displayName` and `supportedGenerationMethods` — translated to native\n * capabilities and unioned with config-derived capabilities.\n * @internal\n */\nasync function callGeminiListModels(\n config: IAiApiConfig,\n providerId: string,\n capabilityConfig: IAiModelCapabilityConfig,\n logger?: Logging.ILogger,\n signal?: AbortSignal\n): Promise<Result<ReadonlyArray<IAiModelInfo>>> {\n const url = `${config.baseUrl}/models`;\n const headers: Record<string, string> = geminiAuthHeader(config.apiKey);\n /* c8 ignore next 1 - optional logger */\n logger?.info(`List models: provider=${providerId}, format=gemini`);\n const jsonResult = await fetchGetJson(url, headers, logger, signal);\n if (jsonResult.isFailure()) {\n return fail(jsonResult.message);\n }\n return geminiListResponse\n .validate(jsonResult.value)\n .withErrorFormat((msg) => `Gemini models API response: ${msg}`)\n .onSuccess((response) => {\n const models = response.models.map((entry) => {\n const id = geminiBareId(entry.name);\n const native = entry.supportedGenerationMethods\n ? geminiMethodsToCapabilities(entry.supportedGenerationMethods)\n : [];\n return buildModelInfo(providerId, id, native, entry.displayName, capabilityConfig);\n });\n return succeed(models);\n });\n}\n\n// ============================================================================\n// List models — dispatcher\n// ============================================================================\n\n/**\n * Lists models available from a provider, routing by `descriptor.apiFormat`.\n * Capabilities are resolved from native provider info and a configurable rule set.\n * @param params - Request parameters (descriptor, API key, optional capability filter)\n * @public\n */\nexport async function callProviderListModels(\n params: IProviderListModelsParams\n): Promise<Result<ReadonlyArray<IAiModelInfo>>> {\n const { descriptor, apiKey, capability, capabilityConfig, logger, signal, endpoint } = params;\n\n const baseUrlResult = resolveEffectiveBaseUrl(descriptor, endpoint);\n if (baseUrlResult.isFailure()) {\n return fail(baseUrlResult.message);\n }\n\n const config: IAiApiConfig = {\n baseUrl: baseUrlResult.value,\n apiKey,\n model: '' // unused by listing\n };\n const effectiveConfig = capabilityConfig ?? DEFAULT_MODEL_CAPABILITY_CONFIG;\n\n let listResult: Result<ReadonlyArray<IAiModelInfo>>;\n switch (descriptor.apiFormat) {\n case 'openai':\n listResult = await callOpenAiListModels(config, descriptor.id, effectiveConfig, logger, signal);\n break;\n case 'anthropic':\n listResult = await callAnthropicListModels(config, descriptor.id, effectiveConfig, logger, signal);\n break;\n case 'gemini':\n listResult = await callGeminiListModels(config, descriptor.id, effectiveConfig, logger, signal);\n break;\n /* c8 ignore next 4 - defensive coding: exhaustive switch guaranteed by TypeScript */\n default: {\n const _exhaustive: never = descriptor.apiFormat;\n return fail(`unsupported API format: ${String(_exhaustive)}`);\n }\n }\n\n if (listResult.isFailure()) {\n return listResult;\n }\n if (capability === undefined) {\n return listResult;\n }\n return succeed(listResult.value.filter((m) => m.capabilities.has(capability)));\n}\n\n// ============================================================================\n// Proxied list models\n// ============================================================================\n\n/**\n * Calls the model-listing endpoint on a proxy server. Endpoint:\n * `POST ${proxyUrl}/api/ai/list-models`. Capability config is not forwarded;\n * `capabilities` is serialized as a string array. Error body `{error: string}`\n * is surfaced as `proxy: ${error}`.\n * @public\n */\nexport async function callProxiedListModels(\n proxyUrl: string,\n params: IProviderListModelsParams\n): Promise<Result<ReadonlyArray<IAiModelInfo>>> {\n const { descriptor, apiKey, capability, logger, signal } = params;\n\n const body: Record<string, unknown> = {\n providerId: descriptor.id,\n apiKey\n };\n if (capability !== undefined) {\n body.capability = capability;\n }\n\n /* c8 ignore next 1 - optional logger */\n logger?.info(`AI list-models proxy request: provider=${descriptor.id}, proxy=${proxyUrl}`);\n\n const url = `${proxyUrl}/api/ai/list-models`;\n const jsonResult = await fetchJson(url, {}, body, logger, signal);\n if (jsonResult.isFailure()) {\n return fail(jsonResult.message);\n }\n\n const response = jsonResult.value as Record<string, unknown>;\n if (typeof response.error === 'string') {\n return fail(`proxy: ${response.error}`);\n }\n\n return proxiedListModelsResponse\n .validate(response)\n .withErrorFormat((msg) => `proxy returned invalid response: ${msg}`)\n .onSuccess((parsed) => {\n const models: IAiModelInfo[] = parsed.models.map((m) => ({\n id: m.id,\n capabilities: new Set<AiModelCapability>(m.capabilities),\n ...(m.displayName !== undefined ? { displayName: m.displayName } : {})\n }));\n return succeed(models);\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/anthropic.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EACL,QAAQ,EAER,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAiC,KAAK,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EACL,gBAAgB,EAMjB,MAAM,UAAU,CAAC;AAMlB;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,CAAC;AAiX7B;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,SAAS,EACvD,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,SAAS,EAC9C,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,uBAAuB,EAC1C,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACnD,oBAAoB,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,EAChD,mBAAmB,GAAE,OAAe,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAuDhD"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../../src/packlets/ai-assist/streamingAdapters/anthropic.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,EACL,QAAQ,EAER,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAiC,KAAK,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EACL,gBAAgB,EAMjB,MAAM,UAAU,CAAC;AAMlB;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB,yBAAyB,GACzB,iCAAiC,GACjC,qBAAqB,GACrB,wBAAwB,CAAC;AAiX7B;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,SAAS,EACvD,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,SAAS,EAC9C,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,uBAAuB,EAC1C,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACnD,oBAAoB,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,EAChD,mBAAmB,GAAE,OAAe,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAmDhD"}
@@ -54,6 +54,7 @@ exports.callAnthropicStream = callAnthropicStream;
54
54
  */
55
55
  const ts_utils_1 = require("@fgv/ts-utils");
56
56
  const chatRequestBuilders_1 = require("../chatRequestBuilders");
57
+ const endpoint_1 = require("../endpoint");
57
58
  const model_1 = require("../model");
58
59
  const sseParser_1 = require("../sseParser");
59
60
  const toolFormats_1 = require("../toolFormats");
@@ -365,11 +366,7 @@ async function callAnthropicStream(config, prompt, messagesBefore, temperature,
365
366
  if (tools && tools.length > 0) {
366
367
  body.tools = (0, toolFormats_1.toAnthropicTools)(tools);
367
368
  }
368
- const headers = {
369
- 'x-api-key': config.apiKey,
370
- 'anthropic-version': '2023-06-01',
371
- 'anthropic-dangerous-direct-browser-access': 'true'
372
- };
369
+ const headers = (0, endpoint_1.anthropicAuthHeaders)(config.apiKey);
373
370
  /* c8 ignore next 4 - optional logger diagnostic output */
374
371
  if (logger) {
375
372
  const toolTypes = tools && tools.length > 0 ? tools.map((t) => t.type).join(',') : 'none';