@roarpeng/graphflow 0.6.6 → 0.6.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +166 -303
  3. package/dist/config/defaults.d.ts +6 -0
  4. package/dist/config/defaults.d.ts.map +1 -1
  5. package/dist/config/defaults.js +20 -7
  6. package/dist/config/defaults.js.map +1 -1
  7. package/dist/config/loader.d.ts +8 -0
  8. package/dist/config/loader.d.ts.map +1 -1
  9. package/dist/config/loader.js +42 -9
  10. package/dist/config/loader.js.map +1 -1
  11. package/dist/config/paths.d.ts.map +1 -1
  12. package/dist/config/paths.js +6 -5
  13. package/dist/config/paths.js.map +1 -1
  14. package/dist/config/resolve.d.ts +3 -0
  15. package/dist/config/resolve.d.ts.map +1 -1
  16. package/dist/config/resolve.js +58 -24
  17. package/dist/config/resolve.js.map +1 -1
  18. package/dist/config/secrets.d.ts +6 -1
  19. package/dist/config/secrets.d.ts.map +1 -1
  20. package/dist/config/secrets.js +9 -1
  21. package/dist/config/secrets.js.map +1 -1
  22. package/dist/core/dag-engine.d.ts.map +1 -1
  23. package/dist/core/dag-engine.js +9 -3
  24. package/dist/core/dag-engine.js.map +1 -1
  25. package/dist/core/errors.d.ts +28 -1
  26. package/dist/core/errors.d.ts.map +1 -1
  27. package/dist/core/errors.js +55 -2
  28. package/dist/core/errors.js.map +1 -1
  29. package/dist/core/orchestrator.d.ts.map +1 -1
  30. package/dist/core/orchestrator.js +16 -0
  31. package/dist/core/orchestrator.js.map +1 -1
  32. package/dist/graph/file-indexer.d.ts +2 -0
  33. package/dist/graph/file-indexer.d.ts.map +1 -1
  34. package/dist/graph/file-indexer.js +65 -36
  35. package/dist/graph/file-indexer.js.map +1 -1
  36. package/dist/graph/graph-utils.d.ts +4 -0
  37. package/dist/graph/graph-utils.d.ts.map +1 -0
  38. package/dist/graph/graph-utils.js +29 -0
  39. package/dist/graph/graph-utils.js.map +1 -0
  40. package/dist/graph/graphify-client.d.ts +2 -1
  41. package/dist/graph/graphify-client.d.ts.map +1 -1
  42. package/dist/graph/graphify-client.js +6 -17
  43. package/dist/graph/graphify-client.js.map +1 -1
  44. package/dist/graph/graphify-file-client.js +3 -3
  45. package/dist/graph/graphify-file-client.js.map +1 -1
  46. package/dist/graph/snapshot-view.d.ts +26 -0
  47. package/dist/graph/snapshot-view.d.ts.map +1 -0
  48. package/dist/graph/snapshot-view.js +228 -0
  49. package/dist/graph/snapshot-view.js.map +1 -0
  50. package/dist/index.d.ts +3 -2
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +3 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/integrations/agent-mcp-installer.d.ts +3 -0
  55. package/dist/integrations/agent-mcp-installer.d.ts.map +1 -1
  56. package/dist/integrations/agent-mcp-installer.js +7 -5
  57. package/dist/integrations/agent-mcp-installer.js.map +1 -1
  58. package/dist/learning/episodic-memory.d.ts.map +1 -1
  59. package/dist/learning/episodic-memory.js +2 -8
  60. package/dist/learning/episodic-memory.js.map +1 -1
  61. package/dist/learning/reflector.d.ts.map +1 -1
  62. package/dist/learning/reflector.js +2 -8
  63. package/dist/learning/reflector.js.map +1 -1
  64. package/dist/learning/skill-evolution.d.ts +16 -0
  65. package/dist/learning/skill-evolution.d.ts.map +1 -0
  66. package/dist/learning/skill-evolution.js +154 -0
  67. package/dist/learning/skill-evolution.js.map +1 -0
  68. package/dist/learning/skill-flywheel.d.ts +4 -47
  69. package/dist/learning/skill-flywheel.d.ts.map +1 -1
  70. package/dist/learning/skill-flywheel.js +44 -337
  71. package/dist/learning/skill-flywheel.js.map +1 -1
  72. package/dist/learning/skill-store.d.ts +20 -0
  73. package/dist/learning/skill-store.d.ts.map +1 -0
  74. package/dist/learning/skill-store.js +170 -0
  75. package/dist/learning/skill-store.js.map +1 -0
  76. package/dist/learning/skill-types.d.ts +43 -0
  77. package/dist/learning/skill-types.d.ts.map +1 -0
  78. package/dist/learning/skill-types.js +6 -0
  79. package/dist/learning/skill-types.js.map +1 -0
  80. package/dist/learning/vector-store.d.ts +2 -0
  81. package/dist/learning/vector-store.d.ts.map +1 -1
  82. package/dist/learning/vector-store.js +4 -0
  83. package/dist/learning/vector-store.js.map +1 -1
  84. package/dist/routing/provider-executor.d.ts.map +1 -1
  85. package/dist/routing/provider-executor.js +5 -4
  86. package/dist/routing/provider-executor.js.map +1 -1
  87. package/dist/surfaces/cli/init.d.ts.map +1 -1
  88. package/dist/surfaces/cli/init.js +25 -39
  89. package/dist/surfaces/cli/init.js.map +1 -1
  90. package/dist/surfaces/cli/runtime/env.d.ts +8 -0
  91. package/dist/surfaces/cli/runtime/env.d.ts.map +1 -0
  92. package/dist/surfaces/cli/runtime/env.js +134 -0
  93. package/dist/surfaces/cli/runtime/env.js.map +1 -0
  94. package/dist/surfaces/cli/runtime/facade.d.ts +45 -0
  95. package/dist/surfaces/cli/runtime/facade.d.ts.map +1 -0
  96. package/dist/surfaces/cli/runtime/facade.js +34 -0
  97. package/dist/surfaces/cli/runtime/facade.js.map +1 -0
  98. package/dist/surfaces/cli/runtime/graph.d.ts +25 -0
  99. package/dist/surfaces/cli/runtime/graph.d.ts.map +1 -0
  100. package/dist/surfaces/cli/runtime/graph.js +416 -0
  101. package/dist/surfaces/cli/runtime/graph.js.map +1 -0
  102. package/dist/surfaces/cli/runtime/helpers.d.ts +30 -0
  103. package/dist/surfaces/cli/runtime/helpers.d.ts.map +1 -0
  104. package/dist/surfaces/cli/runtime/helpers.js +159 -0
  105. package/dist/surfaces/cli/runtime/helpers.js.map +1 -0
  106. package/dist/surfaces/cli/runtime/panel.d.ts +5 -0
  107. package/dist/surfaces/cli/runtime/panel.d.ts.map +1 -0
  108. package/dist/surfaces/cli/runtime/panel.js +91 -0
  109. package/dist/surfaces/cli/runtime/panel.js.map +1 -0
  110. package/dist/surfaces/cli/runtime/routing.d.ts +11 -0
  111. package/dist/surfaces/cli/runtime/routing.d.ts.map +1 -0
  112. package/dist/surfaces/cli/runtime/routing.js +233 -0
  113. package/dist/surfaces/cli/runtime/routing.js.map +1 -0
  114. package/dist/surfaces/cli/runtime/settings.d.ts +6 -0
  115. package/dist/surfaces/cli/runtime/settings.d.ts.map +1 -0
  116. package/dist/surfaces/cli/runtime/settings.js +334 -0
  117. package/dist/surfaces/cli/runtime/settings.js.map +1 -0
  118. package/dist/surfaces/cli/runtime/types.d.ts +218 -0
  119. package/dist/surfaces/cli/runtime/types.d.ts.map +1 -0
  120. package/dist/surfaces/cli/runtime/types.js +3 -0
  121. package/dist/surfaces/cli/runtime/types.js.map +1 -0
  122. package/dist/surfaces/cli/runtime.d.ts +8 -257
  123. package/dist/surfaces/cli/runtime.d.ts.map +1 -1
  124. package/dist/surfaces/cli/runtime.js +52 -1264
  125. package/dist/surfaces/cli/runtime.js.map +1 -1
  126. package/dist/surfaces/mcp/server.js +18 -0
  127. package/dist/surfaces/mcp/server.js.map +1 -1
  128. package/dist/utils/hash.d.ts +11 -0
  129. package/dist/utils/hash.d.ts.map +1 -0
  130. package/dist/utils/hash.js +27 -0
  131. package/dist/utils/hash.js.map +1 -0
  132. package/package.json +3 -1
  133. package/scripts/safe-postinstall.cjs +6 -0
