@oneuptime/common 11.5.8 → 11.5.9
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/AIAgentTaskPullRequest.ts +15 -6
- package/Models/DatabaseModels/AIRun.ts +37 -0
- package/Models/DatabaseModels/AIRunEvent.ts +34 -1
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +215 -0
- package/Models/DatabaseModels/Project.ts +25 -0
- package/Models/DatabaseModels/StatusPage.ts +42 -0
- package/Server/API/AIAgentTaskAPI.ts +38 -12
- package/Server/API/AIAgentTaskLogAPI.ts +49 -0
- package/Server/API/AIChatAPI.ts +16 -0
- package/Server/API/AIReadinessAPI.ts +84 -0
- package/Server/API/CodeFixRunAPI.ts +182 -0
- package/Server/API/TelemetryExceptionAPI.ts +6 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.ts +95 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.ts +52 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Services/AIRunEventService.ts +15 -1
- package/Server/Services/AIRunService.ts +38 -1
- package/Server/Services/LlmProviderService.ts +2 -0
- package/Server/Services/ProjectService.ts +42 -0
- package/Server/Services/StatusPageService.ts +87 -0
- package/Server/Services/TelemetryExceptionService.ts +19 -90
- package/Server/Types/Markdown.ts +9 -9
- package/Server/Types/MarkdownSlugify.ts +47 -0
- package/Server/Utils/AI/AIRunTranscript.ts +240 -0
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +9 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +119 -5
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +75 -0
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +235 -0
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +2 -3
- package/Server/Utils/AI/Toolbox/CodeTools.ts +883 -0
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +519 -0
- package/Server/Utils/AI/Toolbox/Index.ts +27 -0
- package/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.ts +279 -0
- package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +19 -1
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +600 -0
- package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +7 -2
- package/Server/Utils/LLM/LLMService.ts +397 -18
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +4 -11
- package/Tests/Models/StatusPageEnableMcpServer.test.ts +125 -0
- package/Tests/Server/Services/StatusPageServiceMcp.test.ts +223 -0
- package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +26 -3
- package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +12 -0
- package/Tests/Server/Types/Markdown.test.ts +106 -0
- package/Tests/Server/Utils/AI/AIRunTranscript.test.ts +182 -0
- package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +411 -0
- package/Tests/Server/Utils/AI/CodeTools.test.ts +596 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +475 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +548 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +142 -0
- package/Tests/Server/Utils/AI/ScheduledMaintenanceTools.test.ts +176 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +63 -0
- package/Tests/Server/Utils/GitHubGetFileContent.test.ts +197 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +502 -0
- package/Tests/Types/AI/AIAgentTaskStatus.test.ts +7 -6
- package/Tests/Types/AI/AIChatPageContext.test.ts +0 -0
- package/Tests/Types/AI/AIRunStatus.test.ts +42 -0
- package/Tests/Types/Log/LogSeverity.test.ts +78 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +167 -0
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +66 -0
- package/Tests/UI/Utils/AIChatExport/ChatWidgetData.test.ts +319 -0
- package/Tests/UI/Utils/AIChatExport/ChatWidgetMarkdown.test.ts +188 -0
- package/Types/AI/AIAgentTaskStatus.ts +13 -0
- package/Types/AI/AIChatPageContext.ts +137 -0
- package/Types/AI/AIChatTypes.ts +44 -0
- package/Types/AI/AIFixReadiness.ts +46 -0
- package/Types/AI/AIRunStatus.ts +11 -0
- package/Types/Log/LogSeverity.ts +61 -0
- package/Types/Monitor/SnmpMonitor/SnmpVersion.ts +40 -0
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +8 -2
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +3 -1
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +8 -2
- package/UI/Components/Forms/BasicForm.tsx +26 -8
- package/UI/Styles/Theme.css +1314 -0
- package/UI/Utils/AIChatExport/ChatWidgetData.ts +316 -0
- package/UI/Utils/AIChatExport/ChatWidgetMarkdown.ts +349 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +177 -0
- package/UI/Utils/AIChatExport/MarkdownBlocks.ts +327 -0
- package/UI/Utils/AIChatExport/MarkdownSafety.ts +215 -0
- package/UI/Utils/DownloadFile.ts +54 -0
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +15 -7
- package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRun.js +38 -0
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIRunEvent.js +31 -0
- package/build/dist/Models/DatabaseModels/AIRunEvent.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +225 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +27 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +43 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskAPI.js +37 -11
- package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
- package/build/dist/Server/API/AIAgentTaskLogAPI.js +32 -7
- package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +9 -0
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIReadinessAPI.js +57 -0
- package/build/dist/Server/API/AIReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/CodeFixRunAPI.js +142 -0
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryExceptionAPI.js +4 -0
- package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js +80 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784124919694-AddAITaskNumberAndRunTranscript.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784135099754-AllowNullAiAgentOnPullRequest.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784137457184-AddEnableMcpServerToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIRunEventService.js +8 -0
- package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +29 -0
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/LlmProviderService.js +2 -0
- package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +39 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +81 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryExceptionService.js +14 -61
- package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +8 -8
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/MarkdownSlugify.js +47 -0
- package/build/dist/Server/Types/MarkdownSlugify.js.map +1 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js +180 -0
- package/build/dist/Server/Utils/AI/AIRunTranscript.js.map +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +1 -0
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +103 -5
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +55 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +211 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +654 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +389 -0
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +19 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js +239 -0
- package/build/dist/Server/Utils/AI/Toolbox/ScheduledMaintenanceTools.js.map +1 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +19 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +439 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +1 -1
- package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +275 -19
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +2 -11
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Types/AI/AIAgentTaskStatus.js +12 -0
- package/build/dist/Types/AI/AIAgentTaskStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatPageContext.js +101 -0
- package/build/dist/Types/AI/AIChatPageContext.js.map +1 -0
- package/build/dist/Types/AI/AIChatTypes.js +2 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/AI/AIFixReadiness.js +9 -0
- package/build/dist/Types/AI/AIFixReadiness.js.map +1 -0
- package/build/dist/Types/AI/AIRunStatus.js +11 -0
- package/build/dist/Types/AI/AIRunStatus.js.map +1 -1
- package/build/dist/Types/Log/LogSeverity.js +56 -0
- package/build/dist/Types/Log/LogSeverity.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js +38 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVersion.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +9 -2
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +3 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +9 -2
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +24 -6
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js +217 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetData.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js +234 -0
- package/build/dist/UI/Utils/AIChatExport/ChatWidgetMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +111 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js +233 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownBlocks.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js +134 -0
- package/build/dist/UI/Utils/AIChatExport/MarkdownSafety.js.map +1 -0
- package/build/dist/UI/Utils/DownloadFile.js +41 -0
- package/build/dist/UI/Utils/DownloadFile.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import Express, {
|
|
2
|
+
ExpressRequest,
|
|
3
|
+
ExpressResponse,
|
|
4
|
+
ExpressRouter,
|
|
5
|
+
NextFunction,
|
|
6
|
+
} from "../Utils/Express";
|
|
7
|
+
import Response from "../Utils/Response";
|
|
8
|
+
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
9
|
+
import CommonAPI from "./CommonAPI";
|
|
10
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
11
|
+
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
12
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
13
|
+
import { JSONArray } from "../../Types/JSON";
|
|
14
|
+
import { AIFixReadiness } from "../../Types/AI/AIFixReadiness";
|
|
15
|
+
import CodeFixReadiness from "../Utils/AI/CodeFix/CodeFixReadiness";
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Project-wide "can AI actually do anything here?" — the gates a CodeFix run
|
|
19
|
+
* passes through, answered for the whole project rather than one exception.
|
|
20
|
+
* The AI Tasks page renders this instead of a static prerequisites banner, so
|
|
21
|
+
* what the user reads reflects what the server would actually decide.
|
|
22
|
+
*
|
|
23
|
+
* The per-exception equivalent lives at
|
|
24
|
+
* GET /telemetry-exception/ai-fix-readiness/:id; both share the checks in
|
|
25
|
+
* CodeFixReadiness, so they cannot drift apart.
|
|
26
|
+
*/
|
|
27
|
+
const router: ExpressRouter = Express.getRouter();
|
|
28
|
+
|
|
29
|
+
router.post(
|
|
30
|
+
"/ai-readiness/code-fix",
|
|
31
|
+
UserMiddleware.getUserMiddleware,
|
|
32
|
+
async (
|
|
33
|
+
req: ExpressRequest,
|
|
34
|
+
res: ExpressResponse,
|
|
35
|
+
next: NextFunction,
|
|
36
|
+
): Promise<void> => {
|
|
37
|
+
try {
|
|
38
|
+
const props: DatabaseCommonInteractionProps =
|
|
39
|
+
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
* Authorize explicitly. getUserMiddleware admits anonymous callers
|
|
43
|
+
* (it sets userType = Public and calls next()), and tenantId is read
|
|
44
|
+
* straight off the caller-supplied `tenantid` header before any auth
|
|
45
|
+
* runs — so neither is evidence of anything on its own. The readiness
|
|
46
|
+
* checks below all query with `isRoot: true`, which means there is no
|
|
47
|
+
* RBAC layer underneath to catch an unauthorized caller: this handler
|
|
48
|
+
* is the only gate. The per-exception sibling gets away without this
|
|
49
|
+
* because it loads the exception with the caller's props first, and
|
|
50
|
+
* derives the project from that authorized row.
|
|
51
|
+
*/
|
|
52
|
+
if (!props.userId) {
|
|
53
|
+
throw new NotAuthorizedException(
|
|
54
|
+
"AI readiness requires a logged-in user session.",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!props.tenantId) {
|
|
59
|
+
throw new BadDataException("Project ID is required (tenantid header).");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Being logged in somewhere is not access to THIS project.
|
|
63
|
+
if (!props.userTenantAccessPermission?.[props.tenantId.toString()]) {
|
|
64
|
+
throw new NotAuthorizedException(
|
|
65
|
+
"You do not have access to this project.",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const readiness: AIFixReadiness =
|
|
70
|
+
await CodeFixReadiness.getProjectReadiness({
|
|
71
|
+
projectId: props.tenantId,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
75
|
+
ready: readiness.ready,
|
|
76
|
+
checks: readiness.checks as unknown as JSONArray,
|
|
77
|
+
});
|
|
78
|
+
} catch (err) {
|
|
79
|
+
next(err);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
export default router;
|
|
@@ -8,21 +8,27 @@ import Express, {
|
|
|
8
8
|
} from "../Utils/Express";
|
|
9
9
|
import Response from "../Utils/Response";
|
|
10
10
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
11
|
+
import DatabaseCommonInteractionPropsUtil, {
|
|
12
|
+
PermissionType,
|
|
13
|
+
} from "../../Types/BaseDatabase/DatabaseCommonInteractionPropsUtil";
|
|
11
14
|
import ObjectID from "../../Types/ObjectID";
|
|
12
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
13
16
|
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
14
17
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
15
18
|
import Select from "../Types/Database/Select";
|
|
16
19
|
import { JSONObject } from "../../Types/JSON";
|
|
20
|
+
import Permission, { UserPermission } from "../../Types/Permission";
|
|
17
21
|
import AIRunType from "../../Types/AI/AIRunType";
|
|
18
22
|
import { CodeFixTaskTypeHelper } from "../../Types/AI/CodeFixTaskType";
|
|
19
23
|
import AIRun from "../../Models/DatabaseModels/AIRun";
|
|
20
24
|
import AIRunEvent from "../../Models/DatabaseModels/AIRunEvent";
|
|
25
|
+
import LlmLog from "../../Models/DatabaseModels/LlmLog";
|
|
21
26
|
import Project from "../../Models/DatabaseModels/Project";
|
|
22
27
|
import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
23
28
|
import ProjectService from "../Services/ProjectService";
|
|
24
29
|
import AIRunService from "../Services/AIRunService";
|
|
25
30
|
import AIRunEventService from "../Services/AIRunEventService";
|
|
31
|
+
import LlmLogService from "../Services/LlmLogService";
|
|
26
32
|
|
|
27
33
|
const MAX_EVENTS: number = 500;
|
|
28
34
|
|
|
@@ -56,6 +62,7 @@ const RUN_SELECT: Select<AIRun> = {
|
|
|
56
62
|
triggeredByTelemetryExceptionId: true,
|
|
57
63
|
totalTokens: true,
|
|
58
64
|
codeFixTaskType: true,
|
|
65
|
+
taskNumber: true,
|
|
59
66
|
attemptCount: true,
|
|
60
67
|
llmCallCount: true,
|
|
61
68
|
toolCallCount: true,
|
|
@@ -67,6 +74,50 @@ const RUN_SELECT: Select<AIRun> = {
|
|
|
67
74
|
*/
|
|
68
75
|
};
|
|
69
76
|
|
|
77
|
+
/*
|
|
78
|
+
* The Logs page's event trail.
|
|
79
|
+
*
|
|
80
|
+
* toolArguments is deliberately NOT selected, even though this endpoint reads
|
|
81
|
+
* as root and could. A code-fix write_file call carries the file's full new
|
|
82
|
+
* content in its arguments, and that column's own read ACL stops at
|
|
83
|
+
* ProjectMember — narrower than this endpoint's Project-read gate, which also
|
|
84
|
+
* admits Viewers. Returning it would leak the same customer source code that
|
|
85
|
+
* contentPayload is stripped below to protect, to an even wider audience. The
|
|
86
|
+
* page never needed it: Logs.tsx renders tool arguments from
|
|
87
|
+
* contentPayload.responseToolCalls, the owner/admin-gated copy.
|
|
88
|
+
*/
|
|
89
|
+
const LOG_EVENT_SELECT: Select<AIRunEvent> = {
|
|
90
|
+
_id: true,
|
|
91
|
+
sequence: true,
|
|
92
|
+
eventType: true,
|
|
93
|
+
toolName: true,
|
|
94
|
+
resultSummary: true,
|
|
95
|
+
citationId: true,
|
|
96
|
+
createdAt: true,
|
|
97
|
+
contentPayload: true,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* The per-LLM-call metering shown beside the transcript. Read under the
|
|
102
|
+
* CALLER's permissions (not root), so LlmLog's own table ACL decides who sees
|
|
103
|
+
* it rather than this endpoint's broader Project-read gate.
|
|
104
|
+
*/
|
|
105
|
+
const LLM_LOG_SELECT: Select<LlmLog> = {
|
|
106
|
+
_id: true,
|
|
107
|
+
modelName: true,
|
|
108
|
+
llmProviderName: true,
|
|
109
|
+
status: true,
|
|
110
|
+
statusMessage: true,
|
|
111
|
+
totalTokens: true,
|
|
112
|
+
completionTokens: true,
|
|
113
|
+
durationMs: true,
|
|
114
|
+
requestStartedAt: true,
|
|
115
|
+
requestCompletedAt: true,
|
|
116
|
+
createdAt: true,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const MAX_LLM_LOGS: number = 500;
|
|
120
|
+
|
|
70
121
|
/*
|
|
71
122
|
* Serialize a run with codeFixTaskType normalized: a null column means
|
|
72
123
|
* FixException (rows created before task recipes existed), and clients
|
|
@@ -163,6 +214,137 @@ export default class CodeFixRunAPI {
|
|
|
163
214
|
}
|
|
164
215
|
},
|
|
165
216
|
);
|
|
217
|
+
|
|
218
|
+
/*
|
|
219
|
+
* The Logs page: the same run, its FULL event trail, and the per-call LLM
|
|
220
|
+
* metering — everything recorded about a run, for debugging one that went
|
|
221
|
+
* wrong.
|
|
222
|
+
*
|
|
223
|
+
* Two things are gated more tightly than the trail itself:
|
|
224
|
+
*
|
|
225
|
+
* - contentPayload (the verbatim prompts, model replies and tool output)
|
|
226
|
+
* is returned only to ProjectOwner/ProjectAdmin. It embeds customer
|
|
227
|
+
* source code, which is why the column's own read ACL is empty and why
|
|
228
|
+
* LlmLog redacts the same content — this endpoint is the single
|
|
229
|
+
* deliberate door to it, and it is not open to every project member.
|
|
230
|
+
*
|
|
231
|
+
* - LlmLog rows are read under the CALLER's permissions rather than as
|
|
232
|
+
* root, so LlmLog's table ACL — not this endpoint's broader Project-read
|
|
233
|
+
* gate — decides who sees the metering.
|
|
234
|
+
*/
|
|
235
|
+
this.router.post(
|
|
236
|
+
"/code-fix-run/logs/:runId",
|
|
237
|
+
UserMiddleware.getUserMiddleware,
|
|
238
|
+
async (
|
|
239
|
+
req: ExpressRequest,
|
|
240
|
+
res: ExpressResponse,
|
|
241
|
+
next: NextFunction,
|
|
242
|
+
): Promise<void> => {
|
|
243
|
+
try {
|
|
244
|
+
const props: DatabaseCommonInteractionProps =
|
|
245
|
+
await this.getAccessCheckedProps(req);
|
|
246
|
+
|
|
247
|
+
const runIdString: string | undefined = req.params["runId"];
|
|
248
|
+
|
|
249
|
+
if (!runIdString) {
|
|
250
|
+
throw new BadDataException("runId is required.");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const runId: ObjectID = new ObjectID(runIdString);
|
|
254
|
+
|
|
255
|
+
const run: AIRun | null = await AIRunService.findOneBy({
|
|
256
|
+
query: {
|
|
257
|
+
_id: runId.toString(),
|
|
258
|
+
projectId: props.tenantId!,
|
|
259
|
+
runType: AIRunType.CodeFix,
|
|
260
|
+
},
|
|
261
|
+
select: RUN_SELECT,
|
|
262
|
+
props: { isRoot: true },
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
if (!run) {
|
|
266
|
+
throw new BadDataException(
|
|
267
|
+
"Code fix run not found (or it does not belong to this project).",
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const canReadContent: boolean = this.callerCanReadRunContent(props);
|
|
272
|
+
|
|
273
|
+
const events: Array<AIRunEvent> = await AIRunEventService.findBy({
|
|
274
|
+
query: { aiRunId: run.id! },
|
|
275
|
+
select: LOG_EVENT_SELECT,
|
|
276
|
+
sort: { sequence: SortOrder.Ascending },
|
|
277
|
+
limit: MAX_EVENTS,
|
|
278
|
+
skip: 0,
|
|
279
|
+
props: { isRoot: true },
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const eventsJson: Array<JSONObject> = BaseModel.toJSONArray(
|
|
283
|
+
events,
|
|
284
|
+
AIRunEvent,
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
if (!canReadContent) {
|
|
288
|
+
for (const eventJson of eventsJson) {
|
|
289
|
+
delete eventJson["contentPayload"];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/*
|
|
294
|
+
* Under the caller's own permissions on purpose — see the note
|
|
295
|
+
* above. A caller without LlmLog read simply gets no metering rows.
|
|
296
|
+
*/
|
|
297
|
+
const llmLogs: Array<LlmLog> = await LlmLogService.findBy({
|
|
298
|
+
query: { aiRunId: runId, projectId: props.tenantId! },
|
|
299
|
+
select: LLM_LOG_SELECT,
|
|
300
|
+
sort: { createdAt: SortOrder.Ascending },
|
|
301
|
+
limit: MAX_LLM_LOGS,
|
|
302
|
+
skip: 0,
|
|
303
|
+
props: props,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
Response.sendJsonObjectResponse(req, res, {
|
|
307
|
+
run: runToJson(run),
|
|
308
|
+
events: eventsJson,
|
|
309
|
+
llmLogs: BaseModel.toJSONArray(llmLogs, LlmLog),
|
|
310
|
+
canReadContent: canReadContent,
|
|
311
|
+
});
|
|
312
|
+
return;
|
|
313
|
+
} catch (err) {
|
|
314
|
+
next(err);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/*
|
|
322
|
+
* Whether the caller may see a run's verbatim LLM/tool content. Project
|
|
323
|
+
* owners and admins only: the content embeds customer source code, so the
|
|
324
|
+
* bar is higher than the Project-read gate that admits them to the page.
|
|
325
|
+
*
|
|
326
|
+
* Read through getUserPermissions(Allow) rather than off
|
|
327
|
+
* userTenantAccessPermission directly, because that array holds GRANTS AND
|
|
328
|
+
* DENIALS together, discriminated only by isBlockPermission. Mapping it raw
|
|
329
|
+
* counts a team's explicit "block ProjectAdmin" entry as a grant of
|
|
330
|
+
* ProjectAdmin — inverting the control, so the admin action that restricts a
|
|
331
|
+
* team would be what hands it the source code.
|
|
332
|
+
*/
|
|
333
|
+
private callerCanReadRunContent(
|
|
334
|
+
props: DatabaseCommonInteractionProps,
|
|
335
|
+
): boolean {
|
|
336
|
+
const permissions: Array<Permission> =
|
|
337
|
+
DatabaseCommonInteractionPropsUtil.getUserPermissions(
|
|
338
|
+
props,
|
|
339
|
+
PermissionType.Allow,
|
|
340
|
+
).map((userPermission: UserPermission) => {
|
|
341
|
+
return userPermission.permission;
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
return (
|
|
345
|
+
permissions.includes(Permission.ProjectOwner) ||
|
|
346
|
+
permissions.includes(Permission.ProjectAdmin)
|
|
347
|
+
);
|
|
166
348
|
}
|
|
167
349
|
|
|
168
350
|
/*
|
|
@@ -4,11 +4,11 @@ import BadDataException from "../../Types/Exception/BadDataException";
|
|
|
4
4
|
import ObjectID from "../../Types/ObjectID";
|
|
5
5
|
import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
6
6
|
import TelemetryExceptionService, {
|
|
7
|
-
AIFixReadiness,
|
|
8
7
|
DashboardServiceSummary,
|
|
9
8
|
DashboardSummaryResult,
|
|
10
9
|
Service as TelemetryExceptionServiceType,
|
|
11
10
|
} from "../Services/TelemetryExceptionService";
|
|
11
|
+
import { AIFixReadiness } from "../../Types/AI/AIFixReadiness";
|
|
12
12
|
import AIRunService from "../Services/AIRunService";
|
|
13
13
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
14
14
|
import Response from "../Utils/Response";
|
|
@@ -51,6 +51,11 @@ const CODE_FIX_STATUS_TEXT: {
|
|
|
51
51
|
description:
|
|
52
52
|
"The AI agent finished. Review the pull request it opened for the proposed fix.",
|
|
53
53
|
},
|
|
54
|
+
[AIRunStatus.NoFixFound]: {
|
|
55
|
+
title: "No Fix Found",
|
|
56
|
+
description:
|
|
57
|
+
"The AI agent reviewed the code and did not find a fix to propose, so it opened no pull request.",
|
|
58
|
+
},
|
|
54
59
|
[AIRunStatus.Error]: {
|
|
55
60
|
title: "Error",
|
|
56
61
|
description: "The AI agent could not complete the fix.",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Two additions, both in service of debugging a code-fix run that went wrong.
|
|
5
|
+
*
|
|
6
|
+
* 1. AIRun.taskNumber + Project.aiRunCounter — the per-project "#42" handle,
|
|
7
|
+
* allocated exactly like Incident.incidentNumber (ProjectService holds the
|
|
8
|
+
* counter behind a Redis semaphore; see incrementAndGetAIRunCounter).
|
|
9
|
+
* 2. AIRunEvent.contentPayload — the verbatim prompt/response/tool transcript.
|
|
10
|
+
*
|
|
11
|
+
* The DDL here was produced by `npm run generate-postgres-migration`. Two
|
|
12
|
+
* unrelated OnCallDutyPolicyScheduleLayer default changes the generator also
|
|
13
|
+
* emitted (pre-existing whitespace drift between the entity defaults and the
|
|
14
|
+
* local schema) were dropped: they are not part of this change.
|
|
15
|
+
*
|
|
16
|
+
* The backfill rides along in the same migration rather than a follow-up so
|
|
17
|
+
* there is no window in which existing tasks are on-screen with a blank
|
|
18
|
+
* number.
|
|
19
|
+
*/
|
|
20
|
+
export class AddAITaskNumberAndRunTranscript1784124919694
|
|
21
|
+
implements MigrationInterface
|
|
22
|
+
{
|
|
23
|
+
public name: string = "AddAITaskNumberAndRunTranscript1784124919694";
|
|
24
|
+
|
|
25
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
26
|
+
await queryRunner.query(
|
|
27
|
+
`ALTER TABLE "Project" ADD "aiRunCounter" integer NOT NULL DEFAULT '0'`,
|
|
28
|
+
);
|
|
29
|
+
await queryRunner.query(`ALTER TABLE "AIRun" ADD "taskNumber" integer`);
|
|
30
|
+
await queryRunner.query(
|
|
31
|
+
`ALTER TABLE "AIRunEvent" ADD "contentPayload" jsonb`,
|
|
32
|
+
);
|
|
33
|
+
await queryRunner.query(
|
|
34
|
+
`CREATE INDEX "IDX_ede30aa8b14a167586bd555fa9" ON "AIRun" ("taskNumber") `,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* Number the tasks that already exist, oldest first, per project — so the
|
|
39
|
+
* list does not read "#1, -, -, #2" the day this ships. Scoped to
|
|
40
|
+
* runType = 'CodeFix' because only code-fix runs are tasks; chat and
|
|
41
|
+
* investigation runs share this table and must stay null.
|
|
42
|
+
*
|
|
43
|
+
* Soft-deleted rows are numbered too. Not to prevent reuse (a skipped row
|
|
44
|
+
* would hold no number to reuse) but to keep the sequence a stable
|
|
45
|
+
* function of creation order: a run that is soft-deleted later must not
|
|
46
|
+
* renumber the runs after it, and an undeleted row must not collide with
|
|
47
|
+
* a number already handed out. The cost is gaps in what the list shows,
|
|
48
|
+
* which is the same thing incidents do.
|
|
49
|
+
*/
|
|
50
|
+
await queryRunner.query(`
|
|
51
|
+
WITH numbered AS (
|
|
52
|
+
SELECT
|
|
53
|
+
"_id",
|
|
54
|
+
ROW_NUMBER() OVER (
|
|
55
|
+
PARTITION BY "projectId"
|
|
56
|
+
ORDER BY "createdAt" ASC, "_id" ASC
|
|
57
|
+
) AS "rowNumber"
|
|
58
|
+
FROM "AIRun"
|
|
59
|
+
WHERE "runType" = 'CodeFix'
|
|
60
|
+
)
|
|
61
|
+
UPDATE "AIRun"
|
|
62
|
+
SET "taskNumber" = numbered."rowNumber"
|
|
63
|
+
FROM numbered
|
|
64
|
+
WHERE "AIRun"."_id" = numbered."_id"
|
|
65
|
+
`);
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Advance each project's counter past what the backfill just handed out,
|
|
69
|
+
* so the next allocation continues the sequence instead of restarting at
|
|
70
|
+
* #1 and colliding. Projects with no code-fix runs keep the 0 default.
|
|
71
|
+
*/
|
|
72
|
+
await queryRunner.query(`
|
|
73
|
+
UPDATE "Project"
|
|
74
|
+
SET "aiRunCounter" = "maxPerProject"."maxTaskNumber"
|
|
75
|
+
FROM (
|
|
76
|
+
SELECT "projectId", MAX("taskNumber") AS "maxTaskNumber"
|
|
77
|
+
FROM "AIRun"
|
|
78
|
+
WHERE "runType" = 'CodeFix' AND "taskNumber" IS NOT NULL
|
|
79
|
+
GROUP BY "projectId"
|
|
80
|
+
) AS "maxPerProject"
|
|
81
|
+
WHERE "Project"."_id" = "maxPerProject"."projectId"
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
86
|
+
await queryRunner.query(
|
|
87
|
+
`DROP INDEX "public"."IDX_ede30aa8b14a167586bd555fa9"`,
|
|
88
|
+
);
|
|
89
|
+
await queryRunner.query(
|
|
90
|
+
`ALTER TABLE "AIRunEvent" DROP COLUMN "contentPayload"`,
|
|
91
|
+
);
|
|
92
|
+
await queryRunner.query(`ALTER TABLE "AIRun" DROP COLUMN "taskNumber"`);
|
|
93
|
+
await queryRunner.query(`ALTER TABLE "Project" DROP COLUMN "aiRunCounter"`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* A pull request can now be proposed from an AI chat conversation, which has
|
|
5
|
+
* no AIAgent behind it (the AIAgent record belongs to the autonomous fix
|
|
6
|
+
* worker). aiAgentId becomes nullable so chat-authored PRs can be recorded at
|
|
7
|
+
* all — and recording them is what makes them count against the per-repository
|
|
8
|
+
* open-PR cap, which reads AIAgentTaskPullRequest rows.
|
|
9
|
+
*
|
|
10
|
+
* A null aiAgentId therefore means "proposed from chat". Existing rows all
|
|
11
|
+
* have an agent, so dropping NOT NULL needs no backfill and the down migration
|
|
12
|
+
* is safe until the first chat-authored PR exists.
|
|
13
|
+
*/
|
|
14
|
+
export class AllowNullAiAgentOnPullRequest1784135099754
|
|
15
|
+
implements MigrationInterface
|
|
16
|
+
{
|
|
17
|
+
public name = "AllowNullAiAgentOnPullRequest1784135099754";
|
|
18
|
+
|
|
19
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
20
|
+
/*
|
|
21
|
+
* The FK is dropped and re-added because Postgres will not alter a column's
|
|
22
|
+
* nullability while a foreign key references it. ON DELETE CASCADE is
|
|
23
|
+
* preserved exactly as it was.
|
|
24
|
+
*/
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "AIAgentTaskPullRequest" DROP CONSTRAINT "FK_b1e01ecfe9eecfb555428471073"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "AIAgentTaskPullRequest" ALTER COLUMN "aiAgentId" DROP NOT NULL`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "AIAgentTaskPullRequest" ADD CONSTRAINT "FK_b1e01ecfe9eecfb555428471073" FOREIGN KEY ("aiAgentId") REFERENCES "AIAgent"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
37
|
+
/*
|
|
38
|
+
* Restoring NOT NULL fails if any chat-authored (null-agent) rows exist.
|
|
39
|
+
* That is deliberate: silently deleting or reassigning a customer's pull
|
|
40
|
+
* request records to satisfy a rollback would be worse than a loud failure.
|
|
41
|
+
*/
|
|
42
|
+
await queryRunner.query(
|
|
43
|
+
`ALTER TABLE "AIAgentTaskPullRequest" DROP CONSTRAINT "FK_b1e01ecfe9eecfb555428471073"`,
|
|
44
|
+
);
|
|
45
|
+
await queryRunner.query(
|
|
46
|
+
`ALTER TABLE "AIAgentTaskPullRequest" ALTER COLUMN "aiAgentId" SET NOT NULL`,
|
|
47
|
+
);
|
|
48
|
+
await queryRunner.query(
|
|
49
|
+
`ALTER TABLE "AIAgentTaskPullRequest" ADD CONSTRAINT "FK_b1e01ecfe9eecfb555428471073" FOREIGN KEY ("aiAgentId") REFERENCES "AIAgent"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Status page owners can now stop AI agents from reading their status page over
|
|
5
|
+
* the public OneUptime MCP server. MCP access stays on unless it is turned off,
|
|
6
|
+
* so the column defaults to true.
|
|
7
|
+
*
|
|
8
|
+
* ADD COLUMN ... NOT NULL DEFAULT true populates every existing row with true in
|
|
9
|
+
* the same statement, so no backfill is needed and existing status pages keep
|
|
10
|
+
* working exactly as they do today. That is what makes the
|
|
11
|
+
* `enableMcpServer: true` predicate in StatusPageService.isMcpServerEnabled
|
|
12
|
+
* safe — there are no NULL rows for it to silently drop.
|
|
13
|
+
*/
|
|
14
|
+
export class AddEnableMcpServerToStatusPage1784137457184
|
|
15
|
+
implements MigrationInterface
|
|
16
|
+
{
|
|
17
|
+
public name = "AddEnableMcpServerToStatusPage1784137457184";
|
|
18
|
+
|
|
19
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
20
|
+
await queryRunner.query(
|
|
21
|
+
`ALTER TABLE "StatusPage" ADD "enableMcpServer" boolean NOT NULL DEFAULT true`,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
26
|
+
await queryRunner.query(
|
|
27
|
+
`ALTER TABLE "StatusPage" DROP COLUMN "enableMcpServer"`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan1784200000000
|
|
4
|
+
implements MigrationInterface
|
|
5
|
+
{
|
|
6
|
+
public name = "AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan1784200000000";
|
|
7
|
+
|
|
8
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
9
|
+
await queryRunner.query(
|
|
10
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3SecurityLevel" character varying(100)`,
|
|
11
|
+
);
|
|
12
|
+
await queryRunner.query(
|
|
13
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3Username" character varying(100)`,
|
|
14
|
+
);
|
|
15
|
+
await queryRunner.query(
|
|
16
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3AuthProtocol" character varying(100)`,
|
|
17
|
+
);
|
|
18
|
+
await queryRunner.query(
|
|
19
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3AuthKey" text`,
|
|
20
|
+
);
|
|
21
|
+
await queryRunner.query(
|
|
22
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3PrivProtocol" character varying(100)`,
|
|
23
|
+
);
|
|
24
|
+
await queryRunner.query(
|
|
25
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" ADD "snmpV3PrivKey" text`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
30
|
+
await queryRunner.query(
|
|
31
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3PrivKey"`,
|
|
32
|
+
);
|
|
33
|
+
await queryRunner.query(
|
|
34
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3PrivProtocol"`,
|
|
35
|
+
);
|
|
36
|
+
await queryRunner.query(
|
|
37
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3AuthKey"`,
|
|
38
|
+
);
|
|
39
|
+
await queryRunner.query(
|
|
40
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3AuthProtocol"`,
|
|
41
|
+
);
|
|
42
|
+
await queryRunner.query(
|
|
43
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3Username"`,
|
|
44
|
+
);
|
|
45
|
+
await queryRunner.query(
|
|
46
|
+
`ALTER TABLE "NetworkDeviceDiscoveryScan" DROP COLUMN "snmpV3SecurityLevel"`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -451,6 +451,10 @@ import { RenameSentinelToAI1784030612266 } from "./1784030612266-RenameSentinelT
|
|
|
451
451
|
import { MigrationName1784033837629 } from "./1784033837629-MigrationName";
|
|
452
452
|
import { AddCreatedByUserToUser1784048917994 } from "./1784048917994-AddCreatedByUserToUser";
|
|
453
453
|
import { BackfillCodeFixTaskType1784105912819 } from "./1784105912819-BackfillCodeFixTaskType";
|
|
454
|
+
import { AddAITaskNumberAndRunTranscript1784124919694 } from "./1784124919694-AddAITaskNumberAndRunTranscript";
|
|
455
|
+
import { AllowNullAiAgentOnPullRequest1784135099754 } from "./1784135099754-AllowNullAiAgentOnPullRequest";
|
|
456
|
+
import { AddEnableMcpServerToStatusPage1784137457184 } from "./1784137457184-AddEnableMcpServerToStatusPage";
|
|
457
|
+
import { AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan1784200000000 } from "./1784200000000-AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan";
|
|
454
458
|
|
|
455
459
|
export default [
|
|
456
460
|
InitialMigration,
|
|
@@ -906,4 +910,8 @@ export default [
|
|
|
906
910
|
MigrationName1784033837629,
|
|
907
911
|
AddCreatedByUserToUser1784048917994,
|
|
908
912
|
BackfillCodeFixTaskType1784105912819,
|
|
913
|
+
AddAITaskNumberAndRunTranscript1784124919694,
|
|
914
|
+
AllowNullAiAgentOnPullRequest1784135099754,
|
|
915
|
+
AddEnableMcpServerToStatusPage1784137457184,
|
|
916
|
+
AddSnmpV3ColumnsToNetworkDeviceDiscoveryScan1784200000000,
|
|
909
917
|
];
|
|
@@ -2,13 +2,17 @@ import PositiveNumber from "../../Types/PositiveNumber";
|
|
|
2
2
|
import ObjectID from "../../Types/ObjectID";
|
|
3
3
|
import { JSONObject } from "../../Types/JSON";
|
|
4
4
|
import AIRunEventType from "../../Types/AI/AIRunEventType";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AIRunEventContentPayload,
|
|
7
|
+
AIRunEventResultSummary,
|
|
8
|
+
} from "../../Types/AI/AIChatTypes";
|
|
6
9
|
import CountBy from "../Types/Database/CountBy";
|
|
7
10
|
import FindBy from "../Types/Database/FindBy";
|
|
8
11
|
import { OnFind } from "../Types/Database/Hooks";
|
|
9
12
|
import DatabaseService from "./DatabaseService";
|
|
10
13
|
import Model from "../../Models/DatabaseModels/AIRunEvent";
|
|
11
14
|
import { pinQueryToRequestingUser } from "../Utils/AI/AIChatPrivacyFilter";
|
|
15
|
+
import AIRunTranscript from "../Utils/AI/AIRunTranscript";
|
|
12
16
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
13
17
|
import logger from "../Utils/Logger";
|
|
14
18
|
|
|
@@ -36,6 +40,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
36
40
|
toolArguments?: JSONObject | undefined;
|
|
37
41
|
resultSummary?: AIRunEventResultSummary | undefined;
|
|
38
42
|
citationId?: string | undefined;
|
|
43
|
+
contentPayload?: AIRunEventContentPayload | undefined;
|
|
39
44
|
}): Promise<void> {
|
|
40
45
|
try {
|
|
41
46
|
const sequence: number = (
|
|
@@ -63,6 +68,15 @@ export class Service extends DatabaseService<Model> {
|
|
|
63
68
|
if (data.citationId) {
|
|
64
69
|
event.citationId = data.citationId;
|
|
65
70
|
}
|
|
71
|
+
/*
|
|
72
|
+
* Capped here rather than at the call sites, so no caller can write an
|
|
73
|
+
* unbounded transcript row by forgetting to clamp.
|
|
74
|
+
*/
|
|
75
|
+
if (data.contentPayload) {
|
|
76
|
+
event.contentPayload = AIRunTranscript.clampPayload(
|
|
77
|
+
data.contentPayload,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
66
80
|
|
|
67
81
|
await this.create({
|
|
68
82
|
data: event,
|