flowseeker 0.1.7

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 (82) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/COMPATIBILITY.md +281 -0
  3. package/LICENSE +21 -0
  4. package/README.md +375 -0
  5. package/dist/adapters/frameworkEdges.js +586 -0
  6. package/dist/agent/approvalPolicy.js +81 -0
  7. package/dist/agent/commandRunner.js +166 -0
  8. package/dist/agent/flowCommandRunner.js +124 -0
  9. package/dist/agent/mcpToolRunner.js +167 -0
  10. package/dist/auth/githubAuth.js +71 -0
  11. package/dist/auth/modelList.js +127 -0
  12. package/dist/auth/oauthHandler.js +377 -0
  13. package/dist/chat/nativeChatParticipant.js +616 -0
  14. package/dist/cli/mcpServer.js +383 -0
  15. package/dist/cli/runEvaluation.js +789 -0
  16. package/dist/cli/runReplay.js +481 -0
  17. package/dist/commands/checkHostCompatibility.js +149 -0
  18. package/dist/commands/copyAgentPrompt.js +52 -0
  19. package/dist/commands/copyContext.js +54 -0
  20. package/dist/commands/explainSelectionRelevance.js +57 -0
  21. package/dist/commands/findRelevantContext.js +127 -0
  22. package/dist/commands/openEvidence.js +49 -0
  23. package/dist/commands/openMcpConfig.js +81 -0
  24. package/dist/commands/openRelatedTests.js +54 -0
  25. package/dist/commands/rebuildIndex.js +45 -0
  26. package/dist/commands/runEvaluationSuite.js +323 -0
  27. package/dist/commands/runReplaySuite.js +228 -0
  28. package/dist/config/defaultConfig.js +72 -0
  29. package/dist/config/loadConfig.js +84 -0
  30. package/dist/config/loadConfigFromPath.js +60 -0
  31. package/dist/extension.js +513 -0
  32. package/dist/gateway/agentPrompts.js +176 -0
  33. package/dist/gateway/aiGateway.js +1255 -0
  34. package/dist/gateway/aiProviders.js +901 -0
  35. package/dist/gateway/contextExpansion.js +331 -0
  36. package/dist/gateway/editProposalStore.js +238 -0
  37. package/dist/gateway/planProposalStore.js +28 -0
  38. package/dist/index/cacheStore.js +51 -0
  39. package/dist/index/chunker.js +45 -0
  40. package/dist/index/dependencyExtractor.js +107 -0
  41. package/dist/index/fileDiscovery.js +177 -0
  42. package/dist/index/structuredExtractor.js +256 -0
  43. package/dist/index/workspaceIndex.js +518 -0
  44. package/dist/mcp/mcpConfig.js +154 -0
  45. package/dist/mcp/mcpProvider.js +109 -0
  46. package/dist/mcp/mcpTools.js +215 -0
  47. package/dist/pipeline/agentPrompt.js +79 -0
  48. package/dist/pipeline/agentPromptHeadless.js +85 -0
  49. package/dist/pipeline/contextBlueprint.js +346 -0
  50. package/dist/pipeline/contextPack.js +80 -0
  51. package/dist/pipeline/diffPreview.js +79 -0
  52. package/dist/pipeline/evaluationMetrics.js +154 -0
  53. package/dist/pipeline/evidenceGraph.js +389 -0
  54. package/dist/pipeline/feedback.js +215 -0
  55. package/dist/pipeline/fileGroups.js +84 -0
  56. package/dist/pipeline/fileScanner.js +866 -0
  57. package/dist/pipeline/nodeScan.js +219 -0
  58. package/dist/pipeline/ranker.js +563 -0
  59. package/dist/pipeline/responseLanguage.js +39 -0
  60. package/dist/pipeline/retrievalPlan.js +163 -0
  61. package/dist/pipeline/runHeadless.js +54 -0
  62. package/dist/pipeline/runPipeline.js +114 -0
  63. package/dist/pipeline/solvePacket.js +382 -0
  64. package/dist/pipeline/subsystem.js +257 -0
  65. package/dist/pipeline/taskUnderstanding.js +453 -0
  66. package/dist/pipeline/tokenSavings.js +146 -0
  67. package/dist/pipeline/universalScan.js +216 -0
  68. package/dist/pipeline/verifyAfterApply.js +233 -0
  69. package/dist/runtime/capabilities.js +71 -0
  70. package/dist/runtime/hostDetect.js +98 -0
  71. package/dist/runtime/hostTier.js +68 -0
  72. package/dist/runtime/statusBar.js +80 -0
  73. package/dist/skills/skillRegistry.js +208 -0
  74. package/dist/types.js +3 -0
  75. package/dist/ui/chatViewProvider.js +3899 -0
  76. package/dist/ui/resultTreeProvider.js +174 -0
  77. package/dist/usage/quotaTracker.js +358 -0
  78. package/dist/utils/async.js +30 -0
  79. package/dist/utils/logger.js +64 -0
  80. package/dist/utils/text.js +364 -0
  81. package/dist/utils/updateChecker.js +140 -0
  82. package/package.json +561 -0