@@ -1,1278 +1,66 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installMcpToDetectedAgents = exports.formatModelConfigGuide = exports.detectInstalledAgents = exports.buildMcpServerNode = exports.resolveConfigPath = exports.resolveConfig = exports.resolveGlobalConfigPath = exports.ensureWorkspaceGraphFlowConfig = exports.ensureGlobalGraphFlowConfig = exports.getDefaultConfig = void 0;
4
- exports.prepareSemanticEnrichmentRuntime = prepareSemanticEnrichmentRuntime;
5
- exports.applyEnrichmentProviderEnv = applyEnrichmentProviderEnv;
6
- exports.applyOpenBmbRuntimeEnv = applyOpenBmbRuntimeEnv;
7
- exports.getGraphFlowSettings = getGraphFlowSettings;
8
- exports.saveGraphFlowSettings = saveGraphFlowSettings;
9
- exports.previewContext = previewContext;
10
- exports.indexGraph = indexGraph;
11
- exports.rebuildGraph = rebuildGraph;
12
- exports.enrichSemanticsSilent = enrichSemanticsSilent;
13
- exports.downloadOpenBmbModel = downloadOpenBmbModel;
14
- exports.inspectGraph = inspectGraph;
15
- exports.getSkillInsights = getSkillInsights;
16
- exports.runTaskResult = runTaskResult;
17
- exports.runTask = runTask;
18
- exports.diagnoseRoutingResult = diagnoseRoutingResult;
19
- exports.diagnoseRouting = diagnoseRouting;
20
- exports.validateSettingsForGraphIndex = validateSettingsForGraphIndex;
21
- exports.indexGraphFromSettings = indexGraphFromSettings;
22
- exports.validateSettingsForRouting = validateSettingsForRouting;
23
- exports.testRoutingAndIndexGraph = testRoutingAndIndexGraph;
24
- exports.getSettingsPanelStatus = getSettingsPanelStatus;
25
- exports.runLearningNightlyResult = runLearningNightlyResult;
26
- exports.runLearningNightly = runLearningNightly;
27
- exports.planAndBrainstormResult = planAndBrainstormResult;
28
- exports.planAndBrainstorm = planAndBrainstorm;
29
- const node_fs_1 = require("node:fs");
30
- const node_path_1 = require("node:path");
31
- const node_crypto_1 = require("node:crypto");
32
- const node_os_1 = require("node:os");
33
- const brainstormer_1 = require("../../agents/brainstormer");
34
- const planner_1 = require("../../agents/planner");
35
- const loader_1 = require("../../config/loader");
36
- const secrets_1 = require("../../config/secrets");
37
- const merge_1 = require("../../config/merge");
38
- const resolve_1 = require("../../config/resolve");
39
- const embedding_factory_1 = require("../../config/embedding-factory");
40
- const paths_1 = require("../../config/paths");
41
- const triage_1 = require("../../core/triage");
42
- const orchestrator_1 = require("../../core/orchestrator");
43
- const client_factory_1 = require("../../graph/client-factory");
44
- const semantic_enricher_1 = require("../../graph/semantic-enricher");
45
- const sqlite_client_1 = require("../../graph/sqlite-client");
46
- const file_indexer_1 = require("../../graph/file-indexer");
47
- const context_slicer_1 = require("../../graph/context-slicer");
48
- const nightly_trainer_1 = require("../../learning/nightly-trainer");
49
- const learning_events_1 = require("../../learning/learning-events");
50
- const model_router_1 = require("../../routing/model-router");
51
- const provider_health_1 = require("../../routing/provider-health");
52
- const provider_executor_1 = require("../../routing/provider-executor");
53
- const file_lock_1 = require("../../utils/file-lock");
54
- const logger_1 = require("../../utils/logger");
17
+ exports.installMcpToDetectedAgents = exports.formatModelConfigGuide = exports.detectInstalledAgents = exports.buildMcpServerNode = exports.assertGraphFlowRuntime = exports.testRoutingAndIndexGraph = exports.indexGraphFromSettings = exports.getSettingsPanelStatus = exports.planAndBrainstormResult = exports.planAndBrainstorm = exports.runLearningNightlyResult = exports.runLearningNightly = exports.diagnoseRoutingResult = exports.diagnoseRouting = exports.runTaskResult = exports.runTask = exports.getSkillInsights = exports.inspectGraph = exports.downloadOpenBmbModel = exports.enrichSemanticsSilent = exports.rebuildGraph = exports.indexGraph = exports.previewContext = exports.validateSettingsForRouting = exports.validateSettingsForGraphIndex = exports.saveGraphFlowSettings = exports.getGraphFlowSettings = exports.applyOpenBmbRuntimeEnv = exports.applyEnrichmentProviderEnv = exports.prepareSemanticEnrichmentRuntime = exports.resolveWritableConfigPath = exports.resolveConfigPath = exports.resolveConfig = exports.resolveGlobalConfigPath = exports.ensureWorkspaceGraphFlowConfig = exports.ensureGlobalGraphFlowConfig = exports.getDefaultConfig = void 0;
55
18
  var defaults_1 = require("../../config/defaults");
56
19
  Object.defineProperty(exports, "getDefaultConfig", { enumerable: true, get: function () { return defaults_1.getDefaultConfig; } });
57
20
  var scaffold_1 = require("../../config/scaffold");
58
21
  Object.defineProperty(exports, "ensureGlobalGraphFlowConfig", { enumerable: true, get: function () { return scaffold_1.ensureGlobalGraphFlowConfig; } });
59
22
  Object.defineProperty(exports, "ensureWorkspaceGraphFlowConfig", { enumerable: true, get: function () { return scaffold_1.ensureWorkspaceGraphFlowConfig; } });
60
23
  Object.defineProperty(exports, "resolveGlobalConfigPath", { enumerable: true, get: function () { return scaffold_1.resolveGlobalConfigPath; } });
