@m6d/cortex-server 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/src/{adapters → lib/adapters}/database.d.ts +16 -1
- package/dist/src/lib/ai/context/compressor.d.ts +18 -0
- package/dist/src/{ai → lib/ai}/context/index.d.ts +2 -1
- package/dist/src/lib/ai/context/intra-turn-compressor.d.ts +24 -0
- package/dist/src/{ai → lib/ai}/context/types.d.ts +2 -0
- package/dist/src/lib/config.d.ts +153 -0
- package/dist/src/{db → lib/db}/schema.d.ts +104 -1
- package/dist/src/{index.d.ts → lib/index.d.ts} +2 -2
- package/dist/src/{types.d.ts → lib/types.d.ts} +15 -14
- package/index.ts +1 -1
- package/package.json +8 -3
- package/src/{adapters → lib/adapters}/database.ts +20 -1
- package/src/{adapters → lib/adapters}/minio.ts +2 -1
- package/src/{adapters → lib/adapters}/mssql.ts +38 -2
- package/src/lib/ai/context/compressor.ts +259 -0
- package/src/{ai → lib/ai}/context/index.ts +6 -1
- package/src/lib/ai/context/intra-turn-compressor.ts +264 -0
- package/src/{ai → lib/ai}/context/types.ts +4 -1
- package/src/{ai → lib/ai}/index.ts +114 -13
- package/src/lib/ai/prompt.ts +354 -0
- package/src/{ai → lib/ai}/tools/execute-code.tool.ts +5 -2
- package/src/{auth → lib/auth}/middleware.ts +7 -0
- package/src/lib/config.ts +181 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/20260326231647_nice_speedball}/migration.sql +12 -0
- package/src/{db/migrations/20260309012148_cloudy_maria_hill → lib/db/migrations/20260326231647_nice_speedball}/snapshot.json +106 -1
- package/src/{db → lib/db}/schema.ts +15 -2
- package/src/{factory.ts → lib/factory.ts} +1 -0
- package/src/{index.ts → lib/index.ts} +3 -1
- package/src/{routes → lib/routes}/files.ts +9 -2
- package/src/{routes → lib/routes}/threads.ts +8 -1
- package/src/{types.ts → lib/types.ts} +16 -15
- package/src/sample/db/client.ts +9 -0
- package/src/sample/db/migrations/20260411023125_rich_purple_man/migration.sql +5 -0
- package/src/sample/db/migrations/20260411023125_rich_purple_man/snapshot.json +50 -0
- package/src/sample/db/schema.ts +10 -0
- package/src/sample/domains/account/concepts/session.concept.ts +17 -0
- package/src/sample/domains/account/endpoints/listCurrentSessions.endpoint.ts +31 -0
- package/src/sample/domains/account/endpoints/revokeAllOtherSessions.endpoint.ts +22 -0
- package/src/sample/domains/account/endpoints/revokeCurrentSession.endpoint.ts +33 -0
- package/src/sample/domains/account/index.ts +18 -0
- package/src/sample/domains/appraisals/concepts/appraisalCycle.concept.ts +15 -0
- package/src/sample/domains/appraisals/concepts/appraisalRecord.concept.ts +20 -0
- package/src/sample/domains/appraisals/concepts/appraisalRecordCompetency.concept.ts +10 -0
- package/src/sample/domains/appraisals/concepts/appraisalRecordFunctionalRequirement.concept.ts +10 -0
- package/src/sample/domains/appraisals/concepts/appraisalRecordGoal.concept.ts +17 -0
- package/src/sample/domains/appraisals/endpoints/getAppraisalRecordById.endpoint.ts +321 -0
- package/src/sample/domains/appraisals/endpoints/getAppraisalRecordCompetencies.endpoint.ts +120 -0
- package/src/sample/domains/appraisals/endpoints/getAppraisalRecordFunctionalRequirements.endpoint.ts +126 -0
- package/src/sample/domains/appraisals/endpoints/getAppraisalRecordGoals.endpoint.ts +104 -0
- package/src/sample/domains/appraisals/endpoints/getAppraisalRecordScore.endpoint.ts +58 -0
- package/src/sample/domains/appraisals/endpoints/listAppraisalCyclesSimple.endpoint.ts +52 -0
- package/src/sample/domains/appraisals/endpoints/listAppraisalRecords.endpoint.ts +245 -0
- package/src/sample/domains/appraisals/endpoints/listAppraisalTemplatesSimple.endpoint.ts +52 -0
- package/src/sample/domains/appraisals/index.ts +40 -0
- package/src/sample/domains/appraisals/rules/appraisalRecordScoping.rule.ts +7 -0
- package/src/sample/domains/attendance/concepts/attendancePermission.concept.ts +17 -0
- package/src/sample/domains/attendance/concepts/attendanceTransaction.concept.ts +17 -0
- package/src/sample/domains/attendance/concepts/publicHoliday.concept.ts +10 -0
- package/src/sample/domains/attendance/concepts/punch.concept.ts +19 -0
- package/src/sample/domains/attendance/endpoints/getAttendanceTransactionById.endpoint.ts +444 -0
- package/src/sample/domains/attendance/endpoints/getCurrentAttendanceProfile.endpoint.ts +886 -0
- package/src/sample/domains/attendance/endpoints/getCurrentAttendanceStatistics.endpoint.ts +49 -0
- package/src/sample/domains/attendance/endpoints/listAttendancePermissions.endpoint.ts +176 -0
- package/src/sample/domains/attendance/endpoints/listAttendanceTransactionStates.endpoint.ts +26 -0
- package/src/sample/domains/attendance/endpoints/listAttendanceTransactions.endpoint.ts +373 -0
- package/src/sample/domains/attendance/endpoints/listPublicHolidaysSimple.endpoint.ts +52 -0
- package/src/sample/domains/attendance/endpoints/listPunchTypes.endpoint.ts +25 -0
- package/src/sample/domains/attendance/endpoints/listPunches.endpoint.ts +178 -0
- package/src/sample/domains/attendance/index.ts +41 -0
- package/src/sample/domains/attendance/services/attendancePermissions.service.ts +15 -0
- package/src/sample/domains/employees/concepts/employee.concept.ts +20 -0
- package/src/sample/domains/employees/concepts/employeeBankAccount.concept.ts +19 -0
- package/src/sample/domains/employees/concepts/employeeChild.concept.ts +19 -0
- package/src/sample/domains/employees/concepts/employeeDocument.concept.ts +21 -0
- package/src/sample/domains/employees/concepts/employeeEvent.concept.ts +21 -0
- package/src/sample/domains/employees/concepts/employeeExperience.concept.ts +18 -0
- package/src/sample/domains/employees/concepts/employeeJobLevelChange.concept.ts +21 -0
- package/src/sample/domains/employees/concepts/employeeMedal.concept.ts +20 -0
- package/src/sample/domains/employees/concepts/employeeQualification.concept.ts +20 -0
- package/src/sample/domains/employees/concepts/employeeSpouse.concept.ts +21 -0
- package/src/sample/domains/employees/concepts/employeeViolation.concept.ts +19 -0
- package/src/sample/domains/employees/endpoints/getCurrentEmployee.endpoint.ts +1651 -0
- package/src/sample/domains/employees/endpoints/getCurrentIdentity.endpoint.ts +197 -0
- package/src/sample/domains/employees/endpoints/getCurrentManagers.endpoint.ts +142 -0
- package/src/sample/domains/employees/endpoints/getEmployeeById.endpoint.ts +1659 -0
- package/src/sample/domains/employees/endpoints/getEmployeeStatistics.endpoint.ts +43 -0
- package/src/sample/domains/employees/endpoints/listBankAccounts.endpoint.ts +223 -0
- package/src/sample/domains/employees/endpoints/listChildren.endpoint.ts +211 -0
- package/src/sample/domains/employees/endpoints/listDocuments.endpoint.ts +222 -0
- package/src/sample/domains/employees/endpoints/listEmployeesSimple.endpoint.ts +156 -0
- package/src/sample/domains/employees/endpoints/listEvents.endpoint.ts +120 -0
- package/src/sample/domains/employees/endpoints/listExperiences.endpoint.ts +188 -0
- package/src/sample/domains/employees/endpoints/listJobLevelChanges.endpoint.ts +240 -0
- package/src/sample/domains/employees/endpoints/listMedals.endpoint.ts +266 -0
- package/src/sample/domains/employees/endpoints/listQualifications.endpoint.ts +265 -0
- package/src/sample/domains/employees/endpoints/listSpouses.endpoint.ts +278 -0
- package/src/sample/domains/employees/endpoints/listViolations.endpoint.ts +245 -0
- package/src/sample/domains/employees/index.ts +75 -0
- package/src/sample/domains/employees/services/employees.service.ts +181 -0
- package/src/sample/domains/index.ts +10 -0
- package/src/sample/domains/leaves/concepts/leave.concept.ts +21 -0
- package/src/sample/domains/leaves/concepts/leaveBalance.concept.ts +17 -0
- package/src/sample/domains/leaves/concepts/leaveBalanceTransaction.concept.ts +16 -0
- package/src/sample/domains/leaves/concepts/leaveType.concept.ts +13 -0
- package/src/sample/domains/leaves/concepts/leaveTypes.concept.ts +205 -0
- package/src/sample/domains/leaves/endpoints/getBalance.endpoint.ts +53 -0
- package/src/sample/domains/leaves/endpoints/getLeaveById.endpoint.ts +53 -0
- package/src/sample/domains/leaves/endpoints/listBalanceTransactions.endpoint.ts +196 -0
- package/src/sample/domains/leaves/endpoints/listBalanceTypes.endpoint.ts +26 -0
- package/src/sample/domains/leaves/endpoints/listBalances.endpoint.ts +201 -0
- package/src/sample/domains/leaves/endpoints/listLeaveTypes.endpoint.ts +28 -0
- package/src/sample/domains/leaves/endpoints/listLeaves.endpoint.ts +234 -0
- package/src/sample/domains/leaves/index.ts +38 -0
- package/src/sample/domains/leaves/services/leaveRequests.service.ts +232 -0
- package/src/sample/domains/notifications/concepts/notification.concept.ts +19 -0
- package/src/sample/domains/notifications/endpoints/countMyNotifications.endpoint.ts +21 -0
- package/src/sample/domains/notifications/endpoints/getMyNotification.endpoint.ts +57 -0
- package/src/sample/domains/notifications/endpoints/listMyNotifications.endpoint.ts +59 -0
- package/src/sample/domains/notifications/endpoints/markMyNotificationAsRead.endpoint.ts +32 -0
- package/src/sample/domains/notifications/index.ts +20 -0
- package/src/sample/domains/payroll/concepts/payslip.concept.ts +18 -0
- package/src/sample/domains/payroll/concepts/salaryCertificate.concept.ts +17 -0
- package/src/sample/domains/payroll/concepts/salaryCertificateRequestingEntity.concept.ts +8 -0
- package/src/sample/domains/payroll/endpoints/getPayslipById.endpoint.ts +238 -0
- package/src/sample/domains/payroll/endpoints/listPayslips.endpoint.ts +216 -0
- package/src/sample/domains/payroll/endpoints/listSalaryCertificateLanguages.endpoint.ts +25 -0
- package/src/sample/domains/payroll/endpoints/listSalaryCertificateRequestingEntities.endpoint.ts +62 -0
- package/src/sample/domains/payroll/endpoints/listSalaryCertificateTypes.endpoint.ts +24 -0
- package/src/sample/domains/payroll/endpoints/listSalaryCertificates.endpoint.ts +122 -0
- package/src/sample/domains/payroll/endpoints/previewSalaryCertificate.endpoint.ts +45 -0
- package/src/sample/domains/payroll/index.ts +32 -0
- package/src/sample/domains/payroll/rules/payrollEmployeeContext.rule.ts +7 -0
- package/src/sample/domains/payroll/services/salaryCertificates.service.ts +15 -0
- package/src/sample/domains/servicing/concepts/service.concept.ts +6 -0
- package/src/sample/domains/servicing/concepts/serviceRequest.concept.ts +12 -0
- package/src/sample/domains/servicing/concepts/serviceRequestApproval.concept.ts +9 -0
- package/src/sample/domains/servicing/endpoints/cancelServiceRequest.endpoint.ts +21 -0
- package/src/sample/domains/servicing/endpoints/createServiceRequest.endpoint.ts +511 -0
- package/src/sample/domains/servicing/endpoints/getServiceRequest.endpoint.ts +352 -0
- package/src/sample/domains/servicing/endpoints/getServiceRequestFormItems.endpoint.ts +219 -0
- package/src/sample/domains/servicing/endpoints/getServiceRequestTransactionFormItems.endpoint.ts +216 -0
- package/src/sample/domains/servicing/endpoints/getServiceStates.endpoint.ts +47 -0
- package/src/sample/domains/servicing/endpoints/invokeServiceRequestAction.endpoint.ts +139 -0
- package/src/sample/domains/servicing/endpoints/listServiceRequests.endpoint.ts +292 -0
- package/src/sample/domains/servicing/endpoints/listServices.endpoint.ts +108 -0
- package/src/sample/domains/servicing/endpoints/updateServiceRequest.endpoint.ts +355 -0
- package/src/sample/domains/servicing/index.ts +44 -0
- package/src/sample/domains/servicing/rules/checkValidActions.rule.ts +7 -0
- package/src/sample/domains/servicing/rules/createServiceRequest.rule.ts +7 -0
- package/src/sample/domains/servicing/rules/filterServiceRequestsByState.rule.ts +7 -0
- package/src/sample/domains/servicing/rules/passingOptionFields.rule.ts +7 -0
- package/src/sample/domains/shared/rules/pagination.rule.ts +7 -0
- package/src/sample/domains/suggestions/concepts/suggestion.concept.ts +19 -0
- package/src/sample/domains/suggestions/concepts/suggestionCategory.concept.ts +7 -0
- package/src/sample/domains/suggestions/concepts/suggestionImpactLevel.concept.ts +7 -0
- package/src/sample/domains/suggestions/endpoints/createSuggestion.endpoint.ts +705 -0
- package/src/sample/domains/suggestions/endpoints/deleteSuggestion.endpoint.ts +32 -0
- package/src/sample/domains/suggestions/endpoints/getSuggestionById.endpoint.ts +635 -0
- package/src/sample/domains/suggestions/endpoints/listSuggestionCategories.endpoint.ts +62 -0
- package/src/sample/domains/suggestions/endpoints/listSuggestionImpactLevels.endpoint.ts +62 -0
- package/src/sample/domains/suggestions/endpoints/listSuggestionStates.endpoint.ts +24 -0
- package/src/sample/domains/suggestions/endpoints/listSuggestions.endpoint.ts +132 -0
- package/src/sample/domains/suggestions/endpoints/updateSuggestion.endpoint.ts +690 -0
- package/src/sample/domains/suggestions/endpoints/updateSuggestionState.endpoint.ts +39 -0
- package/src/sample/domains/suggestions/index.ts +34 -0
- package/src/sample/domains/suggestions/rules/suggestionScope.rule.ts +7 -0
- package/src/sample/domains/surveys/concepts/survey.concept.ts +10 -0
- package/src/sample/domains/surveys/concepts/surveyResponse.concept.ts +14 -0
- package/src/sample/domains/surveys/endpoints/getSurveyResponseById.endpoint.ts +131 -0
- package/src/sample/domains/surveys/endpoints/getTargetedSurvey.endpoint.ts +129 -0
- package/src/sample/domains/surveys/endpoints/listTargetedSurveys.endpoint.ts +160 -0
- package/src/sample/domains/surveys/endpoints/respondToSurvey.endpoint.ts +144 -0
- package/src/sample/domains/surveys/index.ts +21 -0
- package/src/sample/drizzle.config.ts +11 -0
- package/src/sample/index.bak.ts +341 -0
- package/src/sample/index.ts +318 -0
- package/src/sample/official-statements/defaults.ts +57 -0
- package/src/sample/official-statements/routes.ts +137 -0
- package/src/sample/official-statements/service.ts +148 -0
- package/src/sample/official-statements/types.ts +23 -0
- package/dist/src/ai/context/compressor.d.ts +0 -7
- package/dist/src/ai/tools/call-endpoint.tool.d.ts +0 -7
- package/dist/src/config.d.ts +0 -159
- package/src/ai/context/compressor.ts +0 -47
- package/src/ai/prompt.ts +0 -126
- package/src/ai/tools/call-endpoint.tool.ts +0 -89
- package/src/config.ts +0 -164
- package/src/db/migrations/20260315000000_add_context_meta/migration.sql +0 -1
- package/dist/src/{adapters → lib/adapters}/minio.d.ts +0 -0
- package/dist/src/{adapters → lib/adapters}/mssql.d.ts +0 -0
- package/dist/src/{adapters → lib/adapters}/storage.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/active-streams.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/context/builder.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/context/summarizer.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/context/token-estimator.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/fetch.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/helpers.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/index.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/interceptors/request-interceptor.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/prompt.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/tools/capture-files.tool.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/tools/execute-code.tool.d.ts +0 -0
- package/dist/src/{ai → lib/ai}/tools/query-graph.tool.d.ts +0 -0
- package/dist/src/{auth → lib/auth}/middleware.d.ts +0 -0
- package/dist/src/{cli → lib/cli}/extract-endpoints.d.ts +0 -0
- package/dist/src/{db → lib/db}/migrate.d.ts +0 -0
- package/dist/src/{factory.d.ts → lib/factory.d.ts} +0 -0
- package/dist/src/{graph → lib/graph}/expand-domains.d.ts +0 -0
- package/dist/src/{graph → lib/graph}/generate-cypher.d.ts +0 -0
- package/dist/src/{graph → lib/graph}/helpers.d.ts +2 -2
- /package/dist/src/{graph → lib/graph}/index.d.ts +0 -0
- /package/dist/src/{graph → lib/graph}/neo4j.d.ts +0 -0
- /package/dist/src/{graph → lib/graph}/resolver.d.ts +0 -0
- /package/dist/src/{graph → lib/graph}/seed.d.ts +0 -0
- /package/dist/src/{graph → lib/graph}/types.d.ts +0 -0
- /package/dist/src/{graph → lib/graph}/validate.d.ts +0 -0
- /package/dist/src/{routes → lib/routes}/chat.d.ts +0 -0
- /package/dist/src/{routes → lib/routes}/files.d.ts +0 -0
- /package/dist/src/{routes → lib/routes}/index.d.ts +0 -0
- /package/dist/src/{routes → lib/routes}/threads.d.ts +0 -0
- /package/dist/src/{routes → lib/routes}/ws.d.ts +0 -0
- /package/dist/src/{ws → lib/ws}/connections.d.ts +0 -0
- /package/dist/src/{ws → lib/ws}/events.d.ts +0 -0
- /package/dist/src/{ws → lib/ws}/index.d.ts +0 -0
- /package/dist/src/{ws → lib/ws}/notify.d.ts +0 -0
- /package/src/{adapters → lib/adapters}/storage.ts +0 -0
- /package/src/{ai → lib/ai}/active-streams.ts +0 -0
- /package/src/{ai → lib/ai}/context/builder.ts +0 -0
- /package/src/{ai → lib/ai}/context/summarizer.ts +0 -0
- /package/src/{ai → lib/ai}/context/token-estimator.ts +0 -0
- /package/src/{ai → lib/ai}/fetch.ts +0 -0
- /package/src/{ai → lib/ai}/helpers.ts +0 -0
- /package/src/{ai → lib/ai}/interceptors/request-interceptor.ts +0 -0
- /package/src/{ai → lib/ai}/tools/capture-files.tool.ts +0 -0
- /package/src/{ai → lib/ai}/tools/query-graph.tool.ts +0 -0
- /package/src/{cli → lib/cli}/extract-endpoints.ts +0 -0
- /package/src/{db → lib/db}/migrate.ts +0 -0
- /package/src/{graph → lib/graph}/expand-domains.ts +0 -0
- /package/src/{graph → lib/graph}/generate-cypher.ts +0 -0
- /package/src/{graph → lib/graph}/helpers.ts +0 -0
- /package/src/{graph → lib/graph}/index.ts +0 -0
- /package/src/{graph → lib/graph}/neo4j.ts +0 -0
- /package/src/{graph → lib/graph}/resolver.ts +0 -0
- /package/src/{graph → lib/graph}/seed.ts +0 -0
- /package/src/{graph → lib/graph}/types.ts +0 -0
- /package/src/{graph → lib/graph}/validate.ts +0 -0
- /package/src/{routes → lib/routes}/chat.ts +0 -0
- /package/src/{routes → lib/routes}/index.ts +0 -0
- /package/src/{routes → lib/routes}/ws.ts +0 -0
- /package/src/{ws → lib/ws}/connections.ts +0 -0
- /package/src/{ws → lib/ws}/events.ts +0 -0
- /package/src/{ws → lib/ws}/index.ts +0 -0
- /package/src/{ws → lib/ws}/notify.ts +0 -0
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
safeValidateUIMessages,
|
|
8
8
|
stepCountIs,
|
|
9
9
|
streamText,
|
|
10
|
+
wrapLanguageModel,
|
|
10
11
|
} from "ai";
|
|
11
12
|
import { HTTPException } from "hono/http-exception";
|
|
12
13
|
import type { ResolvedCortexAgentConfig } from "../config.ts";
|
|
13
|
-
import type { MessageMetadata, Thread } from "../types.ts";
|
|
14
|
+
import type { MessageMetadata, Thread, TokenUsage } from "../types.ts";
|
|
14
15
|
import { createModel, createEmbeddingModel } from "./helpers.ts";
|
|
15
16
|
import { buildSystemPrompt, resolveSession } from "./prompt.ts";
|
|
16
17
|
import { createQueryGraphTool } from "./tools/query-graph.tool.ts";
|
|
17
|
-
import { createCallEndpointTool } from "./tools/call-endpoint.tool.ts";
|
|
18
18
|
import { createExecuteCodeTool } from "./tools/execute-code.tool.ts";
|
|
19
19
|
import { captureFilesTool } from "./tools/capture-files.tool.ts";
|
|
20
20
|
import { createRequestInterceptor } from "./interceptors/request-interceptor.ts";
|
|
@@ -23,6 +23,11 @@ import { resolveFromGraph } from "../graph/resolver.ts";
|
|
|
23
23
|
import { notify } from "../ws/index.ts";
|
|
24
24
|
import { buildContextMessages } from "./context/builder.ts";
|
|
25
25
|
import { optimizeThreadContext, estimateTokens, trimMessagesToFit } from "./context/index.ts";
|
|
26
|
+
import {
|
|
27
|
+
compressIntraTurnToolResults,
|
|
28
|
+
estimateToolResultTokens,
|
|
29
|
+
summarizeOldStepResults,
|
|
30
|
+
} from "./context/intra-turn-compressor.ts";
|
|
26
31
|
import {
|
|
27
32
|
registerStream,
|
|
28
33
|
attachSseStream,
|
|
@@ -67,18 +72,20 @@ export async function stream(
|
|
|
67
72
|
|
|
68
73
|
const model = createModel(config.model);
|
|
69
74
|
const embeddingModel = createEmbeddingModel(config.embedding);
|
|
70
|
-
const neo4j = createNeo4jClient(config.neo4j, embeddingModel);
|
|
75
|
+
const neo4j = config.neo4j ? createNeo4jClient(config.neo4j, embeddingModel) : undefined;
|
|
71
76
|
|
|
72
77
|
// Run independent operations in parallel
|
|
73
78
|
const [contextResult, resolved, session] = await Promise.all([
|
|
74
79
|
// Branch A: Load messages + build token-aware context window
|
|
75
80
|
buildContextMessages(userId, thread, config.db, config.context),
|
|
76
81
|
// Branch B: Resolve graph context (400-2000ms, the bottleneck)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
neo4j
|
|
83
|
+
? resolveFromGraph(prompt, {
|
|
84
|
+
neo4j,
|
|
85
|
+
embeddingModel,
|
|
86
|
+
reranker: config.reranker,
|
|
87
|
+
})
|
|
88
|
+
: Promise.resolve(null),
|
|
82
89
|
// Branch C: Resolve session data
|
|
83
90
|
resolveSession(config, thread, token),
|
|
84
91
|
]);
|
|
@@ -88,9 +95,12 @@ export async function stream(
|
|
|
88
95
|
// Build tools
|
|
89
96
|
const builtInTools: ToolSet = {
|
|
90
97
|
captureFiles: captureFilesTool,
|
|
91
|
-
queryGraph: createQueryGraphTool(neo4j),
|
|
92
98
|
};
|
|
93
99
|
|
|
100
|
+
if (neo4j) {
|
|
101
|
+
builtInTools["queryGraph"] = createQueryGraphTool(neo4j);
|
|
102
|
+
}
|
|
103
|
+
|
|
94
104
|
if (config.backendFetch) {
|
|
95
105
|
const backendFetchWithInterceptor = {
|
|
96
106
|
...config.backendFetch,
|
|
@@ -103,13 +113,17 @@ export async function stream(
|
|
|
103
113
|
),
|
|
104
114
|
};
|
|
105
115
|
|
|
106
|
-
builtInTools["callEndpoint"] = createCallEndpointTool(backendFetchWithInterceptor, token);
|
|
107
116
|
builtInTools["executeCode"] = createExecuteCodeTool(backendFetchWithInterceptor, token);
|
|
108
117
|
}
|
|
109
118
|
|
|
119
|
+
const resolvedUserTools =
|
|
120
|
+
typeof config.tools === "function"
|
|
121
|
+
? config.tools({ thread, userId, token, session, requestContext })
|
|
122
|
+
: config.tools;
|
|
123
|
+
|
|
110
124
|
const tools = {
|
|
111
125
|
...builtInTools,
|
|
112
|
-
...
|
|
126
|
+
...resolvedUserTools,
|
|
113
127
|
} as ToolSet;
|
|
114
128
|
|
|
115
129
|
const systemPrompt = await buildSystemPrompt(config, resolved, {
|
|
@@ -129,13 +143,82 @@ export async function stream(
|
|
|
129
143
|
|
|
130
144
|
const recentMessages = await convertToModelMessages(trimmedMessages);
|
|
131
145
|
|
|
146
|
+
const { context: contextConfig } = config;
|
|
147
|
+
|
|
148
|
+
const capturedSteps: {
|
|
149
|
+
prompt: string;
|
|
150
|
+
output: string | null;
|
|
151
|
+
tokenUsage: TokenUsage | null;
|
|
152
|
+
}[] = [];
|
|
153
|
+
|
|
132
154
|
const result = streamText({
|
|
133
|
-
model
|
|
155
|
+
model: wrapLanguageModel({
|
|
156
|
+
model,
|
|
157
|
+
middleware: {
|
|
158
|
+
specificationVersion: "v3",
|
|
159
|
+
transformParams: async ({ params }) => {
|
|
160
|
+
// Strategy 1: Compress older step tool results to one-liners
|
|
161
|
+
let optimizedPrompt = compressIntraTurnToolResults(
|
|
162
|
+
params.prompt,
|
|
163
|
+
contextConfig.toolResultMaxTokens,
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Strategy 5: If still over threshold, summarize with LLM
|
|
167
|
+
const summarizationModel = contextConfig.summarizationModel ?? config.model;
|
|
168
|
+
const toolTokens = estimateToolResultTokens(optimizedPrompt);
|
|
169
|
+
|
|
170
|
+
if (toolTokens > contextConfig.intraTurnSummarizationThresholdTokens) {
|
|
171
|
+
try {
|
|
172
|
+
optimizedPrompt = await summarizeOldStepResults(
|
|
173
|
+
optimizedPrompt,
|
|
174
|
+
contextConfig.intraTurnSummarizationThresholdTokens,
|
|
175
|
+
summarizationModel,
|
|
176
|
+
);
|
|
177
|
+
} catch (err) {
|
|
178
|
+
console.error("[cortex-server] Intra-turn summarization failed:", err);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { ...params, prompt: optimizedPrompt };
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
}),
|
|
134
186
|
system: systemPrompt,
|
|
135
187
|
tools,
|
|
136
188
|
messages: recentMessages,
|
|
137
189
|
abortSignal: abortController.signal,
|
|
138
|
-
stopWhen: stepCountIs(
|
|
190
|
+
stopWhen: stepCountIs(25),
|
|
191
|
+
onStepFinish: (step) => {
|
|
192
|
+
const usage = step.usage;
|
|
193
|
+
capturedSteps.push({
|
|
194
|
+
prompt: JSON.stringify(step.request.body),
|
|
195
|
+
output: JSON.stringify({
|
|
196
|
+
text: step.text,
|
|
197
|
+
content: step.content,
|
|
198
|
+
finishReason: step.finishReason,
|
|
199
|
+
response: {
|
|
200
|
+
id: step.response.id,
|
|
201
|
+
modelId: step.response.modelId,
|
|
202
|
+
messages: step.response.messages,
|
|
203
|
+
},
|
|
204
|
+
providerMetadata: step.providerMetadata,
|
|
205
|
+
}),
|
|
206
|
+
tokenUsage: {
|
|
207
|
+
input: {
|
|
208
|
+
noCache: usage.inputTokenDetails.noCacheTokens ?? 0,
|
|
209
|
+
cacheRead: usage.inputTokenDetails.cacheReadTokens ?? 0,
|
|
210
|
+
cacheWrite: usage.inputTokenDetails.cacheWriteTokens ?? 0,
|
|
211
|
+
total: usage.inputTokens ?? 0,
|
|
212
|
+
},
|
|
213
|
+
output: {
|
|
214
|
+
reasoning: usage.outputTokenDetails.reasoningTokens ?? 0,
|
|
215
|
+
text: usage.outputTokenDetails.textTokens ?? 0,
|
|
216
|
+
total: usage.outputTokens ?? 0,
|
|
217
|
+
},
|
|
218
|
+
total: usage.totalTokens ?? 0,
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
},
|
|
139
222
|
});
|
|
140
223
|
|
|
141
224
|
return result.toUIMessageStreamResponse<UIMessage<MessageMetadata>>({
|
|
@@ -193,6 +276,24 @@ export async function stream(
|
|
|
193
276
|
}
|
|
194
277
|
|
|
195
278
|
await config.db.messages.upsert(thread.id, finishedMessages);
|
|
279
|
+
|
|
280
|
+
// Persist captured LLM request/response data per step
|
|
281
|
+
if (capturedSteps.length > 0 && lastAssistantMessage) {
|
|
282
|
+
const llmRequestInserts = capturedSteps.map((step, index) => ({
|
|
283
|
+
messageId: lastAssistantMessage.id,
|
|
284
|
+
stepNumber: index,
|
|
285
|
+
prompt: step.prompt,
|
|
286
|
+
output: step.output,
|
|
287
|
+
tokenUsage: step.tokenUsage,
|
|
288
|
+
}));
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
await config.db.llmRequests.insert(llmRequestInserts);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
console.error("[cortex-server] Failed to persist AI requests:", err);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
196
297
|
config.onStreamFinish?.({ messages: finishedMessages, isAborted });
|
|
197
298
|
|
|
198
299
|
// XXX: we need to notify the user so that the client can
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { ResolvedContext, ResolvedEndpoint, ResolvedService } from "../graph/resolver.ts";
|
|
2
|
+
import type { PromptContext, ResolvedCortexAgentConfig } from "../config.ts";
|
|
3
|
+
import type { Thread } from "../types.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolves session data for the thread, loading from the configured
|
|
7
|
+
* session loader if not already cached on the thread.
|
|
8
|
+
*/
|
|
9
|
+
export async function resolveSession(
|
|
10
|
+
config: ResolvedCortexAgentConfig,
|
|
11
|
+
thread: Thread,
|
|
12
|
+
token: string,
|
|
13
|
+
) {
|
|
14
|
+
let session = thread.session;
|
|
15
|
+
|
|
16
|
+
if (!session && config.loadSessionData) {
|
|
17
|
+
session = await config.loadSessionData(token);
|
|
18
|
+
// Persist to DB for future cache hits
|
|
19
|
+
await config.db.threads.updateSession(thread.id, session);
|
|
20
|
+
thread.session = session;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return session;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function buildSystemPrompt(
|
|
27
|
+
config: ResolvedCortexAgentConfig,
|
|
28
|
+
resolved: ResolvedContext | null,
|
|
29
|
+
promptContext: PromptContext,
|
|
30
|
+
) {
|
|
31
|
+
// Resolve the consumer's base system prompt
|
|
32
|
+
let basePrompt: string;
|
|
33
|
+
if (typeof config.systemPrompt === "function") {
|
|
34
|
+
basePrompt = await config.systemPrompt(promptContext);
|
|
35
|
+
} else {
|
|
36
|
+
basePrompt = config.systemPrompt;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const sections: string[] = [basePrompt];
|
|
40
|
+
|
|
41
|
+
// Pre-resolved endpoints from knowledge graph
|
|
42
|
+
if (resolved) {
|
|
43
|
+
sections.push(buildResolvedSection(resolved));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return sections.join("\n");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Schema field type (parsed from endpoint JSON strings)
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
type SchemaField = {
|
|
54
|
+
name: string;
|
|
55
|
+
required?: boolean;
|
|
56
|
+
type?: string;
|
|
57
|
+
isArray?: boolean;
|
|
58
|
+
properties?: SchemaField[];
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Layer 2: Schema compression
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
/** Compact param/body: `name?: type, nested?: {a: string, b: number}[]` */
|
|
66
|
+
function compactParamFields(fields: SchemaField[]): string {
|
|
67
|
+
return fields
|
|
68
|
+
.map((f) => {
|
|
69
|
+
const opt = f.required ? "" : "?";
|
|
70
|
+
const arr = f.isArray ? "[]" : "";
|
|
71
|
+
if (f.properties && f.properties.length > 0) {
|
|
72
|
+
return `${f.name}${opt}: {${compactParamFields(f.properties)}}${arr}`;
|
|
73
|
+
}
|
|
74
|
+
return `${f.name}${opt}: ${f.type ?? "unknown"}${arr}`;
|
|
75
|
+
})
|
|
76
|
+
.join(", ");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function compactParams(jsonStr: string) {
|
|
80
|
+
try {
|
|
81
|
+
const fields = JSON.parse(jsonStr) as SchemaField[];
|
|
82
|
+
if (!Array.isArray(fields) || fields.length === 0) return "(none)";
|
|
83
|
+
return compactParamFields(fields);
|
|
84
|
+
} catch {
|
|
85
|
+
return jsonStr;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Compact response: `items[].{id, employee.{id, name.{ar, en}}}, count` */
|
|
90
|
+
function compactResponseFields(fields: SchemaField[]): string {
|
|
91
|
+
return fields
|
|
92
|
+
.map((f) => {
|
|
93
|
+
const arr = f.isArray ? "[]" : "";
|
|
94
|
+
if (f.properties && f.properties.length > 0) {
|
|
95
|
+
return `${f.name}${arr}.{${compactResponseFields(f.properties)}}`;
|
|
96
|
+
}
|
|
97
|
+
return f.name;
|
|
98
|
+
})
|
|
99
|
+
.join(", ");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function compactResponse(jsonStr: string) {
|
|
103
|
+
try {
|
|
104
|
+
const fields = JSON.parse(jsonStr) as SchemaField[];
|
|
105
|
+
if (!Array.isArray(fields) || fields.length === 0) return "(none)";
|
|
106
|
+
return compactResponseFields(fields);
|
|
107
|
+
} catch {
|
|
108
|
+
return jsonStr;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// Layer 1: Group endpoints by method + path
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
type GroupedEndpoint = Omit<ResolvedEndpoint, "concept"> & {
|
|
117
|
+
concepts: string[];
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
function groupEndpointsBySignature(endpoints: ResolvedEndpoint[]) {
|
|
121
|
+
const groups = new Map<string, GroupedEndpoint>();
|
|
122
|
+
|
|
123
|
+
for (const ep of endpoints) {
|
|
124
|
+
const key = `${ep.method}|${ep.path}`;
|
|
125
|
+
const existing = groups.get(key);
|
|
126
|
+
|
|
127
|
+
if (existing) {
|
|
128
|
+
if (!existing.concepts.includes(ep.concept)) {
|
|
129
|
+
existing.concepts.push(ep.concept);
|
|
130
|
+
}
|
|
131
|
+
for (const rule of ep.rules) {
|
|
132
|
+
if (!existing.rules.includes(rule)) {
|
|
133
|
+
existing.rules.push(rule);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (const dep of ep.dependencies) {
|
|
137
|
+
const isDuplicate = existing.dependencies.some(
|
|
138
|
+
(d) => d.depPath === dep.depPath && d.paramName === dep.paramName,
|
|
139
|
+
);
|
|
140
|
+
if (!isDuplicate) {
|
|
141
|
+
existing.dependencies.push(dep);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
groups.set(key, {
|
|
146
|
+
concepts: [ep.concept],
|
|
147
|
+
relation: ep.relation,
|
|
148
|
+
name: ep.name,
|
|
149
|
+
path: ep.path,
|
|
150
|
+
method: ep.method,
|
|
151
|
+
params: ep.params,
|
|
152
|
+
body: ep.body,
|
|
153
|
+
response: ep.response,
|
|
154
|
+
dependencies: [...ep.dependencies],
|
|
155
|
+
rules: [...ep.rules],
|
|
156
|
+
metadata: ep.metadata,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return Array.from(groups.values());
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
// Layer 3: Extract shared rules into a global section
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
function extractSharedRules(groups: GroupedEndpoint[], services: ResolvedService[]) {
|
|
169
|
+
const ruleCounts = new Map<string, number>();
|
|
170
|
+
|
|
171
|
+
for (const ep of groups) {
|
|
172
|
+
for (const rule of ep.rules) {
|
|
173
|
+
ruleCounts.set(rule, (ruleCounts.get(rule) ?? 0) + 1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
for (const svc of services) {
|
|
177
|
+
for (const rule of svc.rules) {
|
|
178
|
+
ruleCounts.set(rule, (ruleCounts.get(rule) ?? 0) + 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const sharedRules = [...ruleCounts.entries()]
|
|
183
|
+
.filter(([, count]) => count >= 2)
|
|
184
|
+
.map(([rule]) => rule);
|
|
185
|
+
|
|
186
|
+
const sharedSet = new Set(sharedRules);
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
sharedRules,
|
|
190
|
+
groups: groups.map((ep) => ({
|
|
191
|
+
...ep,
|
|
192
|
+
rules: ep.rules.filter((r) => !sharedSet.has(r)),
|
|
193
|
+
})),
|
|
194
|
+
services: services.map((svc) => ({
|
|
195
|
+
...svc,
|
|
196
|
+
rules: svc.rules.filter((r) => !sharedSet.has(r)),
|
|
197
|
+
})),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Layer 4: Deduplicate identical response schemas across endpoints
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
|
|
205
|
+
type ResponseShapeRefs = {
|
|
206
|
+
shapeDefs: { name: string; content: string }[];
|
|
207
|
+
refMap: Map<string, string>;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
function buildResponseShapeRefs(groups: GroupedEndpoint[]): ResponseShapeRefs {
|
|
211
|
+
// Key on the raw JSON string (byte-identical for endpoints sharing the same
|
|
212
|
+
// Endpoint node in Neo4j). Fall back to the compact string for cases where
|
|
213
|
+
// different raw JSON produces the same compact shape.
|
|
214
|
+
const rawToEndpoints = new Map<string, string[]>();
|
|
215
|
+
|
|
216
|
+
for (const ep of groups) {
|
|
217
|
+
if (ep.response === "[]") continue;
|
|
218
|
+
const existing = rawToEndpoints.get(ep.response);
|
|
219
|
+
if (existing) {
|
|
220
|
+
existing.push(`${ep.method} ${ep.path}`);
|
|
221
|
+
} else {
|
|
222
|
+
rawToEndpoints.set(ep.response, [`${ep.method} ${ep.path}`]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Second pass: also group by compact output to catch different raw JSON
|
|
227
|
+
// that normalizes to the same shape
|
|
228
|
+
const compactToRaws = new Map<string, Set<string>>();
|
|
229
|
+
for (const raw of rawToEndpoints.keys()) {
|
|
230
|
+
const compact = compactResponse(raw);
|
|
231
|
+
const existing = compactToRaws.get(compact);
|
|
232
|
+
if (existing) {
|
|
233
|
+
existing.add(raw);
|
|
234
|
+
} else {
|
|
235
|
+
compactToRaws.set(compact, new Set([raw]));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Merge: a shape is shared if its raw string appears on 2+ endpoints,
|
|
240
|
+
// OR if multiple raw strings compact to the same output
|
|
241
|
+
const shapeDefs: { name: string; content: string }[] = [];
|
|
242
|
+
const refMap = new Map<string, string>();
|
|
243
|
+
let idx = 1;
|
|
244
|
+
|
|
245
|
+
for (const [compact, raws] of compactToRaws) {
|
|
246
|
+
let totalEndpoints = 0;
|
|
247
|
+
for (const raw of raws) {
|
|
248
|
+
totalEndpoints += rawToEndpoints.get(raw)!.length;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (totalEndpoints >= 2) {
|
|
252
|
+
const name = `$R${idx++}`;
|
|
253
|
+
shapeDefs.push({ name, content: compact });
|
|
254
|
+
refMap.set(compact, name);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return { shapeDefs, refMap };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
// Pre-resolved section builder
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
|
|
265
|
+
function buildResolvedSection(resolved: ResolvedContext) {
|
|
266
|
+
const allEndpoints = [...resolved.readEndpoints, ...resolved.writeEndpoints];
|
|
267
|
+
|
|
268
|
+
if (allEndpoints.length === 0 && resolved.services.length === 0) {
|
|
269
|
+
return "\n## Pre-resolved API Endpoints\nNo matching endpoints found. Use queryGraph to search the knowledge graph manually.";
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Layer 1: deduplicate endpoints by method+path
|
|
273
|
+
const grouped = groupEndpointsBySignature(allEndpoints);
|
|
274
|
+
|
|
275
|
+
// Layer 3: hoist repeated rules to a shared section
|
|
276
|
+
const {
|
|
277
|
+
sharedRules,
|
|
278
|
+
groups: cleanedGroups,
|
|
279
|
+
services: cleanedServices,
|
|
280
|
+
} = extractSharedRules(grouped, resolved.services);
|
|
281
|
+
|
|
282
|
+
// Layer 4: deduplicate identical response schemas
|
|
283
|
+
const { shapeDefs, refMap } = buildResponseShapeRefs(cleanedGroups);
|
|
284
|
+
|
|
285
|
+
const parts: string[] = [
|
|
286
|
+
`
|
|
287
|
+
## Pre-resolved API Endpoints
|
|
288
|
+
The following endpoints were automatically matched to the user's message.`,
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
// Shared rules
|
|
292
|
+
if (sharedRules.length > 0) {
|
|
293
|
+
parts.push("\n### General Rules");
|
|
294
|
+
for (const rule of sharedRules) {
|
|
295
|
+
parts.push(`\n- ${rule}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Response shape definitions
|
|
300
|
+
if (shapeDefs.length > 0) {
|
|
301
|
+
parts.push("\n### Response Shapes");
|
|
302
|
+
for (const def of shapeDefs) {
|
|
303
|
+
parts.push(`\n${def.name}: ${def.content}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Endpoints (Layer 2: compact schemas)
|
|
308
|
+
for (const ep of cleanedGroups) {
|
|
309
|
+
const concepts = ep.concepts.join(", ");
|
|
310
|
+
const params = compactParams(ep.params);
|
|
311
|
+
const body = compactParams(ep.body);
|
|
312
|
+
const compactResp = compactResponse(ep.response);
|
|
313
|
+
const response = refMap.get(compactResp) ?? compactResp;
|
|
314
|
+
|
|
315
|
+
const rules = ep.rules.length > 0 ? `\n Rules: ${ep.rules.join("; ")}` : "";
|
|
316
|
+
const deps =
|
|
317
|
+
ep.dependencies.length > 0
|
|
318
|
+
? "\n Dependencies:\n" +
|
|
319
|
+
ep.dependencies
|
|
320
|
+
.map(
|
|
321
|
+
(d) =>
|
|
322
|
+
` - Call ${d.depMethod} ${d.depPath} first → use its "${d.fromField}" as "${d.paramName}"`,
|
|
323
|
+
)
|
|
324
|
+
.join("\n")
|
|
325
|
+
: "";
|
|
326
|
+
const meta = ep.metadata !== "{}" ? `\n Metadata: ${ep.metadata}` : "";
|
|
327
|
+
|
|
328
|
+
let block = `\n### ${ep.name} — ${ep.method} ${ep.path} (${ep.relation})`;
|
|
329
|
+
block += `\n- Concepts: ${concepts}`;
|
|
330
|
+
block += `\n- Params: ${params}`;
|
|
331
|
+
if (body !== "(none)") {
|
|
332
|
+
block += `\n- Body: ${body}`;
|
|
333
|
+
}
|
|
334
|
+
block += `\n- Response: ${response}`;
|
|
335
|
+
block += rules;
|
|
336
|
+
block += deps;
|
|
337
|
+
block += meta;
|
|
338
|
+
|
|
339
|
+
parts.push(block);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Services
|
|
343
|
+
for (const svc of cleanedServices) {
|
|
344
|
+
const rules = svc.rules.length > 0 ? `\n Rules: ${svc.rules.join("; ")}` : "";
|
|
345
|
+
const meta = svc.metadata !== "{}" ? `\n- Metadata: ${svc.metadata}` : "";
|
|
346
|
+
parts.push(
|
|
347
|
+
`\n### ${svc.concept} via ${svc.serviceName} (service)` +
|
|
348
|
+
`\n- Built-in ID: ${svc.builtInId}` +
|
|
349
|
+
`\n- Description: ${svc.description || "N/A"}${rules}${meta}`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return parts.join("");
|
|
354
|
+
}
|
|
@@ -131,8 +131,11 @@ export function createExecuteCodeTool(
|
|
|
131
131
|
) {
|
|
132
132
|
return tool({
|
|
133
133
|
title: "Executes JavaScript code",
|
|
134
|
-
description:
|
|
135
|
-
|
|
134
|
+
description: `Run a JavaScript script that calls APIs and returns only relevant data.
|
|
135
|
+
The script has an \`api\` helper: api.get(path, params?), api.post(path, body?), api.put(path, body?), api.del(path).
|
|
136
|
+
Each returns parsed JSON and throws on error.
|
|
137
|
+
For parameters of type file, use \`capturedFile#[uploadId]\` as the value. If you try to upload files in any other way
|
|
138
|
+
you are going to get an error. All file uploads follow this rule without exception.`,
|
|
136
139
|
inputSchema: z.object({
|
|
137
140
|
code: z
|
|
138
141
|
.string()
|
|
@@ -6,6 +6,13 @@ import type { AppEnv, AuthedAppEnv } from "../types";
|
|
|
6
6
|
import type { CortexConfig } from "../config";
|
|
7
7
|
|
|
8
8
|
export function createUserLoaderMiddleware(authConfig: CortexConfig["auth"]) {
|
|
9
|
+
if (!authConfig) {
|
|
10
|
+
return createMiddleware<AppEnv>(async (c, next) => {
|
|
11
|
+
c.set("user", { id: "00000000-0000-0000-0000-000000000000", token: "" });
|
|
12
|
+
await next();
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
const jwks = createRemoteJWKSet(new URL(authConfig.jwksUri));
|
|
10
17
|
|
|
11
18
|
return createMiddleware<AppEnv>(async (c, next) => {
|