@oneuptime/common 11.3.25 → 11.3.28
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/Models/DatabaseModels/AIConversation.ts +322 -0
- package/Models/DatabaseModels/AIConversationMessage.ts +495 -0
- package/Models/DatabaseModels/AIRun.ts +584 -0
- package/Models/DatabaseModels/AIRunEvent.ts +443 -0
- package/Models/DatabaseModels/IncidentEpisodeRoleMember.ts +1 -1
- package/Models/DatabaseModels/IncidentMember.ts +1 -1
- package/Models/DatabaseModels/IncomingCallPolicy.ts +13 -0
- package/Models/DatabaseModels/Index.ts +11 -0
- package/Models/DatabaseModels/LlmLog.ts +26 -0
- package/Models/DatabaseModels/LlmProvider.ts +2 -2
- package/Models/DatabaseModels/MigrationFailure.ts +170 -0
- package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +51 -2
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +44 -0
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +6 -0
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.ts +6 -0
- package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +1 -1
- package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +2 -2
- package/Server/API/AIChatAPI.ts +693 -0
- package/Server/API/AlertAPI.ts +1 -1
- package/Server/API/IncidentAPI.ts +2 -2
- package/Server/API/IncidentEpisodeAPI.ts +1 -1
- package/Server/API/LlmProviderAPI.ts +170 -0
- package/Server/API/MicrosoftTeamsAPI.ts +5 -0
- package/Server/API/ScheduledMaintenanceAPI.ts +1 -1
- package/Server/API/SlackAPI.ts +663 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.ts +245 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.ts +36 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.ts +46 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.ts +119 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.ts +81 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
- package/Server/Infrastructure/PostgresDatabase.ts +11 -0
- package/Server/Services/AIConversationMessageService.ts +39 -0
- package/Server/Services/AIConversationService.ts +63 -0
- package/Server/Services/AIRunEventService.ts +39 -0
- package/Server/Services/AIRunService.ts +39 -0
- package/Server/Services/AIService.ts +127 -33
- package/Server/Services/AnalyticsDatabaseService.ts +10 -1
- package/Server/Services/DatabaseService.ts +29 -1
- package/Server/Services/IncidentService.ts +1 -1
- package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +75 -2
- package/Server/Services/IncomingCallPolicyService.ts +42 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LlmProviderService.ts +110 -0
- package/Server/Services/MigrationFailureService.ts +9 -0
- package/Server/Services/MonitorProbeService.ts +33 -7
- package/Server/Services/MonitorService.ts +19 -7
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +185 -41
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +23 -15
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +39 -0
- package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +148 -0
- package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +11 -2
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +502 -26
- package/Server/Services/OnCallDutyPolicyTimeLogService.ts +49 -7
- package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +218 -4
- package/Server/Services/ProjectCallSMSConfigService.ts +82 -1
- package/Server/Services/ProjectService.ts +24 -0
- package/Server/Services/TeamMemberService.ts +6 -0
- package/Server/Services/UserNotificationRuleService.ts +13 -42
- package/Server/Services/UserOnCallLogService.ts +90 -0
- package/Server/Services/UserOnCallLogTimelineService.ts +43 -1
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +74 -9
- package/Server/Types/Database/QueryUtil.ts +57 -0
- package/Server/Utils/AI/AIChatPrivacyFilter.ts +28 -0
- package/Server/Utils/AI/AlertAIContextBuilder.ts +6 -1
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +1066 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +239 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +51 -0
- package/Server/Utils/AI/IncidentAIContextBuilder.ts +18 -3
- package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +6 -1
- package/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.ts +12 -2
- package/Server/Utils/AI/Toolbox/AlertTools.ts +201 -0
- package/Server/Utils/AI/Toolbox/AlertWriteTools.ts +174 -0
- package/Server/Utils/AI/Toolbox/ContextTools.ts +189 -0
- package/Server/Utils/AI/Toolbox/ExceptionTools.ts +149 -0
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +386 -0
- package/Server/Utils/AI/Toolbox/IncidentWriteTools.ts +350 -0
- package/Server/Utils/AI/Toolbox/Index.ts +231 -0
- package/Server/Utils/AI/Toolbox/LogTools.ts +339 -0
- package/Server/Utils/AI/Toolbox/MetricTools.ts +179 -0
- package/Server/Utils/AI/Toolbox/MonitorTools.ts +193 -0
- package/Server/Utils/AI/Toolbox/RecentChangesTools.ts +208 -0
- package/Server/Utils/AI/Toolbox/Serializer.ts +299 -0
- package/Server/Utils/AI/Toolbox/ToolTypes.ts +249 -0
- package/Server/Utils/AI/Toolbox/TraceTools.ts +402 -0
- package/Server/Utils/AI/Toolbox/WidgetBuilder.ts +189 -0
- package/Server/Utils/Database/MigrationFailureLog.ts +240 -0
- package/Server/Utils/IncomingCallPhoneNumber.ts +41 -0
- package/Server/Utils/LLM/LLMService.ts +605 -96
- package/Server/Utils/Telemetry/IoTSnapshotScan.ts +12 -9
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +12 -9
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +512 -19
- package/Server/Utils/Workspace/Slack/Slack.ts +80 -0
- package/Server/Utils/Workspace/Slack/app-manifest.json +16 -1
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +0 -8
- package/Tests/Server/Services/OnCallDutyPolicyScheduleLayerUserReorder.test.ts +233 -0
- package/Tests/Server/Services/OnCallDutyPolicyTimeLogServiceScoping.test.ts +242 -0
- package/Tests/Server/Services/OnCallDutyPolicyUserOverrideEdit.test.ts +198 -0
- package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +495 -0
- package/Tests/Server/Types/Database/QueryUtil.test.ts +74 -0
- package/Tests/Server/Utils/AI/AIChatModelACL.test.ts +42 -0
- package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +89 -0
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +139 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +386 -0
- package/Tests/Server/Utils/AI/ToolArgsGetTimeRange.test.ts +62 -0
- package/Tests/Server/Utils/AI/ToolArgsScopeServiceIds.test.ts +79 -0
- package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +223 -0
- package/Tests/Types/Billing/SubscriptionStatus.test.ts +127 -0
- package/Tests/Types/DateExhaustiveTimezone.test.ts +700 -0
- package/Tests/Types/DateTimezoneWallClock.test.ts +99 -0
- package/Tests/Types/Events/Recurring.test.ts +22 -9
- package/Tests/Types/Metrics/RecordingRuleDefinition.test.ts +213 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixes.test.ts +291 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixesRound2.test.ts +398 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeekendGap.test.ts +114 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeeklyDayShift.test.ts +76 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyMutation.test.ts +128 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyProbe.test.ts +203 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilDiffFuzz.test.ts +322 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilEdgeCases.test.ts +280 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveCurrentUser.test.ts +863 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveDaily.test.ts +900 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveMultiLayer.test.ts +1104 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +957 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveWeekly.test.ts +1095 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilInvariants.test.ts +232 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +227 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMonthYearAudit.test.ts +255 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerAudit.test.ts +388 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerEdge.test.ts +300 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilOvernightDSTAudit.test.ts +158 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapFix.test.ts +253 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapRepro.test.ts +157 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilRotationFixes.test.ts +414 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilTimezone.test.ts +243 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilWeekendGapRepro.test.ts +112 -0
- package/Tests/Types/OnCallDutyPolicy/OverrideLensAudit.test.ts +117 -0
- package/Tests/Types/OnCallDutyPolicy/RestrictionTimes.test.ts +8 -6
- package/Tests/Types/OnCallDutyPolicy/RestrictionTimesDefaultDayAudit.test.ts +112 -0
- package/Tests/Types/OnCallDutyPolicy/RestrictionTimesExhaustive.test.ts +821 -0
- package/Tests/Types/OnCallDutyPolicy/RestrictionTimesMutationInvariant.test.ts +886 -0
- package/Tests/Types/OnCallDutyPolicy/UserOverrideUtil.test.ts +255 -0
- package/Tests/Types/OnCallDutyPolicy/UserOverrideUtilExhaustive.test.ts +1126 -0
- package/Types/AI/AIChatMessageRole.ts +6 -0
- package/Types/AI/AIChatMessageStatus.ts +32 -0
- package/Types/AI/AIChatPermissionMode.ts +69 -0
- package/Types/AI/AIChatTypes.ts +231 -0
- package/Types/AI/AIRunEventType.ts +17 -0
- package/Types/AI/AIRunStatus.ts +28 -0
- package/Types/AI/AIRunType.ts +6 -0
- package/Types/Date.ts +200 -15
- package/Types/LLM/LlmType.ts +6 -0
- package/Types/OnCallDutyPolicy/Layer.ts +790 -260
- package/Types/OnCallDutyPolicy/RestrictionTimes.ts +39 -13
- package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +21 -5
- package/UI/Components/Events/RecurringFieldElement.tsx +16 -0
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +22 -12
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +35 -3
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +8 -0
- package/UI/Components/Page/Page.tsx +14 -0
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +1 -1
- package/UI/Utils/LlmTypeDropdownOptions.ts +40 -0
- package/UI/Utils/TestLLMProvider.ts +59 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js +345 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js +521 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +619 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -0
- package/build/dist/Models/DatabaseModels/AIRunEvent.js +469 -0
- package/build/dist/Models/DatabaseModels/AIRunEvent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentMember.js +1 -1
- package/build/dist/Models/DatabaseModels/IncidentMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +10 -0
- package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LlmLog.js +28 -0
- package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LlmProvider.js +2 -2
- package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MigrationFailure.js +196 -0
- package/build/dist/Models/DatabaseModels/MigrationFailure.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +52 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +45 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +6 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js +6 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +498 -0
- package/build/dist/Server/API/AIChatAPI.js.map +1 -0
- package/build/dist/Server/API/AlertAPI.js +1 -1
- package/build/dist/Server/API/IncidentAPI.js +2 -2
- package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -1
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +4 -0
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
- package/build/dist/Server/API/SlackAPI.js +442 -0
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.js +96 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.js +25 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.js +46 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/PostgresDatabase.js +9 -0
- package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
- package/build/dist/Server/Services/AIConversationMessageService.js +34 -0
- package/build/dist/Server/Services/AIConversationMessageService.js.map +1 -0
- package/build/dist/Server/Services/AIConversationService.js +42 -0
- package/build/dist/Server/Services/AIConversationService.js.map +1 -0
- package/build/dist/Server/Services/AIRunEventService.js +34 -0
- package/build/dist/Server/Services/AIRunEventService.js.map +1 -0
- package/build/dist/Server/Services/AIRunService.js +34 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -0
- package/build/dist/Server/Services/AIService.js +84 -25
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +10 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +20 -1
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +55 -2
- package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyService.js +40 -0
- package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LlmProviderService.js +108 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/MigrationFailureService.js +9 -0
- package/build/dist/Server/Services/MigrationFailureService.js.map +1 -0
- package/build/dist/Server/Services/MonitorProbeService.js +33 -7
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +12 -5
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +81 -22
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +134 -31
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +21 -13
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +36 -0
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +121 -0
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +11 -2
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +409 -36
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js +52 -8
- package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +170 -3
- package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js +72 -0
- package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +25 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +6 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +12 -30
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +75 -0
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogTimelineService.js +31 -1
- package/build/dist/Server/Services/UserOnCallLogTimelineService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +50 -7
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryUtil.js +45 -0
- package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +18 -0
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -0
- package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +6 -1
- package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +756 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +165 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +44 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -0
- package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +18 -3
- package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +6 -1
- package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js +12 -2
- package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +167 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertWriteTools.js +136 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/ContextTools.js +141 -0
- package/build/dist/Server/Utils/AI/Toolbox/ContextTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/ExceptionTools.js +117 -0
- package/build/dist/Server/Utils/AI/Toolbox/ExceptionTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +318 -0
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/IncidentWriteTools.js +280 -0
- package/build/dist/Server/Utils/AI/Toolbox/IncidentWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +153 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/LogTools.js +246 -0
- package/build/dist/Server/Utils/AI/Toolbox/LogTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js +120 -0
- package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +158 -0
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js +165 -0
- package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +228 -0
- package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/ToolTypes.js +142 -0
- package/build/dist/Server/Utils/AI/Toolbox/ToolTypes.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js +309 -0
- package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/WidgetBuilder.js +120 -0
- package/build/dist/Server/Utils/AI/Toolbox/WidgetBuilder.js.map +1 -0
- package/build/dist/Server/Utils/Database/MigrationFailureLog.js +174 -0
- package/build/dist/Server/Utils/Database/MigrationFailureLog.js.map +1 -0
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +30 -0
- package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +452 -92
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js +11 -8
- package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +11 -8
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +378 -15
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +59 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +16 -1
- package/build/dist/Types/AI/AIChatMessageRole.js +7 -0
- package/build/dist/Types/AI/AIChatMessageRole.js.map +1 -0
- package/build/dist/Types/AI/AIChatMessageStatus.js +27 -0
- package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -0
- package/build/dist/Types/AI/AIChatPermissionMode.js +53 -0
- package/build/dist/Types/AI/AIChatPermissionMode.js.map +1 -0
- package/build/dist/Types/AI/AIChatTypes.js +74 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -0
- package/build/dist/Types/AI/AIRunEventType.js +18 -0
- package/build/dist/Types/AI/AIRunEventType.js.map +1 -0
- package/build/dist/Types/AI/AIRunStatus.js +26 -0
- package/build/dist/Types/AI/AIRunStatus.js.map +1 -0
- package/build/dist/Types/AI/AIRunType.js +7 -0
- package/build/dist/Types/AI/AIRunType.js.map +1 -0
- package/build/dist/Types/Date.js +153 -15
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/LLM/LlmType.js +6 -0
- package/build/dist/Types/LLM/LlmType.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +602 -171
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js +27 -13
- package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +20 -5
- package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
- package/build/dist/UI/Components/Events/RecurringFieldElement.js +13 -0
- package/build/dist/UI/Components/Events/RecurringFieldElement.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +10 -5
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +18 -4
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/Page/Page.js +3 -1
- package/build/dist/UI/Components/Page/Page.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Utils/LlmTypeDropdownOptions.js +38 -0
- package/build/dist/UI/Utils/LlmTypeDropdownOptions.js.map +1 -0
- package/build/dist/UI/Utils/TestLLMProvider.js +37 -0
- package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -0
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
11
11
|
import URL from "../../../Types/API/URL";
|
|
12
|
+
import JSONFunctions from "../../../Types/JSONFunctions";
|
|
12
13
|
import API from "../../../Utils/API";
|
|
13
14
|
import LlmType from "../../../Types/LLM/LlmType";
|
|
14
15
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
@@ -21,6 +22,7 @@ class LLMService {
|
|
|
21
22
|
case LlmType.OpenAI:
|
|
22
23
|
case LlmType.Groq:
|
|
23
24
|
case LlmType.Mistral:
|
|
25
|
+
case LlmType.OpenAICompatible:
|
|
24
26
|
return await this.getOpenAICompatibleCompletion(config, request);
|
|
25
27
|
case LlmType.AzureOpenAI:
|
|
26
28
|
return await this.getAzureOpenAICompletion(config, request);
|
|
@@ -32,11 +34,227 @@ class LLMService {
|
|
|
32
34
|
throw new BadDataException(`Unsupported LLM type: ${config.llmType}`);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
/*
|
|
38
|
+
* OpenAI-compatible wire format (OpenAI, Groq, Mistral, Azure OpenAI).
|
|
39
|
+
*/
|
|
40
|
+
static toOpenAIMessages(messages) {
|
|
41
|
+
return messages.map((msg) => {
|
|
42
|
+
if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length) {
|
|
43
|
+
return {
|
|
44
|
+
role: "assistant",
|
|
45
|
+
content: msg.content || null,
|
|
46
|
+
tool_calls: msg.toolCalls.map((toolCall) => {
|
|
47
|
+
return {
|
|
48
|
+
id: toolCall.id,
|
|
49
|
+
type: "function",
|
|
50
|
+
function: {
|
|
51
|
+
name: toolCall.name,
|
|
52
|
+
arguments: JSON.stringify(toolCall.arguments),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (msg.role === "tool") {
|
|
59
|
+
return {
|
|
60
|
+
role: "tool",
|
|
61
|
+
tool_call_id: msg.toolCallId || "",
|
|
62
|
+
content: msg.content,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
role: msg.role,
|
|
67
|
+
content: msg.content,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
static toOpenAITools(tools) {
|
|
72
|
+
return tools.map((tool) => {
|
|
73
|
+
return {
|
|
74
|
+
type: "function",
|
|
75
|
+
function: {
|
|
76
|
+
name: tool.name,
|
|
77
|
+
description: tool.description,
|
|
78
|
+
parameters: tool.inputSchema,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
static parseOpenAIToolCalls(message) {
|
|
84
|
+
const rawToolCalls = message["tool_calls"];
|
|
85
|
+
if (!rawToolCalls || rawToolCalls.length === 0) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
return rawToolCalls.map((rawToolCall, index) => {
|
|
89
|
+
const fn = rawToolCall["function"] || {};
|
|
90
|
+
const parsed = this.parseToolCallArguments(fn["arguments"] || "{}");
|
|
91
|
+
return {
|
|
92
|
+
id: rawToolCall["id"] || `tool_call_${index}`,
|
|
93
|
+
name: fn["name"] || "",
|
|
94
|
+
arguments: parsed.arguments,
|
|
95
|
+
argumentsParseError: parsed.error,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/*
|
|
100
|
+
* Models sometimes emit slightly malformed argument JSON (trailing commas,
|
|
101
|
+
* single quotes). Try strict JSON first, then tolerant JSON5, and report a
|
|
102
|
+
* parse error instead of silently executing with empty arguments.
|
|
103
|
+
*/
|
|
104
|
+
static parseToolCallArguments(rawArguments) {
|
|
105
|
+
try {
|
|
106
|
+
return { arguments: JSON.parse(rawArguments) };
|
|
107
|
+
}
|
|
108
|
+
catch (_a) {
|
|
109
|
+
// fall through to tolerant parsing
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSONFunctions.parse(rawArguments);
|
|
113
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
114
|
+
return { arguments: parsed };
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
arguments: {},
|
|
118
|
+
error: "Tool arguments were not a JSON object.",
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (_b) {
|
|
122
|
+
return {
|
|
123
|
+
arguments: {},
|
|
124
|
+
error: "Tool arguments were malformed JSON and could not be parsed.",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
static buildOpenAIRequestBody(modelName, request) {
|
|
36
129
|
var _a;
|
|
37
|
-
|
|
130
|
+
const data = {
|
|
131
|
+
model: modelName,
|
|
132
|
+
messages: this.toOpenAIMessages(request.messages),
|
|
133
|
+
temperature: (_a = request.temperature) !== null && _a !== void 0 ? _a : 0.7,
|
|
134
|
+
};
|
|
135
|
+
if (request.maxTokens) {
|
|
136
|
+
data["max_tokens"] = request.maxTokens;
|
|
137
|
+
}
|
|
138
|
+
if (request.tools && request.tools.length > 0) {
|
|
139
|
+
data["tools"] = this.toOpenAITools(request.tools);
|
|
140
|
+
}
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
static parseOpenAIResponse(jsonData, providerName) {
|
|
144
|
+
var _a;
|
|
145
|
+
const choices = jsonData["choices"];
|
|
146
|
+
if (!choices || choices.length === 0) {
|
|
147
|
+
throw new BadDataException(`No response from ${providerName}`);
|
|
148
|
+
}
|
|
149
|
+
const message = choices[0]["message"];
|
|
150
|
+
const usage = jsonData["usage"];
|
|
151
|
+
const toolCalls = this.parseOpenAIToolCalls(message);
|
|
152
|
+
/*
|
|
153
|
+
* OpenAI (and Azure OpenAI) automatically cache a stable prompt prefix
|
|
154
|
+
* once it is long enough and report the cache hit under
|
|
155
|
+
* prompt_tokens_details.cached_tokens — surface it for cost visibility.
|
|
156
|
+
*/
|
|
157
|
+
const cachedTokens = usage
|
|
158
|
+
? (_a = usage["prompt_tokens_details"]) === null || _a === void 0 ? void 0 : _a["cached_tokens"]
|
|
159
|
+
: undefined;
|
|
160
|
+
return {
|
|
161
|
+
content: message["content"] || "",
|
|
162
|
+
toolCalls: toolCalls,
|
|
163
|
+
stopReason: toolCalls && toolCalls.length > 0 ? "tool_use" : "stop",
|
|
164
|
+
usage: usage
|
|
165
|
+
? {
|
|
166
|
+
promptTokens: usage["prompt_tokens"],
|
|
167
|
+
completionTokens: usage["completion_tokens"],
|
|
168
|
+
totalTokens: usage["total_tokens"],
|
|
169
|
+
cachedInputTokens: cachedTokens || undefined,
|
|
170
|
+
}
|
|
171
|
+
: undefined,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/*
|
|
175
|
+
* Build the chat completions URL for an OpenAI-compatible server from the
|
|
176
|
+
* configured base URL. Users enter the base URL in a few different ways, and
|
|
177
|
+
* we normalize all of them onto the right endpoint instead of 404-ing:
|
|
178
|
+
*
|
|
179
|
+
* - Already a full endpoint (".../chat/completions") -> used as-is.
|
|
180
|
+
* - Includes a path (".../v1", ".../openai/v1") -> append "/chat/completions".
|
|
181
|
+
* - Bare server root ("http://host:8000") -> append "/v1/chat/completions",
|
|
182
|
+
* since vLLM, LocalAI and similar servers expose the OpenAI-compatible API
|
|
183
|
+
* under /v1 by default. This is the most common self-hosted setup and the
|
|
184
|
+
* easiest one for users to get wrong (omitting /v1 returns FastAPI's
|
|
185
|
+
* {"detail":"Not Found"}).
|
|
186
|
+
*
|
|
187
|
+
* The endpoint segment is only ever appended to the PATH portion: any
|
|
188
|
+
* ?query or #fragment on the base URL is split off first and re-attached
|
|
189
|
+
* afterwards (otherwise "/chat/completions" would land inside the query or
|
|
190
|
+
* fragment). Trailing slashes are stripped so we never emit
|
|
191
|
+
* ".../v1//chat/completions", and the URL scheme is lower-cased because URL
|
|
192
|
+
* schemes are case-insensitive but downstream URL parsing only recognizes
|
|
193
|
+
* lowercase http/https.
|
|
194
|
+
*/
|
|
195
|
+
static buildOpenAICompatibleChatCompletionsUrl(baseUrl) {
|
|
196
|
+
const raw = baseUrl.trim();
|
|
197
|
+
// Split off #fragment, then ?query, so we can operate on the path alone.
|
|
198
|
+
const fragmentIndex = raw.indexOf("#");
|
|
199
|
+
const fragment = fragmentIndex >= 0 ? raw.substring(fragmentIndex) : "";
|
|
200
|
+
const withoutFragment = fragmentIndex >= 0 ? raw.substring(0, fragmentIndex) : raw;
|
|
201
|
+
const queryIndex = withoutFragment.indexOf("?");
|
|
202
|
+
const query = queryIndex >= 0 ? withoutFragment.substring(queryIndex) : "";
|
|
203
|
+
let base = queryIndex >= 0
|
|
204
|
+
? withoutFragment.substring(0, queryIndex)
|
|
205
|
+
: withoutFragment;
|
|
206
|
+
/*
|
|
207
|
+
* Lower-case the scheme (e.g. "HTTP://" -> "http://") and strip trailing
|
|
208
|
+
* slashes.
|
|
209
|
+
*/
|
|
210
|
+
const schemeRegex = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
211
|
+
base = base
|
|
212
|
+
.replace(schemeRegex, (scheme) => {
|
|
213
|
+
return scheme.toLowerCase();
|
|
214
|
+
})
|
|
215
|
+
.replace(/\/+$/, "");
|
|
216
|
+
let path;
|
|
217
|
+
const fullEndpointRegex = /\/chat\/completions$/i;
|
|
218
|
+
const hasPathAfterHostRegex = /^[a-z][a-z0-9+.-]*:\/\/[^/]+\/.+/i;
|
|
219
|
+
if (fullEndpointRegex.test(base)) {
|
|
220
|
+
// The user already pointed us at the full endpoint.
|
|
221
|
+
path = base;
|
|
222
|
+
}
|
|
223
|
+
else if (hasPathAfterHostRegex.test(base)) {
|
|
224
|
+
/*
|
|
225
|
+
* The base URL carries a path after the host[:port] (e.g.
|
|
226
|
+
* "http://host:8000/v1" or ".../openai/v1") — trust it and only append
|
|
227
|
+
* the endpoint.
|
|
228
|
+
*/
|
|
229
|
+
path = `${base}/chat/completions`;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
/*
|
|
233
|
+
* Bare server root ("http://host:8000") — add the conventional /v1
|
|
234
|
+
* prefix that OpenAI-compatible servers (vLLM, LocalAI, ...) use.
|
|
235
|
+
*/
|
|
236
|
+
path = `${base}/v1/chat/completions`;
|
|
237
|
+
}
|
|
238
|
+
return `${path}${query}${fragment}`;
|
|
239
|
+
}
|
|
240
|
+
static async getOpenAICompatibleCompletion(config, request) {
|
|
241
|
+
/*
|
|
242
|
+
* Generic OpenAI-compatible servers (vLLM, LocalAI, etc.) are usually
|
|
243
|
+
* self-hosted, frequently keyless, and have no canonical endpoint or
|
|
244
|
+
* default model — so the API key is optional but the base URL and model
|
|
245
|
+
* name must be provided. The hosted providers (OpenAI, Groq, Mistral)
|
|
246
|
+
* keep requiring a key and fall back to sensible defaults.
|
|
247
|
+
*/
|
|
248
|
+
const isGenericOpenAICompatible = config.llmType === LlmType.OpenAICompatible;
|
|
249
|
+
if (!isGenericOpenAICompatible && !config.apiKey) {
|
|
38
250
|
throw new BadDataException(`${config.llmType} API key is required`);
|
|
39
251
|
}
|
|
252
|
+
if (isGenericOpenAICompatible && !config.baseUrl) {
|
|
253
|
+
throw new BadDataException("Base URL is required for OpenAI-compatible providers (e.g. http://your-vllm-server:8000/v1)");
|
|
254
|
+
}
|
|
255
|
+
if (isGenericOpenAICompatible && !config.modelName) {
|
|
256
|
+
throw new BadDataException("Model Name is required for OpenAI-compatible providers. It must match a model your server exposes.");
|
|
257
|
+
}
|
|
40
258
|
const defaultBaseUrls = {
|
|
41
259
|
[LlmType.OpenAI]: "https://api.openai.com/v1",
|
|
42
260
|
[LlmType.Groq]: "https://api.groq.com/openai/v1",
|
|
@@ -52,21 +270,11 @@ class LLMService {
|
|
|
52
270
|
"https://api.openai.com/v1";
|
|
53
271
|
const modelName = config.modelName || defaultModels[config.llmType] || "gpt-4o";
|
|
54
272
|
const response = await API.post({
|
|
55
|
-
url: URL.fromString(
|
|
56
|
-
data:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
role: msg.role,
|
|
61
|
-
content: msg.content,
|
|
62
|
-
};
|
|
63
|
-
}),
|
|
64
|
-
temperature: (_a = request.temperature) !== null && _a !== void 0 ? _a : 0.7,
|
|
65
|
-
},
|
|
66
|
-
headers: {
|
|
67
|
-
Authorization: `Bearer ${config.apiKey}`,
|
|
68
|
-
"Content-Type": "application/json",
|
|
69
|
-
},
|
|
273
|
+
url: URL.fromString(this.buildOpenAICompatibleChatCompletionsUrl(baseUrl)),
|
|
274
|
+
data: this.buildOpenAIRequestBody(modelName, request),
|
|
275
|
+
headers: Object.assign({ "Content-Type": "application/json" }, (config.apiKey
|
|
276
|
+
? { Authorization: `Bearer ${config.apiKey}` }
|
|
277
|
+
: {})),
|
|
70
278
|
options: {
|
|
71
279
|
retries: 2,
|
|
72
280
|
exponentialBackoff: true,
|
|
@@ -82,23 +290,7 @@ class LLMService {
|
|
|
82
290
|
logger.error(response, logAttributes);
|
|
83
291
|
throw new BadDataException(`${config.llmType} API error: ${JSON.stringify(response.jsonData)}`);
|
|
84
292
|
}
|
|
85
|
-
|
|
86
|
-
const choices = jsonData["choices"];
|
|
87
|
-
if (!choices || choices.length === 0) {
|
|
88
|
-
throw new BadDataException(`No response from ${config.llmType}`);
|
|
89
|
-
}
|
|
90
|
-
const message = choices[0]["message"];
|
|
91
|
-
const usage = jsonData["usage"];
|
|
92
|
-
return {
|
|
93
|
-
content: message["content"],
|
|
94
|
-
usage: usage
|
|
95
|
-
? {
|
|
96
|
-
promptTokens: usage["prompt_tokens"],
|
|
97
|
-
completionTokens: usage["completion_tokens"],
|
|
98
|
-
totalTokens: usage["total_tokens"],
|
|
99
|
-
}
|
|
100
|
-
: undefined,
|
|
101
|
-
};
|
|
293
|
+
return this.parseOpenAIResponse(response.jsonData, config.llmType);
|
|
102
294
|
}
|
|
103
295
|
static buildAzureOpenAIChatCompletionsUrl(baseUrl) {
|
|
104
296
|
const trimmed = baseUrl.replace(/\/+$/, "");
|
|
@@ -112,7 +304,6 @@ class LLMService {
|
|
|
112
304
|
return `${pathPart}/chat/completions?${params.toString()}`;
|
|
113
305
|
}
|
|
114
306
|
static async getAzureOpenAICompletion(config, request) {
|
|
115
|
-
var _a;
|
|
116
307
|
if (!config.apiKey) {
|
|
117
308
|
throw new BadDataException("Azure OpenAI API key is required");
|
|
118
309
|
}
|
|
@@ -123,16 +314,7 @@ class LLMService {
|
|
|
123
314
|
const requestUrl = LLMService.buildAzureOpenAIChatCompletionsUrl(config.baseUrl);
|
|
124
315
|
const response = await API.post({
|
|
125
316
|
url: URL.fromString(requestUrl),
|
|
126
|
-
data:
|
|
127
|
-
model: modelName,
|
|
128
|
-
messages: request.messages.map((msg) => {
|
|
129
|
-
return {
|
|
130
|
-
role: msg.role,
|
|
131
|
-
content: msg.content,
|
|
132
|
-
};
|
|
133
|
-
}),
|
|
134
|
-
temperature: (_a = request.temperature) !== null && _a !== void 0 ? _a : 0.7,
|
|
135
|
-
},
|
|
317
|
+
data: this.buildOpenAIRequestBody(modelName, request),
|
|
136
318
|
headers: {
|
|
137
319
|
"api-key": config.apiKey,
|
|
138
320
|
"Content-Type": "application/json",
|
|
@@ -152,23 +334,83 @@ class LLMService {
|
|
|
152
334
|
logger.error(response, logAttributes);
|
|
153
335
|
throw new BadDataException(`Azure OpenAI API error: ${JSON.stringify(response.jsonData)}`);
|
|
154
336
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
completionTokens: usage["completion_tokens"],
|
|
168
|
-
totalTokens: usage["total_tokens"],
|
|
337
|
+
return this.parseOpenAIResponse(response.jsonData, "Azure OpenAI");
|
|
338
|
+
}
|
|
339
|
+
static toAnthropicMessages(messages) {
|
|
340
|
+
const anthropicMessages = [];
|
|
341
|
+
for (const msg of messages) {
|
|
342
|
+
if (msg.role === "system") {
|
|
343
|
+
continue; // hoisted separately
|
|
344
|
+
}
|
|
345
|
+
if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length) {
|
|
346
|
+
const contentBlocks = [];
|
|
347
|
+
if (msg.content) {
|
|
348
|
+
contentBlocks.push({ type: "text", text: msg.content });
|
|
169
349
|
}
|
|
170
|
-
|
|
171
|
-
|
|
350
|
+
for (const toolCall of msg.toolCalls) {
|
|
351
|
+
contentBlocks.push({
|
|
352
|
+
type: "tool_use",
|
|
353
|
+
id: toolCall.id,
|
|
354
|
+
name: toolCall.name,
|
|
355
|
+
input: toolCall.arguments,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
anthropicMessages.push({ role: "assistant", content: contentBlocks });
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
if (msg.role === "tool") {
|
|
362
|
+
const toolResultBlock = {
|
|
363
|
+
type: "tool_result",
|
|
364
|
+
tool_use_id: msg.toolCallId || "",
|
|
365
|
+
content: msg.content,
|
|
366
|
+
};
|
|
367
|
+
/*
|
|
368
|
+
* Tool results must be user messages. Merge consecutive tool
|
|
369
|
+
* results into one user message so roles keep alternating.
|
|
370
|
+
*/
|
|
371
|
+
const lastMessage = anthropicMessages[anthropicMessages.length - 1];
|
|
372
|
+
if (lastMessage &&
|
|
373
|
+
lastMessage["role"] === "user" &&
|
|
374
|
+
Array.isArray(lastMessage["content"])) {
|
|
375
|
+
lastMessage["content"].push(toolResultBlock);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
anthropicMessages.push({
|
|
379
|
+
role: "user",
|
|
380
|
+
content: [toolResultBlock],
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
/*
|
|
386
|
+
* Anthropic requires strictly alternating user/assistant turns and
|
|
387
|
+
* returns a 400 on two consecutive same-role messages. The agent loop
|
|
388
|
+
* can legitimately emit back-to-back user turns (e.g. a tool_result
|
|
389
|
+
* user message immediately followed by the "budget exhausted, answer
|
|
390
|
+
* now" nudge), so coalesce a run of same-role messages into one instead
|
|
391
|
+
* of failing the whole request.
|
|
392
|
+
*/
|
|
393
|
+
const previousMessage = anthropicMessages[anthropicMessages.length - 1];
|
|
394
|
+
if (previousMessage && previousMessage["role"] === msg.role) {
|
|
395
|
+
if (typeof previousMessage["content"] === "string") {
|
|
396
|
+
previousMessage["content"] =
|
|
397
|
+
`${previousMessage["content"]}\n\n${msg.content}`;
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
if (Array.isArray(previousMessage["content"])) {
|
|
401
|
+
previousMessage["content"].push({
|
|
402
|
+
type: "text",
|
|
403
|
+
text: msg.content,
|
|
404
|
+
});
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
anthropicMessages.push({
|
|
409
|
+
role: msg.role,
|
|
410
|
+
content: msg.content,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
return anthropicMessages;
|
|
172
414
|
}
|
|
173
415
|
static async getAnthropicCompletion(config, request) {
|
|
174
416
|
var _a;
|
|
@@ -177,27 +419,50 @@ class LLMService {
|
|
|
177
419
|
}
|
|
178
420
|
const baseUrl = config.baseUrl || "https://api.anthropic.com/v1";
|
|
179
421
|
const modelName = config.modelName || "claude-sonnet-4-20250514";
|
|
180
|
-
// Anthropic requires system message to be separate
|
|
181
422
|
let systemMessage = "";
|
|
182
|
-
const userMessages = [];
|
|
183
423
|
for (const msg of request.messages) {
|
|
184
424
|
if (msg.role === "system") {
|
|
185
425
|
systemMessage = msg.content;
|
|
186
426
|
}
|
|
187
|
-
else {
|
|
188
|
-
userMessages.push({
|
|
189
|
-
role: msg.role,
|
|
190
|
-
content: msg.content,
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
427
|
}
|
|
194
428
|
const requestData = {
|
|
195
429
|
model: modelName,
|
|
196
|
-
messages:
|
|
430
|
+
messages: this.toAnthropicMessages(request.messages),
|
|
197
431
|
temperature: (_a = request.temperature) !== null && _a !== void 0 ? _a : 0.7,
|
|
432
|
+
// Anthropic requires max_tokens on every request.
|
|
433
|
+
max_tokens: request.maxTokens || LLMService.ANTHROPIC_DEFAULT_MAX_TOKENS,
|
|
198
434
|
};
|
|
435
|
+
/*
|
|
436
|
+
* Prompt caching. The system prompt and tool definitions are the large,
|
|
437
|
+
* stable prefix re-sent on every turn of the agent loop, so caching them is
|
|
438
|
+
* the biggest single cost + latency lever (cached input is billed at ~10%).
|
|
439
|
+
* An ephemeral cache_control breakpoint on the system block and on the LAST
|
|
440
|
+
* tool caches the whole system + tools prefix. cache_control is GA under
|
|
441
|
+
* anthropic-version 2023-06-01, so no beta header is required.
|
|
442
|
+
*/
|
|
199
443
|
if (systemMessage) {
|
|
200
|
-
requestData["system"] =
|
|
444
|
+
requestData["system"] = [
|
|
445
|
+
{
|
|
446
|
+
type: "text",
|
|
447
|
+
text: systemMessage,
|
|
448
|
+
cache_control: { type: "ephemeral" },
|
|
449
|
+
},
|
|
450
|
+
];
|
|
451
|
+
}
|
|
452
|
+
if (request.tools && request.tools.length > 0) {
|
|
453
|
+
const anthropicTools = request.tools.map((tool) => {
|
|
454
|
+
return {
|
|
455
|
+
name: tool.name,
|
|
456
|
+
description: tool.description,
|
|
457
|
+
input_schema: tool.inputSchema,
|
|
458
|
+
};
|
|
459
|
+
});
|
|
460
|
+
// A breakpoint on the last tool caches the entire tools block before it.
|
|
461
|
+
const lastTool = anthropicTools[anthropicTools.length - 1];
|
|
462
|
+
if (lastTool) {
|
|
463
|
+
lastTool["cache_control"] = { type: "ephemeral" };
|
|
464
|
+
}
|
|
465
|
+
requestData["tools"] = anthropicTools;
|
|
201
466
|
}
|
|
202
467
|
const response = await API.post({
|
|
203
468
|
url: URL.fromString(`${baseUrl}/messages`),
|
|
@@ -227,46 +492,94 @@ class LLMService {
|
|
|
227
492
|
if (!content || content.length === 0) {
|
|
228
493
|
throw new BadDataException("No response from Anthropic");
|
|
229
494
|
}
|
|
230
|
-
const textContent = content
|
|
231
|
-
|
|
495
|
+
const textContent = content
|
|
496
|
+
.filter((block) => {
|
|
497
|
+
return block["type"] === "text";
|
|
498
|
+
})
|
|
499
|
+
.map((block) => {
|
|
500
|
+
return block["text"];
|
|
501
|
+
})
|
|
502
|
+
.join("");
|
|
503
|
+
const toolCalls = content
|
|
504
|
+
.filter((block) => {
|
|
505
|
+
return block["type"] === "tool_use";
|
|
506
|
+
})
|
|
507
|
+
.map((block) => {
|
|
508
|
+
return {
|
|
509
|
+
id: block["id"] || "",
|
|
510
|
+
name: block["name"] || "",
|
|
511
|
+
arguments: block["input"] || {},
|
|
512
|
+
};
|
|
232
513
|
});
|
|
233
|
-
if (!textContent) {
|
|
514
|
+
if (!textContent && toolCalls.length === 0) {
|
|
234
515
|
throw new BadDataException("No text content in Anthropic response");
|
|
235
516
|
}
|
|
236
517
|
const usage = jsonData["usage"];
|
|
237
518
|
return {
|
|
238
|
-
content: textContent
|
|
519
|
+
content: textContent,
|
|
520
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
521
|
+
stopReason: jsonData["stop_reason"] === "tool_use" ? "tool_use" : "stop",
|
|
239
522
|
usage: usage
|
|
240
523
|
? {
|
|
241
|
-
promptTokens: usage["input_tokens"],
|
|
242
|
-
completionTokens: usage["output_tokens"],
|
|
524
|
+
promptTokens: usage["input_tokens"] || 0,
|
|
525
|
+
completionTokens: usage["output_tokens"] || 0,
|
|
526
|
+
/*
|
|
527
|
+
* Anthropic reports cache-read and cache-creation input tokens
|
|
528
|
+
* separately from input_tokens. Surface them and fold them into
|
|
529
|
+
* totalTokens so the logged total reflects the full billable input.
|
|
530
|
+
*/
|
|
531
|
+
cachedInputTokens: usage["cache_read_input_tokens"] || undefined,
|
|
532
|
+
cacheCreationTokens: usage["cache_creation_input_tokens"] || undefined,
|
|
243
533
|
totalTokens: (usage["input_tokens"] || 0) +
|
|
534
|
+
(usage["cache_read_input_tokens"] || 0) +
|
|
535
|
+
(usage["cache_creation_input_tokens"] || 0) +
|
|
244
536
|
(usage["output_tokens"] || 0),
|
|
245
537
|
}
|
|
246
538
|
: undefined,
|
|
247
539
|
};
|
|
248
540
|
}
|
|
541
|
+
/*
|
|
542
|
+
* Ollama native /api/chat. Deliberately NOT routed through the
|
|
543
|
+
* OpenAI-compatible branch: Ollama deployments are keyless by design and
|
|
544
|
+
* the OpenAI branch requires an API key.
|
|
545
|
+
*/
|
|
249
546
|
static async getOllamaCompletion(config, request) {
|
|
250
547
|
var _a;
|
|
251
548
|
if (!config.baseUrl) {
|
|
252
549
|
throw new BadDataException("Ollama base URL is required");
|
|
253
550
|
}
|
|
254
551
|
const modelName = config.modelName || "llama2";
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
messages: request.messages.map((msg) => {
|
|
552
|
+
const requestData = {
|
|
553
|
+
model: modelName,
|
|
554
|
+
messages: request.messages.map((msg) => {
|
|
555
|
+
if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length) {
|
|
260
556
|
return {
|
|
261
|
-
role:
|
|
262
|
-
content: msg.content,
|
|
557
|
+
role: "assistant",
|
|
558
|
+
content: msg.content || "",
|
|
559
|
+
tool_calls: msg.toolCalls.map((toolCall) => {
|
|
560
|
+
return {
|
|
561
|
+
function: {
|
|
562
|
+
name: toolCall.name,
|
|
563
|
+
arguments: toolCall.arguments,
|
|
564
|
+
},
|
|
565
|
+
};
|
|
566
|
+
}),
|
|
263
567
|
};
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
},
|
|
568
|
+
}
|
|
569
|
+
return {
|
|
570
|
+
role: msg.role,
|
|
571
|
+
content: msg.content,
|
|
572
|
+
};
|
|
573
|
+
}),
|
|
574
|
+
stream: false,
|
|
575
|
+
options: Object.assign({ temperature: (_a = request.temperature) !== null && _a !== void 0 ? _a : 0.7 }, (request.maxTokens ? { num_predict: request.maxTokens } : {})),
|
|
576
|
+
};
|
|
577
|
+
if (request.tools && request.tools.length > 0) {
|
|
578
|
+
requestData["tools"] = this.toOpenAITools(request.tools);
|
|
579
|
+
}
|
|
580
|
+
const response = await API.post({
|
|
581
|
+
url: URL.fromString(`${config.baseUrl}/api/chat`),
|
|
582
|
+
data: requestData,
|
|
270
583
|
headers: {
|
|
271
584
|
"Content-Type": "application/json",
|
|
272
585
|
},
|
|
@@ -290,9 +603,50 @@ class LLMService {
|
|
|
290
603
|
if (!message) {
|
|
291
604
|
throw new BadDataException("No response from Ollama");
|
|
292
605
|
}
|
|
606
|
+
const rawToolCalls = message["tool_calls"];
|
|
607
|
+
let toolCalls = undefined;
|
|
608
|
+
if (rawToolCalls && rawToolCalls.length > 0) {
|
|
609
|
+
toolCalls = rawToolCalls.map((rawToolCall, index) => {
|
|
610
|
+
const fn = rawToolCall["function"] || {};
|
|
611
|
+
let parsedArguments = {};
|
|
612
|
+
let parseError = undefined;
|
|
613
|
+
const rawArguments = fn["arguments"];
|
|
614
|
+
if (typeof rawArguments === "string") {
|
|
615
|
+
const parsed = this.parseToolCallArguments(rawArguments);
|
|
616
|
+
parsedArguments = parsed.arguments;
|
|
617
|
+
parseError = parsed.error;
|
|
618
|
+
}
|
|
619
|
+
else if (rawArguments && typeof rawArguments === "object") {
|
|
620
|
+
parsedArguments = rawArguments;
|
|
621
|
+
}
|
|
622
|
+
// Ollama does not return tool-call ids; synthesize stable ones.
|
|
623
|
+
return {
|
|
624
|
+
id: `tool_call_${index}`,
|
|
625
|
+
name: fn["name"] || "",
|
|
626
|
+
arguments: parsedArguments,
|
|
627
|
+
argumentsParseError: parseError,
|
|
628
|
+
};
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
/*
|
|
632
|
+
* Ollama reports token counts on the final /api/chat response as
|
|
633
|
+
* prompt_eval_count (input) and eval_count (output). Populate usage from
|
|
634
|
+
* them so LlmLog, the AI dashboards and (costed self-hosted Ollama)
|
|
635
|
+
* billing are not silently blind to token spend.
|
|
636
|
+
*/
|
|
637
|
+
const ollamaPromptTokens = jsonData["prompt_eval_count"] || 0;
|
|
638
|
+
const ollamaCompletionTokens = jsonData["eval_count"] || 0;
|
|
293
639
|
return {
|
|
294
|
-
content: message["content"],
|
|
295
|
-
|
|
640
|
+
content: message["content"] || "",
|
|
641
|
+
toolCalls: toolCalls,
|
|
642
|
+
stopReason: toolCalls && toolCalls.length > 0 ? "tool_use" : "stop",
|
|
643
|
+
usage: ollamaPromptTokens || ollamaCompletionTokens
|
|
644
|
+
? {
|
|
645
|
+
promptTokens: ollamaPromptTokens,
|
|
646
|
+
completionTokens: ollamaCompletionTokens,
|
|
647
|
+
totalTokens: ollamaPromptTokens + ollamaCompletionTokens,
|
|
648
|
+
}
|
|
649
|
+
: undefined,
|
|
296
650
|
};
|
|
297
651
|
}
|
|
298
652
|
}
|
|
@@ -301,6 +655,12 @@ class LLMService {
|
|
|
301
655
|
* ?api-version=... in their configured base URL.
|
|
302
656
|
*/
|
|
303
657
|
LLMService.AZURE_OPENAI_DEFAULT_API_VERSION = "2024-10-21";
|
|
658
|
+
/*
|
|
659
|
+
* Anthropic wire format. System message is hoisted, tool results ride in
|
|
660
|
+
* user messages as tool_result blocks, and max_tokens is required by the
|
|
661
|
+
* API.
|
|
662
|
+
*/
|
|
663
|
+
LLMService.ANTHROPIC_DEFAULT_MAX_TOKENS = 4096;
|
|
304
664
|
export default LLMService;
|
|
305
665
|
__decorate([
|
|
306
666
|
CaptureSpan(),
|