61
- var resolve_2 = require("../../config/resolve");
62
- Object.defineProperty(exports, "resolveConfig", { enumerable: true, get: function () { return resolve_2.resolveConfig; } });
63
- Object.defineProperty(exports, "resolveConfigPath", { enumerable: true, get: function () { return resolve_2.resolveConfigPath; } });
64
- function buildEmbeddingOptions(config) {
65
- const embeddingProvider = (0, embedding_factory_1.createEmbeddingProviderFromConfig)(config);
66
- if (!embeddingProvider) {
67
- return {};
68
- }
69
- return {
70
- embeddingProvider,
71
- enableVectorRecall: true,
72
- ...(config.embeddingPolicy?.topK !== undefined ? { vectorTopK: config.embeddingPolicy.topK } : {}),
73
- ...(config.embeddingPolicy?.minSimilarity !== undefined
74
- ? { vectorMinSimilarity: config.embeddingPolicy.minSimilarity }
75
- : {}),
76
- };
77
- }
78
- function resolveEnrichmentBackend(policy) {
79
- if (policy?.backend === "network" || policy?.backend === "local" || policy?.backend === "inherit") {
80
- return policy.backend;
81
- }
82
- if (policy?.provider === "openbmb") {
83
- return "local";
84
- }
85
- if (policy?.model || policy?.provider || policy?.apiKey || policy?.baseUrl) {
86
- return "network";
87
- }
88
- return "inherit";
89
- }
90
- /** Apply enrichment-specific cloud credentials over generic provider env (network backend only). */
91
- function prepareSemanticEnrichmentRuntime(configPath) {
92
- if (!configPath) {
93
- return;
94
- }
95
- const config = (0, resolve_1.resolveConfig)(configPath);
96
- applyOpenBmbRuntimeEnv(config);
97
- applyEnrichmentProviderEnv(config);
98
- }
99
- function applyEnrichmentProviderEnv(config) {
100
- const policy = config.graphPolicy.semanticEnrichment;
101
- const backend = resolveEnrichmentBackend(policy);
102
- if (backend === "local") {
103
- return;
104
- }
105
- const providerName = (policy?.provider ?? config.tiers.economy.provider).toUpperCase();
106
- const providerCfg = config.providers[providerName.toLowerCase()] ?? {};
107
- const apiKey = (0, secrets_1.resolveConfigSecret)(policy?.apiKey) ?? (0, secrets_1.resolveConfigSecret)(providerCfg.apiKey);
108
- const baseUrl = policy?.baseUrl ?? providerCfg.baseUrl;
109
- if (apiKey) {
110
- process.env[`${providerName}_API_KEY`] = apiKey;
111
- }
112
- if (baseUrl) {
113
- process.env[`${providerName}_BASE_URL`] = baseUrl;
114
- }
115
- }
116
- function applyOpenBmbRuntimeEnv(config) {
117
- const genericProviders = ["openai", "anthropic", "bailian", "doubao"];
118
- for (const name of genericProviders) {
119
- const cfg = config.providers[name];
120
- if (!cfg) {
121
- continue;
122
- }
123
- const envPrefix = name.toUpperCase();
124
- const apiKey = (0, secrets_1.resolveConfigSecret)(cfg.apiKey);
125
- if (apiKey) {
126
- process.env[`${envPrefix}_API_KEY`] = apiKey;
127
- }
128
- if (cfg.baseUrl) {
129
- process.env[`${envPrefix}_BASE_URL`] = cfg.baseUrl;
130
- }
131
- }
132
- const openbmb = config.providers.openbmb;
133
- if (!openbmb) {
134
- return;
135
- }
136
- if (openbmb.mode) {
137
- process.env.GRAPHFLOW_OPENBMB_MODE = openbmb.mode;
138
- }
139
- if (openbmb.baseUrl) {
140
- process.env.GRAPHFLOW_OPENBMB_BASE_URL = openbmb.baseUrl;
141
- }
142
- const openbmbApiKey = (0, secrets_1.resolveConfigSecret)(openbmb.apiKey);
143
- if (openbmbApiKey) {
144
- process.env.GRAPHFLOW_OPENBMB_API_KEY = openbmbApiKey;
145
- }
146
- const modelPath = (0, secrets_1.resolveConfigSecret)(openbmb.modelPath);
147
- if (modelPath) {
148
- process.env.GRAPHFLOW_OPENBMB_MODEL_PATH = modelPath;
149
- }
150
- const commandPath = (0, secrets_1.resolveConfigSecret)(openbmb.commandPath);
151
- if (commandPath) {
152
- process.env.GRAPHFLOW_MINICPM_COMMAND = commandPath;
153
- }
154
- if (openbmb.modelUrl) {
155
- process.env.GRAPHFLOW_MINICPM_MODEL_URL = openbmb.modelUrl;
156
- }
157
- if (openbmb.modelSha256) {
158
- process.env.GRAPHFLOW_MINICPM_MODEL_SHA256 = openbmb.modelSha256;
159
- }
160
- if (openbmb.autoDownloadModel !== undefined) {
161
- process.env.GRAPHFLOW_OPENBMB_AUTO_DOWNLOAD = openbmb.autoDownloadModel ? "1" : "0";
162
- }
163
- if (openbmb.engine) {
164
- process.env.GRAPHFLOW_MINICPM_ENGINE = openbmb.engine;
165
- }
166
- if (openbmb.timeoutMs !== undefined) {
167
- process.env.GRAPHFLOW_OPENBMB_TIMEOUT_MS = String(openbmb.timeoutMs);
168
- }
169
- if (openbmb.maxTokens !== undefined) {
170
- process.env.GRAPHFLOW_OPENBMB_MAX_TOKENS = String(openbmb.maxTokens);
171
- }
172
- if (openbmb.temperature !== undefined) {
173
- process.env.GRAPHFLOW_OPENBMB_TEMPERATURE = String(openbmb.temperature);
174
- }
175
- const evolution = config.learningPolicy.skillEvolution;
176
- if (evolution?.model) {
177
- process.env.GRAPHFLOW_SKILL_EVOLVE_MODEL = evolution.model;
178
- }
179
- if (evolution?.minCoOccur !== undefined) {
180
- process.env.GRAPHFLOW_SKILL_EVOLVE_MIN_COOCCUR = String(evolution.minCoOccur);
181
- }
182
- if (evolution?.minSuccess !== undefined) {
183
- process.env.GRAPHFLOW_SKILL_EVOLVE_MIN_SUCCESS = String(evolution.minSuccess);
184
- }
185
- process.env.GRAPHFLOW_SKILL_TRIPLE_FUSION = evolution?.enableTripleFusion === false ? "0" : "1";
186
- }
187
- function getGraphFlowSettings(configPath = "graphflow.config.json") {
188
- const actualPath = (0, resolve_1.resolveConfigPath)(configPath);
189
- const config = (0, resolve_1.resolveConfig)(actualPath);
190
- const provider = config.tiers.smart.provider;
191
- const rawConfig = readRawConfig(actualPath);
192
- const providerConfig = config.providers[provider] ?? {};
193
- const rawProviderConfig = rawConfig?.providers?.[provider] ?? {};
194
- const rawOpenBmbConfig = rawConfig?.providers?.openbmb ?? {};
195
- const openbmbConfig = config.providers.openbmb ?? {};
196
- const apiKeyEnvVar = (0, secrets_1.formatApiKeyForSettings)(rawProviderConfig.apiKey ?? providerConfig.apiKey);
197
- const openbmbModelUrl = rawOpenBmbConfig.modelUrl ?? openbmbConfig.modelUrl ?? process.env.GRAPHFLOW_MINICPM_MODEL_URL;
198
- const openbmbModelSha256 = rawOpenBmbConfig.modelSha256 ?? openbmbConfig.modelSha256 ?? process.env.GRAPHFLOW_MINICPM_MODEL_SHA256;
199
- const openbmbAutoDownloadRaw = rawOpenBmbConfig.autoDownloadModel ?? openbmbConfig.autoDownloadModel;
200
- const openbmbAutoDownload = typeof openbmbAutoDownloadRaw === "boolean"
201
- ? openbmbAutoDownloadRaw
202
- : String(process.env.GRAPHFLOW_OPENBMB_AUTO_DOWNLOAD ?? "0") === "1";
203
- return {
204
- configPath: actualPath,
205
- provider,
206
- smartModel: config.tiers.smart.model ?? "",
207
- economyModel: config.tiers.economy.model ?? "",
208
- ...(apiKeyEnvVar ? { apiKeyEnvVar } : {}),
209
- ...(rawProviderConfig.baseUrl || providerConfig.baseUrl
210
- ? { baseUrl: rawProviderConfig.baseUrl ?? providerConfig.baseUrl }
211
- : {}),
212
- maxContextTokens: config.graphPolicy.maxContextTokens,
213
- layerQuota: config.graphPolicy.layerQuota ?? { l1: 6, l2: 4, l3: 3 },
214
- enableNearLosslessMode: config.graphPolicy.enableNearLosslessMode ?? false,
215
- autoIndexOnPreview: config.graphPolicy.autoIndexOnPreview ?? true,
216
- autoIndexOnRun: config.graphPolicy.autoIndexOnRun ?? true,
217
- autoIndexOnSave: config.graphPolicy.autoIndexOnSave ?? false,
218
- transport: config.graphPolicy.transport,
219
- graphStorePath: config.graphPolicy.graphStorePath ?? "tmp/graphflow-graph.json",
220
- enrichmentBackend: resolveEnrichmentBackend(config.graphPolicy.semanticEnrichment),
221
- enrichmentProvider: config.graphPolicy.semanticEnrichment?.provider ?? "",
222
- enrichmentModel: config.graphPolicy.semanticEnrichment?.model ?? "",
223
- ...(() => {
224
- const enrichPolicy = config.graphPolicy.semanticEnrichment;
225
- const enrichProvider = enrichPolicy?.provider ?? config.tiers.economy.provider;
226
- const rawEnrichPolicy = rawConfig?.graphPolicy?.semanticEnrichment ?? {};
227
- const rawEnrichProvider = rawConfig?.providers?.[enrichProvider] ?? {};
228
- const apiKey = (0, secrets_1.formatApiKeyForSettings)(rawEnrichPolicy.apiKey ?? rawEnrichProvider.apiKey);
229
- const baseUrl = rawEnrichPolicy.baseUrl ?? rawEnrichProvider.baseUrl;
230
- return {
231
- ...(apiKey ? { enrichmentApiKey: apiKey } : {}),
232
- ...(typeof baseUrl === "string" && baseUrl.trim() ? { enrichmentBaseUrl: baseUrl.trim() } : {}),
233
- };
234
- })(),
235
- openbmbMode: (openbmbConfig.mode ?? "embedded"),
236
- openbmbEngine: (openbmbConfig.engine ?? "command"),
237
- openbmbModel: config.learningPolicy.skillEvolution?.model ??
238
- (provider === "openbmb" ? config.tiers.economy.model ?? config.tiers.smart.model ?? "" : ""),
239
- ...(rawOpenBmbConfig.baseUrl || openbmbConfig.baseUrl
240
- ? { openbmbBaseUrl: rawOpenBmbConfig.baseUrl ?? openbmbConfig.baseUrl }
241
- : {}),
242
- ...(rawOpenBmbConfig.modelPath || openbmbConfig.modelPath
243
- ? { openbmbModelPath: rawOpenBmbConfig.modelPath ?? openbmbConfig.modelPath }
244
- : {}),
245
- ...(rawOpenBmbConfig.commandPath || openbmbConfig.commandPath
246
- ? { openbmbCommandPath: rawOpenBmbConfig.commandPath ?? openbmbConfig.commandPath }
247
- : {}),
248
- openbmbAutoDownload,
249
- ...(typeof openbmbModelUrl === "string" && openbmbModelUrl.trim().length > 0
250
- ? { openbmbModelUrl }
251
- : {}),
252
- ...(typeof openbmbModelSha256 === "string" && openbmbModelSha256.trim().length > 0
253
- ? { openbmbModelSha256 }
254
- : {}),
255
- };
256
- }
257
- function saveGraphFlowSettings(settings, configPath = "graphflow.config.json") {
258
- const actualPath = (0, resolve_1.resolveConfigPath)(configPath);
259
- const current = (0, resolve_1.resolveConfig)(actualPath);
260
- const providerConfig = {
261
- ...(settings.apiKeyEnvVar?.trim() ? { apiKey: (0, secrets_1.formatApiKeyForConfig)(settings.apiKeyEnvVar) } : {}),
262
- ...(settings.baseUrl ? { baseUrl: settings.baseUrl } : {}),
263
- };
264
- const openbmbProviderConfig = {
265
- ...(settings.openbmbBaseUrl ? { baseUrl: settings.openbmbBaseUrl } : {}),
266
- ...(settings.openbmbModelPath ? { modelPath: settings.openbmbModelPath } : {}),
267
- ...(settings.openbmbCommandPath ? { commandPath: settings.openbmbCommandPath } : {}),
268
- ...(settings.openbmbModelUrl ? { modelUrl: settings.openbmbModelUrl } : {}),
269
- ...(settings.openbmbModelSha256 ? { modelSha256: settings.openbmbModelSha256 } : {}),
270
- mode: settings.openbmbMode,
271
- engine: settings.openbmbEngine,
272
- autoDownloadModel: settings.openbmbAutoDownload,
273
- };
274
- const nextSmartModel = settings.provider === "openbmb" ? settings.openbmbModel : settings.smartModel;
275
- const nextEconomyModel = settings.provider === "openbmb" ? settings.openbmbModel : settings.economyModel;
276
- const updated = (0, loader_1.validateConfig)({
277
- ...current,
278
- providers: {
279
- ...current.providers,
280
- [settings.provider]: providerConfig,
281
- openbmb: {
282
- ...(current.providers.openbmb ?? {}),
283
- ...openbmbProviderConfig,
284
- },
285
- },
286
- tiers: {
287
- smart: {
288
- provider: settings.provider,
289
- ...(nextSmartModel?.trim()
290
- ? { model: nextSmartModel.trim() }
291
- : current.tiers.smart.model
292
- ? { model: current.tiers.smart.model }
293
- : {}),
294
- },
295
- economy: {
296
- provider: settings.provider,
297
- ...(nextEconomyModel?.trim()
298
- ? { model: nextEconomyModel.trim() }
299
- : current.tiers.economy.model
300
- ? { model: current.tiers.economy.model }
301
- : {}),
302
- },
303
- },
304
- graphPolicy: {
305
- ...current.graphPolicy,
306
- enableNearLosslessMode: settings.enableNearLosslessMode,
307
- autoIndexOnPreview: settings.autoIndexOnPreview,
308
- autoIndexOnRun: settings.autoIndexOnRun,
309
- autoIndexOnSave: settings.autoIndexOnSave,
310
- transport: settings.transport,
311
- graphStorePath: settings.graphStorePath,
312
- maxContextTokens: Math.max(1, Math.floor(settings.maxContextTokens)),
313
- layerQuota: {
314
- l1: Math.max(0, Math.floor(settings.layerQuota.l1)),
315
- l2: Math.max(0, Math.floor(settings.layerQuota.l2)),
316
- l3: Math.max(0, Math.floor(settings.layerQuota.l3)),
317
- },
318
- semanticEnrichment: {
319
- ...(current.graphPolicy.semanticEnrichment ?? {}),
320
- backend: settings.enrichmentBackend,
321
- ...(settings.enrichmentBackend === "local"
322
- ? { provider: "openbmb" }
323
- : settings.enrichmentProvider?.trim()
324
- ? { provider: settings.enrichmentProvider.trim() }
325
- : settings.enrichmentBackend === "inherit"
326
- ? {}
327
- : current.graphPolicy.semanticEnrichment?.provider
328
- ? { provider: current.graphPolicy.semanticEnrichment.provider }
329
- : {}),
330
- ...(settings.enrichmentModel?.trim()
331
- ? { model: settings.enrichmentModel.trim() }
332
- : current.graphPolicy.semanticEnrichment?.model
333
- ? { model: current.graphPolicy.semanticEnrichment.model }
334
- : {}),
335
- ...(settings.enrichmentBackend !== "local" && settings.enrichmentApiKey?.trim()
336
- ? { apiKey: (0, secrets_1.formatApiKeyForConfig)(settings.enrichmentApiKey) }
337
- : {}),
338
- ...(settings.enrichmentBackend !== "local" && settings.enrichmentBaseUrl?.trim()
339
- ? { baseUrl: settings.enrichmentBaseUrl.trim() }
340
- : {}),
341
- },
342
- },
343
- learningPolicy: {
344
- ...current.learningPolicy,
345
- skillEvolution: {
346
- ...(current.learningPolicy.skillEvolution ?? {}),
347
- ...(settings.openbmbModel?.trim() ? { model: settings.openbmbModel.trim() } : {}),
348
- },
349
- },
350
- });
351
- if (settings.openbmbModelUrl) {
352
- process.env.GRAPHFLOW_MINICPM_MODEL_URL = settings.openbmbModelUrl;
353
- }
354
- if (settings.openbmbModelSha256) {
355
- process.env.GRAPHFLOW_MINICPM_MODEL_SHA256 = settings.openbmbModelSha256;
356
- }
357
- process.env.GRAPHFLOW_OPENBMB_AUTO_DOWNLOAD = settings.openbmbAutoDownload ? "1" : "0";
358
- const dir = (0, node_path_1.dirname)(actualPath);
359
- if (dir && dir !== ".") {
360
- (0, node_fs_1.mkdirSync)(dir, { recursive: true });
361
- }
362
- (0, node_fs_1.writeFileSync)(actualPath, `${JSON.stringify(updated, null, 2)}\n`, "utf8");
363
- return getGraphFlowSettings(actualPath);
364
- }
365
- async function previewContext(query, configPath) {
366
- const config = (0, resolve_1.resolveConfig)(configPath);
367
- applyOpenBmbRuntimeEnv(config);
368
- const graphClient = (0, client_factory_1.createGraphClient)(config);
369
- if (config.graphPolicy.autoIndexOnPreview) {
370
- const indexOptions = config.graphPolicy.includeExtensions
371
- ? { includeExtensions: config.graphPolicy.includeExtensions }
372
- : undefined;
373
- await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, config.graphPolicy.workspaceRoot ?? process.cwd(), {
374
- ...indexOptions,
375
- });
376
- }
377
- const packageOptions = {
378
- ...(config.graphPolicy.layerQuota ? { layerQuota: config.graphPolicy.layerQuota } : {}),
379
- ...buildEmbeddingOptions(config),
380
- };
381
- const pkg = await (0, context_slicer_1.buildLayeredContextPackage)(graphClient, query, config.graphPolicy.maxContextTokens, packageOptions);
382
- const refill = (0, context_slicer_1.createContextRefillManager)(graphClient, config.graphPolicy.maxContextTokens, packageOptions);
383
- await refill.initialPackage(query);
384
- const refillPreview = await refill.refill([query]);
385
- const rawTokenEstimate = estimateRawContextTokens(await resolveGraphStoreAfterIndex(config, graphClient), query, pkg.tokenEstimate);
386
- return {
387
- query,
388
- summaryCount: pkg.summaryChannel.length,
389
- anchorCount: pkg.anchorChannel.length,
390
- tokenEstimate: pkg.tokenEstimate,
391
- truncated: pkg.truncated,
392
- anchorsByLayer: {
393
- l1: pkg.anchorChannel.filter((item) => item.layer === "L1").length,
394
- l2: pkg.anchorChannel.filter((item) => item.layer === "L2").length,
395
- l3: pkg.anchorChannel.filter((item) => item.layer === "L3").length,
396
- },
397
- refillPreview,
398
- summary: pkg.summaryChannel,
399
- anchors: pkg.anchorChannel,
400
- tokenBudget: {
401
- maxContextTokens: config.graphPolicy.maxContextTokens,
402
- estimatedRawTokens: rawTokenEstimate,
403
- compressedTokens: pkg.tokenEstimate,
404
- estimatedSavingsPercent: calculateSavingsPercent(rawTokenEstimate, pkg.tokenEstimate),
405
- budgetUsedPercent: calculateBudgetUsedPercent(pkg.tokenEstimate, config.graphPolicy.maxContextTokens),
406
- },
407
- };
408
- }
409
- async function indexGraph(rootDir, configPath) {
410
- const config = (0, resolve_1.resolveConfig)(configPath);
411
- applyOpenBmbRuntimeEnv(config);
412
- const graphClient = (0, client_factory_1.createGraphClient)(config);
413
- const targetDir = rootDir || config.graphPolicy.workspaceRoot || process.cwd();
414
- const indexOptions = config.graphPolicy.includeExtensions
415
- ? { includeExtensions: config.graphPolicy.includeExtensions }
416
- : undefined;
417
- const indexed = await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, targetDir, {
418
- ...indexOptions,
419
- });
420
- await maybeRunSemanticEnrichment(config, graphClient);
421
- return indexed;
422
- }
423
- async function rebuildGraph(rootDir, configPath) {
424
- const config = (0, resolve_1.resolveConfig)(configPath);
425
- applyOpenBmbRuntimeEnv(config);
426
- const graphClient = (0, client_factory_1.createGraphClient)(config);
427
- const targetDir = rootDir || config.graphPolicy.workspaceRoot || process.cwd();
428
- const storePath = (0, paths_1.resolveGraphStorePath)(config);
429
- (0, file_indexer_1.clearGraphIndexArtifacts)(targetDir, storePath);
430
- const indexOptions = config.graphPolicy.includeExtensions
431
- ? { includeExtensions: config.graphPolicy.includeExtensions }
432
- : undefined;
433
- const indexed = await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, targetDir, {
434
- ...indexOptions,
435
- forceReindex: true,
436
- });
437
- await maybeRunSemanticEnrichment(config, graphClient);
438
- return {
439
- ...indexed,
440
- cleared: true,
441
- storePath,
442
- };
443
- }
444
- async function maybeRunSemanticEnrichment(config, graphClient) {
445
- const enrichPolicy = config.graphPolicy.semanticEnrichment;
446
- if (!enrichPolicy?.enabled || !enrichPolicy.autoRunOnIndex || enrichPolicy.mode === "off") {
447
- return;
448
- }
449
- const selection = (0, model_router_1.resolveModelForRole)("enricher");
450
- const health = (0, provider_health_1.buildProviderHealthMap)(config);
451
- if (!health[selection.provider]) {
452
- logger_1.logger.warn(`Skipping semantic enrichment: ${selection.provider} provider is not configured or healthy`);
453
- return;
454
- }
455
- applyEnrichmentProviderEnv(config);
456
- try {
457
- await (0, semantic_enricher_1.enrichGraphSemanticsSilent)(graphClient, {
458
- ...(enrichPolicy.batchSize !== undefined ? { batchSize: enrichPolicy.batchSize } : {}),
459
- ...(enrichPolicy.sleepMs !== undefined ? { sleepMs: enrichPolicy.sleepMs } : {}),
460
- ...(enrichPolicy.model ? { model: enrichPolicy.model } : {}),
461
- ...(enrichPolicy.timeoutMs !== undefined ? { timeoutMs: enrichPolicy.timeoutMs } : {}),
462
- });
463
- }
464
- catch (error) {
465
- logger_1.logger.warn({ error }, "Semantic enrichment skipped after provider failure");
466
- }
467
- }
468
- async function enrichSemanticsSilent(configPath, options) {
469
- const config = (0, resolve_1.resolveConfig)(configPath);
470
- applyOpenBmbRuntimeEnv(config);
471
- applyEnrichmentProviderEnv(config);
472
- const graphClient = (0, client_factory_1.createGraphClient)(config);
473
- const enrichPolicy = config.graphPolicy.semanticEnrichment;
474
- const enricherOptions = {};
475
- const batchSize = options?.batchSize ?? enrichPolicy?.batchSize;
476
- if (batchSize !== undefined) {
477
- enricherOptions.batchSize = batchSize;
478
- }
479
- const sleepMs = options?.sleepMs ?? enrichPolicy?.sleepMs;
480
- if (sleepMs !== undefined) {
481
- enricherOptions.sleepMs = sleepMs;
482
- }
483
- const timeoutMs = options?.timeoutMs ?? enrichPolicy?.timeoutMs;
484
- if (timeoutMs !== undefined) {
485
- enricherOptions.timeoutMs = timeoutMs;
486
- }
487
- if (enrichPolicy?.model) {
488
- enricherOptions.model = enrichPolicy.model;
489
- }
490
- return (0, semantic_enricher_1.enrichGraphSemanticsSilent)(graphClient, enricherOptions);
491
- }
492
- async function downloadOpenBmbModel(configPath, options) {
493
- const config = (0, resolve_1.resolveConfig)(configPath);
494
- applyOpenBmbRuntimeEnv(config);
495
- const model = options?.model ?? "minicpm5-1b";
496
- const defaultUrl = process.env.GRAPHFLOW_MINICPM_MODEL_URL;
497
- const url = options?.url ?? defaultUrl;
498
- const configuredPath = options?.targetPath ?? config.providers.openbmb?.modelPath;
499
- const fallbackPath = (0, node_path_1.join)((0, node_os_1.tmpdir)(), "graphflow-models", `${model}.gguf`);
500
- const targetPath = configuredPath ?? fallbackPath;
501
- const force = options?.force ?? false;
502
- const expectedSha = options?.sha256 ?? process.env.GRAPHFLOW_MINICPM_MODEL_SHA256;
503
- const partialPath = `${targetPath}.part`;
504
- const lockPath = `${targetPath}.lock`;
505
- return (0, file_lock_1.withFileLock)(lockPath, async () => {
506
- if ((0, node_fs_1.existsSync)(targetPath) && !force) {
507
- const bytes = getFileSize(targetPath);
508
- const verified = expectedSha ? (await sha256File(targetPath)) === expectedSha.toLowerCase() : true;
509
- options?.onProgress?.({
510
- model,
511
- targetPath,
512
- downloadedBytes: bytes,
513
- totalBytes: bytes,
514
- resumed: false,
515
- percent: 100,
516
- stage: "skipped",
517
- });
518
- return {
519
- model,
520
- targetPath,
521
- bytes,
522
- skipped: true,
523
- verified,
524
- };
525
- }
526
- if (!url) {
527
- throw new Error("Model download URL is required. Set GRAPHFLOW_MINICPM_MODEL_URL or pass --url.");
528
- }
529
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(targetPath), { recursive: true });
530
- let partialSize = 0;
531
- if ((0, node_fs_1.existsSync)(partialPath) && !force) {
532
- try {
533
- partialSize = (0, node_fs_1.statSync)(partialPath).size;
534
- }
535
- catch {
536
- partialSize = 0;
537
- }
538
- }
539
- if (force) {
540
- (0, node_fs_1.rmSync)(partialPath, { force: true });
541
- partialSize = 0;
542
- }
543
- options?.onProgress?.({
544
- model,
545
- targetPath,
546
- downloadedBytes: partialSize,
547
- resumed: partialSize > 0,
548
- stage: "starting",
549
- });
550
- const fetchInit = {};
551
- if (partialSize > 0) {
552
- fetchInit.headers = { range: `bytes=${partialSize}-` };
553
- }
554
- const response = await fetch(url, fetchInit);
555
- if (!response.ok) {
556
- throw new Error(`Model download failed: ${response.status} ${response.statusText}`);
557
- }
558
- const acceptsRange = response.status === 206;
559
- if (!acceptsRange && partialSize > 0) {
560
- (0, node_fs_1.rmSync)(partialPath, { force: true });
561
- partialSize = 0;
562
- }
563
- const contentLength = Number(response.headers.get("content-length") ?? "0");
564
- const totalBytes = Number.isFinite(contentLength) && contentLength > 0
565
- ? partialSize + contentLength
566
- : undefined;
567
- const stream = response.body;
568
- if (!stream) {
569
- throw new Error("Model download failed: empty response body");
570
- }
571
- const reader = stream.getReader();
572
- const resumed = partialSize > 0 && acceptsRange;
573
- const writer = (0, node_fs_1.createWriteStream)(partialPath, { flags: resumed ? "a" : "w" });
574
- let downloadedBytes = partialSize;
575
- let lastReportedBytes = -1;
576
- const emitProgress = (stage) => {
577
- if (downloadedBytes === lastReportedBytes && stage === "downloading") {
578
- return;
579
- }
580
- lastReportedBytes = downloadedBytes;
581
- const percent = totalBytes && totalBytes > 0
582
- ? Math.min(100, Number(((downloadedBytes / totalBytes) * 100).toFixed(1)))
583
- : undefined;
584
- options?.onProgress?.({
585
- model,
586
- targetPath,
587
- downloadedBytes,
588
- ...(totalBytes ? { totalBytes } : {}),
589
- resumed,
590
- ...(percent !== undefined ? { percent } : {}),
591
- stage,
592
- });
593
- };
594
- emitProgress("downloading");
595
- while (true) {
596
- const { done, value } = await reader.read();
597
- if (done) {
598
- break;
599
- }
600
- if (value) {
601
- const chunk = Buffer.from(value);
602
- await new Promise((resolve, reject) => {
603
- writer.write(chunk, (error) => {
604
- if (error) {
605
- reject(error);
606
- return;
607
- }
608
- resolve();
609
- });
610
- });
611
- downloadedBytes += chunk.length;
612
- emitProgress("downloading");
613
- }
614
- }
615
- await new Promise((resolve, reject) => {
616
- writer.end((error) => {
617
- if (error) {
618
- reject(error);
619
- return;
620
- }
621
- resolve();
622
- });
623
- });
624
- (0, node_fs_1.renameSync)(partialPath, targetPath);
625
- if (expectedSha) {
626
- options?.onProgress?.({
627
- model,
628
- targetPath,
629
- downloadedBytes,
630
- ...(totalBytes ? { totalBytes } : {}),
631
- resumed,
632
- percent: 100,
633
- stage: "verifying",
634
- });
635
- const actual = await sha256File(targetPath);
636
- if (actual !== expectedSha.toLowerCase()) {
637
- (0, node_fs_1.rmSync)(targetPath, { force: true });
638
- throw new Error(`Model sha256 mismatch. expected=${expectedSha.toLowerCase()} actual=${actual}`);
639
- }
640
- }
641
- const finalBytes = getFileSize(targetPath);
642
- options?.onProgress?.({
643
- model,
644
- targetPath,
645
- downloadedBytes: finalBytes,
646
- totalBytes: finalBytes,
647
- resumed,
648
- percent: 100,
649
- stage: "completed",
650
- });
651
- return {
652
- model,
653
- targetPath,
654
- bytes: finalBytes,
655
- skipped: false,
656
- verified: Boolean(expectedSha),
657
- ...(resumed ? { resumed: true } : {}),
658
- };
659
- });
660
- }
661
- async function inspectGraph(configPath, options) {
662
- const config = (0, resolve_1.resolveConfig)(configPath);
663
- const nodeLimit = Math.max(1, options?.nodeLimit ?? 24);
664
- const edgeLimit = Math.max(1, options?.edgeLimit ?? 36);
665
- const emptyTypeCount = {
666
- File: 0,
667
- Symbol: 0,
668
- Module: 0,
669
- TaskRun: 0,
670
- Decision: 0,
671
- Skill: 0,
672
- };
673
- if (config.graphPolicy.transport === "mcp-http") {
674
- return {
675
- transport: config.graphPolicy.transport,
676
- storePath: (0, paths_1.resolveGraphStorePath)(config),
677
- nodeCount: 0,
678
- edgeCount: 0,
679
- nodeTypeCount: emptyTypeCount,
680
- topRelations: [],
681
- sampleNodes: [],
682
- sampleEdges: [],
683
- };
684
- }
685
- let store = loadGraphStore(config);
686
- if (store.nodes.length === 0) {
687
- const graphClient = (0, client_factory_1.createGraphClient)(config);
688
- const indexOptions = config.graphPolicy.includeExtensions
689
- ? { includeExtensions: config.graphPolicy.includeExtensions }
690
- : undefined;
691
- await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, config.graphPolicy.workspaceRoot ?? process.cwd(), {
692
- ...indexOptions,
693
- });
694
- store = await resolveGraphStoreAfterIndex(config, graphClient);
695
- }
696
- const relationCounts = new Map();
697
- for (const edge of store.edges) {
698
- relationCounts.set(edge.relation, (relationCounts.get(edge.relation) ?? 0) + 1);
699
- }
700
- const nodeTypeCount = { ...emptyTypeCount };
701
- for (const node of store.nodes) {
702
- nodeTypeCount[node.type] += 1;
703
- }
704
- return {
705
- transport: config.graphPolicy.transport,
706
- storePath: (0, paths_1.resolveGraphStorePath)(config),
707
- nodeCount: store.nodes.length,
708
- edgeCount: store.edges.length,
709
- nodeTypeCount,
710
- topRelations: Array.from(relationCounts.entries())
711
- .map(([relation, count]) => ({ relation, count }))
712
- .sort((a, b) => b.count - a.count || a.relation.localeCompare(b.relation))
713
- .slice(0, 8),
714
- ...(() => {
715
- const isMetaFile = (id) => {
716
- const lower = id.toLowerCase();
717
- return lower.includes(".md") || lower.includes(".json") || lower.includes(".yml") || lower.includes(".yaml") || lower.includes(".github") || lower.includes(".claude") || lower.includes(".codex");
718
- };
719
- const adj = new Map();
720
- for (const e of store.edges) {
721
- if (!adj.has(e.from))
722
- adj.set(e.from, []);
723
- if (!adj.has(e.to))
724
- adj.set(e.to, []);
725
- adj.get(e.from).push(e.to);
726
- adj.get(e.to).push(e.from);
727
- }
728
- const nodeMap = new Map(store.nodes.map(n => [n.id, n]));
729
- const degree = (id) => adj.get(id)?.length || 0;
730
- const sortedCandidates = store.nodes
731
- .filter(n => n.type === "File" && !isMetaFile(n.id))
732
- .sort((a, b) => degree(b.id) - degree(a.id));
733
- if (sortedCandidates.length === 0) {
734
- return { sampleNodes: [], sampleEdges: [] };
735
- }
736
- const visited = new Set();
737
- const selected = [];
738
- let candidateIndex = 0;
739
- while (selected.length < nodeLimit && candidateIndex < sortedCandidates.length) {
740
- let root = sortedCandidates[candidateIndex++];
741
- while (root && visited.has(root.id) && candidateIndex < sortedCandidates.length) {
742
- root = sortedCandidates[candidateIndex++];
743
- }
744
- if (!root || visited.has(root.id))
745
- break;
746
- const queue = [root.id];
747
- while (queue.length > 0 && selected.length < nodeLimit) {
748
- const id = queue.shift();
749
- if (visited.has(id))
750
- continue;
751
- visited.add(id);
752
- const node = nodeMap.get(id);
753
- if (node) {
754
- selected.push(node);
755
- const neighbors = adj.get(id) || [];
756
- queue.push(...neighbors);
757
- }
758
- }
759
- }
760
- const sampleNodeIds = new Set(selected.map(n => n.id));
761
- return {
762
- sampleNodes: selected.map(node => ({
763
- id: node.id,
764
- type: node.type,
765
- contentPreview: compactPreview(node.content, 96),
766
- })),
767
- sampleEdges: store.edges
768
- .filter(edge => sampleNodeIds.has(edge.from) && sampleNodeIds.has(edge.to))
769
- .slice(0, edgeLimit)
770
- .map(edge => ({
771
- from: edge.from,
772
- relation: edge.relation,
773
- to: edge.to,
774
- }))
775
- };
776
- })(),
777
- };
778
- }
779
- async function getSkillInsights(configPath, limit = 12) {
780
- const config = (0, resolve_1.resolveConfig)(configPath);
781
- const boundedLimit = Math.max(1, limit);
782
- if (config.graphPolicy.transport === "mcp-http") {
783
- return {
784
- source: "unavailable",
785
- transport: config.graphPolicy.transport,
786
- storePath: (0, paths_1.resolveGraphStorePath)(config),
787
- skills: [],
788
- };
789
- }
790
- let store = loadGraphStore(config);
791
- if (store.nodes.length === 0) {
792
- const graphClient = (0, client_factory_1.createGraphClient)(config);
793
- const indexOptions = config.graphPolicy.includeExtensions
794
- ? { includeExtensions: config.graphPolicy.includeExtensions }
795
- : undefined;
796
- await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, config.graphPolicy.workspaceRoot ?? process.cwd(), {
797
- ...indexOptions,
798
- });
799
- store = await resolveGraphStoreAfterIndex(config, graphClient);
800
- }
801
- const skills = store.nodes
802
- .filter((node) => node.type === "Skill")
803
- .map((node) => parseSkillInsight(node))
804
- .filter((state) => Boolean(state))
805
- .sort((a, b) => b.score - a.score || b.uses - a.uses || b.updatedAt - a.updatedAt)
806
- .slice(0, boundedLimit);
807
- return {
808
- source: "graph-store",
809
- transport: config.graphPolicy.transport,
810
- storePath: (0, paths_1.resolveGraphStorePath)(config),
811
- skills,
812
- };
813
- }
814
- async function runTaskResult(task, configPath) {
815
- const config = (0, resolve_1.resolveConfig)(configPath);
816
- applyOpenBmbRuntimeEnv(config);
817
- const eventsPath = (0, paths_1.resolveLearningPath)(config, "eventsPath");
818
- try {
819
- const graphClient = (0, client_factory_1.createGraphClient)(config);
820
- if (config.graphPolicy.autoIndexOnRun) {
821
- const indexOptions = config.graphPolicy.includeExtensions
822
- ? { includeExtensions: config.graphPolicy.includeExtensions }
823
- : undefined;
824
- await (0, file_indexer_1.indexWorkspaceFiles)(graphClient, config.graphPolicy.workspaceRoot ?? process.cwd(), {
825
- ...indexOptions,
826
- });
827
- }
828
- const embeddingOptions = buildEmbeddingOptions(config);
829
- const orchestrateOptions = {
830
- graphClient,
831
- enableAutoGraphSync: config.graphPolicy.enableAutoBuild,
832
- maxContextTokens: config.graphPolicy.maxContextTokens,
833
- enableEpisodicMemory: config.learningPolicy.enableFlywheel,
834
- enableLlmAgents: config.tiers.smart.provider === "openbmb" || config.tiers.economy.provider === "openbmb",
835
- enableLlmTriage: config.tiers.smart.provider === "openbmb" || config.tiers.economy.provider === "openbmb",
836
- ...(configPath ? { configPath } : {}),
837
- ...embeddingOptions,
838
- ...(config.skillPolicy?.enableSkillFlywheel
839
- ? {
840
- enableSkillFlywheel: true,
841
- ...(config.skillPolicy.maxSkillHints !== undefined
842
- ? { skillHintsLimit: config.skillPolicy.maxSkillHints }
843
- : {}),
844
- }
845
- : { enableSkillFlywheel: false }),
846
- providerHealth: (0, provider_health_1.buildProviderHealthMap)(config),
847
- ...(config.routingPolicy?.enableDynamicRouting
848
- ? { providerFallbackChain: (0, provider_health_1.buildFallbackChain)(config) }
849
- : {}),
850
- ...(config.graphPolicy.enableNearLosslessMode !== undefined
851
- ? { enableNearLosslessMode: config.graphPolicy.enableNearLosslessMode }
852
- : {}),
853
- ...(config.graphPolicy.layerQuota ? { layerQuota: config.graphPolicy.layerQuota } : {}),
854
- };
855
- const result = await (0, orchestrator_1.orchestrate)({ task }, orchestrateOptions);
856
- (0, learning_events_1.appendFeedbackEvent)(eventsPath, {
857
- query: task,
858
- passed: result.status === "COMPLETED",
859
- tokenCost: extractTokenCost(result.feedback),
860
- retries: Math.max(0, result.attempts - 1),
861
- });
862
- return {
863
- status: result.status,
864
- attempts: result.attempts,
865
- feedback: result.feedback,
866
- };
867
- }
868
- catch (error) {
869
- (0, learning_events_1.appendFeedbackEvent)(eventsPath, {
870
- query: task,
871
- passed: false,
872
- tokenCost: 0,
873
- retries: 0,
874
- });
875
- throw error;
876
- }
877
- }
878
- async function runTask(task, configPath) {
879
- const result = await runTaskResult(task, configPath);
880
- return `status=${result.status}; attempts=${result.attempts}; feedback=${result.feedback}`;
881
- }
882
- function diagnoseRoutingResult(configPath) {
883
- const config = (0, resolve_1.resolveConfig)(configPath);
884
- const health = (0, provider_health_1.buildProviderHealthMap)(config);
885
- const chain = (0, provider_health_1.buildFallbackChain)(config);
886
- const resolve = (role) => {
887
- if (!config.routingPolicy?.enableDynamicRouting) {
888
- return (0, model_router_1.resolveModelForRole)(role);
889
- }
890
- return (0, model_router_1.resolveModelWithFallback)(role, health, chain);
891
- };
892
- const planner = resolve("planner");
893
- const worker = resolve("worker");
894
- const validator = resolve("validator");
895
- return {
896
- dynamicRouting: config.routingPolicy?.enableDynamicRouting ?? false,
897
- health,
898
- priority: chain,
899
- planner: {
900
- provider: planner.provider,
901
- model: planner.model,
902
- fallbackApplied: planner.fallbackApplied,
903
- },
904
- worker: {
905
- provider: worker.provider,
906
- model: worker.model,
907
- fallbackApplied: worker.fallbackApplied,
908
- },
909
- validator: {
910
- provider: validator.provider,
911
- model: validator.model,
912
- fallbackApplied: validator.fallbackApplied,
913
- },
914
- };
915
- }
916
- function diagnoseRouting(configPath) {
917
- const result = diagnoseRoutingResult(configPath);
918
- return [
919
- `dynamicRouting=${result.dynamicRouting ? "on" : "off"}`,
920
- `health=openai:${result.health.openai},anthropic:${result.health.anthropic},bailian:${result.health.bailian},doubao:${result.health.doubao},openbmb:${result.health.openbmb}`,
921
- `priority=${result.priority.join(",")}`,
922
- `planner=${result.planner.provider}/${result.planner.model}${result.planner.fallbackApplied ? ":fallback" : ""}`,
923
- `worker=${result.worker.provider}/${result.worker.model}${result.worker.fallbackApplied ? ":fallback" : ""}`,
924
- `validator=${result.validator.provider}/${result.validator.model}${result.validator.fallbackApplied ? ":fallback" : ""}`,
925
- ].join("; ");
926
- }
927
- function hasResolvableApiKey(apiKeyEnvVar) {
928
- if (!apiKeyEnvVar?.trim()) {
929
- return false;
930
- }
931
- return Boolean((0, secrets_1.resolveConfigSecret)((0, secrets_1.formatApiKeyForConfig)(apiKeyEnvVar)));
932
- }
933
- function validateSettingsForGraphIndex(settings) {
934
- const issues = [];
935
- if (!settings.graphStorePath?.trim()) {
936
- issues.push({ field: "graphStorePath", message: "请填写图谱存储路径" });
937
- }
938
- return issues;
939
- }
940
- async function indexGraphFromSettings(settings, workspaceRoot, configPath) {
941
- const validationIssues = validateSettingsForGraphIndex(settings);
942
- const actualPath = (0, resolve_1.resolveConfigPath)(configPath ?? "graphflow.config.json");
943
- if (validationIssues.length > 0) {
944
- return { ok: false, validationIssues };
945
- }
946
- saveGraphFlowSettings(settings, actualPath);
947
- const graphIndex = await indexGraph(workspaceRoot, actualPath);
948
- const snapshot = await inspectGraph(actualPath, { nodeLimit: 1, edgeLimit: 1 });
949
- return {
950
- ok: true,
951
- validationIssues: [],
952
- graphIndex,
953
- graphSnapshot: {
954
- nodeCount: snapshot.nodeCount,
955
- edgeCount: snapshot.edgeCount,
956
- },
957
- };
958
- }
959
- function validateSettingsForRouting(settings) {
960
- const issues = [];
961
- const provider = settings.provider?.trim();
962
- if (!provider) {
963
- issues.push({ field: "provider", message: "请选择 LLM Provider" });
964
- }
965
- if (provider === "openbmb") {
966
- if (settings.openbmbMode === "embedded" && !settings.openbmbModelPath?.trim() && !settings.openbmbAutoDownload) {
967
- issues.push({ field: "openbmbModelPath", message: "本地 OpenBMB 需填写模型路径或勾选自动下载" });
968
- }
969
- if ((settings.openbmbMode === "ollama" || settings.openbmbMode === "openai-compat") &&
970
- !settings.openbmbBaseUrl?.trim()) {
971
- issues.push({ field: "openbmbBaseUrl", message: "OpenBMB 手动模式需填写 Base URL" });
972
- }
973
- }
974
- else if (!hasResolvableApiKey(settings.apiKeyEnvVar)) {
975
- issues.push({ field: "apiKeyEnvVar", message: "请填写可用的 API Key 或已配置的环境变量名" });
976
- }
977
- if (provider === "openai" && !settings.baseUrl?.trim()) {
978
- issues.push({ field: "baseUrl", message: "OpenAI 兼容接口需填写 Base URL(如 DeepSeek)" });
979
- }
980
- if (!settings.graphStorePath?.trim()) {
981
- issues.push({ field: "graphStorePath", message: "请填写图谱存储路径" });
982
- }
983
- if (!settings.enableNearLosslessMode) {
984
- issues.push({ field: "enableNearLosslessMode", message: "请开启 near-lossless 上下文压缩" });
985
- }
986
- if (!settings.autoIndexOnPreview) {
987
- issues.push({ field: "autoIndexOnPreview", message: "请开启 Auto index on preview" });
988
- }
989
- if (!settings.autoIndexOnRun) {
990
- issues.push({ field: "autoIndexOnRun", message: "请开启 Auto index on run" });
991
- }
992
- return issues;
993
- }
994
- function diagnosisRoleToSelection(role, diagnosis) {
995
- const entry = diagnosis[role];
996
- return {
997
- provider: entry.provider,
998
- model: entry.model,
999
- tier: role === "planner" ? "smart" : "economy",
1000
- fallbackApplied: entry.fallbackApplied,
1001
- };
1002
- }
1003
- async function probeRoleConnectivity(role, selection) {
1004
- const started = Date.now();
1005
- try {
1006
- const sample = await (0, provider_executor_1.executeRolePrompt)(role, "Reply with exactly: ok", selection);
1007
- const cleaned = sample.trim().slice(0, 120);
1008
- const ok = cleaned.length > 0 && !/^\[(openai|anthropic|openbmb|bailian|doubao):/i.test(cleaned);
1009
- return {
1010
- role,
1011
- provider: selection.provider,
1012
- model: selection.model,
1013
- ok,
1014
- latencyMs: Date.now() - started,
1015
- sample: cleaned,
1016
- ...(ok ? {} : { error: "Provider returned placeholder/fallback output" }),
1017
- };
1018
- }
1019
- catch (error) {
1020
- return {
1021
- role,
1022
- provider: selection.provider,
1023
- model: selection.model,
1024
- ok: false,
1025
- latencyMs: Date.now() - started,
1026
- error: error instanceof Error ? error.message : String(error),
1027
- };
1028
- }
1029
- }
1030
- async function testRoutingAndIndexGraph(settings, workspaceRoot, configPath) {
1031
- const validationIssues = validateSettingsForRouting(settings);
1032
- const actualPath = (0, resolve_1.resolveConfigPath)(configPath ?? "graphflow.config.json");
1033
- if (validationIssues.length > 0) {
1034
- return {
1035
- ok: false,
1036
- validationIssues,
1037
- diagnosis: diagnoseRoutingResult(actualPath),
1038
- probes: [],
1039
- };
1040
- }
1041
- saveGraphFlowSettings(settings, actualPath);
1042
- const diagnosis = diagnoseRoutingResult(actualPath);
1043
- const probes = await Promise.all([
1044
- probeRoleConnectivity("planner", diagnosisRoleToSelection("planner", diagnosis)),
1045
- probeRoleConnectivity("worker", diagnosisRoleToSelection("worker", diagnosis)),
1046
- ]);
1047
- const connectivityOk = probes.every((probe) => probe.ok);
1048
- if (!connectivityOk) {
1049
- return {
1050
- ok: false,
1051
- validationIssues: [],
1052
- diagnosis,
1053
- probes,
1054
- };
1055
- }
1056
- const graphIndex = await indexGraph(workspaceRoot, actualPath);
1057
- const snapshot = await inspectGraph(actualPath, { nodeLimit: 1, edgeLimit: 1 });
1058
- return {
1059
- ok: true,
1060
- validationIssues: [],
1061
- diagnosis,
1062
- probes,
1063
- graphIndex,
1064
- graphSnapshot: {
1065
- nodeCount: snapshot.nodeCount,
1066
- edgeCount: snapshot.edgeCount,
1067
- },
1068
- };
1069
- }
1070
- async function getSettingsPanelStatus(configPath) {
1071
- const config = (0, resolve_1.resolveConfig)(configPath);
1072
- const snapshot = await inspectGraph(configPath, { nodeLimit: 1, edgeLimit: 1 });
1073
- const storePath = (0, paths_1.resolveGraphStorePath)(config);
1074
- let graphLastModified = null;
1075
- if ((0, node_fs_1.existsSync)(storePath)) {
1076
- graphLastModified = new Date((0, node_fs_1.statSync)(storePath).mtimeMs).toISOString();
1077
- }
1078
- return {
1079
- graphNodeCount: snapshot.nodeCount,
1080
- graphEdgeCount: snapshot.edgeCount,
1081
- graphLastModified,
1082
- diagnoseSummary: diagnoseRouting(configPath),
1083
- overlayKeys: (0, merge_1.listConfigOverlayKeys)(),
1084
- baseConfigPath: (0, node_fs_1.existsSync)("graphflow.config.json") ? "graphflow.config.json" : "(未创建)",
1085
- };
1086
- }
1087
- function runLearningNightlyResult(configPath) {
1088
- const config = (0, resolve_1.resolveConfig)(configPath);
1089
- const summary = (0, nightly_trainer_1.runNightlyLearning)(config);
1090
- return {
1091
- events: summary.totalEvents,
1092
- passRate: summary.passRate,
1093
- avgTokens: summary.averageTokenCost,
1094
- canary: summary.canaryAllowed ? "allow" : "block",
1095
- reason: summary.canaryReason,
1096
- dataset: summary.exportedPath,
1097
- };
1098
- }
1099
- function runLearningNightly(configPath) {
1100
- const result = runLearningNightlyResult(configPath);
1101
- return [
1102
- `events=${result.events}`,
1103
- `passRate=${result.passRate.toFixed(3)}`,
1104
- `avgTokens=${result.avgTokens.toFixed(1)}`,
1105
- `canary=${result.canary}`,
1106
- `reason=${result.reason}`,
1107
- `dataset=${result.dataset}`,
1108
- ].join("; ");
1109
- }
1110
- function planAndBrainstormResult(task) {
1111
- const mode = (0, triage_1.triageTask)(task);
1112
- const ideas = (0, brainstormer_1.brainstormTask)(task);
1113
- const nodes = (0, planner_1.planTasks)(task).map((node) => ({
1114
- id: node.id,
1115
- description: node.description,
1116
- dependencies: node.dependencies,
1117
- }));
1118
- return {
1119
- mode,
1120
- ideas,
1121
- nodes,
1122
- };
1123
- }
1124
- function planAndBrainstorm(task) {
1125
- const result = planAndBrainstormResult(task);
1126
- return [
1127
- `mode=${result.mode}`,
1128
- `ideas=${result.ideas.join(" | ")}`,
1129
- `plan=${result.nodes
1130
- .map((node) => `${node.id}[${node.dependencies.join(",") || "-"}]:${node.description}`)
1131
- .join(" | ")}`,
1132
- ].join("; ");
1133
- }
24
+ var resolve_1 = require("../../config/resolve");
25
+ Object.defineProperty(exports, "resolveConfig", { enumerable: true, get: function () { return resolve_1.resolveConfig; } });
26
+ Object.defineProperty(exports, "resolveConfigPath", { enumerable: true, get: function () { return resolve_1.resolveConfigPath; } });
27
+ Object.defineProperty(exports, "resolveWritableConfigPath", { enumerable: true, get: function () { return resolve_1.resolveWritableConfigPath; } });
28
+ __exportStar(require("./runtime/types.js"), exports);
29
+ var env_js_1 = require("./runtime/env.js");
30
+ Object.defineProperty(exports, "prepareSemanticEnrichmentRuntime", { enumerable: true, get: function () { return env_js_1.prepareSemanticEnrichmentRuntime; } });
31
+ Object.defineProperty(exports, "applyEnrichmentProviderEnv", { enumerable: true, get: function () { return env_js_1.applyEnrichmentProviderEnv; } });
32
+ Object.defineProperty(exports, "applyOpenBmbRuntimeEnv", { enumerable: true, get: function () { return env_js_1.applyOpenBmbRuntimeEnv; } });
33
+ var settings_js_1 = require("./runtime/settings.js");
34
+ Object.defineProperty(exports, "getGraphFlowSettings", { enumerable: true, get: function () { return settings_js_1.getGraphFlowSettings; } });
35
+ Object.defineProperty(exports, "saveGraphFlowSettings", { enumerable: true, get: function () { return settings_js_1.saveGraphFlowSettings; } });
36
+ Object.defineProperty(exports, "validateSettingsForGraphIndex", { enumerable: true, get: function () { return settings_js_1.validateSettingsForGraphIndex; } });
37
+ Object.defineProperty(exports, "validateSettingsForRouting", { enumerable: true, get: function () { return settings_js_1.validateSettingsForRouting; } });
38
+ var graph_js_1 = require("./runtime/graph.js");
39
+ Object.defineProperty(exports, "previewContext", { enumerable: true, get: function () { return graph_js_1.previewContext; } });
40
+ Object.defineProperty(exports, "indexGraph", { enumerable: true, get: function () { return graph_js_1.indexGraph; } });
41
+ Object.defineProperty(exports, "rebuildGraph", { enumerable: true, get: function () { return graph_js_1.rebuildGraph; } });
42
+ Object.defineProperty(exports, "enrichSemanticsSilent", { enumerable: true, get: function () { return graph_js_1.enrichSemanticsSilent; } });
43
+ Object.defineProperty(exports, "downloadOpenBmbModel", { enumerable: true, get: function () { return graph_js_1.downloadOpenBmbModel; } });
44
+ Object.defineProperty(exports, "inspectGraph", { enumerable: true, get: function () { return graph_js_1.inspectGraph; } });
45
+ Object.defineProperty(exports, "getSkillInsights", { enumerable: true, get: function () { return graph_js_1.getSkillInsights; } });
46
+ var routing_js_1 = require("./runtime/routing.js");
47
+ Object.defineProperty(exports, "runTask", { enumerable: true, get: function () { return routing_js_1.runTask; } });
48
+ Object.defineProperty(exports, "runTaskResult", { enumerable: true, get: function () { return routing_js_1.runTaskResult; } });
49
+ Object.defineProperty(exports, "diagnoseRouting", { enumerable: true, get: function () { return routing_js_1.diagnoseRouting; } });
50
+ Object.defineProperty(exports, "diagnoseRoutingResult", { enumerable: true, get: function () { return routing_js_1.diagnoseRoutingResult; } });
51
+ Object.defineProperty(exports, "runLearningNightly", { enumerable: true, get: function () { return routing_js_1.runLearningNightly; } });
52
+ Object.defineProperty(exports, "runLearningNightlyResult", { enumerable: true, get: function () { return routing_js_1.runLearningNightlyResult; } });
53
+ Object.defineProperty(exports, "planAndBrainstorm", { enumerable: true, get: function () { return routing_js_1.planAndBrainstorm; } });
54
+ Object.defineProperty(exports, "planAndBrainstormResult", { enumerable: true, get: function () { return routing_js_1.planAndBrainstormResult; } });
55
+ var panel_js_1 = require("./runtime/panel.js");
56
+ Object.defineProperty(exports, "getSettingsPanelStatus", { enumerable: true, get: function () { return panel_js_1.getSettingsPanelStatus; } });
57
+ Object.defineProperty(exports, "indexGraphFromSettings", { enumerable: true, get: function () { return panel_js_1.indexGraphFromSettings; } });
58
+ Object.defineProperty(exports, "testRoutingAndIndexGraph", { enumerable: true, get: function () { return panel_js_1.testRoutingAndIndexGraph; } });
59
+ var facade_js_1 = require("./runtime/facade.js");
60
+ Object.defineProperty(exports, "assertGraphFlowRuntime", { enumerable: true, get: function () { return facade_js_1.assertGraphFlowRuntime; } });
1134
61
  var agent_mcp_installer_1 = require("../../integrations/agent-mcp-installer");
1135
62
  Object.defineProperty(exports, "buildMcpServerNode", { enumerable: true, get: function () { return agent_mcp_installer_1.buildMcpServerNode; } });
1136
63
  Object.defineProperty(exports, "detectInstalledAgents", { enumerable: true, get: function () { return agent_mcp_installer_1.detectInstalledAgents; } });
1137
64
  Object.defineProperty(exports, "formatModelConfigGuide", { enumerable: true, get: function () { return agent_mcp_installer_1.formatModelConfigGuide; } });
1138
65
  Object.defineProperty(exports, "installMcpToDetectedAgents", { enumerable: true, get: function () { return agent_mcp_installer_1.installMcpToDetectedAgents; } });
1139
- function extractTokenCost(feedback) {
1140
- const match = feedback.match(/tokens=(\d+)/);
1141
- if (match && match[1]) {
1142
- return Number(match[1]);
1143
- }
1144
- return Math.max(1, Math.ceil(feedback.length / 4));
1145
- }
1146
- function loadGraphStore(config) {
1147
- const transport = config.graphPolicy.transport;
1148
- if (transport === "memory") {
1149
- return { nodes: [], edges: [] };
1150
- }
1151
- if (transport === "sqlite") {
1152
- const dbPath = (0, paths_1.resolveGraphStorePath)(config);
1153
- try {
1154
- const client = new sqlite_client_1.GraphifySqliteClient(dbPath);
1155
- const snapshot = client.readSnapshot();
1156
- client.close();
1157
- return snapshot;
1158
- }
1159
- catch {
1160
- const fallbackPath = dbPath.replace(/\.sqlite$/i, ".json");
1161
- return readFileGraphStore(fallbackPath);
1162
- }
1163
- }
1164
- return readFileGraphStore((0, paths_1.resolveGraphStorePath)(config));
1165
- }
1166
- async function resolveGraphStoreAfterIndex(config, graphClient) {
1167
- if (config.graphPolicy.transport === "memory" && graphClient.readSnapshot) {
1168
- return graphClient.readSnapshot();
1169
- }
1170
- return loadGraphStore(config);
1171
- }
1172
- function readFileGraphStore(storePath) {
1173
- if (!storePath || !(0, node_fs_1.existsSync)(storePath)) {
1174
- return { nodes: [], edges: [] };
1175
- }
1176
- try {
1177
- const raw = (0, node_fs_1.readFileSync)(storePath, "utf8");
1178
- if (!raw.trim()) {
1179
- return { nodes: [], edges: [] };
1180
- }
1181
- const parsed = JSON.parse(raw);
1182
- return {
1183
- nodes: parsed.nodes ?? [],
1184
- edges: parsed.edges ?? [],
1185
- };
1186
- }
1187
- catch {
1188
- return { nodes: [], edges: [] };
1189
- }
1190
- }
1191
- function getFileSize(path) {
1192
- try {
1193
- return (0, node_fs_1.statSync)(path).size;
1194
- }
1195
- catch {
1196
- return 0;
1197
- }
1198
- }
1199
- async function sha256File(path) {
1200
- const hash = (0, node_crypto_1.createHash)("sha256");
1201
- const stream = (0, node_fs_1.createReadStream)(path);
1202
- for await (const chunk of stream) {
1203
- hash.update(chunk);
1204
- }
1205
- return hash.digest("hex");
1206
- }
1207
- function readRawConfig(configPath) {
1208
- if (!(0, node_fs_1.existsSync)(configPath)) {
1209
- return undefined;
1210
- }
1211
- try {
1212
- return JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf8"));
1213
- }
1214
- catch {
1215
- return undefined;
1216
- }
1217
- }
1218
- function estimateRawContextTokens(store, query, compressedTokens) {
1219
- const matching = store.nodes.filter((node) => {
1220
- const haystack = `${node.id} ${node.type} ${node.content}`.toLowerCase();
1221
- const terms = query
1222
- .toLowerCase()
1223
- .split(/[^a-z0-9_]+/g)
1224
- .filter((item) => item.length >= 2);
1225
- return terms.length === 0 || terms.some((term) => haystack.includes(term));
1226
- });
1227
- const nodes = matching.length > 0 ? matching : store.nodes;
1228
- const rawTokens = nodes.reduce((sum, node) => sum + estimateTokenCount(`${node.id}\n${node.type}\n${node.content}`), 0);
1229
- return Math.max(compressedTokens, rawTokens, estimateTokenCount(query));
1230
- }
1231
- function calculateSavingsPercent(rawTokens, compressedTokens) {
1232
- if (rawTokens <= 0) {
1233
- return 0;
1234
- }
1235
- return Math.max(0, Math.min(100, Math.round(((rawTokens - compressedTokens) / rawTokens) * 100)));
1236
- }
1237
- function calculateBudgetUsedPercent(compressedTokens, maxContextTokens) {
1238
- if (maxContextTokens <= 0) {
1239
- return 0;
1240
- }
1241
- return Math.max(0, Math.round((compressedTokens / maxContextTokens) * 100));
1242
- }
1243
- function estimateTokenCount(text) {
1244
- try {
1245
- const { encode } = require("gpt-tokenizer/model/gpt-4o");
1246
- return Math.max(1, encode(text).length);
1247
- }
1248
- catch {
1249
- return Math.max(1, Math.ceil(text.replace(/\s+/g, " ").trim().length / 4));
1250
- }
1251
- }
1252
- function compactPreview(content, maxLength) {
1253
- const compacted = content.replace(/\s+/g, " ").trim();
1254
- if (compacted.length <= maxLength) {
1255
- return compacted;
1256
- }
1257
- return `${compacted.slice(0, Math.max(0, maxLength - 1))}\u2026`;
1258
- }
1259
- function parseSkillInsight(node) {
1260
- try {
1261
- const parsed = JSON.parse(node.content);
1262
- if (!parsed.id || !parsed.name) {
1263
- return undefined;
1264
- }
1265
- return {
1266
- id: parsed.id,
1267
- name: parsed.name,
1268
- score: parsed.score ?? 0,
1269
- uses: parsed.uses ?? 0,
1270
- lastOutcome: parsed.lastOutcome === "fail" ? "fail" : "pass",
1271
- updatedAt: parsed.updatedAt ?? 0,
1272
- };
1273
- }
1274
- catch {
1275
- return undefined;
1276
- }
1277
- }
1278
66
  //# sourceMappingURL=runtime.js.map