@runfusion/fusion 0.73.0-beta.6 → 0.74.0-beta.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/bin.js +524 -106
- package/dist/child-process-worker.js +252 -29
- package/dist/client/.vite/manifest.json +263 -263
- package/dist/client/assets/{AgentDetailView-jg-430Wv.js → AgentDetailView-CUXS0Odh.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-0iybC0Dg.js → AgentPermissionPolicyEditor-CzjHjB5r.js} +1 -1
- package/dist/client/assets/{AgentsView-DeVI7IJy.js → AgentsView-B5stgI5m.js} +3 -3
- package/dist/client/assets/ChatView-CpoOgZ4X.js +13 -0
- package/dist/client/assets/{CommandCenter-CPpYSmxm.js → CommandCenter-BdEQ_ZOX.js} +1 -1
- package/dist/client/assets/{DevServerView-C7Uib0ck.js → DevServerView-BHgAmF3y.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-Ba9x3E72.js → DirectoryPicker-BQXVc5YW.js} +1 -1
- package/dist/client/assets/{DocumentsView-DkuxxEAC.js → DocumentsView-CxN0Ptrj.js} +1 -1
- package/dist/client/assets/{EvalsView-DwRsXihY.js → EvalsView-DAgJtpO5.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-C2g8TiAY.js → ExperimentalAgentOnboardingModal-NZcXkGrN.js} +1 -1
- package/dist/client/assets/{GoalsView-hQSajINq.js → GoalsView-Dwq7NW4j.js} +1 -1
- package/dist/client/assets/{InsightsView-p7j5T5a8.js → InsightsView-CUlL5NSC.js} +1 -1
- package/dist/client/assets/{MemoryView-DoVBk38U.js → MemoryView-WfHzJflp.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-DzT94cPg.js → PiExtensionsManager-BS1dkauB.js} +1 -1
- package/dist/client/assets/{PluginManager-5DK-HUkf.js → PluginManager-B1oLb0pn.js} +1 -1
- package/dist/client/assets/{PullRequestView-c8_Nl91A.js → PullRequestView-Cdp662lx.js} +1 -1
- package/dist/client/assets/{ReportModal-BfNu73zb.js → ReportModal-C92wQO-k.js} +1 -1
- package/dist/client/assets/{ResearchView-Cc_DZq5v.js → ResearchView-4-SoxmQv.js} +1 -1
- package/dist/client/assets/{SecretsView-DMETxbnI.js → SecretsView-C5UQ1Mms.js} +1 -1
- package/dist/client/assets/SessionTerminal-BTjX9p3a.js +2 -0
- package/dist/client/assets/SettingsModal-BcnOOo9g.js +21 -0
- package/dist/client/assets/{SettingsModal-oTMDyzjF.js → SettingsModal-BfHAE14s.js} +1 -1
- package/dist/client/assets/{SettingsTextareaRow-B63cJNsI.js → SettingsTextareaRow-C2JqzQdD.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-BZnyRPT7.js → SetupWizardModal-C1KmMVfU.js} +2 -2
- package/dist/client/assets/{SkillsView-DGwWIOqX.js → SkillsView-DyLNdfDy.js} +1 -1
- package/dist/client/assets/{TodoView-BoLH6qHP.js → TodoView-DyrniX19.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-DHqpPcSv.js → WorkflowNodeEditor-Bh-Hn1Kx.js} +1 -1
- package/dist/client/assets/{agent-import-generation-Dl3UAfFr.js → agent-import-generation-C5pyefIj.js} +1 -1
- package/dist/client/assets/{app-B4dURBVF.js → app-Bl764LdY.js} +1 -1
- package/dist/client/assets/{app-DxbSLeuH.js → app-DNrauoYS.js} +1 -1
- package/dist/client/assets/{app-DfQxLcCr.js → app-DdCnRHSe.js} +1 -1
- package/dist/client/assets/{app-R0cG-sq5.js → app-QmIotwFZ.js} +1 -1
- package/dist/client/assets/{app-DLG7AA6O.js → app-YM47G7Ks.js} +1 -1
- package/dist/client/assets/{app-JOLkwq4O.js → app-oUEtzFOj.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DRSMeXsR.js → architectureDiagram-3BPJPVTR-B6axGlaS.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-xBxQf_Gy.js → blockDiagram-GPEHLZMM-BENjJaZD.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CememwlP.js → c4Diagram-AAUBKEIU-Cl2qKhuO.js} +1 -1
- package/dist/client/assets/channel-CktWdAhK.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-B62t8Ow1.js → chunk-2J33WTMH-BWo7R8T7.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-CHzxnH6A.js → chunk-4BX2VUAB-DiRoI7pq.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-BXJotoWf.js → chunk-55IACEB6-DPtv1GVO.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DGFhyp03.js → chunk-727SXJPM-BVcm5ITs.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-C-nRZZBE.js → chunk-AQP2D5EJ-CFT4bmXK.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CFS2iW51.js → chunk-FMBD7UC4-BDcEHQ0o.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-DFleK3tP.js → chunk-ND2GUHAM-CYlDBFdI.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-E7rqTspj.js → chunk-QZHKN3VN-3Wv3WxYt.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CrUS4gHO.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CrUS4gHO.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-VYcUIreA.js → cose-bilkent-S5V4N54A-BuMkKBMC.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-B4VeH0Nz.js → dagre-BM42HDAG-D1P4z_OM.js} +1 -1
- package/dist/client/assets/{dashboard-view-DoNpCbHQ.js → dashboard-view-BgQBLynI.js} +1 -1
- package/dist/client/assets/{dashboard-view-BpeWPcmh.js → dashboard-view-CcK2sH0v.js} +1 -1
- package/dist/client/assets/{dashboard-view-DGcOsOey.js → dashboard-view-DaRKU5oU.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BM8FU7fY.js → diagram-2AECGRRQ-hmY-reWF.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-Do8IJG5T.js → diagram-5GNKFQAL-CGfRqm_0.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-C_-zygdh.js → diagram-KO2AKTUF-BfKo4Jd4.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CSPiBke9.js → diagram-LMA3HP47-BZqpNemd.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BVuoiZg-.js → diagram-OG6HWLK6-CxLTV4DH.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CIY48OYH.js → erDiagram-TEJ5UH35-vw3tx2tK.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-B6zav8SR.js → flowDiagram-I6XJVG4X-OEm-Us2U.js} +1 -1
- package/dist/client/assets/{folder-open-Dc23V8n6.js → folder-open-D_zgZHWi.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-_F49rUcG.js → ganttDiagram-6RSMTGT7-C5bc1DG1.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-Fk-V-buo.js → gitGraphDiagram-PVQCEYII-DEvcWRBq.js} +1 -1
- package/dist/client/assets/index-BinRUCFV.js +2661 -0
- package/dist/client/assets/index-DGmuyTtv.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-DvnBGHv4.js → infoDiagram-5YYISTIA-kFOE9wxd.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-Df7TrITT.js → ishikawaDiagram-YF4QCWOH-DvLbzHmR.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CieUO8Cz.js → journeyDiagram-JHISSGLW-ov6Tbcuz.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BBR_Cj7I.js → kanban-definition-UN3LZRKU-Dr0foW2M.js} +1 -1
- package/dist/client/assets/{mermaid.core-whEVIkYk.js → mermaid.core-CM55309V.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-utsoG884.js → mindmap-definition-RKZ34NQL-xNyB6Z6o.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-B6_-ma_S.js → pieDiagram-4H26LBE5-DlS5Kpga.js} +1 -1
- package/dist/client/assets/{puzzle-CY7o6u4N.js → puzzle-BrEvi5DH.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CCAEPNEU.js → quadrantDiagram-W4KKPZXB-D4z2CHAA.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-C0rKKe1e.js → requirementDiagram-4Y6WPE33-Bcwt6-p9.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DpeRsnkc.js → sankeyDiagram-5OEKKPKP-C54N76yk.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DWYg86A1.js → sequenceDiagram-3UESZ5HK-DtqryztE.js} +1 -1
- package/dist/client/assets/{shield-alert-j_jHfoeI.js → shield-alert-DhxKVKek.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-CCI99V8d.js → standing-instructions-template-CdHJwmLI.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-CalOQ-6v.js → stateDiagram-AJRCARHV-DQAvSrHw.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-Dd8RLebl.js → stateDiagram-v2-BHNVJYJU-BzIGKq7y.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-D1PZw-aB.js → timeline-definition-PNZ67QCA-GDj_48Um.js} +1 -1
- package/dist/client/assets/{upload-CFL3ZlNN.js → upload-B7GKZiF1.js} +1 -1
- package/dist/client/assets/{users-DGOPLxzy.js → users-CBtvFVLM.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DKQAihMR.js → vennDiagram-CIIHVFJN-PQDmLFbj.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-B_XzYoGe.js → wardley-L42UT6IY-GmGtXctI.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DBu7IvQK.js → wardleyDiagram-YWT4CUSO-Bv6slmsW.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-CKrqMXvh.js → xychartDiagram-2RQKCTM6-CK1RJHwB.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +349 -60
- package/dist/migrations/0036_chat_session_tags.sql +64 -0
- package/dist/plugin-sdk/index.js +27 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/.bundled.reload-1.js +8835 -0
- package/package.json +3 -3
- package/dist/client/assets/ChatView-BWosYwf6.js +0 -8
- package/dist/client/assets/SessionTerminal-B4c2w5zb.js +0 -2
- package/dist/client/assets/SettingsModal-vpkxpahA.js +0 -21
- package/dist/client/assets/channel-DwxxVJWv.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CU_MxE3u.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CU_MxE3u.js +0 -1
- package/dist/client/assets/index-C77ORgtm.css +0 -1
- package/dist/client/assets/index-D8TQBkB7.js +0 -2661
package/dist/bin.js
CHANGED
|
@@ -707,7 +707,7 @@ var init_merge_queue = __esm({
|
|
|
707
707
|
function isLocale(value) {
|
|
708
708
|
return typeof value === "string" && SUPPORTED_LOCALES.includes(value);
|
|
709
709
|
}
|
|
710
|
-
var HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, REVIEW_ARTIFACTS_MODES, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE;
|
|
710
|
+
var HIGH_FANOUT_BLOCKER_TODO_THRESHOLD, STALE_HIGH_FANOUT_BLOCKER_AGE_THRESHOLD_MS, EXECUTION_MODES, DEFAULT_EXECUTION_MODE, PLANNER_OVERSIGHT_LEVELS, DEFAULT_PLANNER_OVERSIGHT_LEVEL, REVIEW_ARTIFACTS_MODES, ANTHROPIC_AUTH_PREFERENCES, THEME_MODES, COLOR_THEMES, SUPPORTED_LOCALES, DEFAULT_LOCALE;
|
|
711
711
|
var init_execution_and_ui = __esm({
|
|
712
712
|
"../core/src/types/execution-and-ui.ts"() {
|
|
713
713
|
"use strict";
|
|
@@ -718,6 +718,7 @@ var init_execution_and_ui = __esm({
|
|
|
718
718
|
PLANNER_OVERSIGHT_LEVELS = ["off", "observe", "steer", "autonomous"];
|
|
719
719
|
DEFAULT_PLANNER_OVERSIGHT_LEVEL = "autonomous";
|
|
720
720
|
REVIEW_ARTIFACTS_MODES = ["off", "user-facing", "on"];
|
|
721
|
+
ANTHROPIC_AUTH_PREFERENCES = ["api-key", "subscription"];
|
|
721
722
|
THEME_MODES = ["dark", "light", "system"];
|
|
722
723
|
COLOR_THEMES = [
|
|
723
724
|
"default",
|
|
@@ -1531,6 +1532,12 @@ var init_settings_schema = __esm({
|
|
|
1531
1532
|
FNXC:DashboardTheming 2026-07-03-00:00:
|
|
1532
1533
|
Fresh installs must follow the operating system theme until the user explicitly chooses Light, Dark, or System. Keep this global default aligned with dashboard and desktop pre-hydration fallbacks.
|
|
1533
1534
|
*/
|
|
1535
|
+
/*
|
|
1536
|
+
FNXC:ProviderAuth 2026-07-24-17:05:
|
|
1537
|
+
Default to the historical precedence (raw API key beats subscription OAuth, FN-7391/FN-7396)
|
|
1538
|
+
so upgrading never silently moves an operator's traffic from their key onto their subscription.
|
|
1539
|
+
*/
|
|
1540
|
+
anthropicAuthPreference: "api-key",
|
|
1534
1541
|
themeMode: "system",
|
|
1535
1542
|
/*
|
|
1536
1543
|
FNXC:DashboardTheming 2026-06-30-00:00:
|
|
@@ -12799,7 +12806,9 @@ __export(project_exports, {
|
|
|
12799
12806
|
chatRoomMembers: () => chatRoomMembers,
|
|
12800
12807
|
chatRoomMessages: () => chatRoomMessages,
|
|
12801
12808
|
chatRooms: () => chatRooms,
|
|
12809
|
+
chatSessionTags: () => chatSessionTags,
|
|
12802
12810
|
chatSessions: () => chatSessions,
|
|
12811
|
+
chatTags: () => chatTags,
|
|
12803
12812
|
chatTokenUsage: () => chatTokenUsage,
|
|
12804
12813
|
cliSessions: () => cliSessions,
|
|
12805
12814
|
completionHandoffMarkers: () => completionHandoffMarkers,
|
|
@@ -12876,7 +12885,7 @@ __export(project_exports, {
|
|
|
12876
12885
|
workflowWorkItems: () => workflowWorkItems,
|
|
12877
12886
|
workflows: () => workflows
|
|
12878
12887
|
});
|
|
12879
|
-
var projectSchema, tasks, config, legacyBoards, legacyProjectAuthUsers, legacyProjectAuthMemberships, legacyProjectAuthProviders, legacyProjectAuthSessions, legacyTaskReviewerRuns, distributedTaskIdState, distributedTaskIdReservations, symbolLocks, workflowSteps, workflows, taskWorkflowSelection, taskVerificationRequests, activityLog, archivedTasks, taskCommitAssociations, automations, agents, agentHeartbeats, agentRuns, agentTaskSessions, agentApiKeys, agentConfigRevisions, agentBlockedStates, mergeQueue, mergeRequests, completionHandoffMarkers, workflowWorkItems, workflowRunBranches, workflowRunStepInstances, workflowSettings, workflowPromptOverrides, configurationRevisions, taskDocuments, artifacts, taskDocumentRevisions, researchRuns, researchExports, researchRunEvents, experimentSessions, experimentSessionRecords, evalRuns, evalTaskResults, evalRunEvents, secrets, projectMeta, missions, branchGroups, pullRequests, pullRequestThreadState, goals, missionGoals, goalCitations, milestones, slices, missionFeatures, ideationSessions, ideationCandidates, missionEvents, plugins, routines, projectInsights, projectInsightRuns, projectInsightRunEvents, todoLists, todoItems, usageEvents, pluginActivations, knowledgePages, deployments, incidents, aiSessions, messages, agentRatings, chatSessions, cliSessions, chatMessages, chatTokenUsage, runAuditEvents, missionContractAssertions, missionFeatureAssertions, missionValidatorRuns, missionValidatorFailures, missionFixFeatureLineage, missionLineageStops, verificationCache, importTranslationCache, approvalRequests, approvalRequestAuditEvents, chatRooms, chatRoomMembers, chatRoomMessages, projectTableNames;
|
|
12888
|
+
var projectSchema, tasks, config, legacyBoards, legacyProjectAuthUsers, legacyProjectAuthMemberships, legacyProjectAuthProviders, legacyProjectAuthSessions, legacyTaskReviewerRuns, distributedTaskIdState, distributedTaskIdReservations, symbolLocks, workflowSteps, workflows, taskWorkflowSelection, taskVerificationRequests, activityLog, archivedTasks, taskCommitAssociations, automations, agents, agentHeartbeats, agentRuns, agentTaskSessions, agentApiKeys, agentConfigRevisions, agentBlockedStates, mergeQueue, mergeRequests, completionHandoffMarkers, workflowWorkItems, workflowRunBranches, workflowRunStepInstances, workflowSettings, workflowPromptOverrides, configurationRevisions, taskDocuments, artifacts, taskDocumentRevisions, researchRuns, researchExports, researchRunEvents, experimentSessions, experimentSessionRecords, evalRuns, evalTaskResults, evalRunEvents, secrets, projectMeta, missions, branchGroups, pullRequests, pullRequestThreadState, goals, missionGoals, goalCitations, milestones, slices, missionFeatures, ideationSessions, ideationCandidates, missionEvents, plugins, routines, projectInsights, projectInsightRuns, projectInsightRunEvents, todoLists, todoItems, usageEvents, pluginActivations, knowledgePages, deployments, incidents, aiSessions, messages, agentRatings, chatSessions, chatTags, chatSessionTags, cliSessions, chatMessages, chatTokenUsage, runAuditEvents, missionContractAssertions, missionFeatureAssertions, missionValidatorRuns, missionValidatorFailures, missionFixFeatureLineage, missionLineageStops, verificationCache, importTranslationCache, approvalRequests, approvalRequestAuditEvents, chatRooms, chatRoomMembers, chatRoomMessages, projectTableNames;
|
|
12880
12889
|
var init_project = __esm({
|
|
12881
12890
|
"../core/src/postgres/schema/project.ts"() {
|
|
12882
12891
|
"use strict";
|
|
@@ -14587,7 +14596,33 @@ var init_project = __esm({
|
|
|
14587
14596
|
cliExecutorAdapterId: text("cli_executor_adapter_id")
|
|
14588
14597
|
}, (t) => [
|
|
14589
14598
|
index("idxChatSessionsAgentId").on(t.agentId),
|
|
14590
|
-
index("idxChatSessionsProjectId").on(t.projectId)
|
|
14599
|
+
index("idxChatSessionsProjectId").on(t.projectId),
|
|
14600
|
+
uniqueIndex("uqChatSessionsProjectIdId").on(t.projectId, t.id)
|
|
14601
|
+
]);
|
|
14602
|
+
chatTags = projectSchema.table("chat_tags", {
|
|
14603
|
+
id: text("id").notNull(),
|
|
14604
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
14605
|
+
ownerProjectId: text("owner_project_id").notNull(),
|
|
14606
|
+
name: text("name").notNull(),
|
|
14607
|
+
normalizedName: text("normalized_name").notNull(),
|
|
14608
|
+
createdAt: text("created_at").notNull(),
|
|
14609
|
+
updatedAt: text("updated_at").notNull()
|
|
14610
|
+
}, (t) => [
|
|
14611
|
+
primaryKey({ columns: [t.projectId, t.id] }),
|
|
14612
|
+
uniqueIndex("uqChatTagsScopeName").on(t.projectId, t.normalizedName),
|
|
14613
|
+
index("idxChatTagsScopeName").on(t.projectId, t.normalizedName)
|
|
14614
|
+
]);
|
|
14615
|
+
chatSessionTags = projectSchema.table("chat_session_tags", {
|
|
14616
|
+
sessionId: text("session_id").notNull(),
|
|
14617
|
+
tagId: text("tag_id").notNull(),
|
|
14618
|
+
projectId: text("project_id").notNull().default(sql`current_setting('fusion.project_id', true)`),
|
|
14619
|
+
assignedAt: text("assigned_at").notNull()
|
|
14620
|
+
}, (t) => [
|
|
14621
|
+
// FNXC:ChatTags 2026-08-05-12:15: both parents include the RLS partition, preventing bypass/admin access from joining a same-named ID in another project.
|
|
14622
|
+
primaryKey({ columns: [t.projectId, t.sessionId, t.tagId] }),
|
|
14623
|
+
foreignKey({ columns: [t.projectId, t.sessionId], foreignColumns: [chatSessions.projectId, chatSessions.id] }).onDelete("cascade"),
|
|
14624
|
+
foreignKey({ columns: [t.projectId, t.tagId], foreignColumns: [chatTags.projectId, chatTags.id] }).onDelete("cascade"),
|
|
14625
|
+
index("idxChatSessionTagsTag").on(t.projectId, t.tagId, t.sessionId)
|
|
14591
14626
|
]);
|
|
14592
14627
|
cliSessions = projectSchema.table("cli_sessions", {
|
|
14593
14628
|
id: text("id").primaryKey(),
|
|
@@ -36530,6 +36565,7 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
36530
36565
|
const taskWedgeNotificationAlreadyApplied = applied.includes(TASK_WEDGE_NOTIFICATION_VERSION);
|
|
36531
36566
|
const milestoneAssertionProvenanceAlreadyApplied = applied.includes(MILESTONE_ASSERTION_PROVENANCE_VERSION);
|
|
36532
36567
|
const missionLineageStopAlreadyApplied = applied.includes(MISSION_LINEAGE_STOP_VERSION);
|
|
36568
|
+
const chatSessionTagsAlreadyApplied = applied.includes(CHAT_SESSION_TAGS_VERSION);
|
|
36533
36569
|
assertBinaryNotOlderThanDatabase(applied);
|
|
36534
36570
|
let schemaChanged = false;
|
|
36535
36571
|
if (!baselineAlreadyApplied) {
|
|
@@ -36875,17 +36911,23 @@ async function applySchemaBaseline(db, options = {}) {
|
|
|
36875
36911
|
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${MISSION_LINEAGE_STOP_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
36876
36912
|
schemaChanged = true;
|
|
36877
36913
|
}
|
|
36914
|
+
if (!chatSessionTagsAlreadyApplied) {
|
|
36915
|
+
const migrationSql = await readFile4(CHAT_SESSION_TAGS_MIGRATION_PATH, "utf8");
|
|
36916
|
+
await tx.execute(sql.raw(migrationSql));
|
|
36917
|
+
await tx.execute(sql`INSERT INTO public.${sql.identifier(MIGRATION_BOOKKEEPING_TABLE)} (version) VALUES (${CHAT_SESSION_TAGS_VERSION}) ON CONFLICT (version) DO NOTHING`);
|
|
36918
|
+
schemaChanged = true;
|
|
36919
|
+
}
|
|
36878
36920
|
return { applied: schemaChanged, pluginHooksRun: pluginHooks.length };
|
|
36879
36921
|
});
|
|
36880
36922
|
}
|
|
36881
|
-
var SCHEMA_BASELINE_VERSION, TASK_DECLARED_SYMBOLS_VERSION, INITIAL_SCHEMA_VERSION, AUTOMATION_ISOLATION_SCHEMA_VERSION, ANALYTICS_ISOLATION_SCHEMA_VERSION, MONITOR_APPROVAL_ISOLATION_SCHEMA_VERSION, LEGACY_CUTOVER_PRESERVATION_SCHEMA_VERSION, MULTI_PROJECT_CUTOVER_SCHEMA_VERSION, PROJECT_OWNERSHIP_SCHEMA_VERSION, SQLITE_SCHEMA_PARITY_VERSION, SESSION_ADVISOR_ENABLED_SCHEMA_VERSION, MISSION_FIX_IDEMPOTENCY_VERSION, IMPORT_TRANSLATION_CACHE_VERSION, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_VERSION, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_VERSION, OWNER_PROJECT_ID_SPLIT_VERSION, CHAT_SESSION_PINS_VERSION, EXECUTOR_TOOL_FAILURE_RETRY_VERSION, EXECUTOR_ESCALATION_ATTEMPT_VERSION, GLOBAL_ROUTINES_SCHEMA_VERSION, TASK_MERGER_MODEL_LANE_VERSION, BULK_COMPLETION_REFUSAL_AT_VERSION, TASK_PROPOSAL_CLAIM_VERSION, CONFIGURATION_REVISIONS_VERSION, IDEATION_SCHEMA_VERSION, RESEARCH_FEATURE_PROVENANCE_VERSION, TASK_VERIFICATION_REQUEST_VERSION, SYMBOL_LOCKS_SCHEMA_VERSION, BIGINT_COUNTERS_VERSION, PLANNING_ACTIVE_TIMING_VERSION, SQLITE_MIGRATION_RUNTIME_READ_VERSION, WORKFLOW_TASK_CONTINUATIONS_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_VERSION, TASK_WEDGE_NOTIFICATION_VERSION, MILESTONE_ASSERTION_PROVENANCE_VERSION, MISSION_LINEAGE_STOP_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION, StaleBinarySchemaError, MIGRATION_BOOKKEEPING_TABLE, LEGACY_ADOPTION_DRAINED_MARKER, __dirname, MIGRATIONS_DIR, BASELINE_MIGRATION_PATH, AUTOMATION_ISOLATION_MIGRATION_PATH, ANALYTICS_ISOLATION_MIGRATION_PATH, MONITOR_APPROVAL_ISOLATION_MIGRATION_PATH, LEGACY_CUTOVER_PRESERVATION_MIGRATION_PATH, MULTI_PROJECT_CUTOVER_MIGRATION_PATH, PROJECT_OWNERSHIP_MIGRATION_PATH, SQLITE_SCHEMA_PARITY_MIGRATION_PATH, SESSION_ADVISOR_ENABLED_MIGRATION_PATH, MISSION_FIX_IDEMPOTENCY_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_MIGRATION_PATH, OWNER_PROJECT_ID_SPLIT_MIGRATION_PATH, CHAT_SESSION_PINS_MIGRATION_PATH, EXECUTOR_TOOL_FAILURE_RETRY_MIGRATION_PATH, EXECUTOR_ESCALATION_ATTEMPT_MIGRATION_PATH, GLOBAL_ROUTINES_MIGRATION_PATH, TASK_MERGER_MODEL_LANE_MIGRATION_PATH, BULK_COMPLETION_REFUSAL_AT_MIGRATION_PATH, TASK_PROPOSAL_CLAIM_MIGRATION_PATH, CONFIGURATION_REVISIONS_MIGRATION_PATH, IDEATION_MIGRATION_PATH, RESEARCH_FEATURE_PROVENANCE_MIGRATION_PATH, TASK_VERIFICATION_REQUEST_MIGRATION_PATH, SYMBOL_LOCKS_MIGRATION_PATH, BIGINT_COUNTERS_MIGRATION_PATH, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_VERSION, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_MIGRATION_PATH, PLANNING_ACTIVE_TIMING_MIGRATION_PATH, TASK_DECLARED_SYMBOLS_MIGRATION_PATH, SQLITE_MIGRATION_RUNTIME_READ_PATH, WORKFLOW_TASK_CONTINUATIONS_PATH, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_PATH, TASK_WEDGE_NOTIFICATION_MIGRATION_PATH, MILESTONE_ASSERTION_PROVENANCE_MIGRATION_PATH, MISSION_LINEAGE_STOP_MIGRATION_PATH;
|
|
36923
|
+
var SCHEMA_BASELINE_VERSION, TASK_DECLARED_SYMBOLS_VERSION, INITIAL_SCHEMA_VERSION, AUTOMATION_ISOLATION_SCHEMA_VERSION, ANALYTICS_ISOLATION_SCHEMA_VERSION, MONITOR_APPROVAL_ISOLATION_SCHEMA_VERSION, LEGACY_CUTOVER_PRESERVATION_SCHEMA_VERSION, MULTI_PROJECT_CUTOVER_SCHEMA_VERSION, PROJECT_OWNERSHIP_SCHEMA_VERSION, SQLITE_SCHEMA_PARITY_VERSION, SESSION_ADVISOR_ENABLED_SCHEMA_VERSION, MISSION_FIX_IDEMPOTENCY_VERSION, IMPORT_TRANSLATION_CACHE_VERSION, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_VERSION, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_VERSION, OWNER_PROJECT_ID_SPLIT_VERSION, CHAT_SESSION_PINS_VERSION, EXECUTOR_TOOL_FAILURE_RETRY_VERSION, EXECUTOR_ESCALATION_ATTEMPT_VERSION, GLOBAL_ROUTINES_SCHEMA_VERSION, TASK_MERGER_MODEL_LANE_VERSION, BULK_COMPLETION_REFUSAL_AT_VERSION, TASK_PROPOSAL_CLAIM_VERSION, CONFIGURATION_REVISIONS_VERSION, IDEATION_SCHEMA_VERSION, RESEARCH_FEATURE_PROVENANCE_VERSION, TASK_VERIFICATION_REQUEST_VERSION, SYMBOL_LOCKS_SCHEMA_VERSION, BIGINT_COUNTERS_VERSION, PLANNING_ACTIVE_TIMING_VERSION, SQLITE_MIGRATION_RUNTIME_READ_VERSION, WORKFLOW_TASK_CONTINUATIONS_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_VERSION, TASK_WEDGE_NOTIFICATION_VERSION, MILESTONE_ASSERTION_PROVENANCE_VERSION, MISSION_LINEAGE_STOP_VERSION, CHAT_SESSION_TAGS_VERSION, LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION, StaleBinarySchemaError, MIGRATION_BOOKKEEPING_TABLE, LEGACY_ADOPTION_DRAINED_MARKER, __dirname, MIGRATIONS_DIR, BASELINE_MIGRATION_PATH, AUTOMATION_ISOLATION_MIGRATION_PATH, ANALYTICS_ISOLATION_MIGRATION_PATH, MONITOR_APPROVAL_ISOLATION_MIGRATION_PATH, LEGACY_CUTOVER_PRESERVATION_MIGRATION_PATH, MULTI_PROJECT_CUTOVER_MIGRATION_PATH, PROJECT_OWNERSHIP_MIGRATION_PATH, SQLITE_SCHEMA_PARITY_MIGRATION_PATH, SESSION_ADVISOR_ENABLED_MIGRATION_PATH, MISSION_FIX_IDEMPOTENCY_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_SCOPE_FIX_MIGRATION_PATH, IMPORT_TRANSLATION_CACHE_LEGACY_PARTITION_BACKFILL_MIGRATION_PATH, OWNER_PROJECT_ID_SPLIT_MIGRATION_PATH, CHAT_SESSION_PINS_MIGRATION_PATH, EXECUTOR_TOOL_FAILURE_RETRY_MIGRATION_PATH, EXECUTOR_ESCALATION_ATTEMPT_MIGRATION_PATH, GLOBAL_ROUTINES_MIGRATION_PATH, TASK_MERGER_MODEL_LANE_MIGRATION_PATH, BULK_COMPLETION_REFUSAL_AT_MIGRATION_PATH, TASK_PROPOSAL_CLAIM_MIGRATION_PATH, CONFIGURATION_REVISIONS_MIGRATION_PATH, IDEATION_MIGRATION_PATH, RESEARCH_FEATURE_PROVENANCE_MIGRATION_PATH, TASK_VERIFICATION_REQUEST_MIGRATION_PATH, SYMBOL_LOCKS_MIGRATION_PATH, BIGINT_COUNTERS_MIGRATION_PATH, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_VERSION, WORKFLOW_IR_PIN_AND_LEGACY_ADOPTION_MIGRATION_PATH, PLANNING_ACTIVE_TIMING_MIGRATION_PATH, TASK_DECLARED_SYMBOLS_MIGRATION_PATH, SQLITE_MIGRATION_RUNTIME_READ_PATH, WORKFLOW_TASK_CONTINUATIONS_PATH, LEGACY_ADOPTION_DRAINED_MARKER_RUNTIME_GRANTS_PATH, TASK_WEDGE_NOTIFICATION_MIGRATION_PATH, MILESTONE_ASSERTION_PROVENANCE_MIGRATION_PATH, MISSION_LINEAGE_STOP_MIGRATION_PATH, CHAT_SESSION_TAGS_MIGRATION_PATH;
|
|
36882
36924
|
var init_schema_applier = __esm({
|
|
36883
36925
|
"../core/src/postgres/schema-applier.ts"() {
|
|
36884
36926
|
"use strict";
|
|
36885
36927
|
init_drizzle_orm();
|
|
36886
36928
|
init_plugin_schema_hook();
|
|
36887
36929
|
init_advisory_locks();
|
|
36888
|
-
SCHEMA_BASELINE_VERSION = "
|
|
36930
|
+
SCHEMA_BASELINE_VERSION = "0036";
|
|
36889
36931
|
TASK_DECLARED_SYMBOLS_VERSION = "0028";
|
|
36890
36932
|
INITIAL_SCHEMA_VERSION = "0000";
|
|
36891
36933
|
AUTOMATION_ISOLATION_SCHEMA_VERSION = "0001";
|
|
@@ -36921,6 +36963,7 @@ var init_schema_applier = __esm({
|
|
|
36921
36963
|
TASK_WEDGE_NOTIFICATION_VERSION = "0033";
|
|
36922
36964
|
MILESTONE_ASSERTION_PROVENANCE_VERSION = "0034";
|
|
36923
36965
|
MISSION_LINEAGE_STOP_VERSION = "0035";
|
|
36966
|
+
CHAT_SESSION_TAGS_VERSION = "0036";
|
|
36924
36967
|
LEGACY_ADOPTION_DRAINED_MARKER_FUNCTION = "fusion_mark_legacy_adoption_drained";
|
|
36925
36968
|
StaleBinarySchemaError = class extends Error {
|
|
36926
36969
|
constructor(databaseVersion, binaryVersion) {
|
|
@@ -37036,6 +37079,7 @@ var init_schema_applier = __esm({
|
|
|
37036
37079
|
"0034_milestone_assertion_provenance.sql"
|
|
37037
37080
|
);
|
|
37038
37081
|
MISSION_LINEAGE_STOP_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0035_fn_8543_mission_lineage_stop.sql");
|
|
37082
|
+
CHAT_SESSION_TAGS_MIGRATION_PATH = join8(MIGRATIONS_DIR, "0036_chat_session_tags.sql");
|
|
37039
37083
|
}
|
|
37040
37084
|
});
|
|
37041
37085
|
|
|
@@ -63261,6 +63305,14 @@ function archiveEntryToTask(entry, slim = false) {
|
|
|
63261
63305
|
planningStartedAt: entry.planningStartedAt,
|
|
63262
63306
|
executionStartedAt: entry.executionStartedAt,
|
|
63263
63307
|
executionCompletedAt: entry.executionCompletedAt,
|
|
63308
|
+
/*
|
|
63309
|
+
FNXC:ArchiveLifecycle 2026-07-24-11:02:
|
|
63310
|
+
FN-8561 needs archived TaskCard completion fallback to use the immutable
|
|
63311
|
+
archive transition, not the pre-archive columnMovedAt snapshot or updatedAt.
|
|
63312
|
+
Preserve archivedAt on every slim and full archive read without changing
|
|
63313
|
+
restore persistence semantics.
|
|
63314
|
+
*/
|
|
63315
|
+
archivedAt: entry.archivedAt,
|
|
63264
63316
|
modelPresetId: entry.modelPresetId,
|
|
63265
63317
|
modelProvider: entry.modelProvider,
|
|
63266
63318
|
modelId: entry.modelId,
|
|
@@ -127002,9 +127054,14 @@ var init_org_bundle = __esm({
|
|
|
127002
127054
|
});
|
|
127003
127055
|
|
|
127004
127056
|
// ../core/src/async-chat-store.ts
|
|
127057
|
+
import { randomUUID as randomUUID41 } from "node:crypto";
|
|
127058
|
+
function rowToTag(row) {
|
|
127059
|
+
return { id: row.id, projectId: row.ownerProjectId === "__default__" ? null : row.ownerProjectId, name: row.name, createdAt: row.createdAt, updatedAt: row.updatedAt };
|
|
127060
|
+
}
|
|
127005
127061
|
function rowToSession3(row) {
|
|
127006
127062
|
return {
|
|
127007
127063
|
id: row.id,
|
|
127064
|
+
tags: [],
|
|
127008
127065
|
agentId: row.agentId,
|
|
127009
127066
|
title: row.title ?? null,
|
|
127010
127067
|
status: row.status,
|
|
@@ -127093,7 +127150,7 @@ async function createChatSession(handle, session) {
|
|
|
127093
127150
|
}
|
|
127094
127151
|
async function getChatSession(handle, id) {
|
|
127095
127152
|
const rows = await handle.select().from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
|
|
127096
|
-
return rows[0] ? rowToSession3(rows[0]) : void 0;
|
|
127153
|
+
return rows[0] ? attachTags(handle, rowToSession3(rows[0])) : void 0;
|
|
127097
127154
|
}
|
|
127098
127155
|
async function listChatSessions(handle, options) {
|
|
127099
127156
|
const conditions = [];
|
|
@@ -127102,12 +127159,104 @@ async function listChatSessions(handle, options) {
|
|
|
127102
127159
|
if (options?.status) conditions.push(eq(project_exports.chatSessions.status, options.status));
|
|
127103
127160
|
const query = handle.select().from(project_exports.chatSessions).orderBy(desc(project_exports.chatSessions.updatedAt));
|
|
127104
127161
|
const rows = conditions.length > 0 ? await query.where(and(...conditions)) : await query;
|
|
127105
|
-
return rows.map(rowToSession3);
|
|
127162
|
+
return attachTagsToSessions(handle, rows.map(rowToSession3));
|
|
127106
127163
|
}
|
|
127107
127164
|
async function deleteChatSession(handle, id) {
|
|
127108
|
-
const
|
|
127165
|
+
const [session] = await handle.select({ projectId: project_exports.chatSessions.projectId }).from(project_exports.chatSessions).where(eq(project_exports.chatSessions.id, id));
|
|
127166
|
+
if (!session) return false;
|
|
127167
|
+
const sessionProjectId = session.projectId;
|
|
127168
|
+
if (!sessionProjectId) throw new Error("Chat session is missing its required project partition");
|
|
127169
|
+
await handle.delete(project_exports.chatSessionTags).where(and(
|
|
127170
|
+
eq(project_exports.chatSessionTags.sessionId, id),
|
|
127171
|
+
eq(project_exports.chatSessionTags.projectId, sessionProjectId)
|
|
127172
|
+
));
|
|
127173
|
+
const result = await handle.delete(project_exports.chatSessions).where(and(eq(project_exports.chatSessions.id, id), eq(project_exports.chatSessions.projectId, sessionProjectId))).returning({ id: project_exports.chatSessions.id });
|
|
127109
127174
|
return result.length > 0;
|
|
127110
127175
|
}
|
|
127176
|
+
function tagScope(projectId) {
|
|
127177
|
+
return projectId ?? "__default__";
|
|
127178
|
+
}
|
|
127179
|
+
function normalizeTagName(name2) {
|
|
127180
|
+
const cleaned = name2.trim().replace(/\s+/g, " ");
|
|
127181
|
+
if (!cleaned || cleaned.length > 64) throw new Error("Tag name must be between 1 and 64 characters");
|
|
127182
|
+
return { name: cleaned, normalizedName: cleaned.toLocaleLowerCase() };
|
|
127183
|
+
}
|
|
127184
|
+
async function attachTags(handle, session) {
|
|
127185
|
+
const [attached] = await attachTagsToSessions(handle, [session]);
|
|
127186
|
+
return attached ?? session;
|
|
127187
|
+
}
|
|
127188
|
+
async function attachTagsToSessions(handle, sessions7) {
|
|
127189
|
+
if (!sessions7.length) return sessions7;
|
|
127190
|
+
const rows = await handle.select({ sessionId: project_exports.chatSessionTags.sessionId, id: project_exports.chatTags.id, ownerProjectId: project_exports.chatTags.ownerProjectId, name: project_exports.chatTags.name, createdAt: project_exports.chatTags.createdAt, updatedAt: project_exports.chatTags.updatedAt }).from(project_exports.chatSessionTags).innerJoin(project_exports.chatTags, and(
|
|
127191
|
+
eq(project_exports.chatSessionTags.tagId, project_exports.chatTags.id),
|
|
127192
|
+
eq(project_exports.chatSessionTags.projectId, project_exports.chatTags.projectId)
|
|
127193
|
+
)).innerJoin(project_exports.chatSessions, and(
|
|
127194
|
+
eq(project_exports.chatSessionTags.sessionId, project_exports.chatSessions.id),
|
|
127195
|
+
eq(project_exports.chatSessionTags.projectId, project_exports.chatSessions.projectId)
|
|
127196
|
+
)).where(inArray(project_exports.chatSessionTags.sessionId, sessions7.map((session) => session.id))).orderBy(asc(project_exports.chatTags.normalizedName), asc(project_exports.chatTags.id));
|
|
127197
|
+
const tagsBySession = /* @__PURE__ */ new Map();
|
|
127198
|
+
for (const row of rows) {
|
|
127199
|
+
const tags = tagsBySession.get(row.sessionId) ?? [];
|
|
127200
|
+
tags.push(rowToTag(row));
|
|
127201
|
+
tagsBySession.set(row.sessionId, tags);
|
|
127202
|
+
}
|
|
127203
|
+
return sessions7.map((session) => ({ ...session, tags: tagsBySession.get(session.id) ?? [] }));
|
|
127204
|
+
}
|
|
127205
|
+
async function listChatTags(handle, projectId) {
|
|
127206
|
+
const rows = await handle.select().from(project_exports.chatTags).where(eq(project_exports.chatTags.ownerProjectId, tagScope(projectId))).orderBy(asc(project_exports.chatTags.normalizedName), asc(project_exports.chatTags.id));
|
|
127207
|
+
return rows.map(rowToTag);
|
|
127208
|
+
}
|
|
127209
|
+
async function createChatTag(layer, input) {
|
|
127210
|
+
const { name: name2, normalizedName } = normalizeTagName(input.name);
|
|
127211
|
+
const projectId = input.projectId ?? null;
|
|
127212
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127213
|
+
return layer.transactionImmediate(async (tx) => {
|
|
127214
|
+
const id = `chat-tag-${randomUUID41().slice(0, 8)}`;
|
|
127215
|
+
const rows = await tx.insert(project_exports.chatTags).values({ id, ownerProjectId: tagScope(projectId), name: name2, normalizedName, createdAt: now, updatedAt: now }).onConflictDoNothing().returning();
|
|
127216
|
+
if (!rows[0]) throw new Error("A tag with that name already exists");
|
|
127217
|
+
return rowToTag(rows[0]);
|
|
127218
|
+
});
|
|
127219
|
+
}
|
|
127220
|
+
async function renameChatTag(layer, id, projectId, input) {
|
|
127221
|
+
const { name: name2, normalizedName } = normalizeTagName(input.name);
|
|
127222
|
+
return layer.transactionImmediate(async (tx) => {
|
|
127223
|
+
const rows = await tx.update(project_exports.chatTags).set({ name: name2, normalizedName, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.ownerProjectId, tagScope(projectId)))).returning();
|
|
127224
|
+
if (!rows[0]) return void 0;
|
|
127225
|
+
return rowToTag(rows[0]);
|
|
127226
|
+
});
|
|
127227
|
+
}
|
|
127228
|
+
async function deleteChatTag(layer, id, projectId) {
|
|
127229
|
+
return layer.transactionImmediate(async (tx) => {
|
|
127230
|
+
const [tag] = await tx.select({ projectId: project_exports.chatTags.projectId }).from(project_exports.chatTags).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.ownerProjectId, tagScope(projectId))));
|
|
127231
|
+
if (!tag?.projectId) return false;
|
|
127232
|
+
const tagProjectId = tag.projectId;
|
|
127233
|
+
await tx.delete(project_exports.chatSessionTags).where(and(
|
|
127234
|
+
eq(project_exports.chatSessionTags.tagId, id),
|
|
127235
|
+
eq(project_exports.chatSessionTags.projectId, tagProjectId)
|
|
127236
|
+
));
|
|
127237
|
+
return (await tx.delete(project_exports.chatTags).where(and(eq(project_exports.chatTags.id, id), eq(project_exports.chatTags.projectId, tagProjectId))).returning({ id: project_exports.chatTags.id })).length > 0;
|
|
127238
|
+
});
|
|
127239
|
+
}
|
|
127240
|
+
async function replaceChatSessionTags(layer, sessionId, projectId, tagIds) {
|
|
127241
|
+
return layer.transactionImmediate(async (tx) => {
|
|
127242
|
+
const session = await getChatSessionForUpdate(tx, sessionId);
|
|
127243
|
+
if (!session || session.projectId !== projectId) return void 0;
|
|
127244
|
+
const ownerProjectCondition = projectId === null ? isNull(project_exports.chatSessions.ownerProjectId) : eq(project_exports.chatSessions.ownerProjectId, projectId);
|
|
127245
|
+
const [sessionPartition] = await tx.select({ projectId: project_exports.chatSessions.projectId }).from(project_exports.chatSessions).where(and(eq(project_exports.chatSessions.id, sessionId), ownerProjectCondition)).for("update");
|
|
127246
|
+
if (!sessionPartition?.projectId) return void 0;
|
|
127247
|
+
const sessionProjectId = sessionPartition.projectId;
|
|
127248
|
+
const uniqueIds = [...new Set(tagIds)];
|
|
127249
|
+
const tags = uniqueIds.length ? await tx.select().from(project_exports.chatTags).where(and(
|
|
127250
|
+
inArray(project_exports.chatTags.id, uniqueIds),
|
|
127251
|
+
eq(project_exports.chatTags.ownerProjectId, tagScope(projectId)),
|
|
127252
|
+
eq(project_exports.chatTags.projectId, sessionProjectId)
|
|
127253
|
+
)) : [];
|
|
127254
|
+
if (tags.length !== uniqueIds.length) throw new Error("One or more tags do not belong to this project");
|
|
127255
|
+
await tx.delete(project_exports.chatSessionTags).where(and(eq(project_exports.chatSessionTags.sessionId, sessionId), eq(project_exports.chatSessionTags.projectId, sessionProjectId)));
|
|
127256
|
+
if (uniqueIds.length) await tx.insert(project_exports.chatSessionTags).values(uniqueIds.map((tagId) => ({ projectId: sessionProjectId, sessionId, tagId, assignedAt: (/* @__PURE__ */ new Date()).toISOString() }))).onConflictDoNothing();
|
|
127257
|
+
return attachTags(tx, session);
|
|
127258
|
+
});
|
|
127259
|
+
}
|
|
127111
127260
|
async function addChatMessage(handle, message) {
|
|
127112
127261
|
const sanitizedAttachments = message.attachments === void 0 ? void 0 : sanitizeJsonbValue(message.attachments);
|
|
127113
127262
|
const sanitized = {
|
|
@@ -127499,7 +127648,7 @@ var init_async_chat_store = __esm({
|
|
|
127499
127648
|
|
|
127500
127649
|
// ../core/src/chat-store.ts
|
|
127501
127650
|
import { EventEmitter as EventEmitter23 } from "node:events";
|
|
127502
|
-
import { randomUUID as
|
|
127651
|
+
import { randomUUID as randomUUID42 } from "node:crypto";
|
|
127503
127652
|
var ChatStore;
|
|
127504
127653
|
var init_chat_store = __esm({
|
|
127505
127654
|
"../core/src/chat-store.ts"() {
|
|
@@ -127534,8 +127683,9 @@ var init_chat_store = __esm({
|
|
|
127534
127683
|
async createSession(input) {
|
|
127535
127684
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127536
127685
|
const session = {
|
|
127537
|
-
id: `chat-${
|
|
127686
|
+
id: `chat-${randomUUID42().slice(0, 8)}`,
|
|
127538
127687
|
agentId: input.agentId,
|
|
127688
|
+
tags: [],
|
|
127539
127689
|
title: input.title ?? null,
|
|
127540
127690
|
status: "active",
|
|
127541
127691
|
projectId: input.projectId ?? null,
|
|
@@ -127705,6 +127855,29 @@ var init_chat_store = __esm({
|
|
|
127705
127855
|
}
|
|
127706
127856
|
return deletedCount;
|
|
127707
127857
|
}
|
|
127858
|
+
/*
|
|
127859
|
+
FNXC:ChatTags 2026-08-05-10:55:
|
|
127860
|
+
Direct-conversation tags are project-scoped by the session's owner project.
|
|
127861
|
+
Tag mutations are transactional and return an enriched session so SSE clients
|
|
127862
|
+
never receive an assignment update without its deterministic tag array.
|
|
127863
|
+
*/
|
|
127864
|
+
async listTags(projectId = null) {
|
|
127865
|
+
return listChatTags(this.asyncLayer.db, projectId);
|
|
127866
|
+
}
|
|
127867
|
+
async createTag(input) {
|
|
127868
|
+
return createChatTag(this.asyncLayer, input);
|
|
127869
|
+
}
|
|
127870
|
+
async renameTag(id, projectId, input) {
|
|
127871
|
+
return renameChatTag(this.asyncLayer, id, projectId, input);
|
|
127872
|
+
}
|
|
127873
|
+
async deleteTag(id, projectId) {
|
|
127874
|
+
return deleteChatTag(this.asyncLayer, id, projectId);
|
|
127875
|
+
}
|
|
127876
|
+
async replaceSessionTags(id, projectId, tagIds) {
|
|
127877
|
+
const updated = await replaceChatSessionTags(this.asyncLayer, id, projectId, tagIds);
|
|
127878
|
+
if (updated) this.emit("chat:session:updated", updated);
|
|
127879
|
+
return updated;
|
|
127880
|
+
}
|
|
127708
127881
|
// ── Message CRUD Operations ───────────────────────────────────────
|
|
127709
127882
|
/**
|
|
127710
127883
|
* Add a message to a chat session.
|
|
@@ -127721,7 +127894,7 @@ var init_chat_store = __esm({
|
|
|
127721
127894
|
}
|
|
127722
127895
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127723
127896
|
const message = {
|
|
127724
|
-
id: `msg-${
|
|
127897
|
+
id: `msg-${randomUUID42().slice(0, 8)}`,
|
|
127725
127898
|
sessionId,
|
|
127726
127899
|
role: input.role,
|
|
127727
127900
|
content: input.content,
|
|
@@ -127863,7 +128036,7 @@ var init_chat_store = __esm({
|
|
|
127863
128036
|
if (!slug) throw new Error("Room name must include letters or numbers");
|
|
127864
128037
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127865
128038
|
const room = {
|
|
127866
|
-
id: `room-${
|
|
128039
|
+
id: `room-${randomUUID42().slice(0, 8)}`,
|
|
127867
128040
|
name: normalizedName,
|
|
127868
128041
|
slug,
|
|
127869
128042
|
description: input.description ?? null,
|
|
@@ -127955,7 +128128,7 @@ var init_chat_store = __esm({
|
|
|
127955
128128
|
}
|
|
127956
128129
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
127957
128130
|
const message = {
|
|
127958
|
-
id: `rmsg-${
|
|
128131
|
+
id: `rmsg-${randomUUID42().slice(0, 8)}`,
|
|
127959
128132
|
roomId,
|
|
127960
128133
|
role: input.role,
|
|
127961
128134
|
content: input.content,
|
|
@@ -128010,7 +128183,7 @@ var init_chat_store = __esm({
|
|
|
128010
128183
|
return void 0;
|
|
128011
128184
|
}
|
|
128012
128185
|
const record2 = {
|
|
128013
|
-
id: `chat-tokens-${
|
|
128186
|
+
id: `chat-tokens-${randomUUID42().slice(0, 12)}`,
|
|
128014
128187
|
sourceKind: input.sourceKind,
|
|
128015
128188
|
chatSessionId: input.chatSessionId ?? null,
|
|
128016
128189
|
roomId: input.roomId ?? null,
|
|
@@ -128106,7 +128279,7 @@ var init_cli_session_types = __esm({
|
|
|
128106
128279
|
});
|
|
128107
128280
|
|
|
128108
128281
|
// ../core/src/cli-session-store.ts
|
|
128109
|
-
import { randomUUID as
|
|
128282
|
+
import { randomUUID as randomUUID43 } from "node:crypto";
|
|
128110
128283
|
import { EventEmitter as EventEmitter24 } from "node:events";
|
|
128111
128284
|
function parsePosture(value) {
|
|
128112
128285
|
return fromJson(value) ?? null;
|
|
@@ -128188,7 +128361,7 @@ var init_cli_session_store = __esm({
|
|
|
128188
128361
|
if (!input.adapterId) throw new Error("CLI session requires an adapterId");
|
|
128189
128362
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
128190
128363
|
const session = {
|
|
128191
|
-
id: input.id ?? `cli-${
|
|
128364
|
+
id: input.id ?? `cli-${randomUUID43().slice(0, 8)}`,
|
|
128192
128365
|
taskId: input.taskId ?? null,
|
|
128193
128366
|
chatSessionId: input.chatSessionId ?? null,
|
|
128194
128367
|
purpose: input.purpose,
|
|
@@ -128581,7 +128754,7 @@ var init_task_prefix = __esm({
|
|
|
128581
128754
|
});
|
|
128582
128755
|
|
|
128583
128756
|
// ../core/src/task-store/async-monitor.ts
|
|
128584
|
-
import { randomUUID as
|
|
128757
|
+
import { randomUUID as randomUUID44 } from "node:crypto";
|
|
128585
128758
|
function monitorProjectPartition(projectId) {
|
|
128586
128759
|
return projectId.trim() || "__legacy_unscoped__";
|
|
128587
128760
|
}
|
|
@@ -128625,7 +128798,7 @@ function incidentFromRow(row) {
|
|
|
128625
128798
|
}
|
|
128626
128799
|
async function recordDeploymentAsync(db, input, projectId = "") {
|
|
128627
128800
|
const ownerProjectId = monitorProjectPartition(projectId);
|
|
128628
|
-
const deploymentId = input.deploymentId?.trim() || `dep-${
|
|
128801
|
+
const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID44()}`;
|
|
128629
128802
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
128630
128803
|
const deployedAt = input.deployedAt ?? now;
|
|
128631
128804
|
await db.insert(project_exports.deployments).values({
|
|
@@ -128683,7 +128856,7 @@ async function ingestIncidentSignalAsync(db, input, projectId = "") {
|
|
|
128683
128856
|
const updated = await getIncidentAsync(db, existing.incidentId, ownerProjectId);
|
|
128684
128857
|
return { incident: updated ?? existing, created: false };
|
|
128685
128858
|
}
|
|
128686
|
-
const incidentId = `inc-${
|
|
128859
|
+
const incidentId = `inc-${randomUUID44()}`;
|
|
128687
128860
|
const meta2 = {
|
|
128688
128861
|
...input.meta ?? {},
|
|
128689
128862
|
[OCCURRENCES_META_KEY]: 1,
|
|
@@ -129271,6 +129444,7 @@ __export(src_exports, {
|
|
|
129271
129444
|
AGENT_PERMISSION_POLICY_PRESET_IDS: () => AGENT_PERMISSION_POLICY_PRESET_IDS,
|
|
129272
129445
|
AGENT_PROVISIONING_APPROVAL_MODES: () => AGENT_PROVISIONING_APPROVAL_MODES,
|
|
129273
129446
|
AGENT_VALID_TRANSITIONS: () => AGENT_VALID_TRANSITIONS,
|
|
129447
|
+
ANTHROPIC_AUTH_PREFERENCES: () => ANTHROPIC_AUTH_PREFERENCES,
|
|
129274
129448
|
ANTHROPIC_PROVIDER_ID: () => ANTHROPIC_PROVIDER_ID,
|
|
129275
129449
|
APPROVAL_REQUEST_AUDIT_EVENT_TYPES: () => APPROVAL_REQUEST_AUDIT_EVENT_TYPES,
|
|
129276
129450
|
APPROVAL_REQUEST_STATUSES: () => APPROVAL_REQUEST_STATUSES,
|
|
@@ -130910,7 +131084,7 @@ var init_src2 = __esm({
|
|
|
130910
131084
|
});
|
|
130911
131085
|
|
|
130912
131086
|
// ../dashboard/src/ai-session-diagnostics.ts
|
|
130913
|
-
import { randomUUID as
|
|
131087
|
+
import { randomUUID as randomUUID45 } from "node:crypto";
|
|
130914
131088
|
function defaultSink(level, scope, message, context) {
|
|
130915
131089
|
const prefix = `[${scope}]`;
|
|
130916
131090
|
const logArgs = [prefix, message, context];
|
|
@@ -130957,7 +131131,7 @@ function emit(level, scope, message, context) {
|
|
|
130957
131131
|
const fullContext = {
|
|
130958
131132
|
...context,
|
|
130959
131133
|
_emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
130960
|
-
_diagnosticsId:
|
|
131134
|
+
_diagnosticsId: randomUUID45()
|
|
130961
131135
|
};
|
|
130962
131136
|
try {
|
|
130963
131137
|
_sink(level, scope, message, fullContext);
|
|
@@ -134371,6 +134545,26 @@ function resolveStoredCredentialApiKey(providerId, credential) {
|
|
|
134371
134545
|
}
|
|
134372
134546
|
return void 0;
|
|
134373
134547
|
}
|
|
134548
|
+
function getFusionGlobalSettingsPath(home = getHomeDir5()) {
|
|
134549
|
+
const candidates = [
|
|
134550
|
+
join54(home, ".fusion", "settings.json"),
|
|
134551
|
+
join54(home, ".pi", "fusion", "settings.json"),
|
|
134552
|
+
join54(home, ".pi", "kb", "settings.json")
|
|
134553
|
+
];
|
|
134554
|
+
return candidates.find((candidate) => existsSync41(candidate)) ?? candidates[0];
|
|
134555
|
+
}
|
|
134556
|
+
function readAnthropicAuthPreference(home = getHomeDir5()) {
|
|
134557
|
+
const settingsPath = getFusionGlobalSettingsPath(home);
|
|
134558
|
+
if (!existsSync41(settingsPath)) {
|
|
134559
|
+
return "api-key";
|
|
134560
|
+
}
|
|
134561
|
+
try {
|
|
134562
|
+
const parsed = JSON.parse(readFileSync12(settingsPath, "utf-8"));
|
|
134563
|
+
return parsed?.anthropicAuthPreference === "subscription" ? "subscription" : "api-key";
|
|
134564
|
+
} catch {
|
|
134565
|
+
return "api-key";
|
|
134566
|
+
}
|
|
134567
|
+
}
|
|
134374
134568
|
function readModelsJsonApiKeys(home = getHomeDir5()) {
|
|
134375
134569
|
const apiKeys = /* @__PURE__ */ new Map();
|
|
134376
134570
|
const modelsPath = getModelRegistryModelsPath(home);
|
|
@@ -134576,11 +134770,15 @@ function createFusionAuthStorage() {
|
|
|
134576
134770
|
};
|
|
134577
134771
|
const resolveAnthropicRuntimeApiKey = async () => {
|
|
134578
134772
|
const rawProviderLoggedOut = isAnthropicRawProviderLoggedOut();
|
|
134579
|
-
|
|
134773
|
+
const preferSubscription = readAnthropicAuthPreference() === "subscription";
|
|
134774
|
+
const resolveRawApiKey = () => {
|
|
134775
|
+
if (rawProviderLoggedOut) return void 0;
|
|
134580
134776
|
const anthropicApiKeyCredential = selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "api_key");
|
|
134581
|
-
|
|
134582
|
-
|
|
134583
|
-
|
|
134777
|
+
return anthropicApiKeyCredential ? resolveStoredCredentialApiKey(ANTHROPIC_PROVIDER_ID2, anthropicApiKeyCredential) : void 0;
|
|
134778
|
+
};
|
|
134779
|
+
if (!preferSubscription) {
|
|
134780
|
+
const rawKey = resolveRawApiKey();
|
|
134781
|
+
if (rawKey) return rawKey;
|
|
134584
134782
|
}
|
|
134585
134783
|
const subscriptionLoggedOut = loggedOutProviders.has(ANTHROPIC_SUBSCRIPTION_PROVIDER_ID);
|
|
134586
134784
|
const legacyAnthropicOAuthCredential = rawProviderLoggedOut ? void 0 : selectStoredCredentialByType(ANTHROPIC_PROVIDER_ID2, "oauth");
|
|
@@ -134595,6 +134793,10 @@ function createFusionAuthStorage() {
|
|
|
134595
134793
|
if (subscriptionKey) return subscriptionKey;
|
|
134596
134794
|
}
|
|
134597
134795
|
}
|
|
134796
|
+
if (preferSubscription) {
|
|
134797
|
+
const rawKey = resolveRawApiKey();
|
|
134798
|
+
if (rawKey) return rawKey;
|
|
134799
|
+
}
|
|
134598
134800
|
if (!rawProviderLoggedOut) {
|
|
134599
134801
|
const modelsJsonApiKey = modelsJsonApiKeys.get(ANTHROPIC_PROVIDER_ID2);
|
|
134600
134802
|
if (modelsJsonApiKey) return modelsJsonApiKey;
|
|
@@ -161773,8 +161975,12 @@ var init_provider_registry = __esm({
|
|
|
161773
161975
|
const maxResults = Number(this.settings.researchGlobalMaxSearchResults ?? 10);
|
|
161774
161976
|
const fetchTimeoutMs = Number(this.settings.researchGlobalFetchTimeoutMs ?? 3e4);
|
|
161775
161977
|
const userAgent = this.settings.researchGlobalUserAgent ?? "FusionResearchBot/1.0";
|
|
161776
|
-
const
|
|
161777
|
-
|
|
161978
|
+
const researchSynthesisPair = this.settings.researchGlobalDefaults?.synthesisProvider && this.settings.researchGlobalDefaults?.synthesisModelId ? {
|
|
161979
|
+
provider: this.settings.researchGlobalDefaults.synthesisProvider,
|
|
161980
|
+
modelId: this.settings.researchGlobalDefaults.synthesisModelId
|
|
161981
|
+
} : void 0;
|
|
161982
|
+
const synthesisProvider = researchSynthesisPair?.provider ?? this.settings.defaultProvider;
|
|
161983
|
+
const synthesisModelId = researchSynthesisPair?.modelId ?? this.settings.defaultModelId;
|
|
161778
161984
|
this.providers = /* @__PURE__ */ new Map([
|
|
161779
161985
|
[
|
|
161780
161986
|
"web-search",
|
|
@@ -169339,7 +169545,7 @@ var init_code_node_runner = __esm({
|
|
|
169339
169545
|
// ../engine/src/agent-tools.ts
|
|
169340
169546
|
import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile31, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile25 } from "node:fs/promises";
|
|
169341
169547
|
import { existsSync as existsSync50 } from "node:fs";
|
|
169342
|
-
import { createHash as createHash16, randomUUID as
|
|
169548
|
+
import { createHash as createHash16, randomUUID as randomUUID46 } from "node:crypto";
|
|
169343
169549
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
169344
169550
|
import { extname as extname3, isAbsolute as isAbsolute12, join as join64, relative as relative11, resolve as resolve32, sep as sep9 } from "node:path";
|
|
169345
169551
|
import { Type as Type2 } from "@earendil-works/pi-ai";
|
|
@@ -169946,7 +170152,7 @@ function createTaskCreateTool(store, provenance, options) {
|
|
|
169946
170152
|
toType: "user",
|
|
169947
170153
|
type: "agent-to-user",
|
|
169948
170154
|
content: `Task proposal awaiting validation: ${title2}`,
|
|
169949
|
-
metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey:
|
|
170155
|
+
metadata: { kind: "task-proposal", proposalStatus: "pending", proposalIdempotencyKey: randomUUID46(), taskId: options.sourceTaskId, proposedTask: { title: title2, description: params.description, priority: params.priority, workflowId: params.workflow_id, dependencies: params.dependencies } }
|
|
169950
170156
|
});
|
|
169951
170157
|
return { content: [{ type: "text", text: "Task proposal submitted to the operator for validation; no task was created." }], details: { proposed: true } };
|
|
169952
170158
|
}
|
|
@@ -244052,6 +244258,7 @@ var init_agent_reflection = __esm({
|
|
|
244052
244258
|
"../engine/src/agent-reflection.ts"() {
|
|
244053
244259
|
"use strict";
|
|
244054
244260
|
init_logger3();
|
|
244261
|
+
init_src2();
|
|
244055
244262
|
init_pi();
|
|
244056
244263
|
init_mcp_resolution();
|
|
244057
244264
|
init_run_audit();
|
|
@@ -244092,6 +244299,22 @@ Rules:
|
|
|
244092
244299
|
this.modelProvider = options.modelProvider;
|
|
244093
244300
|
this.modelId = options.modelId;
|
|
244094
244301
|
}
|
|
244302
|
+
async resolveReflectionModel() {
|
|
244303
|
+
if (this.modelProvider && this.modelId) {
|
|
244304
|
+
return { provider: this.modelProvider, modelId: this.modelId };
|
|
244305
|
+
}
|
|
244306
|
+
try {
|
|
244307
|
+
const settings = await this.taskStore.getSettings();
|
|
244308
|
+
const resolved = resolveProjectDefaultModel(settings);
|
|
244309
|
+
if (resolved.provider && resolved.modelId) {
|
|
244310
|
+
return { provider: resolved.provider, modelId: resolved.modelId };
|
|
244311
|
+
}
|
|
244312
|
+
} catch (error2) {
|
|
244313
|
+
reflectionLog.warn(`Failed to resolve reflection model from settings: ${String(error2)}`);
|
|
244314
|
+
}
|
|
244315
|
+
reflectionLog.warn("No provider/model pair resolved for reflection; the runtime will use its built-in default model");
|
|
244316
|
+
return {};
|
|
244317
|
+
}
|
|
244095
244318
|
async generateReflection(agentId, trigger, options = {}) {
|
|
244096
244319
|
const runContext = {
|
|
244097
244320
|
runId: generateSyntheticRunId("reflection", agentId),
|
|
@@ -244112,12 +244335,12 @@ Rules:
|
|
|
244112
244335
|
return null;
|
|
244113
244336
|
}
|
|
244114
244337
|
let responseText = "";
|
|
244338
|
+
const reflectionModel = await this.resolveReflectionModel();
|
|
244115
244339
|
const { session } = await createFnAgent2({
|
|
244116
244340
|
cwd: this.rootDir,
|
|
244117
244341
|
systemPrompt: REFLECTION_SYSTEM_PROMPT,
|
|
244118
244342
|
tools: "readonly",
|
|
244119
|
-
defaultProvider:
|
|
244120
|
-
defaultModelId: this.modelId,
|
|
244343
|
+
...reflectionModel.provider && reflectionModel.modelId ? { defaultProvider: reflectionModel.provider, defaultModelId: reflectionModel.modelId } : {},
|
|
244121
244344
|
mcpServers: (await resolveMcpServersForStore(this.taskStore, { agentId })).servers,
|
|
244122
244345
|
onText: (delta) => {
|
|
244123
244346
|
responseText += delta;
|
|
@@ -245190,7 +245413,7 @@ var init_metric_parser = __esm({
|
|
|
245190
245413
|
});
|
|
245191
245414
|
|
|
245192
245415
|
// ../engine/src/experiment-executor.ts
|
|
245193
|
-
import { randomUUID as
|
|
245416
|
+
import { randomUUID as randomUUID47 } from "node:crypto";
|
|
245194
245417
|
var ExperimentMaxIterationsError, ExperimentGitNotConfiguredError, ExperimentExecutor;
|
|
245195
245418
|
var init_experiment_executor = __esm({
|
|
245196
245419
|
"../engine/src/experiment-executor.ts"() {
|
|
@@ -245258,7 +245481,7 @@ var init_experiment_executor = __esm({
|
|
|
245258
245481
|
}
|
|
245259
245482
|
await this.semaphore.acquire();
|
|
245260
245483
|
const controller = new AbortController();
|
|
245261
|
-
const runHandle =
|
|
245484
|
+
const runHandle = randomUUID47();
|
|
245262
245485
|
if (opts?.abortSignal) {
|
|
245263
245486
|
opts.abortSignal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
245264
245487
|
}
|
|
@@ -263983,8 +264206,19 @@ __export(planning_exports, {
|
|
|
263983
264206
|
updatePlanningSessionTitle: () => updatePlanningSessionTitle,
|
|
263984
264207
|
validateSession: () => validateSession
|
|
263985
264208
|
});
|
|
263986
|
-
import { randomUUID as
|
|
264209
|
+
import { randomUUID as randomUUID48 } from "node:crypto";
|
|
263987
264210
|
import { EventEmitter as EventEmitter34 } from "node:events";
|
|
264211
|
+
async function createPlanningRuntimeSession(options) {
|
|
264212
|
+
const { pluginRunner, runtimeHint, settings, ...runtimeOptions } = options ?? {};
|
|
264213
|
+
const create = createResolvedAgentSession ?? createResolvedAgentSession;
|
|
264214
|
+
return create({
|
|
264215
|
+
sessionPurpose: "executor",
|
|
264216
|
+
...runtimeHint ? { runtimeHint } : {},
|
|
264217
|
+
...pluginRunner ? { pluginRunner } : {},
|
|
264218
|
+
...settings ? { settings } : {},
|
|
264219
|
+
...runtimeOptions
|
|
264220
|
+
});
|
|
264221
|
+
}
|
|
263988
264222
|
function isThinkingLevel(value) {
|
|
263989
264223
|
return THINKING_LEVELS.includes(value);
|
|
263990
264224
|
}
|
|
@@ -264436,7 +264670,7 @@ async function createSession(ip, initialPlan, store, rootDir, promptOverrides, p
|
|
|
264436
264670
|
if (!store) {
|
|
264437
264671
|
throw new Error("store is required for AI-powered planning sessions");
|
|
264438
264672
|
}
|
|
264439
|
-
const sessionId =
|
|
264673
|
+
const sessionId = randomUUID48();
|
|
264440
264674
|
const session = {
|
|
264441
264675
|
id: sessionId,
|
|
264442
264676
|
ip,
|
|
@@ -264475,6 +264709,7 @@ async function runCreateSessionFirstTurn(session, rootDir, store, promptOverride
|
|
|
264475
264709
|
await ensureEngineReady();
|
|
264476
264710
|
}
|
|
264477
264711
|
const skillContext = buildSessionSkillContextSync(null, "executor", rootDir, pluginRunner);
|
|
264712
|
+
const { provider: startProvider, modelId: startModelId } = await resolveSessionPlanningModel(session, store);
|
|
264478
264713
|
const agentResult = await createFnAgent4({
|
|
264479
264714
|
cwd: rootDir,
|
|
264480
264715
|
systemPrompt,
|
|
@@ -264498,6 +264733,8 @@ async function runCreateSessionFirstTurn(session, rootDir, store, promptOverride
|
|
|
264498
264733
|
...createChatTaskDocumentTools(store),
|
|
264499
264734
|
createChatTaskLogsReadTool(store)
|
|
264500
264735
|
],
|
|
264736
|
+
...startProvider && startModelId ? { defaultProvider: startProvider, defaultModelId: startModelId } : {},
|
|
264737
|
+
...pluginRunner ? { pluginRunner } : {},
|
|
264501
264738
|
onThinking: () => {
|
|
264502
264739
|
},
|
|
264503
264740
|
onText: () => {
|
|
@@ -264648,7 +264885,7 @@ async function createDraftSession(ip, initialPlan, _rootDir, modelProvider, mode
|
|
|
264648
264885
|
`Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR} planning sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
|
|
264649
264886
|
);
|
|
264650
264887
|
}
|
|
264651
|
-
const sessionId =
|
|
264888
|
+
const sessionId = randomUUID48();
|
|
264652
264889
|
const title2 = DRAFT_PLACEHOLDER_TITLE;
|
|
264653
264890
|
const hasModelOverride = Boolean(modelProvider && modelId);
|
|
264654
264891
|
const session = {
|
|
@@ -264824,7 +265061,7 @@ async function createSessionWithAgent(ip, initialPlan, rootDir, store, modelProv
|
|
|
264824
265061
|
`Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR} planning sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
|
|
264825
265062
|
);
|
|
264826
265063
|
}
|
|
264827
|
-
const sessionId =
|
|
265064
|
+
const sessionId = randomUUID48();
|
|
264828
265065
|
const session = {
|
|
264829
265066
|
id: sessionId,
|
|
264830
265067
|
ip,
|
|
@@ -264969,6 +265206,8 @@ async function createPlanningAgent(session, rootDir, store, modelProvider, model
|
|
|
264969
265206
|
defaultModelId: modelId
|
|
264970
265207
|
} : {},
|
|
264971
265208
|
...thinkingLevel ? { defaultThinkingLevel: thinkingLevel } : {},
|
|
265209
|
+
// Runtime resolution needs the plugin runner to see plugin-provided runtimes.
|
|
265210
|
+
...pluginRunner ? { pluginRunner } : {},
|
|
264972
265211
|
onThinking: (delta) => {
|
|
264973
265212
|
if (callbacksInvalidated()) return;
|
|
264974
265213
|
markPlanningGenerationProgress(session.id, delta);
|
|
@@ -265002,6 +265241,31 @@ function buildHistoryReplayPrompt(history) {
|
|
|
265002
265241
|
"Treat every recorded selection and Other answer as an accumulated durable decision. Rebuild affected plan fields around those decisions; do not preserve superseded or unselected alternatives as the plan backbone. Use this as context for the next response. Do not repeat prior questions unless necessary."
|
|
265003
265242
|
].join("\n\n");
|
|
265004
265243
|
}
|
|
265244
|
+
async function resolveSessionPlanningModel(session, store) {
|
|
265245
|
+
if (session.draftModelProvider && session.draftModelId) {
|
|
265246
|
+
return { provider: session.draftModelProvider, modelId: session.draftModelId };
|
|
265247
|
+
}
|
|
265248
|
+
try {
|
|
265249
|
+
const settings = await store.getSettings();
|
|
265250
|
+
const resolved = resolvePlanningSettingsModel(settings);
|
|
265251
|
+
if (resolved.provider && resolved.modelId) {
|
|
265252
|
+
session.draftModelProvider = resolved.provider;
|
|
265253
|
+
session.draftModelId = resolved.modelId;
|
|
265254
|
+
return { provider: resolved.provider, modelId: resolved.modelId };
|
|
265255
|
+
}
|
|
265256
|
+
} catch (err) {
|
|
265257
|
+
diagnostics2.warn("Failed to resolve planning model for rebuilt agent", {
|
|
265258
|
+
sessionId: session.id,
|
|
265259
|
+
operation: "resolve-session-planning-model",
|
|
265260
|
+
error: String(err)
|
|
265261
|
+
});
|
|
265262
|
+
}
|
|
265263
|
+
diagnostics2.warn(
|
|
265264
|
+
"Rebuilt planning agent has no resolved provider/model pair; the runtime will use its built-in default model",
|
|
265265
|
+
{ sessionId: session.id, operation: "resolve-session-planning-model" }
|
|
265266
|
+
);
|
|
265267
|
+
return {};
|
|
265268
|
+
}
|
|
265005
265269
|
async function ensureSessionAgent(session, rootDir, historyForReplay, promptOverrides, store) {
|
|
265006
265270
|
if (session.agent) {
|
|
265007
265271
|
return;
|
|
@@ -265018,7 +265282,20 @@ async function ensureSessionAgent(session, rootDir, historyForReplay, promptOver
|
|
|
265018
265282
|
"Planning session has no task store and cannot be resumed without project context"
|
|
265019
265283
|
);
|
|
265020
265284
|
}
|
|
265021
|
-
|
|
265285
|
+
const { provider: resumeProvider, modelId: resumeModelId } = await resolveSessionPlanningModel(
|
|
265286
|
+
session,
|
|
265287
|
+
effectiveStore
|
|
265288
|
+
);
|
|
265289
|
+
session.agent = await createPlanningAgent(
|
|
265290
|
+
session,
|
|
265291
|
+
effectiveRootDir,
|
|
265292
|
+
effectiveStore,
|
|
265293
|
+
resumeProvider,
|
|
265294
|
+
resumeModelId,
|
|
265295
|
+
session.draftThinkingLevel,
|
|
265296
|
+
promptOverrides,
|
|
265297
|
+
session.pluginRunner
|
|
265298
|
+
);
|
|
265022
265299
|
if (historyForReplay.length === 0) {
|
|
265023
265300
|
return;
|
|
265024
265301
|
}
|
|
@@ -265294,7 +265571,7 @@ function normalizePlanningQuestion(input, userInput = "") {
|
|
|
265294
265571
|
const type = source.type === "multi_select" || source.type === "single_select" ? source.type : "single_select";
|
|
265295
265572
|
const question = typeof source.question === "string" && source.question.trim() ? source.question.trim() : fallback2.question;
|
|
265296
265573
|
const normalized = {
|
|
265297
|
-
id: typeof source.id === "string" && source.id.trim() ? source.id :
|
|
265574
|
+
id: typeof source.id === "string" && source.id.trim() ? source.id : randomUUID48(),
|
|
265298
265575
|
type,
|
|
265299
265576
|
question,
|
|
265300
265577
|
...typeof source.description === "string" && source.description.trim() ? { description: source.description.trim() } : {}
|
|
@@ -265320,7 +265597,7 @@ function normalizePlanningQuestion(input, userInput = "") {
|
|
|
265320
265597
|
}
|
|
265321
265598
|
function coerceQuestionResponse(response, session) {
|
|
265322
265599
|
if (response.type === "question") return normalizePlanningQuestion(response.data, session.initialPlan);
|
|
265323
|
-
return normalizePlanningQuestion({ id:
|
|
265600
|
+
return normalizePlanningQuestion({ id: randomUUID48(), type: "single_select", question: planningFallbackCopy(session.initialPlan).question }, session.initialPlan);
|
|
265324
265601
|
}
|
|
265325
265602
|
async function validateSession(sessionId) {
|
|
265326
265603
|
const session = await getSession(sessionId);
|
|
@@ -266250,7 +266527,7 @@ async function createTaskFromPlanSession(sessionId, store, options) {
|
|
|
266250
266527
|
throw new InvalidSessionStateError("PLANNING_CREATED_TASK_MISSING");
|
|
266251
266528
|
}
|
|
266252
266529
|
}
|
|
266253
|
-
const claimOwnerToken =
|
|
266530
|
+
const claimOwnerToken = randomUUID48();
|
|
266254
266531
|
let claimed = await claimPlanningTaskCreation(sessionId, claimOwnerToken, (/* @__PURE__ */ new Date()).toISOString(), claimEpoch);
|
|
266255
266532
|
if (!claimed) {
|
|
266256
266533
|
session = await getDurablePlanningSession(sessionId).catch(() => void 0) ?? session;
|
|
@@ -266545,7 +266822,7 @@ var init_planning = __esm({
|
|
|
266545
266822
|
init_planning_board_tools();
|
|
266546
266823
|
PLANNING_NO_AMBIENT_TASK_ID = "";
|
|
266547
266824
|
PLANNING_BUILTIN_WEB_TOOLS = ["WebSearch", "WebFetch"];
|
|
266548
|
-
createFnAgent4 =
|
|
266825
|
+
createFnAgent4 = createPlanningRuntimeSession;
|
|
266549
266826
|
diagnostics2 = createSessionDiagnostics("planning");
|
|
266550
266827
|
PLANNING_SYSTEM_PROMPT = `## Collaborative Planning Mode
|
|
266551
266828
|
|
|
@@ -266845,6 +267122,37 @@ var init_ai_session_timeout = __esm({
|
|
|
266845
267122
|
}
|
|
266846
267123
|
});
|
|
266847
267124
|
|
|
267125
|
+
// ../dashboard/src/lane-session-model.ts
|
|
267126
|
+
function laneModelOptions(model) {
|
|
267127
|
+
return model.provider && model.modelId ? { defaultProvider: model.provider, defaultModelId: model.modelId } : {};
|
|
267128
|
+
}
|
|
267129
|
+
async function resolveLaneSessionModel(store, cached2, onUnresolved) {
|
|
267130
|
+
if (cached2?.provider && cached2?.modelId) {
|
|
267131
|
+
return { provider: cached2.provider, modelId: cached2.modelId };
|
|
267132
|
+
}
|
|
267133
|
+
if (!store) {
|
|
267134
|
+
onUnresolved?.("no-store");
|
|
267135
|
+
return {};
|
|
267136
|
+
}
|
|
267137
|
+
try {
|
|
267138
|
+
const settings = await store.getSettings();
|
|
267139
|
+
const resolved = resolvePlanningSettingsModel(settings);
|
|
267140
|
+
if (resolved.provider && resolved.modelId) {
|
|
267141
|
+
return { provider: resolved.provider, modelId: resolved.modelId };
|
|
267142
|
+
}
|
|
267143
|
+
onUnresolved?.("unset");
|
|
267144
|
+
} catch (error2) {
|
|
267145
|
+
onUnresolved?.("error", error2);
|
|
267146
|
+
}
|
|
267147
|
+
return {};
|
|
267148
|
+
}
|
|
267149
|
+
var init_lane_session_model = __esm({
|
|
267150
|
+
"../dashboard/src/lane-session-model.ts"() {
|
|
267151
|
+
"use strict";
|
|
267152
|
+
init_src2();
|
|
267153
|
+
}
|
|
267154
|
+
});
|
|
267155
|
+
|
|
266848
267156
|
// ../dashboard/src/subtask-breakdown.ts
|
|
266849
267157
|
var subtask_breakdown_exports = {};
|
|
266850
267158
|
__export(subtask_breakdown_exports, {
|
|
@@ -266868,7 +267176,7 @@ __export(subtask_breakdown_exports, {
|
|
|
266868
267176
|
stopSubtaskGeneration: () => stopSubtaskGeneration,
|
|
266869
267177
|
subtaskStreamManager: () => subtaskStreamManager
|
|
266870
267178
|
});
|
|
266871
|
-
import { randomUUID as
|
|
267179
|
+
import { randomUUID as randomUUID49 } from "node:crypto";
|
|
266872
267180
|
import { EventEmitter as EventEmitter35 } from "node:events";
|
|
266873
267181
|
function __getSubtaskBreakdownDiagnostics() {
|
|
266874
267182
|
return diagnostics3;
|
|
@@ -267022,7 +267330,8 @@ async function decomposeForTriage(description, rootDir, promptOverrides, store)
|
|
|
267022
267330
|
return generateFallbackSubtasks(description);
|
|
267023
267331
|
}
|
|
267024
267332
|
const mcpServers = (await resolveMcpServersForStore(store ?? {})).servers;
|
|
267025
|
-
const
|
|
267333
|
+
const subtaskModel = await resolveLaneSessionModel(store);
|
|
267334
|
+
const agent = await createFnAgent5({ cwd, systemPrompt, tools: "readonly", mcpServers, ...laneModelOptions(subtaskModel) });
|
|
267026
267335
|
try {
|
|
267027
267336
|
await agent.session.prompt(description);
|
|
267028
267337
|
const messages3 = agent.session.state.messages;
|
|
@@ -267042,7 +267351,7 @@ async function decomposeForTriage(description, rootDir, promptOverrides, store)
|
|
|
267042
267351
|
}
|
|
267043
267352
|
}
|
|
267044
267353
|
async function createSubtaskSession(initialDescription, store, rootDir, promptOverrides, projectId) {
|
|
267045
|
-
const sessionId =
|
|
267354
|
+
const sessionId = randomUUID49();
|
|
267046
267355
|
const session = {
|
|
267047
267356
|
sessionId,
|
|
267048
267357
|
projectId,
|
|
@@ -267107,11 +267416,13 @@ async function generateSubtasks(sessionId, cwd, promptOverrides, store) {
|
|
|
267107
267416
|
},
|
|
267108
267417
|
async (abortSignal) => {
|
|
267109
267418
|
const mcpServers = (await resolveMcpServersForStore(store ?? {})).servers;
|
|
267419
|
+
const streamingModel = await resolveLaneSessionModel(store);
|
|
267110
267420
|
const agentPromise = createFnAgent5({
|
|
267111
267421
|
cwd,
|
|
267112
267422
|
systemPrompt,
|
|
267113
267423
|
tools: "readonly",
|
|
267114
267424
|
mcpServers,
|
|
267425
|
+
...laneModelOptions(streamingModel),
|
|
267115
267426
|
onThinking: (delta) => {
|
|
267116
267427
|
const current = sessions2.get(sessionId);
|
|
267117
267428
|
if (!current) return;
|
|
@@ -267325,6 +267636,7 @@ var init_subtask_breakdown = __esm({
|
|
|
267325
267636
|
init_process_lifecycle();
|
|
267326
267637
|
init_ai_session_diagnostics();
|
|
267327
267638
|
init_ai_session_timeout();
|
|
267639
|
+
init_lane_session_model();
|
|
267328
267640
|
init_src5();
|
|
267329
267641
|
createFnAgent5 = createFnAgent2;
|
|
267330
267642
|
diagnostics3 = createSessionDiagnostics("subtask-breakdown");
|
|
@@ -267476,7 +267788,7 @@ __export(mission_interview_exports, {
|
|
|
267476
267788
|
stopMissionInterviewGeneration: () => stopMissionInterviewGeneration,
|
|
267477
267789
|
submitMissionInterviewResponse: () => submitMissionInterviewResponse
|
|
267478
267790
|
});
|
|
267479
|
-
import { randomUUID as
|
|
267791
|
+
import { randomUUID as randomUUID50 } from "node:crypto";
|
|
267480
267792
|
import { EventEmitter as EventEmitter36 } from "node:events";
|
|
267481
267793
|
function __getMissionInterviewDiagnostics() {
|
|
267482
267794
|
return diagnostics4;
|
|
@@ -268219,7 +268531,7 @@ async function createMissionInterviewSession(ip, missionTitle, rootDir, store, p
|
|
|
268219
268531
|
`Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR2} sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
|
|
268220
268532
|
);
|
|
268221
268533
|
}
|
|
268222
|
-
const sessionId =
|
|
268534
|
+
const sessionId = randomUUID50();
|
|
268223
268535
|
const session = {
|
|
268224
268536
|
id: sessionId,
|
|
268225
268537
|
ip,
|
|
@@ -268682,7 +268994,7 @@ __export(milestone_slice_interview_exports, {
|
|
|
268682
268994
|
stopMilestoneSliceInterviewGeneration: () => stopMilestoneSliceInterviewGeneration,
|
|
268683
268995
|
submitTargetInterviewResponse: () => submitTargetInterviewResponse
|
|
268684
268996
|
});
|
|
268685
|
-
import { randomUUID as
|
|
268997
|
+
import { randomUUID as randomUUID51 } from "node:crypto";
|
|
268686
268998
|
import { EventEmitter as EventEmitter37 } from "node:events";
|
|
268687
268999
|
function parseTargetInterviewResponseImpl(text3) {
|
|
268688
269000
|
const candidate = extractJsonCandidate3(text3);
|
|
@@ -269016,11 +269328,19 @@ async function createTargetInterviewAgent(session, rootDir, store, pluginRunner)
|
|
|
269016
269328
|
await ensureEngineReady4();
|
|
269017
269329
|
const skillContext = buildSessionSkillContextSync(null, "executor", rootDir, pluginRunner);
|
|
269018
269330
|
const mcpServers = (await resolveMcpServersForStore(store)).servers;
|
|
269331
|
+
const model = await resolveLaneSessionModel(
|
|
269332
|
+
store,
|
|
269333
|
+
{ provider: session.modelProvider, modelId: session.modelId },
|
|
269334
|
+
(reason) => diagnostics5.warn("Milestone/slice interview has no resolved provider/model pair; the runtime will use its built-in default model", { sessionId: session.id, operation: "resolve-interview-model", reason })
|
|
269335
|
+
);
|
|
269336
|
+
session.modelProvider = model.provider;
|
|
269337
|
+
session.modelId = model.modelId;
|
|
269019
269338
|
return createFnAgent7({
|
|
269020
269339
|
cwd: rootDir,
|
|
269021
269340
|
systemPrompt: getSystemPrompt(session.targetType),
|
|
269022
269341
|
tools: "readonly",
|
|
269023
269342
|
mcpServers,
|
|
269343
|
+
...laneModelOptions(model),
|
|
269024
269344
|
allowMcpToolsInReadonly: true,
|
|
269025
269345
|
customTools: [...createPlanningBoardTools(store)],
|
|
269026
269346
|
/*
|
|
@@ -269303,7 +269623,7 @@ async function createTargetInterviewSession(ip, targetType, targetId, targetTitl
|
|
|
269303
269623
|
`Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR3} sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
|
|
269304
269624
|
);
|
|
269305
269625
|
}
|
|
269306
|
-
const sessionId =
|
|
269626
|
+
const sessionId = randomUUID51();
|
|
269307
269627
|
const session = {
|
|
269308
269628
|
id: sessionId,
|
|
269309
269629
|
ip,
|
|
@@ -269548,6 +269868,7 @@ var init_milestone_slice_interview = __esm({
|
|
|
269548
269868
|
init_mission_interview();
|
|
269549
269869
|
init_src5();
|
|
269550
269870
|
init_planning_board_tools();
|
|
269871
|
+
init_lane_session_model();
|
|
269551
269872
|
diagnostics5 = createSessionDiagnostics("milestone-slice-interview");
|
|
269552
269873
|
createFnAgent7 = createFnAgent2;
|
|
269553
269874
|
SESSION_TTL_MS4 = 7 * 24 * 60 * 60 * 1e3;
|
|
@@ -279183,16 +279504,8 @@ function getHeadBranch(taskId) {
|
|
|
279183
279504
|
return `fusion/${taskId.toLowerCase()}`;
|
|
279184
279505
|
}
|
|
279185
279506
|
function getDefaultSessionModel(settings) {
|
|
279186
|
-
|
|
279187
|
-
|
|
279188
|
-
provider: settings.defaultProviderOverride,
|
|
279189
|
-
modelId: settings.defaultModelIdOverride
|
|
279190
|
-
};
|
|
279191
|
-
}
|
|
279192
|
-
return {
|
|
279193
|
-
provider: settings.defaultProvider,
|
|
279194
|
-
modelId: settings.defaultModelId
|
|
279195
|
-
};
|
|
279507
|
+
const resolved = resolveProjectDefaultModel(settings);
|
|
279508
|
+
return resolved.provider && resolved.modelId ? { provider: resolved.provider, modelId: resolved.modelId } : { provider: void 0, modelId: void 0 };
|
|
279196
279509
|
}
|
|
279197
279510
|
async function pathExists(path14) {
|
|
279198
279511
|
try {
|
|
@@ -279423,6 +279736,7 @@ var GIT_TIMEOUT_MS10, SESSION_PROMPT;
|
|
|
279423
279736
|
var init_pr_conflict_resolver = __esm({
|
|
279424
279737
|
"../dashboard/src/pr-conflict-resolver.ts"() {
|
|
279425
279738
|
"use strict";
|
|
279739
|
+
init_src2();
|
|
279426
279740
|
init_src5();
|
|
279427
279741
|
init_resolve_diff_base();
|
|
279428
279742
|
GIT_TIMEOUT_MS10 = 6e4;
|
|
@@ -279783,11 +280097,13 @@ async function refineText(text3, type, rootDir, promptOverrides, store) {
|
|
|
279783
280097
|
}
|
|
279784
280098
|
const effectivePrompt = resolvePrompt("ai-refine-system", promptOverrides);
|
|
279785
280099
|
const mcpServers = (await resolveMcpServersForStore(store ?? {})).servers;
|
|
280100
|
+
const refineModel = await resolveLaneSessionModel(store);
|
|
279786
280101
|
const agentResult = await createFnAgent8({
|
|
279787
280102
|
cwd: rootDir,
|
|
279788
280103
|
systemPrompt: effectivePrompt,
|
|
279789
280104
|
tools: "readonly",
|
|
279790
|
-
mcpServers
|
|
280105
|
+
mcpServers,
|
|
280106
|
+
...laneModelOptions(refineModel)
|
|
279791
280107
|
});
|
|
279792
280108
|
if (!agentResult?.session) {
|
|
279793
280109
|
throw new AiServiceError3("Failed to initialize AI agent");
|
|
@@ -279826,11 +280142,13 @@ async function draftGoalDescription(title2, rootDir, _promptOverrides, store) {
|
|
|
279826
280142
|
throw new AiServiceError3("AI engine not available");
|
|
279827
280143
|
}
|
|
279828
280144
|
const mcpServers = (await resolveMcpServersForStore(store ?? {})).servers;
|
|
280145
|
+
const goalDraftModel = await resolveLaneSessionModel(store);
|
|
279829
280146
|
const agentResult = await createFnAgent8({
|
|
279830
280147
|
cwd: rootDir,
|
|
279831
280148
|
systemPrompt: GOAL_DRAFT_SYSTEM_PROMPT,
|
|
279832
280149
|
tools: "readonly",
|
|
279833
|
-
mcpServers
|
|
280150
|
+
mcpServers,
|
|
280151
|
+
...laneModelOptions(goalDraftModel)
|
|
279834
280152
|
});
|
|
279835
280153
|
if (!agentResult?.session) {
|
|
279836
280154
|
throw new AiServiceError3("Failed to initialize AI agent");
|
|
@@ -279868,6 +280186,7 @@ var init_ai_refine = __esm({
|
|
|
279868
280186
|
init_src2();
|
|
279869
280187
|
init_src5();
|
|
279870
280188
|
init_process_lifecycle();
|
|
280189
|
+
init_lane_session_model();
|
|
279871
280190
|
createFnAgent8 = createFnAgent2;
|
|
279872
280191
|
VALID_REFINEMENT_TYPES = [
|
|
279873
280192
|
"clarify",
|
|
@@ -292138,7 +292457,7 @@ at this boundary regardless.`;
|
|
|
292138
292457
|
});
|
|
292139
292458
|
|
|
292140
292459
|
// ../dashboard/src/routes/register-planning-subtask-routes.ts
|
|
292141
|
-
import { randomUUID as
|
|
292460
|
+
import { randomUUID as randomUUID52 } from "node:crypto";
|
|
292142
292461
|
async function acquirePlanningCreateLock(sessionId) {
|
|
292143
292462
|
const previous = planningCreateLocks.get(sessionId);
|
|
292144
292463
|
let releaseGate;
|
|
@@ -293098,7 +293417,7 @@ function registerPlanningSubtaskRoutes(ctx, deps) {
|
|
|
293098
293417
|
}
|
|
293099
293418
|
session = await getDurablePlanningSession2(sessionId) ?? session;
|
|
293100
293419
|
if (await returnLinkedTask(session)) return;
|
|
293101
|
-
const claimOwnerToken =
|
|
293420
|
+
const claimOwnerToken = randomUUID52();
|
|
293102
293421
|
claimedOwnerToken = claimOwnerToken;
|
|
293103
293422
|
claimedSessionId = sessionId;
|
|
293104
293423
|
const claimStartedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -294272,7 +294591,7 @@ __export(chat_exports, {
|
|
|
294272
294591
|
resolveFileReferences: () => resolveFileReferences
|
|
294273
294592
|
});
|
|
294274
294593
|
import { EventEmitter as EventEmitter40 } from "node:events";
|
|
294275
|
-
import { randomUUID as
|
|
294594
|
+
import { randomUUID as randomUUID53 } from "node:crypto";
|
|
294276
294595
|
import { existsSync as existsSync70 } from "node:fs";
|
|
294277
294596
|
import { join as join92, resolve as resolve47, relative as relative20 } from "node:path";
|
|
294278
294597
|
import { SessionManager as SessionManager3 } from "@earendil-works/pi-coding-agent";
|
|
@@ -294479,7 +294798,7 @@ function createTaskVerificationTools(taskStore, actionGateContext) {
|
|
|
294479
294798
|
const settings = await taskStore.getSettings();
|
|
294480
294799
|
const command = profile === "verify:fast" ? "pnpm verify:fast" : typeof settings.testCommand === "string" ? settings.testCommand : "";
|
|
294481
294800
|
if (!command) return { content: [{ type: "text", text: "ERROR: the selected verification profile is not configured." }], isError: true, details: {} };
|
|
294482
|
-
const created = await taskStore.createTaskVerificationRequest({ taskId, requestId:
|
|
294801
|
+
const created = await taskStore.createTaskVerificationRequest({ taskId, requestId: randomUUID53(), profile, command, scope: "workspace", requestedBy: "chat" });
|
|
294483
294802
|
if (created.inFlightRequestId) return { content: [{ type: "text", text: `ERROR: verification request ${created.inFlightRequestId} is already in flight.` }], isError: true, details: created };
|
|
294484
294803
|
return { content: [{ type: "text", text: `Queued verification request ${created.request.requestId} for ${taskId}.` }], details: created.request };
|
|
294485
294804
|
}
|
|
@@ -296601,7 +296920,7 @@ var init_rate_limit = __esm({
|
|
|
296601
296920
|
});
|
|
296602
296921
|
|
|
296603
296922
|
// ../dashboard/src/routes/register-chat-routes.ts
|
|
296604
|
-
import { randomUUID as
|
|
296923
|
+
import { randomUUID as randomUUID54 } from "node:crypto";
|
|
296605
296924
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
296606
296925
|
import { mkdir as mkdir30, rm as rm17, writeFile as writeFile33 } from "node:fs/promises";
|
|
296607
296926
|
import { basename as basename23, join as join93, resolve as resolve48 } from "node:path";
|
|
@@ -296660,7 +296979,7 @@ function registerChatRoutes(ctx, deps) {
|
|
|
296660
296979
|
const filePath = join93(sessionDir, filename);
|
|
296661
296980
|
await writeFile33(filePath, file.buffer);
|
|
296662
296981
|
return {
|
|
296663
|
-
id: `att-${
|
|
296982
|
+
id: `att-${randomUUID54().slice(0, 8)}`,
|
|
296664
296983
|
filename,
|
|
296665
296984
|
originalName: file.originalname,
|
|
296666
296985
|
mimeType: file.mimetype,
|
|
@@ -296762,6 +297081,55 @@ function registerChatRoutes(ctx, deps) {
|
|
|
296762
297081
|
rethrowAsApiError9(err, "Failed to create task planner chat session");
|
|
296763
297082
|
}
|
|
296764
297083
|
});
|
|
297084
|
+
router.get("/chat/tags", rateLimit(RATE_LIMITS.api), async (req, res) => {
|
|
297085
|
+
try {
|
|
297086
|
+
const { projectId } = await getProjectContext2(req);
|
|
297087
|
+
const { chatStore } = await resolveScopedChatStore(projectId);
|
|
297088
|
+
res.json({ tags: await chatStore.listTags(projectId ?? null) });
|
|
297089
|
+
} catch (err) {
|
|
297090
|
+
rethrowAsApiError9(err, "Failed to list chat tags");
|
|
297091
|
+
}
|
|
297092
|
+
});
|
|
297093
|
+
router.post("/chat/tags", rateLimit(RATE_LIMITS.mutation), async (req, res) => {
|
|
297094
|
+
try {
|
|
297095
|
+
if (typeof req.body?.name !== "string") throw badRequest("name must be a string");
|
|
297096
|
+
const { projectId } = await getProjectContext2(req);
|
|
297097
|
+
const { chatStore } = await resolveScopedChatStore(projectId);
|
|
297098
|
+
const tag = await chatStore.createTag({ name: req.body.name, projectId: projectId ?? null });
|
|
297099
|
+
res.status(201).json({ tag });
|
|
297100
|
+
} catch (err) {
|
|
297101
|
+
if (err instanceof ApiError) throw err;
|
|
297102
|
+
const message = err instanceof Error ? err.message : "Invalid tag";
|
|
297103
|
+
if (message.includes("tag") || message.includes("Tag")) throw badRequest(message);
|
|
297104
|
+
rethrowAsApiError9(err, "Failed to create chat tag");
|
|
297105
|
+
}
|
|
297106
|
+
});
|
|
297107
|
+
router.patch("/chat/tags/:id", rateLimit(RATE_LIMITS.mutation), async (req, res) => {
|
|
297108
|
+
try {
|
|
297109
|
+
if (typeof req.body?.name !== "string") throw badRequest("name must be a string");
|
|
297110
|
+
const { projectId } = await getProjectContext2(req);
|
|
297111
|
+
const { chatStore } = await resolveScopedChatStore(projectId);
|
|
297112
|
+
const tag = await chatStore.renameTag(String(req.params.id), projectId ?? null, { name: req.body.name });
|
|
297113
|
+
if (!tag) throw notFound("Chat tag not found");
|
|
297114
|
+
res.json({ tag });
|
|
297115
|
+
} catch (err) {
|
|
297116
|
+
if (err instanceof ApiError) throw err;
|
|
297117
|
+
const message = err instanceof Error ? err.message : "Invalid tag";
|
|
297118
|
+
if (message.includes("tag") || message.includes("Tag")) throw badRequest(message);
|
|
297119
|
+
rethrowAsApiError9(err, "Failed to rename chat tag");
|
|
297120
|
+
}
|
|
297121
|
+
});
|
|
297122
|
+
router.delete("/chat/tags/:id", rateLimit(RATE_LIMITS.mutation), async (req, res) => {
|
|
297123
|
+
try {
|
|
297124
|
+
const { projectId } = await getProjectContext2(req);
|
|
297125
|
+
const { chatStore } = await resolveScopedChatStore(projectId);
|
|
297126
|
+
if (!await chatStore.deleteTag(String(req.params.id), projectId ?? null)) throw notFound("Chat tag not found");
|
|
297127
|
+
res.json({ success: true });
|
|
297128
|
+
} catch (err) {
|
|
297129
|
+
if (err instanceof ApiError) throw err;
|
|
297130
|
+
rethrowAsApiError9(err, "Failed to delete chat tag");
|
|
297131
|
+
}
|
|
297132
|
+
});
|
|
296765
297133
|
router.get("/chat/sessions", rateLimit(RATE_LIMITS.api), async (req, res) => {
|
|
296766
297134
|
try {
|
|
296767
297135
|
const { projectId, status, agentId, lookup: lookup2, modelProvider, modelId, q: q2, titleOnly } = req.query;
|
|
@@ -296916,11 +297284,15 @@ function registerChatRoutes(ctx, deps) {
|
|
|
296916
297284
|
modelProvider: rawModelProvider,
|
|
296917
297285
|
modelId: rawModelId,
|
|
296918
297286
|
agentId: rawAgentId,
|
|
296919
|
-
pinned: rawPinned
|
|
297287
|
+
pinned: rawPinned,
|
|
297288
|
+
tagIds: rawTagIds
|
|
296920
297289
|
} = req.body;
|
|
296921
297290
|
if (status !== void 0 && status !== "active" && status !== "archived") {
|
|
296922
297291
|
throw badRequest("status must be 'active' or 'archived'");
|
|
296923
297292
|
}
|
|
297293
|
+
if (rawTagIds !== void 0 && (!Array.isArray(rawTagIds) || rawTagIds.some((id) => typeof id !== "string" || !id.trim()))) {
|
|
297294
|
+
throw badRequest("tagIds must be an array of tag IDs");
|
|
297295
|
+
}
|
|
296924
297296
|
if (rawPinned !== void 0 && typeof rawPinned !== "boolean") {
|
|
296925
297297
|
throw badRequest("pinned must be a boolean");
|
|
296926
297298
|
}
|
|
@@ -296952,6 +297324,15 @@ function registerChatRoutes(ctx, deps) {
|
|
|
296952
297324
|
if (!session) {
|
|
296953
297325
|
throw notFound(`Chat session ${sessionId} not found`);
|
|
296954
297326
|
}
|
|
297327
|
+
if (rawTagIds !== void 0) {
|
|
297328
|
+
try {
|
|
297329
|
+
session = await chatStore.replaceSessionTags(sessionId, session.projectId ?? null, rawTagIds.map((id) => id.trim()));
|
|
297330
|
+
} catch (err) {
|
|
297331
|
+
const message = err instanceof Error ? err.message : "Unable to update conversation tags";
|
|
297332
|
+
throw badRequest(message);
|
|
297333
|
+
}
|
|
297334
|
+
if (!session) throw notFound(`Chat session ${sessionId} not found`);
|
|
297335
|
+
}
|
|
296955
297336
|
if (rawPinned !== void 0) {
|
|
296956
297337
|
try {
|
|
296957
297338
|
session = await chatStore.setSessionPinned(sessionId, rawPinned);
|
|
@@ -297364,7 +297745,7 @@ var init_register_chat_routes = __esm({
|
|
|
297364
297745
|
});
|
|
297365
297746
|
|
|
297366
297747
|
// ../dashboard/src/routes/register-chat-room-routes.ts
|
|
297367
|
-
import { randomUUID as
|
|
297748
|
+
import { randomUUID as randomUUID55 } from "node:crypto";
|
|
297368
297749
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
297369
297750
|
import { mkdir as mkdir31, writeFile as writeFile34 } from "node:fs/promises";
|
|
297370
297751
|
import { basename as basename24, join as join94, resolve as resolve49 } from "node:path";
|
|
@@ -297705,7 +298086,7 @@ function registerChatRoomRoutes(ctx, deps) {
|
|
|
297705
298086
|
const filePath = join94(roomDir, filename);
|
|
297706
298087
|
await writeFile34(filePath, file.buffer);
|
|
297707
298088
|
const attachment = {
|
|
297708
|
-
id: `att-${
|
|
298089
|
+
id: `att-${randomUUID55().slice(0, 8)}`,
|
|
297709
298090
|
filename,
|
|
297710
298091
|
originalName: file.originalname,
|
|
297711
298092
|
mimeType: file.mimetype,
|
|
@@ -305997,7 +306378,7 @@ var init_register_gitlab = __esm({
|
|
|
305997
306378
|
|
|
305998
306379
|
// ../dashboard/src/terminal.ts
|
|
305999
306380
|
import { spawn as spawn11 } from "node:child_process";
|
|
306000
|
-
import { randomUUID as
|
|
306381
|
+
import { randomUUID as randomUUID56 } from "node:crypto";
|
|
306001
306382
|
import { EventEmitter as EventEmitter42 } from "node:events";
|
|
306002
306383
|
function extractBaseCommand(command) {
|
|
306003
306384
|
let trimmed = command.trim();
|
|
@@ -306157,7 +306538,7 @@ var init_terminal = __esm({
|
|
|
306157
306538
|
if (!validation.valid) {
|
|
306158
306539
|
return { sessionId: "", error: validation.error };
|
|
306159
306540
|
}
|
|
306160
|
-
const sessionId =
|
|
306541
|
+
const sessionId = randomUUID56();
|
|
306161
306542
|
const childProcess6 = spawn11(command, [], {
|
|
306162
306543
|
cwd,
|
|
306163
306544
|
shell: true,
|
|
@@ -334941,7 +335322,7 @@ var init_register_node_routes = __esm({
|
|
|
334941
335322
|
});
|
|
334942
335323
|
|
|
334943
335324
|
// ../dashboard/src/routes/register-docker-node-routes.ts
|
|
334944
|
-
import { randomUUID as
|
|
335325
|
+
import { randomUUID as randomUUID57 } from "node:crypto";
|
|
334945
335326
|
function sanitizeHostConfig(input) {
|
|
334946
335327
|
const host = input ?? {};
|
|
334947
335328
|
return {
|
|
@@ -335320,7 +335701,7 @@ var init_register_docker_node_routes = __esm({
|
|
|
335320
335701
|
if (!managedNode) {
|
|
335321
335702
|
throw notFound("Managed Docker node not found");
|
|
335322
335703
|
}
|
|
335323
|
-
const newKey =
|
|
335704
|
+
const newKey = randomUUID57().replace(/-/g, "");
|
|
335324
335705
|
await central.updateManagedDockerNode(managedId, { apiKey: newKey });
|
|
335325
335706
|
if (managedNode.nodeId) {
|
|
335326
335707
|
await central.updateNode(managedNode.nodeId, { apiKey: newKey });
|
|
@@ -343831,7 +344212,7 @@ var init_register_agent_reflection_rating_routes = __esm({
|
|
|
343831
344212
|
});
|
|
343832
344213
|
|
|
343833
344214
|
// ../dashboard/src/agent-generation.ts
|
|
343834
|
-
import { randomUUID as
|
|
344215
|
+
import { randomUUID as randomUUID58 } from "node:crypto";
|
|
343835
344216
|
async function initPromptCatalog() {
|
|
343836
344217
|
if (promptCatalogReady) return;
|
|
343837
344218
|
try {
|
|
@@ -344037,7 +344418,7 @@ async function startAgentGeneration(ip, roleDescription) {
|
|
|
344037
344418
|
`Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR4} generation sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
|
|
344038
344419
|
);
|
|
344039
344420
|
}
|
|
344040
|
-
const sessionId =
|
|
344421
|
+
const sessionId = randomUUID58();
|
|
344041
344422
|
const session = {
|
|
344042
344423
|
id: sessionId,
|
|
344043
344424
|
ip,
|
|
@@ -344074,11 +344455,13 @@ async function generateSpecWithAI(session, rootDir, promptOverrides, store) {
|
|
|
344074
344455
|
}
|
|
344075
344456
|
const effectiveSystemPrompt = resolvePrompt2("agent-generation-system", promptOverrides) || AGENT_GENERATION_SYSTEM_PROMPT;
|
|
344076
344457
|
const mcpServers = (await resolveMcpServersForStore(store ?? {})).servers;
|
|
344458
|
+
const generationModel = await resolveLaneSessionModel(store);
|
|
344077
344459
|
const agent = await createFnAgent11({
|
|
344078
344460
|
cwd: rootDir,
|
|
344079
344461
|
systemPrompt: effectiveSystemPrompt,
|
|
344080
344462
|
tools: "none",
|
|
344081
|
-
mcpServers
|
|
344463
|
+
mcpServers,
|
|
344464
|
+
...laneModelOptions(generationModel)
|
|
344082
344465
|
});
|
|
344083
344466
|
try {
|
|
344084
344467
|
await agent.session.prompt(
|
|
@@ -344131,6 +344514,7 @@ var init_agent_generation = __esm({
|
|
|
344131
344514
|
"use strict";
|
|
344132
344515
|
init_ai_session_diagnostics();
|
|
344133
344516
|
init_process_lifecycle();
|
|
344517
|
+
init_lane_session_model();
|
|
344134
344518
|
init_src5();
|
|
344135
344519
|
resolvePrompt2 = () => "";
|
|
344136
344520
|
promptCatalogReady = false;
|
|
@@ -344233,7 +344617,7 @@ __export(agent_onboarding_exports, {
|
|
|
344233
344617
|
startAgentOnboardingSession: () => startAgentOnboardingSession,
|
|
344234
344618
|
stopAgentOnboardingGeneration: () => stopAgentOnboardingGeneration
|
|
344235
344619
|
});
|
|
344236
|
-
import { randomUUID as
|
|
344620
|
+
import { randomUUID as randomUUID59 } from "node:crypto";
|
|
344237
344621
|
import { EventEmitter as EventEmitter43 } from "node:events";
|
|
344238
344622
|
function extractJsonCandidate6(text3) {
|
|
344239
344623
|
const codeBlockMatch = text3.match(/```(?:json)?\s*([\s\S]*?)\s*```/);
|
|
@@ -344333,7 +344717,7 @@ Current agent configuration:
|
|
|
344333
344717
|
${currentConfigLines}`;
|
|
344334
344718
|
}
|
|
344335
344719
|
async function startAgentOnboardingSession(ip, initialContext, rootDir, modelProvider, modelId, promptOverrides, pluginRunner, store) {
|
|
344336
|
-
const id =
|
|
344720
|
+
const id = randomUUID59();
|
|
344337
344721
|
const mode = initialContext.mode ?? "create";
|
|
344338
344722
|
const session = {
|
|
344339
344723
|
id,
|
|
@@ -347105,7 +347489,7 @@ var init_src8 = __esm({
|
|
|
347105
347489
|
|
|
347106
347490
|
// ../../plugins/fusion-plugin-openclaw-runtime/src/pi-module.ts
|
|
347107
347491
|
import { spawn as spawn15 } from "node:child_process";
|
|
347108
|
-
import { randomUUID as
|
|
347492
|
+
import { randomUUID as randomUUID60 } from "node:crypto";
|
|
347109
347493
|
import { readFile as readFile48 } from "node:fs/promises";
|
|
347110
347494
|
function asString2(v2) {
|
|
347111
347495
|
return typeof v2 === "string" && v2.trim() !== "" ? v2.trim() : void 0;
|
|
@@ -347165,7 +347549,7 @@ function extractStderrError(stderr, stdout) {
|
|
|
347165
347549
|
}
|
|
347166
347550
|
function createCliSession(opts) {
|
|
347167
347551
|
return {
|
|
347168
|
-
sessionId:
|
|
347552
|
+
sessionId: randomUUID60(),
|
|
347169
347553
|
agentId: opts.agentId ?? DEFAULT_AGENT_ID,
|
|
347170
347554
|
systemPrompt: opts.systemPrompt,
|
|
347171
347555
|
messages: [{ role: "developer", content: opts.systemPrompt }],
|
|
@@ -347360,7 +347744,7 @@ var init_mcp_config2 = __esm({
|
|
|
347360
347744
|
});
|
|
347361
347745
|
|
|
347362
347746
|
// ../../plugins/fusion-plugin-openclaw-runtime/src/runtime-adapter.ts
|
|
347363
|
-
import { randomUUID as
|
|
347747
|
+
import { randomUUID as randomUUID61 } from "node:crypto";
|
|
347364
347748
|
var OpenClawRuntimeAdapter;
|
|
347365
347749
|
var init_runtime_adapter2 = __esm({
|
|
347366
347750
|
"../../plugins/fusion-plugin-openclaw-runtime/src/runtime-adapter.ts"() {
|
|
@@ -347383,8 +347767,8 @@ var init_runtime_adapter2 = __esm({
|
|
|
347383
347767
|
let mcpProfile;
|
|
347384
347768
|
let mcpConfigPath;
|
|
347385
347769
|
if (toolDefs.length > 0) {
|
|
347386
|
-
const bridge = writeOpenClawMcpBridgeFiles(toolDefs,
|
|
347387
|
-
mcpProfile = `fusion-${
|
|
347770
|
+
const bridge = writeOpenClawMcpBridgeFiles(toolDefs, randomUUID61());
|
|
347771
|
+
mcpProfile = `fusion-${randomUUID61()}`;
|
|
347388
347772
|
mcpConfigPath = bridge.serverConfigPath;
|
|
347389
347773
|
await configureOpenClawMcpServer({
|
|
347390
347774
|
binaryPath: this.config.binaryPath,
|
|
@@ -351438,7 +351822,7 @@ import { existsSync as existsSync76, writeFileSync as writeFileSync15 } from "no
|
|
|
351438
351822
|
import { tmpdir as tmpdir17 } from "node:os";
|
|
351439
351823
|
import { dirname as dirname45, join as join106 } from "node:path";
|
|
351440
351824
|
import { fileURLToPath as fileURLToPath11 } from "node:url";
|
|
351441
|
-
import { randomUUID as
|
|
351825
|
+
import { randomUUID as randomUUID62 } from "node:crypto";
|
|
351442
351826
|
function toolsToMcpToolDefs2(tools) {
|
|
351443
351827
|
if (!Array.isArray(tools)) return [];
|
|
351444
351828
|
return tools.filter((tool) => tool && typeof tool.name === "string" && tool.name.trim().length > 0 && !BUILT_IN_TOOL_NAMES2.has(tool.name)).map((tool) => ({
|
|
@@ -351489,7 +351873,7 @@ async function startFusionToolBridge(tools) {
|
|
|
351489
351873
|
byName.set(tool.name, tool);
|
|
351490
351874
|
}
|
|
351491
351875
|
}
|
|
351492
|
-
const schemaPath = join106(tmpdir17(), `fusion-grok-mcp-schemas-${process.pid}-${
|
|
351876
|
+
const schemaPath = join106(tmpdir17(), `fusion-grok-mcp-schemas-${process.pid}-${randomUUID62()}.json`);
|
|
351493
351877
|
writeFileSync15(schemaPath, JSON.stringify(defs));
|
|
351494
351878
|
const server = createServer2(async (req, res) => {
|
|
351495
351879
|
if (req.method !== "POST" || req.url !== "/tool-call") {
|
|
@@ -351515,7 +351899,7 @@ async function startFusionToolBridge(tools) {
|
|
|
351515
351899
|
return;
|
|
351516
351900
|
}
|
|
351517
351901
|
try {
|
|
351518
|
-
const result = await tool.execute(`grok-mcp-${
|
|
351902
|
+
const result = await tool.execute(`grok-mcp-${randomUUID62()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
|
|
351519
351903
|
res.statusCode = 200;
|
|
351520
351904
|
res.setHeader("content-type", "application/json");
|
|
351521
351905
|
res.end(
|
|
@@ -353559,7 +353943,7 @@ import { existsSync as existsSync80, rmSync as rmSync13, writeFileSync as writeF
|
|
|
353559
353943
|
import { tmpdir as tmpdir19 } from "node:os";
|
|
353560
353944
|
import { dirname as dirname50, join as join111 } from "node:path";
|
|
353561
353945
|
import { fileURLToPath as fileURLToPath15 } from "node:url";
|
|
353562
|
-
import { randomBytes as randomBytes8, randomUUID as
|
|
353946
|
+
import { randomBytes as randomBytes8, randomUUID as randomUUID63 } from "node:crypto";
|
|
353563
353947
|
function toolsToMcpToolDefs3(tools) {
|
|
353564
353948
|
if (!Array.isArray(tools)) return [];
|
|
353565
353949
|
return tools.filter((tool) => tool && typeof tool.name === "string" && tool.name.trim().length > 0 && !BUILT_IN_TOOL_NAMES3.has(tool.name)).map((tool) => ({
|
|
@@ -353610,7 +353994,7 @@ async function startFusionToolBridge2(tools, options = {}) {
|
|
|
353610
353994
|
byName.set(tool.name, tool);
|
|
353611
353995
|
}
|
|
353612
353996
|
}
|
|
353613
|
-
const schemaPath = join111(tmpdir19(), `fusion-claude-mcp-schemas-${process.pid}-${
|
|
353997
|
+
const schemaPath = join111(tmpdir19(), `fusion-claude-mcp-schemas-${process.pid}-${randomUUID63()}.json`);
|
|
353614
353998
|
writeFileSync17(schemaPath, JSON.stringify(defs));
|
|
353615
353999
|
const capabilityToken = randomBytes8(32).toString("base64url");
|
|
353616
354000
|
const server = createServer3(async (req, res) => {
|
|
@@ -353675,7 +354059,7 @@ async function startFusionToolBridge2(tools, options = {}) {
|
|
|
353675
354059
|
return;
|
|
353676
354060
|
}
|
|
353677
354061
|
try {
|
|
353678
|
-
const result = await tool.execute(`claude-mcp-${
|
|
354062
|
+
const result = await tool.execute(`claude-mcp-${randomUUID63()}`, parsed.arguments ?? {}, void 0, void 0, void 0);
|
|
353679
354063
|
res.statusCode = 200;
|
|
353680
354064
|
res.setHeader("content-type", "application/json");
|
|
353681
354065
|
res.end(
|
|
@@ -355752,7 +356136,7 @@ import { existsSync as existsSync82, unlinkSync as unlinkSync5, writeFileSync as
|
|
|
355752
356136
|
import { tmpdir as tmpdir20 } from "node:os";
|
|
355753
356137
|
import { dirname as dirname53, join as join114 } from "node:path";
|
|
355754
356138
|
import { fileURLToPath as fileURLToPath17 } from "node:url";
|
|
355755
|
-
import { randomUUID as
|
|
356139
|
+
import { randomUUID as randomUUID64 } from "node:crypto";
|
|
355756
356140
|
function toolsToMcpToolDefs4(tools) {
|
|
355757
356141
|
if (!Array.isArray(tools)) return [];
|
|
355758
356142
|
return tools.filter(
|
|
@@ -355809,7 +356193,7 @@ async function startFusionToolBridge3(tools) {
|
|
|
355809
356193
|
byName.set(tool.name, tool);
|
|
355810
356194
|
}
|
|
355811
356195
|
}
|
|
355812
|
-
const schemaPath = join114(tmpdir20(), `fusion-omp-mcp-schemas-${process.pid}-${
|
|
356196
|
+
const schemaPath = join114(tmpdir20(), `fusion-omp-mcp-schemas-${process.pid}-${randomUUID64()}.json`);
|
|
355813
356197
|
writeFileSync18(schemaPath, JSON.stringify(defs));
|
|
355814
356198
|
const server = createServer4(async (req, res) => {
|
|
355815
356199
|
if (req.method !== "POST" || req.url !== "/tool-call") {
|
|
@@ -355836,7 +356220,7 @@ async function startFusionToolBridge3(tools) {
|
|
|
355836
356220
|
}
|
|
355837
356221
|
try {
|
|
355838
356222
|
const result = await tool.execute(
|
|
355839
|
-
`omp-mcp-${
|
|
356223
|
+
`omp-mcp-${randomUUID64()}`,
|
|
355840
356224
|
parsed.arguments ?? {},
|
|
355841
356225
|
void 0,
|
|
355842
356226
|
void 0,
|
|
@@ -356932,7 +357316,7 @@ var init_paperclip_client = __esm({
|
|
|
356932
357316
|
});
|
|
356933
357317
|
|
|
356934
357318
|
// ../../plugins/fusion-plugin-paperclip-runtime/src/runtime-adapter.ts
|
|
356935
|
-
import { randomUUID as
|
|
357319
|
+
import { randomUUID as randomUUID65 } from "node:crypto";
|
|
356936
357320
|
function sleep7(ms2) {
|
|
356937
357321
|
return new Promise((resolve102) => setTimeout(resolve102, ms2));
|
|
356938
357322
|
}
|
|
@@ -357061,7 +357445,7 @@ var init_runtime_adapter10 = __esm({
|
|
|
357061
357445
|
apiKey: effectiveApiKey,
|
|
357062
357446
|
agentId,
|
|
357063
357447
|
companyId,
|
|
357064
|
-
sessionId:
|
|
357448
|
+
sessionId: randomUUID65(),
|
|
357065
357449
|
systemPrompt: options.systemPrompt,
|
|
357066
357450
|
cwd: options.cwd,
|
|
357067
357451
|
mode: normalizeMode3(this.config.mode),
|
|
@@ -360489,7 +360873,7 @@ var init_command_center_csv = __esm({
|
|
|
360489
360873
|
});
|
|
360490
360874
|
|
|
360491
360875
|
// ../dashboard/src/monitor-store.ts
|
|
360492
|
-
import { randomUUID as
|
|
360876
|
+
import { randomUUID as randomUUID66 } from "node:crypto";
|
|
360493
360877
|
function monitorProjectId(layer) {
|
|
360494
360878
|
if (!layer.projectId) {
|
|
360495
360879
|
throw new Error("PostgreSQL monitor writes require asyncLayer.projectId");
|
|
@@ -360521,7 +360905,7 @@ async function recordDeployment(db, input) {
|
|
|
360521
360905
|
return recordDeploymentAsync(layer.db, input, monitorProjectId(layer));
|
|
360522
360906
|
}
|
|
360523
360907
|
const sqliteDb = db;
|
|
360524
|
-
const deploymentId = input.deploymentId?.trim() || `dep-${
|
|
360908
|
+
const deploymentId = input.deploymentId?.trim() || `dep-${randomUUID66()}`;
|
|
360525
360909
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
360526
360910
|
const deployedAt = input.deployedAt ?? now;
|
|
360527
360911
|
const meta2 = input.meta ? JSON.stringify(input.meta) : null;
|
|
@@ -360587,7 +360971,7 @@ async function ingestIncidentSignal(db, input) {
|
|
|
360587
360971
|
const updated = getIncident(sqliteDb, existing.incidentId);
|
|
360588
360972
|
return { incident: updated ?? existing, created: false };
|
|
360589
360973
|
}
|
|
360590
|
-
const incidentId = `inc-${
|
|
360974
|
+
const incidentId = `inc-${randomUUID66()}`;
|
|
360591
360975
|
const meta2 = {
|
|
360592
360976
|
...input.meta ?? {},
|
|
360593
360977
|
[OCCURRENCES_META_KEY2]: 1,
|
|
@@ -365277,7 +365661,7 @@ var init_fn_binary_local_install = __esm({
|
|
|
365277
365661
|
});
|
|
365278
365662
|
|
|
365279
365663
|
// ../dashboard/src/routes/register-system-routes.ts
|
|
365280
|
-
import { randomUUID as
|
|
365664
|
+
import { randomUUID as randomUUID67 } from "node:crypto";
|
|
365281
365665
|
import { existsSync as existsSync86 } from "node:fs";
|
|
365282
365666
|
import { join as join121 } from "node:path";
|
|
365283
365667
|
function rejectCrossOrigin(req, res) {
|
|
@@ -365474,7 +365858,7 @@ function registerSystemRoutes(ctx, deps) {
|
|
|
365474
365858
|
throw new ApiError(409, `Build script missing: ${scriptPath}`);
|
|
365475
365859
|
}
|
|
365476
365860
|
const job = {
|
|
365477
|
-
id:
|
|
365861
|
+
id: randomUUID67(),
|
|
365478
365862
|
kind: "rebuild",
|
|
365479
365863
|
scope,
|
|
365480
365864
|
restartAfter,
|
|
@@ -365760,7 +366144,7 @@ function registerSystemRoutes(ctx, deps) {
|
|
|
365760
366144
|
throw new ApiError(409, `A ${activeJob.kind}/${activeJob.scope} job is already running`);
|
|
365761
366145
|
}
|
|
365762
366146
|
const job = {
|
|
365763
|
-
id:
|
|
366147
|
+
id: randomUUID67(),
|
|
365764
366148
|
kind,
|
|
365765
366149
|
scope,
|
|
365766
366150
|
restartAfter,
|
|
@@ -376999,7 +377383,7 @@ var init_provider_health_monitor = __esm({
|
|
|
376999
377383
|
|
|
377000
377384
|
// ../dashboard/src/server.ts
|
|
377001
377385
|
import express2 from "express";
|
|
377002
|
-
import { randomUUID as
|
|
377386
|
+
import { randomUUID as randomUUID68 } from "node:crypto";
|
|
377003
377387
|
import { join as join126, dirname as dirname57 } from "node:path";
|
|
377004
377388
|
import { existsSync as existsSync88, readFileSync as readFileSync32, statSync as statSync16 } from "node:fs";
|
|
377005
377389
|
import { fileURLToPath as fileURLToPath18 } from "node:url";
|
|
@@ -378429,7 +378813,7 @@ function setupBadgeWebSocket(app, server, store, options) {
|
|
|
378429
378813
|
const dashboardApp = app;
|
|
378430
378814
|
const wsManager = new WebSocketManager();
|
|
378431
378815
|
const badgeSnapshots = /* @__PURE__ */ new Map();
|
|
378432
|
-
const serverId =
|
|
378816
|
+
const serverId = randomUUID68();
|
|
378433
378817
|
const badgePubSub = options?.badgePubSub ?? createBadgePubSub({ sourceId: serverId });
|
|
378434
378818
|
void badgePubSub.start();
|
|
378435
378819
|
const scopedStores = /* @__PURE__ */ new Map();
|
|
@@ -378571,7 +378955,7 @@ function setupBadgeWebSocket(app, server, store, options) {
|
|
|
378571
378955
|
const url2 = new URL(req.url || "", `http://${req.headers.host}`);
|
|
378572
378956
|
const projectId = url2.searchParams.get("projectId") ?? "default";
|
|
378573
378957
|
void ensureScopedListeners(projectId);
|
|
378574
|
-
wsManager.addClient(ws2,
|
|
378958
|
+
wsManager.addClient(ws2, randomUUID68(), projectId);
|
|
378575
378959
|
});
|
|
378576
378960
|
server.once("close", async () => {
|
|
378577
378961
|
for (const cleanup of scopedCleanups.values()) {
|
|
@@ -384987,7 +385371,8 @@ function DashboardApp({ controller }) {
|
|
|
384987
385371
|
controller.setInteractiveView("files");
|
|
384988
385372
|
return;
|
|
384989
385373
|
}
|
|
384990
|
-
|
|
385374
|
+
const utilitiesOwnsInput = state.mode === "status" && state.activeSection === "utilities" && !logsFocused;
|
|
385375
|
+
if ((input === "t" || input === "T") && !utilitiesOwnsInput) {
|
|
384991
385376
|
controller.setMode("interactive");
|
|
384992
385377
|
controller.setInteractiveView("git");
|
|
384993
385378
|
return;
|
|
@@ -388701,7 +389086,7 @@ function tuiDebug2(tag, data) {
|
|
|
388701
389086
|
} catch {
|
|
388702
389087
|
}
|
|
388703
389088
|
}
|
|
388704
|
-
var TUI_DEBUG_LOG2, DashboardTUI;
|
|
389089
|
+
var TUI_DEBUG_LOG2, PAUSE_CONFIRM_WINDOW_MS, DashboardTUI;
|
|
388705
389090
|
var init_controller = __esm({
|
|
388706
389091
|
"src/commands/dashboard-tui/controller.ts"() {
|
|
388707
389092
|
"use strict";
|
|
@@ -388709,6 +389094,7 @@ var init_controller = __esm({
|
|
|
388709
389094
|
init_log_ring_buffer();
|
|
388710
389095
|
init_state();
|
|
388711
389096
|
TUI_DEBUG_LOG2 = process.env.FUSION_TUI_DEBUG_LOG;
|
|
389097
|
+
PAUSE_CONFIRM_WINDOW_MS = 5e3;
|
|
388712
389098
|
DashboardTUI = class {
|
|
388713
389099
|
// State fields mirror the original private layout so tests can access them.
|
|
388714
389100
|
activeSection = "system";
|
|
@@ -388749,6 +389135,15 @@ var init_controller = __esm({
|
|
|
388749
389135
|
lastAutoKillAt = 0;
|
|
388750
389136
|
clipboardFlash = null;
|
|
388751
389137
|
clipboardFlashTimer = null;
|
|
389138
|
+
/*
|
|
389139
|
+
FNXC:DashboardTui 2026-07-24-18:40:
|
|
389140
|
+
Pausing the engine from Utilities [t] is a silent, board-wide stop: triage and
|
|
389141
|
+
planning stall while in-flight tasks drain, so the board keeps moving for
|
|
389142
|
+
minutes and the cause is invisible from the terminal. One unmodified keystroke
|
|
389143
|
+
must not do that — the first `t` arms this deadline and only a second `t`
|
|
389144
|
+
inside the window pauses. Resuming is not destructive and stays single-press.
|
|
389145
|
+
*/
|
|
389146
|
+
pausePendingConfirmUntil = 0;
|
|
388752
389147
|
interactiveData = null;
|
|
388753
389148
|
interactiveView = "board";
|
|
388754
389149
|
interactiveInputLocked = false;
|
|
@@ -389167,6 +389562,22 @@ var init_controller = __esm({
|
|
|
389167
389562
|
const all = this.logBuffer.getAll();
|
|
389168
389563
|
return this.logsSeverityFilter === "all" ? all : all.filter((e) => e.level === this.logsSeverityFilter);
|
|
389169
389564
|
}
|
|
389565
|
+
/**
|
|
389566
|
+
* Two-press confirmation for an engine pause initiated from Utilities [t].
|
|
389567
|
+
*
|
|
389568
|
+
* Returns true when the caller may pause: either a prior press armed the
|
|
389569
|
+
* window and it has not expired, or this call arms it and returns false so the
|
|
389570
|
+
* caller can prompt. Any successful confirmation disarms, so a third press
|
|
389571
|
+
* re-arms rather than toggling twice.
|
|
389572
|
+
*/
|
|
389573
|
+
consumePauseConfirmation(now = Date.now()) {
|
|
389574
|
+
if (this.pausePendingConfirmUntil > now) {
|
|
389575
|
+
this.pausePendingConfirmUntil = 0;
|
|
389576
|
+
return true;
|
|
389577
|
+
}
|
|
389578
|
+
this.pausePendingConfirmUntil = now + PAUSE_CONFIRM_WINDOW_MS;
|
|
389579
|
+
return false;
|
|
389580
|
+
}
|
|
389170
389581
|
async handleUtilityAction(key) {
|
|
389171
389582
|
if (!this.callbacks) return;
|
|
389172
389583
|
switch (key.toLowerCase()) {
|
|
@@ -389180,6 +389591,13 @@ var init_controller = __esm({
|
|
|
389180
389591
|
case "t":
|
|
389181
389592
|
if (this.systemInfo) {
|
|
389182
389593
|
const newPaused = this.systemInfo.engineMode !== "paused";
|
|
389594
|
+
if (newPaused && !this.consumePauseConfirmation()) {
|
|
389595
|
+
this.warn(
|
|
389596
|
+
`Press [t] again within ${Math.round(PAUSE_CONFIRM_WINDOW_MS / 1e3)}s to pause the engine (stops triage, planning, and new dispatch).`,
|
|
389597
|
+
"engine"
|
|
389598
|
+
);
|
|
389599
|
+
break;
|
|
389600
|
+
}
|
|
389183
389601
|
const newSettings = await this.callbacks.onTogglePause(newPaused);
|
|
389184
389602
|
const newEngineMode = newSettings.enginePaused ? "paused" : "active";
|
|
389185
389603
|
this.setSystemInfo({ ...this.systemInfo, engineMode: newEngineMode });
|