@@ -0,0 +1,166 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runAgentCommandProposal = runAgentCommandProposal;
37
+ exports.summarizeAgentCommandRun = summarizeAgentCommandRun;
38
+ exports.formatAgentCommandRunMarkdown = formatAgentCommandRunMarkdown;
39
+ const cp = __importStar(require("child_process"));
40
+ const path = __importStar(require("path"));
41
+ const vscode = __importStar(require("vscode"));
42
+ const approvalPolicy_1 = require("./approvalPolicy");
43
+ const logger_1 = require("../utils/logger");
44
+ async function runAgentCommandProposal(proposal) {
45
+ const command = proposal.command.trim();
46
+ if (!command) {
47
+ await vscode.window.showWarningMessage("FlowSeeker command proposal is empty.");
48
+ return undefined;
49
+ }
50
+ const folders = vscode.workspace.workspaceFolders;
51
+ if (!folders?.[0]) {
52
+ await vscode.window.showWarningMessage("Open a workspace folder before running FlowSeeker agent commands.");
53
+ return undefined;
54
+ }
55
+ const classification = (0, approvalPolicy_1.classifyCommand)(command);
56
+ const approved = await confirmCommandIfNeeded(command, classification);
57
+ if (!approved) {
58
+ return undefined;
59
+ }
60
+ const cwd = resolveCommandCwd(folders[0].uri.fsPath, proposal.cwd);
61
+ (0, logger_1.logInfo)(`FlowSeeker agent command started: ${command}`);
62
+ const started = Date.now();
63
+ const result = await execCommand(command, cwd);
64
+ const run = {
65
+ proposal,
66
+ classification,
67
+ cwd,
68
+ ...result,
69
+ durationMs: Date.now() - started
70
+ };
71
+ await showCommandResult(run);
72
+ return run;
73
+ }
74
+ function summarizeAgentCommandRun(run) {
75
+ const status = run.exitCode === 0 ? "passed" : run.timedOut ? "timed out" : run.exitCode === null ? "errored" : "failed";
76
+ return `Command ${status}: \`${run.proposal.command}\` (${run.durationMs}ms).`;
77
+ }
78
+ function formatAgentCommandRunMarkdown(run) {
79
+ const lines = [
80
+ `# FlowSeeker Agent Command`,
81
+ "",
82
+ `Command: \`${run.proposal.command}\``,
83
+ `Working directory: \`${run.cwd}\``,
84
+ `Status: ${run.exitCode === 0 ? "PASS" : run.timedOut ? "TIMEOUT" : run.exitCode === null ? "ERROR" : "FAIL"}`,
85
+ `Exit code: ${run.exitCode ?? "n/a"}`,
86
+ `Duration: ${run.durationMs}ms`,
87
+ `Safety: ${run.classification.reason}`,
88
+ ""
89
+ ];
90
+ if (run.proposal.rationale) {
91
+ lines.push("## Rationale", "", run.proposal.rationale, "");
92
+ }
93
+ if (run.stdout) {
94
+ lines.push("## Stdout", "", "```", truncate(run.stdout, 12000), "```", "");
95
+ }
96
+ if (run.stderr) {
97
+ lines.push("## Stderr", "", "```", truncate(run.stderr, 6000), "```", "");
98
+ }
99
+ if (!run.stdout && !run.stderr) {
100
+ lines.push("No output was produced.", "");
101
+ }
102
+ return lines.join("\n");
103
+ }
104
+ async function confirmCommandIfNeeded(command, classification) {
105
+ if (classification.destructive) {
106
+ const action = await vscode.window.showWarningMessage(`FlowSeeker classified this command as destructive: ${command}`, { modal: true, detail: classification.reason }, "Run Anyway", "Cancel");
107
+ return action === "Run Anyway";
108
+ }
109
+ const kind = classification.safe ? "safe_command" : "all_command";
110
+ if ((0, approvalPolicy_1.canAutoApprove)(kind)) {
111
+ return true;
112
+ }
113
+ const action = await vscode.window.showInformationMessage(`Run FlowSeeker agent command?\n${command}`, { modal: true, detail: classification.reason }, "Run", "Cancel");
114
+ return action === "Run";
115
+ }
116
+ function execCommand(command, cwd) {
117
+ return new Promise((resolve) => {
118
+ const child = cp.exec(command, {
119
+ cwd,
120
+ timeout: 120000,
121
+ windowsHide: true,
122
+ env: { ...process.env, FORCE_COLOR: "0", CI: "true" },
123
+ maxBuffer: 1024 * 1024
124
+ }, (error, stdout, stderr) => {
125
+ const execError = error;
126
+ resolve({
127
+ exitCode: execError?.code ?? 0,
128
+ stdout: stdout.trim(),
129
+ stderr: stderr.trim(),
130
+ timedOut: Boolean(execError?.killed)
131
+ });
132
+ });
133
+ child.on("error", (error) => {
134
+ resolve({
135
+ exitCode: null,
136
+ stdout: "",
137
+ stderr: error.message,
138
+ timedOut: false
139
+ });
140
+ });
141
+ });
142
+ }
143
+ function resolveCommandCwd(workspaceRoot, requestedCwd) {
144
+ if (!requestedCwd?.trim()) {
145
+ return workspaceRoot;
146
+ }
147
+ const candidate = path.isAbsolute(requestedCwd)
148
+ ? path.normalize(requestedCwd)
149
+ : path.normalize(path.join(workspaceRoot, requestedCwd));
150
+ const relative = path.relative(workspaceRoot, candidate);
151
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
152
+ throw new Error(`Refusing to run command outside the workspace: ${requestedCwd}`);
153
+ }
154
+ return candidate;
155
+ }
156
+ async function showCommandResult(run) {
157
+ const document = await vscode.workspace.openTextDocument({
158
+ content: formatAgentCommandRunMarkdown(run),
159
+ language: "markdown"
160
+ });
161
+ await vscode.window.showTextDocument(document, { preview: true, viewColumn: vscode.ViewColumn.Beside });
162
+ }
163
+ function truncate(value, maxLength) {
164
+ return value.length > maxLength ? `${value.slice(0, maxLength)}\n... (truncated)` : value;
165
+ }
166
+ //# sourceMappingURL=commandRunner.js.map
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runFlowCommand = runFlowCommand;
4
+ exports.commandToMode = commandToMode;
5
+ const agentPrompts_1 = require("../gateway/agentPrompts");
6
+ const runPipeline_1 = require("../pipeline/runPipeline");
7
+ const logger_1 = require("../utils/logger");
8
+ const contextExpansion_1 = require("../gateway/contextExpansion");
9
+ async function runFlowCommand(command, task, gateway, resultProvider, planStore, editStore, callbacks, token, approvedPlan) {
10
+ const mode = command === "auto" ? "auto" : "guide";
11
+ try {
12
+ (0, logger_1.logInfo)(`FlowSeeker ${command} started: ${task}`);
13
+ callbacks.onProgress("Finding relevant files...");
14
+ const result = await (0, runPipeline_1.runFlowSeeker)(task, {
15
+ token,
16
+ progress: { report: (msg) => callbacks.onProgress(msg.message ?? String(msg)) }
17
+ });
18
+ resultProvider.setResult(result);
19
+ callbacks.onRetrievalComplete(result);
20
+ const connection = await gateway.getConnection();
21
+ // If there's an approved plan, generate edits from it
22
+ if (approvedPlan && connection.connected) {
23
+ const providerLabel = connection.providerLabel ?? connection.provider ?? "AI provider";
24
+ callbacks.onProviderAsking(providerLabel, connection.model);
25
+ const answer = await gateway.askWithInstruction(result, "auto", (0, agentPrompts_1.createApprovedEditInstruction)(approvedPlan), { stage: "approved_edits", approvedPlan });
26
+ if (answer.edits?.length) {
27
+ const editId = editStore.store(answer.edits);
28
+ callbacks.onComplete({
29
+ mode: "auto",
30
+ result,
31
+ answer,
32
+ editProposalId: editId
33
+ });
34
+ return {
35
+ mode: "auto",
36
+ result,
37
+ answer,
38
+ editProposalId: editId
39
+ };
40
+ }
41
+ callbacks.onComplete({
42
+ mode: "auto",
43
+ result,
44
+ answer,
45
+ error: "The AI provider did not return structured edits.",
46
+ needsMoreContext: (0, contextExpansion_1.isMissingContextRequest)(answer.message)
47
+ });
48
+ return {
49
+ mode: "auto",
50
+ result,
51
+ answer,
52
+ error: "The AI provider did not return structured edits.",
53
+ needsMoreContext: (0, contextExpansion_1.isMissingContextRequest)(answer.message)
54
+ };
55
+ }
56
+ if (!connection.connected) {
57
+ callbacks.onComplete({
58
+ mode,
59
+ result,
60
+ error: "No AI provider connected. Configure one or use Copy Agent Prompt."
61
+ });
62
+ return { mode, result, error: "No AI provider connected." };
63
+ }
64
+ const providerLabel = connection.providerLabel ?? connection.provider ?? "AI provider";
65
+ callbacks.onProviderAsking(providerLabel, connection.model);
66
+ const answer = await gateway.ask(result, mode);
67
+ if (mode === "auto" && (0, contextExpansion_1.isReviewablePlan)(answer.message)) {
68
+ const planId = planStore.store(result, answer.message);
69
+ callbacks.onComplete({
70
+ mode,
71
+ result,
72
+ answer,
73
+ planText: answer.message,
74
+ planProposalId: planId,
75
+ isApprovablePlan: true
76
+ });
77
+ return {
78
+ mode,
79
+ result,
80
+ answer,
81
+ planText: answer.message,
82
+ planProposalId: planId,
83
+ isApprovablePlan: true
84
+ };
85
+ }
86
+ if (answer.edits?.length) {
87
+ const editId = editStore.store(answer.edits);
88
+ callbacks.onComplete({
89
+ mode,
90
+ result,
91
+ answer,
92
+ editProposalId: editId
93
+ });
94
+ return {
95
+ mode,
96
+ result,
97
+ answer,
98
+ editProposalId: editId
99
+ };
100
+ }
101
+ callbacks.onComplete({
102
+ mode,
103
+ result,
104
+ answer,
105
+ needsMoreContext: (0, contextExpansion_1.isMissingContextRequest)(answer.message)
106
+ });
107
+ return {
108
+ mode,
109
+ result,
110
+ answer,
111
+ needsMoreContext: (0, contextExpansion_1.isMissingContextRequest)(answer.message)
112
+ };
113
+ }
114
+ catch (error) {
115
+ (0, logger_1.logError)(`FlowSeeker ${command} failed.`, error);
116
+ const message = error instanceof Error ? error.message : String(error);
117
+ callbacks.onComplete({ mode, result: undefined, error: message });
118
+ return { mode, result: undefined, error: message };
119
+ }
120
+ }
121
+ function commandToMode(command) {
122
+ return command === "auto" ? "auto" : "guide";
123
+ }
124
+ //# sourceMappingURL=flowCommandRunner.js.map
@@ -0,0 +1,167 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runMcpToolProposal = runMcpToolProposal;
37
+ exports.summarizeMcpToolRun = summarizeMcpToolRun;
38
+ exports.availableToolNames = availableToolNames;
39
+ const vscode = __importStar(require("vscode"));
40
+ const approvalPolicy_1 = require("./approvalPolicy");
41
+ const capabilities_1 = require("../runtime/capabilities");
42
+ const logger_1 = require("../utils/logger");
43
+ async function runMcpToolProposal(proposal) {
44
+ const toolName = proposal.tool.trim();
45
+ if (!toolName) {
46
+ await vscode.window.showWarningMessage("FlowSeeker MCP tool proposal is empty.");
47
+ return undefined;
48
+ }
49
+ const candidate = vscode;
50
+ const capabilities = (0, capabilities_1.getHostCapabilities)();
51
+ if (!capabilities.hasLanguageModelTools || typeof candidate.lm?.invokeTool !== "function") {
52
+ await vscode.window.showWarningMessage("This editor host does not expose the VS Code Language Model tool API to FlowSeeker.");
53
+ return undefined;
54
+ }
55
+ const tool = findTool(toolName, candidate.lm?.tools ?? []);
56
+ if (!tool) {
57
+ await vscode.window.showWarningMessage(`MCP/tool '${toolName}' is not available in this editor. Check FlowSeeker MCP config or host compatibility.`);
58
+ return undefined;
59
+ }
60
+ const approved = await confirmToolIfNeeded(tool.name, proposal);
61
+ if (!approved) {
62
+ return undefined;
63
+ }
64
+ (0, logger_1.logInfo)(`FlowSeeker MCP/tool invocation started: ${tool.name}`);
65
+ const started = Date.now();
66
+ try {
67
+ const result = await candidate.lm.invokeTool(tool.name, {
68
+ input: proposal.input ?? {},
69
+ toolInvocationToken: undefined
70
+ }, undefined);
71
+ const run = {
72
+ proposal,
73
+ toolName: tool.name,
74
+ durationMs: Date.now() - started,
75
+ resultText: toolResultToText(result)
76
+ };
77
+ await showToolResult(run);
78
+ return run;
79
+ }
80
+ catch (error) {
81
+ (0, logger_1.logError)(`FlowSeeker MCP/tool invocation failed: ${tool.name}`, error);
82
+ throw error;
83
+ }
84
+ }
85
+ function summarizeMcpToolRun(run) {
86
+ return `MCP/tool completed: \`${run.toolName}\` (${run.durationMs}ms).`;
87
+ }
88
+ function availableToolNames() {
89
+ const candidate = vscode;
90
+ return [...(candidate.lm?.tools ?? [])].map((tool) => tool.name).sort((left, right) => left.localeCompare(right));
91
+ }
92
+ function findTool(name, tools) {
93
+ const normalized = name.toLowerCase();
94
+ return tools.find((tool) => tool.name.toLowerCase() === normalized)
95
+ ?? tools.find((tool) => tool.name.toLowerCase().endsWith(`.${normalized}`))
96
+ ?? tools.find((tool) => tool.name.toLowerCase().endsWith(`_${normalized}`));
97
+ }
98
+ async function confirmToolIfNeeded(toolName, proposal) {
99
+ if ((0, approvalPolicy_1.canAutoApprove)("mcp_tool")) {
100
+ return true;
101
+ }
102
+ const action = await vscode.window.showInformationMessage(`Invoke FlowSeeker MCP/tool?\n${toolName}`, {
103
+ modal: true,
104
+ detail: proposal.rationale ?? "FlowSeeker will invoke this tool through VS Code's Language Model tool API."
105
+ }, "Invoke", "Cancel");
106
+ return action === "Invoke";
107
+ }
108
+ async function showToolResult(run) {
109
+ const document = await vscode.workspace.openTextDocument({
110
+ content: formatMcpToolRunMarkdown(run),
111
+ language: "markdown"
112
+ });
113
+ await vscode.window.showTextDocument(document, { preview: true, viewColumn: vscode.ViewColumn.Beside });
114
+ }
115
+ function formatMcpToolRunMarkdown(run) {
116
+ return [
117
+ "# FlowSeeker MCP Tool",
118
+ "",
119
+ `Tool: \`${run.toolName}\``,
120
+ `Duration: ${run.durationMs}ms`,
121
+ "",
122
+ run.proposal.rationale ? "## Rationale" : "",
123
+ run.proposal.rationale ?? "",
124
+ run.proposal.rationale ? "" : "",
125
+ "## Input",
126
+ "",
127
+ "```json",
128
+ JSON.stringify(run.proposal.input ?? {}, null, 2),
129
+ "```",
130
+ "",
131
+ "## Result",
132
+ "",
133
+ "```",
134
+ truncate(run.resultText || "(empty result)", 16000),
135
+ "```",
136
+ ""
137
+ ].filter((line, index, lines) => line !== "" || lines[index - 1] !== "").join("\n");
138
+ }
139
+ function toolResultToText(result) {
140
+ return result.content.map(partToText).filter(Boolean).join("\n\n");
141
+ }
142
+ function partToText(part) {
143
+ if (typeof part === "string") {
144
+ return part;
145
+ }
146
+ if (part && typeof part === "object") {
147
+ const value = part.value;
148
+ if (typeof value === "string") {
149
+ return value;
150
+ }
151
+ const data = part.data;
152
+ if (data instanceof Uint8Array) {
153
+ return `[${part.mimeType ?? "data"}: ${data.byteLength} bytes]`;
154
+ }
155
+ try {
156
+ return JSON.stringify(part, null, 2);
157
+ }
158
+ catch {
159
+ return String(part);
160
+ }
161
+ }
162
+ return String(part ?? "");
163
+ }
164
+ function truncate(value, maxLength) {
165
+ return value.length > maxLength ? `${value.slice(0, maxLength)}\n... (truncated)` : value;
166
+ }
167
+ //# sourceMappingURL=mcpToolRunner.js.map
@@ -0,0 +1,71 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getGitHubSession = getGitHubSession;
37
+ exports.getSilentGitHubSession = getSilentGitHubSession;
38
+ exports.hasGitHubSession = hasGitHubSession;
39
+ const vscode = __importStar(require("vscode"));
40
+ const GITHUB_AUTH_PROVIDER = "github";
41
+ const GITHUB_MODELS_SCOPE = "read:user";
42
+ async function getGitHubSession() {
43
+ const session = await vscode.authentication.getSession(GITHUB_AUTH_PROVIDER, [GITHUB_MODELS_SCOPE], {
44
+ createIfNone: true,
45
+ silent: false
46
+ });
47
+ if (!session) {
48
+ return null;
49
+ }
50
+ return {
51
+ accessToken: session.accessToken,
52
+ accountLabel: session.account.label
53
+ };
54
+ }
55
+ async function getSilentGitHubSession() {
56
+ const session = await vscode.authentication.getSession(GITHUB_AUTH_PROVIDER, [GITHUB_MODELS_SCOPE], {
57
+ silent: true
58
+ });
59
+ if (!session) {
60
+ return null;
61
+ }
62
+ return {
63
+ accessToken: session.accessToken,
64
+ accountLabel: session.account.label
65
+ };
66
+ }
67
+ async function hasGitHubSession() {
68
+ const session = await getSilentGitHubSession();
69
+ return session !== null;
70
+ }
71
+ //# sourceMappingURL=githubAuth.js.map
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchModelList = fetchModelList;
4
+ exports.getCachedModels = getCachedModels;
5
+ exports.cacheModels = cacheModels;
6
+ exports.clearCachedModels = clearCachedModels;
7
+ const aiProviders_1 = require("../gateway/aiProviders");
8
+ const MODELS_CACHE_TTL_MS = 10 * 60 * 1000;
9
+ function cacheKey(providerId, baseUrl = "") {
10
+ return `flowseeker.models.${providerId}.${hashString(normalizeBaseUrl(baseUrl))}`;
11
+ }
12
+ async function fetchModelList(providerId, baseUrl, accessToken) {
13
+ const definition = (0, aiProviders_1.getProviderDefinition)(providerId);
14
+ const cleanBaseUrl = normalizeBaseUrl(baseUrl || definition.defaultBaseUrl);
15
+ let response;
16
+ if (providerId === "ollama") {
17
+ response = await fetch(joinUrl(cleanBaseUrl, "/api/tags"), {
18
+ headers: { "Content-Type": "application/json" }
19
+ });
20
+ }
21
+ else if (providerId === "gemini") {
22
+ response = await fetch(`${joinUrl(cleanBaseUrl, "/models")}?key=${encodeURIComponent(accessToken ?? "")}`, {
23
+ headers: { "Content-Type": "application/json" }
24
+ });
25
+ }
26
+ else if (providerId === "anthropic" || providerId === "customAnthropic") {
27
+ response = await fetch(joinUrl(cleanBaseUrl, "/models"), {
28
+ headers: {
29
+ "Content-Type": "application/json",
30
+ "x-api-key": accessToken ?? "",
31
+ "anthropic-version": "2023-06-01"
32
+ }
33
+ });
34
+ }
35
+ else {
36
+ response = await fetch(joinUrl(cleanBaseUrl, "/models"), {
37
+ headers: { Authorization: `Bearer ${accessToken ?? ""}`, "Content-Type": "application/json" }
38
+ });
39
+ }
40
+ if (!response.ok) {
41
+ throw new Error(`Failed to fetch models (${response.status})`);
42
+ }
43
+ return parseModelResponse(providerId, await response.json());
44
+ }
45
+ function parseModelResponse(providerId, data) {
46
+ // GitHub Models returns a plain array
47
+ if (Array.isArray(data)) {
48
+ return data
49
+ .filter(isObject)
50
+ .map((model) => {
51
+ const rawId = stringValue(model.id) ?? stringValue(model.name) ?? stringValue(model.model);
52
+ if (!rawId) {
53
+ return undefined;
54
+ }
55
+ const displayName = stringValue(model.display_name) ?? stringValue(model.displayName) ?? stringValue(model.name) ?? rawId;
56
+ return {
57
+ id: rawId,
58
+ name: displayName,
59
+ owned_by: stringValue(model.owned_by) ?? stringValue(model.ownedBy)
60
+ };
61
+ })
62
+ .filter((model) => Boolean(model?.id));
63
+ }
64
+ if (!isObject(data)) {
65
+ return [];
66
+ }
67
+ const rows = Array.isArray(data.data)
68
+ ? data.data
69
+ : Array.isArray(data.models)
70
+ ? data.models
71
+ : [];
72
+ return rows
73
+ .filter(isObject)
74
+ .map((model) => {
75
+ const rawId = stringValue(model.id) ?? stringValue(model.name) ?? stringValue(model.model);
76
+ if (!rawId) {
77
+ return undefined;
78
+ }
79
+ const id = providerId === "gemini" ? rawId.replace(/^models\//, "") : rawId;
80
+ const displayName = stringValue(model.display_name) ?? stringValue(model.displayName) ?? stringValue(model.name) ?? id;
81
+ return {
82
+ id,
83
+ name: providerId === "gemini" ? displayName.replace(/^models\//, "") : displayName,
84
+ owned_by: stringValue(model.owned_by) ?? stringValue(model.ownedBy)
85
+ };
86
+ })
87
+ .filter((model) => Boolean(model?.id));
88
+ }
89
+ function getCachedModels(context, providerId, baseUrl = "") {
90
+ const cached = context.globalState.get(cacheKey(providerId, baseUrl));
91
+ if (!cached || !Array.isArray(cached.models)) {
92
+ return null;
93
+ }
94
+ if (Date.now() - cached.fetchedAt > MODELS_CACHE_TTL_MS) {
95
+ return null;
96
+ }
97
+ return cached.models;
98
+ }
99
+ async function cacheModels(context, providerId, baseUrl, models) {
100
+ await context.globalState.update(cacheKey(providerId, baseUrl), {
101
+ models,
102
+ fetchedAt: Date.now()
103
+ });
104
+ }
105
+ function clearCachedModels(context, providerId, baseUrl = "") {
106
+ void context.globalState.update(cacheKey(providerId, baseUrl), undefined);
107
+ }
108
+ function joinUrl(baseUrl, path) {
109
+ return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
110
+ }
111
+ function normalizeBaseUrl(value) {
112
+ return value.trim().replace(/\/+$/, "");
113
+ }
114
+ function stringValue(value) {
115
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
116
+ }
117
+ function isObject(value) {
118
+ return typeof value === "object" && value !== null;
119
+ }
120
+ function hashString(value) {
121
+ let hash = 5381;
122
+ for (let index = 0; index < value.length; index += 1) {
123
+ hash = ((hash << 5) + hash) ^ value.charCodeAt(index);
124
+ }
125
+ return (hash >>> 0).toString(36);
126
+ }
127
+ //# sourceMappingURL=modelList.js.map