@marktoflow/gui 2.0.2 → 2.0.4-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -6
- package/dist/client/assets/index-DqVkoerZ.js +838 -0
- package/dist/client/assets/index-DqVkoerZ.js.map +1 -0
- package/dist/client/assets/{index-DQeR1ew6.css → index-eEWndJyn.css} +1 -1
- package/dist/client/index.html +3 -3
- package/dist/server/routes/execute.js +43 -8
- package/dist/server/routes/execute.js.map +1 -1
- package/dist/server/routes/form.js +27 -1
- package/dist/server/routes/form.js.map +1 -1
- package/dist/server/routes/tools.js +30 -884
- package/dist/server/routes/tools.js.map +1 -1
- package/dist/server/routes/workflows.js +24 -5
- package/dist/server/routes/workflows.js.map +1 -1
- package/dist/server/services/AIService.js +16 -6
- package/dist/server/services/AIService.js.map +1 -1
- package/dist/server/services/WorkflowService.js +15 -6
- package/dist/server/services/WorkflowService.js.map +1 -1
- package/dist/server/services/agents/{claude-code-provider.js → claude-agent-provider.js} +11 -11
- package/dist/server/services/agents/claude-agent-provider.js.map +1 -0
- package/dist/server/services/agents/claude-provider.js +4 -5
- package/dist/server/services/agents/claude-provider.js.map +1 -1
- package/dist/server/services/agents/codex-provider.js +5 -6
- package/dist/server/services/agents/codex-provider.js.map +1 -1
- package/dist/server/services/agents/copilot-provider.js +35 -8
- package/dist/server/services/agents/copilot-provider.js.map +1 -1
- package/dist/server/services/agents/openai-provider.js +274 -0
- package/dist/server/services/agents/openai-provider.js.map +1 -0
- package/dist/server/services/agents/opencode-provider.js +258 -0
- package/dist/server/services/agents/opencode-provider.js.map +1 -0
- package/dist/server/services/agents/registry.js +17 -22
- package/dist/server/services/agents/registry.js.map +1 -1
- package/dist/shared/constants.js +42 -0
- package/dist/shared/constants.js.map +1 -1
- package/index.html +1 -1
- package/package.json +21 -6
- package/dist/client/assets/index-LbIVPHbD.js +0 -833
- package/dist/client/assets/index-LbIVPHbD.js.map +0 -1
- package/dist/server/services/agents/claude-code-provider.js.map +0 -1
|
@@ -18,21 +18,44 @@ export class CopilotProvider {
|
|
|
18
18
|
codeExecution: true,
|
|
19
19
|
systemPrompts: true,
|
|
20
20
|
models: [
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
21
|
+
// Anthropic models
|
|
22
|
+
'Claude Opus 4.6',
|
|
23
|
+
'Claude Sonnet 4.5',
|
|
24
|
+
'Claude Haiku 4.5',
|
|
25
|
+
// OpenAI Codex models
|
|
26
|
+
'GPT-5.2-Codex',
|
|
27
|
+
'GPT-5.1-Codex-Max',
|
|
28
|
+
'GPT-5.2',
|
|
29
|
+
'GPT-5.1-Codex-Mini',
|
|
30
|
+
// Gemini models
|
|
31
|
+
'Gemini 3 Pro',
|
|
32
|
+
'Gemini 3 Flash',
|
|
33
|
+
'Gemini 2.5 Pro',
|
|
25
34
|
],
|
|
26
35
|
};
|
|
27
36
|
// Using 'unknown' to handle SDK version differences
|
|
28
37
|
client = null;
|
|
29
|
-
model = '
|
|
38
|
+
model = 'Claude Sonnet 4.5';
|
|
30
39
|
ready = false;
|
|
40
|
+
available = false; // Track if SDK is available
|
|
31
41
|
error;
|
|
32
42
|
cliPath;
|
|
33
43
|
cliUrl;
|
|
34
44
|
cachedModels = null;
|
|
35
45
|
modelsFetchedAt = 0;
|
|
46
|
+
constructor() {
|
|
47
|
+
// Check SDK availability on construction (lightweight check)
|
|
48
|
+
this.checkAvailability();
|
|
49
|
+
}
|
|
50
|
+
async checkAvailability() {
|
|
51
|
+
try {
|
|
52
|
+
const sdkModule = await import(/* webpackIgnore: true */ '@github/copilot-sdk').catch(() => null);
|
|
53
|
+
this.available = !!(sdkModule && sdkModule.CopilotClient);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
this.available = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
36
59
|
async initialize(config) {
|
|
37
60
|
try {
|
|
38
61
|
// Try to import the Copilot SDK (dynamic import with webpackIgnore to avoid bundling issues)
|
|
@@ -62,11 +85,14 @@ export class CopilotProvider {
|
|
|
62
85
|
// Start the client and test connectivity
|
|
63
86
|
try {
|
|
64
87
|
if (this.client) {
|
|
65
|
-
// Some SDK versions have start(), some don't (auto-start)
|
|
66
88
|
const client = this.client;
|
|
89
|
+
// Call start() - this is required even with autoStart: true
|
|
67
90
|
if (typeof client.start === 'function') {
|
|
68
91
|
await client.start();
|
|
69
92
|
}
|
|
93
|
+
// Wait a moment for connection to stabilize
|
|
94
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
95
|
+
// Test connectivity with ping
|
|
70
96
|
if (typeof client.ping === 'function') {
|
|
71
97
|
await client.ping();
|
|
72
98
|
}
|
|
@@ -76,9 +102,9 @@ export class CopilotProvider {
|
|
|
76
102
|
this.fetchAndCacheModels().catch(() => { });
|
|
77
103
|
}
|
|
78
104
|
}
|
|
79
|
-
catch (
|
|
105
|
+
catch (error) {
|
|
80
106
|
this.ready = false;
|
|
81
|
-
this.error = `Cannot connect to GitHub Copilot CLI: ${
|
|
107
|
+
this.error = `Cannot connect to GitHub Copilot CLI: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
|
82
108
|
}
|
|
83
109
|
}
|
|
84
110
|
catch (err) {
|
|
@@ -120,6 +146,7 @@ export class CopilotProvider {
|
|
|
120
146
|
getStatus() {
|
|
121
147
|
return {
|
|
122
148
|
ready: this.ready,
|
|
149
|
+
available: this.available,
|
|
123
150
|
model: this.model,
|
|
124
151
|
error: this.error,
|
|
125
152
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot-provider.js","sourceRoot":"","sources":["../../../../../src/server/services/agents/copilot-provider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAQ1C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEhE,6EAA6E;AAC7E,IAAI,OAAO,UAAU,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;IAC7C,UAAkD,CAAC,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/F,CAAC;AAiCD,MAAM,OAAO,eAAe;IACjB,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,gBAAgB,CAAC;IACjC,YAAY,GAAsB;QAChC,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE;YACN,SAAS;YACT,
|
|
1
|
+
{"version":3,"file":"copilot-provider.js","sourceRoot":"","sources":["../../../../../src/server/services/agents/copilot-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Provider for GUI
|
|
3
|
+
* Supports OpenAI API, VLLM, and any OpenAI-compatible endpoint
|
|
4
|
+
*/
|
|
5
|
+
import { buildPrompt, generateSuggestions } from './prompts.js';
|
|
6
|
+
export class OpenAIProvider {
|
|
7
|
+
id = 'openai';
|
|
8
|
+
name = 'OpenAI';
|
|
9
|
+
capabilities = {
|
|
10
|
+
streaming: true,
|
|
11
|
+
toolUse: true,
|
|
12
|
+
codeExecution: false,
|
|
13
|
+
systemPrompts: true,
|
|
14
|
+
models: ['gpt-4.5', 'gpt-4.1', 'gpt-4.1-mini', 'gpt-4o', 'o3'],
|
|
15
|
+
};
|
|
16
|
+
detectedModels = [];
|
|
17
|
+
apiKey = '';
|
|
18
|
+
baseUrl = 'https://api.openai.com/v1';
|
|
19
|
+
model = 'gpt-4.5';
|
|
20
|
+
ready = false;
|
|
21
|
+
error;
|
|
22
|
+
async initialize(config) {
|
|
23
|
+
try {
|
|
24
|
+
// Get API key from config or environment
|
|
25
|
+
this.apiKey = config.apiKey || process.env.OPENAI_API_KEY || '';
|
|
26
|
+
// For VLLM/local endpoints, use dummy key
|
|
27
|
+
if (config.baseUrl && !this.apiKey) {
|
|
28
|
+
this.apiKey = 'dummy-key';
|
|
29
|
+
}
|
|
30
|
+
if (!this.apiKey) {
|
|
31
|
+
this.ready = false;
|
|
32
|
+
this.error = 'OPENAI_API_KEY not set. Set environment variable or provide in config.';
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Configure base URL (for VLLM or other OpenAI-compatible endpoints)
|
|
36
|
+
if (config.baseUrl) {
|
|
37
|
+
this.baseUrl = config.baseUrl;
|
|
38
|
+
}
|
|
39
|
+
// Configure model
|
|
40
|
+
if (config.model) {
|
|
41
|
+
this.model = config.model;
|
|
42
|
+
}
|
|
43
|
+
// Test the connection and auto-detect models
|
|
44
|
+
try {
|
|
45
|
+
await this.testConnection();
|
|
46
|
+
await this.detectModels();
|
|
47
|
+
this.ready = true;
|
|
48
|
+
this.error = undefined;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
this.ready = false;
|
|
52
|
+
this.error = err instanceof Error ? err.message : 'Failed to connect to OpenAI API';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
this.ready = false;
|
|
57
|
+
this.error = err instanceof Error ? err.message : 'Unknown error initializing OpenAI';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async testConnection() {
|
|
61
|
+
const response = await fetch(`${this.baseUrl}/models`, {
|
|
62
|
+
headers: {
|
|
63
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`API test failed: ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Auto-detect available models from the server.
|
|
72
|
+
* Useful for local servers (llama.cpp, VLLM) that serve specific models.
|
|
73
|
+
*/
|
|
74
|
+
async detectModels() {
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(`${this.baseUrl}/models`, {
|
|
77
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
78
|
+
});
|
|
79
|
+
if (response.ok) {
|
|
80
|
+
const data = (await response.json());
|
|
81
|
+
if (data.data && Array.isArray(data.data)) {
|
|
82
|
+
this.detectedModels = data.data.map((m) => m.id);
|
|
83
|
+
// If using a local endpoint and no model was explicitly configured,
|
|
84
|
+
// auto-select the first available model
|
|
85
|
+
if (this.baseUrl !== 'https://api.openai.com/v1' && this.detectedModels.length > 0) {
|
|
86
|
+
if (this.model === 'gpt-4.5' || !this.detectedModels.includes(this.model)) {
|
|
87
|
+
this.model = this.detectedModels[0];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Non-fatal — use configured model
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
isReady() {
|
|
98
|
+
return this.ready;
|
|
99
|
+
}
|
|
100
|
+
getStatus() {
|
|
101
|
+
return {
|
|
102
|
+
ready: this.ready,
|
|
103
|
+
model: this.model,
|
|
104
|
+
error: this.error,
|
|
105
|
+
...(this.detectedModels.length > 0 ? { detectedModels: this.detectedModels } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async processPrompt(prompt, workflow, context) {
|
|
109
|
+
if (!this.ready) {
|
|
110
|
+
return {
|
|
111
|
+
explanation: 'OpenAI provider not available.',
|
|
112
|
+
error: this.error || 'Provider not initialized',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const { systemPrompt, userPrompt } = buildPrompt(prompt, workflow, context);
|
|
117
|
+
const messages = [
|
|
118
|
+
{ role: 'system', content: systemPrompt },
|
|
119
|
+
{ role: 'user', content: userPrompt },
|
|
120
|
+
];
|
|
121
|
+
const response = await this.callOpenAI(messages);
|
|
122
|
+
const responseText = response.choices[0]?.message?.content || '';
|
|
123
|
+
return await this.parseAIResponse(responseText, workflow);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
return {
|
|
127
|
+
explanation: '',
|
|
128
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async callOpenAI(messages) {
|
|
133
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
138
|
+
},
|
|
139
|
+
body: JSON.stringify({
|
|
140
|
+
model: this.model,
|
|
141
|
+
messages,
|
|
142
|
+
temperature: 0.7,
|
|
143
|
+
max_tokens: 4000,
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
const errorText = await response.text();
|
|
148
|
+
throw new Error(`OpenAI API error: ${response.statusText} - ${errorText}`);
|
|
149
|
+
}
|
|
150
|
+
return response.json();
|
|
151
|
+
}
|
|
152
|
+
async streamPrompt(prompt, workflow, onChunk, context) {
|
|
153
|
+
if (!this.ready) {
|
|
154
|
+
return this.processPrompt(prompt, workflow, context);
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const { systemPrompt, userPrompt } = buildPrompt(prompt, workflow, context);
|
|
158
|
+
const messages = [
|
|
159
|
+
{ role: 'system', content: systemPrompt },
|
|
160
|
+
{ role: 'user', content: userPrompt },
|
|
161
|
+
];
|
|
162
|
+
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
163
|
+
method: 'POST',
|
|
164
|
+
headers: {
|
|
165
|
+
'Content-Type': 'application/json',
|
|
166
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify({
|
|
169
|
+
model: this.model,
|
|
170
|
+
messages,
|
|
171
|
+
temperature: 0.7,
|
|
172
|
+
max_tokens: 4000,
|
|
173
|
+
stream: true,
|
|
174
|
+
}),
|
|
175
|
+
});
|
|
176
|
+
if (!response.ok) {
|
|
177
|
+
throw new Error(`OpenAI API error: ${response.statusText}`);
|
|
178
|
+
}
|
|
179
|
+
let fullResponse = '';
|
|
180
|
+
const reader = response.body?.getReader();
|
|
181
|
+
const decoder = new TextDecoder();
|
|
182
|
+
if (!reader) {
|
|
183
|
+
throw new Error('No response body');
|
|
184
|
+
}
|
|
185
|
+
while (true) {
|
|
186
|
+
const { done, value } = await reader.read();
|
|
187
|
+
if (done)
|
|
188
|
+
break;
|
|
189
|
+
const chunk = decoder.decode(value);
|
|
190
|
+
const lines = chunk.split('\n').filter((line) => line.trim() !== '');
|
|
191
|
+
for (const line of lines) {
|
|
192
|
+
if (line.startsWith('data: ')) {
|
|
193
|
+
const data = line.slice(6);
|
|
194
|
+
if (data === '[DONE]')
|
|
195
|
+
continue;
|
|
196
|
+
try {
|
|
197
|
+
const parsed = JSON.parse(data);
|
|
198
|
+
const content = parsed.choices[0]?.delta?.content;
|
|
199
|
+
if (content) {
|
|
200
|
+
fullResponse += content;
|
|
201
|
+
onChunk(content);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Skip invalid JSON
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return await this.parseAIResponse(fullResponse, workflow);
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return {
|
|
214
|
+
explanation: '',
|
|
215
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getSuggestions(workflow, selectedStepId) {
|
|
220
|
+
return generateSuggestions(workflow, selectedStepId);
|
|
221
|
+
}
|
|
222
|
+
async cancel() {
|
|
223
|
+
// OpenAI doesn't provide a cancel mechanism via API
|
|
224
|
+
// The request will be aborted by closing the connection
|
|
225
|
+
}
|
|
226
|
+
async parseAIResponse(responseText, originalWorkflow) {
|
|
227
|
+
const yamlMatch = responseText.match(/```yaml\n([\s\S]*?)\n```/);
|
|
228
|
+
let modifiedWorkflow;
|
|
229
|
+
let explanation = responseText;
|
|
230
|
+
if (yamlMatch) {
|
|
231
|
+
try {
|
|
232
|
+
const { parse } = await import('yaml');
|
|
233
|
+
const parsedYaml = parse(yamlMatch[1]);
|
|
234
|
+
if (parsedYaml && (parsedYaml.steps || parsedYaml.metadata)) {
|
|
235
|
+
modifiedWorkflow = parsedYaml;
|
|
236
|
+
const explanationMatch = responseText.match(/^([\s\S]*?)```yaml/);
|
|
237
|
+
if (explanationMatch) {
|
|
238
|
+
explanation = explanationMatch[1].trim();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// Failed to parse YAML
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
let diff;
|
|
247
|
+
if (modifiedWorkflow) {
|
|
248
|
+
diff = this.generateDiff(originalWorkflow, modifiedWorkflow);
|
|
249
|
+
}
|
|
250
|
+
return { explanation, workflow: modifiedWorkflow, diff };
|
|
251
|
+
}
|
|
252
|
+
generateDiff(original, modified) {
|
|
253
|
+
const originalStepIds = new Set(original.steps?.map((s) => s.id) || []);
|
|
254
|
+
const modifiedStepIds = new Set(modified.steps?.map((s) => s.id) || []);
|
|
255
|
+
const added = modified.steps?.filter((s) => !originalStepIds.has(s.id)) || [];
|
|
256
|
+
const removed = original.steps?.filter((s) => !modifiedStepIds.has(s.id)) || [];
|
|
257
|
+
let diff = '';
|
|
258
|
+
if (added.length > 0) {
|
|
259
|
+
diff += `+ Added ${added.length} step(s): ${added.map((s) => s.name || s.id).join(', ')}\n`;
|
|
260
|
+
}
|
|
261
|
+
if (removed.length > 0) {
|
|
262
|
+
diff += `- Removed ${removed.length} step(s): ${removed.map((s) => s.name || s.id).join(', ')}\n`;
|
|
263
|
+
}
|
|
264
|
+
return diff || 'No structural changes detected';
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
export function createOpenAIProvider(config) {
|
|
268
|
+
const provider = new OpenAIProvider();
|
|
269
|
+
if (config) {
|
|
270
|
+
provider.initialize(config);
|
|
271
|
+
}
|
|
272
|
+
return provider;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../../../../src/server/services/agents/openai-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Provider for GUI
|
|
3
|
+
* Supports OpenCode in both CLI and server modes
|
|
4
|
+
*
|
|
5
|
+
* Configuration:
|
|
6
|
+
* - CLI mode: Uses local opencode CLI (must be installed)
|
|
7
|
+
* - Server mode: Connects to opencode server
|
|
8
|
+
* - Default server: http://localhost:4096
|
|
9
|
+
* - Configure via baseUrl option in GUI
|
|
10
|
+
* - Start server with: opencode serve --port 4096
|
|
11
|
+
*/
|
|
12
|
+
import { buildPrompt, generateSuggestions } from './prompts.js';
|
|
13
|
+
export class OpenCodeProvider {
|
|
14
|
+
static DEFAULT_PORT = 4096;
|
|
15
|
+
static DEFAULT_SERVER_URL = `http://localhost:${OpenCodeProvider.DEFAULT_PORT}`;
|
|
16
|
+
id = 'opencode';
|
|
17
|
+
name = 'OpenCode';
|
|
18
|
+
capabilities = {
|
|
19
|
+
streaming: true,
|
|
20
|
+
toolUse: true,
|
|
21
|
+
codeExecution: true,
|
|
22
|
+
systemPrompts: true,
|
|
23
|
+
models: [], // OpenCode supports many models via different backends
|
|
24
|
+
};
|
|
25
|
+
mode = 'cli';
|
|
26
|
+
serverUrl = OpenCodeProvider.DEFAULT_SERVER_URL;
|
|
27
|
+
ready = false;
|
|
28
|
+
error;
|
|
29
|
+
model;
|
|
30
|
+
async initialize(config) {
|
|
31
|
+
try {
|
|
32
|
+
// Determine mode (server or CLI)
|
|
33
|
+
if (config.options?.mode === 'server' || config.baseUrl) {
|
|
34
|
+
this.mode = 'server';
|
|
35
|
+
if (config.baseUrl) {
|
|
36
|
+
this.serverUrl = config.baseUrl;
|
|
37
|
+
}
|
|
38
|
+
else if (config.options?.port) {
|
|
39
|
+
// Support direct port configuration
|
|
40
|
+
const port = config.options.port;
|
|
41
|
+
this.serverUrl = `http://localhost:${port}`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Set model if provided
|
|
45
|
+
if (config.model) {
|
|
46
|
+
this.model = config.model;
|
|
47
|
+
}
|
|
48
|
+
// Test availability
|
|
49
|
+
if (this.mode === 'server') {
|
|
50
|
+
await this.testServerConnection();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
await this.testCLI();
|
|
54
|
+
}
|
|
55
|
+
this.ready = true;
|
|
56
|
+
this.error = undefined;
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
this.ready = false;
|
|
60
|
+
this.error = err instanceof Error ? err.message : 'Unknown error initializing OpenCode';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async testServerConnection() {
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch(`${this.serverUrl}/health`).catch(() => null);
|
|
66
|
+
if (!response || !response.ok) {
|
|
67
|
+
throw new Error(`OpenCode server not responding at ${this.serverUrl}. Start with: opencode serve --port 4096`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
throw new Error(`OpenCode server not available. Start with: opencode serve --port 4096`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async testCLI() {
|
|
75
|
+
// Check if opencode CLI is available
|
|
76
|
+
const { spawn } = await import('node:child_process');
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const process = spawn('which', ['opencode']);
|
|
79
|
+
process.on('close', (code) => {
|
|
80
|
+
if (code === 0) {
|
|
81
|
+
resolve();
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
reject(new Error('OpenCode CLI not found. Install from: https://opencode.ai'));
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
process.on('error', () => {
|
|
88
|
+
reject(new Error('OpenCode CLI not found. Install from: https://opencode.ai'));
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
isReady() {
|
|
93
|
+
return this.ready;
|
|
94
|
+
}
|
|
95
|
+
getStatus() {
|
|
96
|
+
const status = {
|
|
97
|
+
ready: this.ready,
|
|
98
|
+
error: this.error,
|
|
99
|
+
};
|
|
100
|
+
// Show current configuration
|
|
101
|
+
if (this.mode === 'server') {
|
|
102
|
+
status.model = `Server: ${this.serverUrl}${this.model ? ` (${this.model})` : ''}`;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
status.model = this.model || 'CLI mode';
|
|
106
|
+
}
|
|
107
|
+
return status;
|
|
108
|
+
}
|
|
109
|
+
async processPrompt(prompt, workflow, context) {
|
|
110
|
+
if (!this.ready) {
|
|
111
|
+
return {
|
|
112
|
+
explanation: 'OpenCode not available.',
|
|
113
|
+
error: this.error || 'Provider not initialized',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const { systemPrompt, userPrompt } = buildPrompt(prompt, workflow, context);
|
|
118
|
+
const fullPrompt = `${systemPrompt}\n\n---\n\nUser request: ${userPrompt}`;
|
|
119
|
+
let responseText;
|
|
120
|
+
if (this.mode === 'server') {
|
|
121
|
+
responseText = await this.callServer(fullPrompt);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
responseText = await this.callCLI(fullPrompt);
|
|
125
|
+
}
|
|
126
|
+
return await this.parseAIResponse(responseText, workflow);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return {
|
|
130
|
+
explanation: '',
|
|
131
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async callServer(prompt) {
|
|
136
|
+
// Create session if needed, then send prompt
|
|
137
|
+
const sessionResponse = await fetch(`${this.serverUrl}/api/session`, {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
headers: { 'Content-Type': 'application/json' },
|
|
140
|
+
body: JSON.stringify({}),
|
|
141
|
+
});
|
|
142
|
+
if (!sessionResponse.ok) {
|
|
143
|
+
throw new Error('Failed to create OpenCode session');
|
|
144
|
+
}
|
|
145
|
+
const sessionData = (await sessionResponse.json());
|
|
146
|
+
const sessionId = sessionData.id;
|
|
147
|
+
// Send prompt to session
|
|
148
|
+
const promptResponse = await fetch(`${this.serverUrl}/api/session/${sessionId}/prompt`, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
headers: { 'Content-Type': 'application/json' },
|
|
151
|
+
body: JSON.stringify({
|
|
152
|
+
parts: [{ type: 'text', text: prompt }],
|
|
153
|
+
model: this.model,
|
|
154
|
+
}),
|
|
155
|
+
});
|
|
156
|
+
if (!promptResponse.ok) {
|
|
157
|
+
throw new Error('OpenCode server error');
|
|
158
|
+
}
|
|
159
|
+
const result = (await promptResponse.json());
|
|
160
|
+
// Extract text from response parts
|
|
161
|
+
if (result.parts) {
|
|
162
|
+
return result.parts
|
|
163
|
+
.filter((p) => p.type === 'text')
|
|
164
|
+
.map((p) => p.text || '')
|
|
165
|
+
.join('\n');
|
|
166
|
+
}
|
|
167
|
+
return result.message || '';
|
|
168
|
+
}
|
|
169
|
+
async callCLI(prompt) {
|
|
170
|
+
const { spawn } = await import('node:child_process');
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
const args = ['run'];
|
|
173
|
+
if (this.model) {
|
|
174
|
+
args.push('--model', this.model);
|
|
175
|
+
}
|
|
176
|
+
args.push(prompt);
|
|
177
|
+
const process = spawn('opencode', args);
|
|
178
|
+
let output = '';
|
|
179
|
+
let errorOutput = '';
|
|
180
|
+
process.stdout.on('data', (data) => {
|
|
181
|
+
output += data.toString();
|
|
182
|
+
});
|
|
183
|
+
process.stderr.on('data', (data) => {
|
|
184
|
+
errorOutput += data.toString();
|
|
185
|
+
});
|
|
186
|
+
process.on('close', (code) => {
|
|
187
|
+
if (code === 0) {
|
|
188
|
+
resolve(output);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
reject(new Error(`OpenCode CLI failed: ${errorOutput || output}`));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
process.on('error', (err) => {
|
|
195
|
+
reject(new Error(`Failed to run OpenCode CLI: ${err.message}`));
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async streamPrompt(prompt, workflow, _onChunk, context) {
|
|
200
|
+
// For now, fall back to non-streaming for GUI
|
|
201
|
+
// Server mode streaming would require SSE implementation
|
|
202
|
+
return this.processPrompt(prompt, workflow, context);
|
|
203
|
+
}
|
|
204
|
+
async getSuggestions(workflow, selectedStepId) {
|
|
205
|
+
return generateSuggestions(workflow, selectedStepId);
|
|
206
|
+
}
|
|
207
|
+
async cancel() {
|
|
208
|
+
// Would need to implement session cancellation for server mode
|
|
209
|
+
}
|
|
210
|
+
async parseAIResponse(responseText, originalWorkflow) {
|
|
211
|
+
const yamlMatch = responseText.match(/```yaml\n([\s\S]*?)\n```/);
|
|
212
|
+
let modifiedWorkflow;
|
|
213
|
+
let explanation = responseText;
|
|
214
|
+
if (yamlMatch) {
|
|
215
|
+
try {
|
|
216
|
+
const { parse } = await import('yaml');
|
|
217
|
+
const parsedYaml = parse(yamlMatch[1]);
|
|
218
|
+
if (parsedYaml && (parsedYaml.steps || parsedYaml.metadata)) {
|
|
219
|
+
modifiedWorkflow = parsedYaml;
|
|
220
|
+
const explanationMatch = responseText.match(/^([\s\S]*?)```yaml/);
|
|
221
|
+
if (explanationMatch) {
|
|
222
|
+
explanation = explanationMatch[1].trim();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Failed to parse YAML
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
let diff;
|
|
231
|
+
if (modifiedWorkflow) {
|
|
232
|
+
diff = this.generateDiff(originalWorkflow, modifiedWorkflow);
|
|
233
|
+
}
|
|
234
|
+
return { explanation, workflow: modifiedWorkflow, diff };
|
|
235
|
+
}
|
|
236
|
+
generateDiff(original, modified) {
|
|
237
|
+
const originalStepIds = new Set(original.steps?.map((s) => s.id) || []);
|
|
238
|
+
const modifiedStepIds = new Set(modified.steps?.map((s) => s.id) || []);
|
|
239
|
+
const added = modified.steps?.filter((s) => !originalStepIds.has(s.id)) || [];
|
|
240
|
+
const removed = original.steps?.filter((s) => !modifiedStepIds.has(s.id)) || [];
|
|
241
|
+
let diff = '';
|
|
242
|
+
if (added.length > 0) {
|
|
243
|
+
diff += `+ Added ${added.length} step(s): ${added.map((s) => s.name || s.id).join(', ')}\n`;
|
|
244
|
+
}
|
|
245
|
+
if (removed.length > 0) {
|
|
246
|
+
diff += `- Removed ${removed.length} step(s): ${removed.map((s) => s.name || s.id).join(', ')}\n`;
|
|
247
|
+
}
|
|
248
|
+
return diff || 'No structural changes detected';
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
export function createOpenCodeProvider(config) {
|
|
252
|
+
const provider = new OpenCodeProvider();
|
|
253
|
+
if (config) {
|
|
254
|
+
provider.initialize(config);
|
|
255
|
+
}
|
|
256
|
+
return provider;
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=opencode-provider.js.map
|