@fractary/faber 2.4.39 → 2.4.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/logs.d.ts.map +1 -1
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/repo.d.ts.map +1 -1
- package/dist/cli/commands/repo.js.map +1 -1
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/cli/commands/work.d.ts.map +1 -1
- package/dist/cli/commands/work.js.map +1 -1
- package/dist/cli/commands/workflow.d.ts.map +1 -1
- package/dist/cli/commands/workflow.js.map +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/executors/cli-entry.d.ts +25 -0
- package/dist/executors/cli-entry.d.ts.map +1 -0
- package/dist/executors/cli-entry.js +86 -0
- package/dist/executors/cli-entry.js.map +1 -0
- package/dist/executors/index.d.ts +19 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js +22 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/providers/claude.d.ts +20 -0
- package/dist/executors/providers/claude.d.ts.map +1 -0
- package/dist/executors/providers/claude.js +123 -0
- package/dist/executors/providers/claude.js.map +1 -0
- package/dist/executors/providers/http.d.ts +21 -0
- package/dist/executors/providers/http.d.ts.map +1 -0
- package/dist/executors/providers/http.js +118 -0
- package/dist/executors/providers/http.js.map +1 -0
- package/dist/executors/providers/index.d.ts +10 -0
- package/dist/executors/providers/index.d.ts.map +1 -0
- package/dist/executors/providers/index.js +10 -0
- package/dist/executors/providers/index.js.map +1 -0
- package/dist/executors/providers/openai-compatible.d.ts +21 -0
- package/dist/executors/providers/openai-compatible.d.ts.map +1 -0
- package/dist/executors/providers/openai-compatible.js +136 -0
- package/dist/executors/providers/openai-compatible.js.map +1 -0
- package/dist/executors/providers/openai.d.ts +20 -0
- package/dist/executors/providers/openai.d.ts.map +1 -0
- package/dist/executors/providers/openai.js +121 -0
- package/dist/executors/providers/openai.js.map +1 -0
- package/dist/executors/registry.d.ts +72 -0
- package/dist/executors/registry.d.ts.map +1 -0
- package/dist/executors/registry.js +146 -0
- package/dist/executors/registry.js.map +1 -0
- package/dist/executors/types.d.ts +148 -0
- package/dist/executors/types.d.ts.map +1 -0
- package/dist/executors/types.js +9 -0
- package/dist/executors/types.js.map +1 -0
- package/dist/executors/workflow-executor.d.ts +92 -0
- package/dist/executors/workflow-executor.d.ts.map +1 -0
- package/dist/executors/workflow-executor.js +176 -0
- package/dist/executors/workflow-executor.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/workflow/__tests__/resolver.test.js +20 -20
- package/dist/workflow/resolver.d.ts +71 -2
- package/dist/workflow/resolver.d.ts.map +1 -1
- package/dist/workflow/resolver.js +140 -12
- package/dist/workflow/resolver.js.map +1 -1
- package/dist/workflows/registry.d.ts.map +1 -1
- package/dist/workflows/registry.js +48 -17
- package/dist/workflows/registry.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - HTTP Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes workflow steps via generic HTTP POST requests.
|
|
5
|
+
* Designed for non-LLM APIs (Banana, Replicate, custom services).
|
|
6
|
+
*
|
|
7
|
+
* The step prompt is sent as the request body (or within a JSON payload).
|
|
8
|
+
* The response body is returned as the executor output.
|
|
9
|
+
*
|
|
10
|
+
* Requires `base_url` in config.
|
|
11
|
+
*/
|
|
12
|
+
export class HttpExecutor {
|
|
13
|
+
provider = 'http';
|
|
14
|
+
async execute(prompt, context, config) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
const baseUrl = config.base_url;
|
|
17
|
+
if (!baseUrl) {
|
|
18
|
+
return {
|
|
19
|
+
output: '',
|
|
20
|
+
status: 'failure',
|
|
21
|
+
error: 'base_url is required for http provider',
|
|
22
|
+
metadata: { provider: this.provider, duration_ms: Date.now() - startTime },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const apiKey = config.api_key_env ? process.env[config.api_key_env] : undefined;
|
|
26
|
+
try {
|
|
27
|
+
const headers = {
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
};
|
|
30
|
+
if (apiKey) {
|
|
31
|
+
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
32
|
+
}
|
|
33
|
+
// Build request body — wrap prompt in a JSON payload with context
|
|
34
|
+
const body = JSON.stringify({
|
|
35
|
+
prompt,
|
|
36
|
+
context: {
|
|
37
|
+
work_id: context.workId,
|
|
38
|
+
phase: context.phase,
|
|
39
|
+
step_id: context.stepId,
|
|
40
|
+
step_name: context.stepName,
|
|
41
|
+
},
|
|
42
|
+
model: config.model,
|
|
43
|
+
});
|
|
44
|
+
const response = await fetch(baseUrl, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers,
|
|
47
|
+
body,
|
|
48
|
+
});
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
const errorBody = await response.text();
|
|
51
|
+
return {
|
|
52
|
+
output: '',
|
|
53
|
+
status: 'failure',
|
|
54
|
+
error: `HTTP error (${response.status}) from ${baseUrl}: ${errorBody}`,
|
|
55
|
+
metadata: { provider: this.provider, duration_ms: Date.now() - startTime },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Try to parse as JSON, fall back to text
|
|
59
|
+
const contentType = response.headers.get('content-type') || '';
|
|
60
|
+
let output;
|
|
61
|
+
if (contentType.includes('application/json')) {
|
|
62
|
+
const data = await response.json();
|
|
63
|
+
// Try common response patterns
|
|
64
|
+
output =
|
|
65
|
+
typeof data === 'string' ? data :
|
|
66
|
+
(data.output ?? data.result ?? data.text ?? data.content ?? data.message ??
|
|
67
|
+
JSON.stringify(data, null, 2));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
output = await response.text();
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
output: String(output),
|
|
74
|
+
status: 'success',
|
|
75
|
+
metadata: {
|
|
76
|
+
provider: this.provider,
|
|
77
|
+
model: config.model,
|
|
78
|
+
duration_ms: Date.now() - startTime,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return {
|
|
84
|
+
output: '',
|
|
85
|
+
status: 'failure',
|
|
86
|
+
error: `HTTP executor error: ${error instanceof Error ? error.message : String(error)}`,
|
|
87
|
+
metadata: { provider: this.provider, duration_ms: Date.now() - startTime },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async validate(config) {
|
|
92
|
+
if (!config.base_url) {
|
|
93
|
+
return {
|
|
94
|
+
valid: false,
|
|
95
|
+
error: "base_url is required for 'http' provider",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Validate URL format
|
|
99
|
+
try {
|
|
100
|
+
new URL(config.base_url);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return {
|
|
104
|
+
valid: false,
|
|
105
|
+
error: `Invalid URL: ${config.base_url}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Check API key if specified
|
|
109
|
+
if (config.api_key_env && !process.env[config.api_key_env]) {
|
|
110
|
+
return {
|
|
111
|
+
valid: false,
|
|
112
|
+
error: `Environment variable '${config.api_key_env}' is not set`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return { valid: true };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/executors/providers/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - Executor Providers
|
|
3
|
+
*
|
|
4
|
+
* Built-in executor implementations for different model providers and services.
|
|
5
|
+
*/
|
|
6
|
+
export { ClaudeExecutor } from './claude.js';
|
|
7
|
+
export { OpenAIExecutor } from './openai.js';
|
|
8
|
+
export { OpenAICompatibleExecutor } from './openai-compatible.js';
|
|
9
|
+
export { HttpExecutor } from './http.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/executors/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - Executor Providers
|
|
3
|
+
*
|
|
4
|
+
* Built-in executor implementations for different model providers and services.
|
|
5
|
+
*/
|
|
6
|
+
export { ClaudeExecutor } from './claude.js';
|
|
7
|
+
export { OpenAIExecutor } from './openai.js';
|
|
8
|
+
export { OpenAICompatibleExecutor } from './openai-compatible.js';
|
|
9
|
+
export { HttpExecutor } from './http.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/executors/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - OpenAI-Compatible Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes workflow steps via any OpenAI-compatible Chat Completions API.
|
|
5
|
+
* Supports: Ollama, vLLM, Together AI, Groq, Fireworks, and any other
|
|
6
|
+
* service implementing the OpenAI Chat Completions interface.
|
|
7
|
+
*
|
|
8
|
+
* Requires `base_url` in config (e.g., 'http://localhost:11434/v1' for Ollama).
|
|
9
|
+
* Default env var: none (many local services don't require auth)
|
|
10
|
+
*/
|
|
11
|
+
import type { Executor, ExecutorResult, ExecutionContext, StepExecutorConfig } from '../types.js';
|
|
12
|
+
export declare class OpenAICompatibleExecutor implements Executor {
|
|
13
|
+
readonly provider = "openai-compatible";
|
|
14
|
+
execute(prompt: string, context: ExecutionContext, config: StepExecutorConfig): Promise<ExecutorResult>;
|
|
15
|
+
validate(config: StepExecutorConfig): Promise<{
|
|
16
|
+
valid: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
}>;
|
|
19
|
+
private buildContextPrefix;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=openai-compatible.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../../src/executors/providers/openai-compatible.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAIrB,qBAAa,wBAAyB,YAAW,QAAQ;IACvD,QAAQ,CAAC,QAAQ,uBAAuB;IAElC,OAAO,CACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,cAAc,CAAC;IAsGpB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA0BvF,OAAO,CAAC,kBAAkB;CAoB3B"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - OpenAI-Compatible Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes workflow steps via any OpenAI-compatible Chat Completions API.
|
|
5
|
+
* Supports: Ollama, vLLM, Together AI, Groq, Fireworks, and any other
|
|
6
|
+
* service implementing the OpenAI Chat Completions interface.
|
|
7
|
+
*
|
|
8
|
+
* Requires `base_url` in config (e.g., 'http://localhost:11434/v1' for Ollama).
|
|
9
|
+
* Default env var: none (many local services don't require auth)
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
12
|
+
export class OpenAICompatibleExecutor {
|
|
13
|
+
provider = 'openai-compatible';
|
|
14
|
+
async execute(prompt, context, config) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
const model = config.model || 'default';
|
|
17
|
+
const maxTokens = config.max_tokens || DEFAULT_MAX_TOKENS;
|
|
18
|
+
const baseUrl = config.base_url;
|
|
19
|
+
if (!baseUrl) {
|
|
20
|
+
return {
|
|
21
|
+
output: '',
|
|
22
|
+
status: 'failure',
|
|
23
|
+
error: 'base_url is required for openai-compatible provider',
|
|
24
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// API key is optional for local services (Ollama, etc.)
|
|
28
|
+
const apiKey = config.api_key_env ? process.env[config.api_key_env] : undefined;
|
|
29
|
+
// Build messages
|
|
30
|
+
const messages = [];
|
|
31
|
+
if (config.system_prompt) {
|
|
32
|
+
messages.push({ role: 'system', content: config.system_prompt });
|
|
33
|
+
}
|
|
34
|
+
if (!config.system_prompt) {
|
|
35
|
+
const contextPrefix = this.buildContextPrefix(context);
|
|
36
|
+
if (contextPrefix) {
|
|
37
|
+
messages.push({ role: 'system', content: contextPrefix });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
messages.push({ role: 'user', content: prompt });
|
|
41
|
+
const body = {
|
|
42
|
+
model,
|
|
43
|
+
max_tokens: maxTokens,
|
|
44
|
+
messages,
|
|
45
|
+
};
|
|
46
|
+
if (config.temperature !== undefined) {
|
|
47
|
+
body.temperature = config.temperature;
|
|
48
|
+
}
|
|
49
|
+
// Normalize base URL (strip trailing slash)
|
|
50
|
+
const normalizedBaseUrl = baseUrl.replace(/\/+$/, '');
|
|
51
|
+
const url = `${normalizedBaseUrl}/chat/completions`;
|
|
52
|
+
try {
|
|
53
|
+
const headers = {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
};
|
|
56
|
+
if (apiKey) {
|
|
57
|
+
headers['Authorization'] = `Bearer ${apiKey}`;
|
|
58
|
+
}
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers,
|
|
62
|
+
body: JSON.stringify(body),
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const errorBody = await response.text();
|
|
66
|
+
return {
|
|
67
|
+
output: '',
|
|
68
|
+
status: 'failure',
|
|
69
|
+
error: `API error (${response.status}) from ${normalizedBaseUrl}: ${errorBody}`,
|
|
70
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const data = await response.json();
|
|
74
|
+
const output = data.choices?.[0]?.message?.content || '';
|
|
75
|
+
return {
|
|
76
|
+
output,
|
|
77
|
+
status: 'success',
|
|
78
|
+
metadata: {
|
|
79
|
+
provider: this.provider,
|
|
80
|
+
model,
|
|
81
|
+
duration_ms: Date.now() - startTime,
|
|
82
|
+
tokens_used: data.usage
|
|
83
|
+
? { input: data.usage.prompt_tokens, output: data.usage.completion_tokens }
|
|
84
|
+
: undefined,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
output: '',
|
|
91
|
+
status: 'failure',
|
|
92
|
+
error: `OpenAI-compatible executor error: ${error instanceof Error ? error.message : String(error)}`,
|
|
93
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async validate(config) {
|
|
98
|
+
if (!config.base_url) {
|
|
99
|
+
return {
|
|
100
|
+
valid: false,
|
|
101
|
+
error: "base_url is required for 'openai-compatible' provider (e.g., 'http://localhost:11434/v1')",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (!config.model) {
|
|
105
|
+
return {
|
|
106
|
+
valid: false,
|
|
107
|
+
error: "model is required for 'openai-compatible' provider (e.g., 'llama3', 'mixtral')",
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Check API key if specified
|
|
111
|
+
if (config.api_key_env && !process.env[config.api_key_env]) {
|
|
112
|
+
return {
|
|
113
|
+
valid: false,
|
|
114
|
+
error: `Environment variable '${config.api_key_env}' is not set`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return { valid: true };
|
|
118
|
+
}
|
|
119
|
+
buildContextPrefix(context) {
|
|
120
|
+
const parts = [];
|
|
121
|
+
if (context.issue) {
|
|
122
|
+
parts.push(`Issue #${context.issue.number}: ${context.issue.title}`);
|
|
123
|
+
if (context.issue.body) {
|
|
124
|
+
parts.push(`Issue description: ${context.issue.body.slice(0, 2000)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (context.phase) {
|
|
128
|
+
parts.push(`Workflow phase: ${context.phase}`);
|
|
129
|
+
}
|
|
130
|
+
if (context.stepName) {
|
|
131
|
+
parts.push(`Step: ${context.stepName}`);
|
|
132
|
+
}
|
|
133
|
+
return parts.length > 0 ? parts.join('\n') : '';
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=openai-compatible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.js","sourceRoot":"","sources":["../../../src/executors/providers/openai-compatible.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC,MAAM,OAAO,wBAAwB;IAC1B,QAAQ,GAAG,mBAAmB,CAAC;IAExC,KAAK,CAAC,OAAO,CACX,MAAc,EACd,OAAyB,EACzB,MAA0B;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC;QACxC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,IAAI,kBAAkB,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC;QAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,qDAAqD;gBAC5D,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;aAClF,CAAC;QACJ,CAAC;QAED,wDAAwD;QACxD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEhF,iBAAiB;QACjB,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAE9D,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACvD,IAAI,aAAa,EAAE,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEjD,MAAM,IAAI,GAA4B;YACpC,KAAK;YACL,UAAU,EAAE,SAAS;YACrB,QAAQ;SACT,CAAC;QAEF,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACxC,CAAC;QAED,4CAA4C;QAC5C,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,GAAG,iBAAiB,mBAAmB,CAAC;QAEpD,IAAI,CAAC;YACH,MAAM,OAAO,GAA2B;gBACtC,cAAc,EAAE,kBAAkB;aACnC,CAAC;YAEF,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;YAChD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,OAAO;oBACL,MAAM,EAAE,EAAE;oBACV,MAAM,EAAE,SAAS;oBACjB,KAAK,EAAE,cAAc,QAAQ,CAAC,MAAM,UAAU,iBAAiB,KAAK,SAAS,EAAE;oBAC/E,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;iBAClF,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAG/B,CAAC;YAEF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;YAEzD,OAAO;gBACL,MAAM;gBACN,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE;oBACR,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,KAAK;oBACL,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBACnC,WAAW,EAAE,IAAI,CAAC,KAAK;wBACrB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;wBAC3E,CAAC,CAAC,SAAS;iBACd;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACpG,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;aAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAA0B;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,2FAA2F;aACnG,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,gFAAgF;aACxF,CAAC;QACJ,CAAC;QAED,6BAA6B;QAC7B,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3D,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,yBAAyB,MAAM,CAAC,WAAW,cAAc;aACjE,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAEO,kBAAkB,CAAC,OAAyB;QAClD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACrE,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,sBAAsB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - OpenAI Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes workflow steps via the OpenAI Chat Completions API.
|
|
5
|
+
* Supports GPT-4o, o3, and other OpenAI models.
|
|
6
|
+
*
|
|
7
|
+
* Default env var: OPENAI_API_KEY
|
|
8
|
+
* Default model: gpt-4o
|
|
9
|
+
*/
|
|
10
|
+
import type { Executor, ExecutorResult, ExecutionContext, StepExecutorConfig } from '../types.js';
|
|
11
|
+
export declare class OpenAIExecutor implements Executor {
|
|
12
|
+
readonly provider = "openai";
|
|
13
|
+
execute(prompt: string, context: ExecutionContext, config: StepExecutorConfig): Promise<ExecutorResult>;
|
|
14
|
+
validate(config: StepExecutorConfig): Promise<{
|
|
15
|
+
valid: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
}>;
|
|
18
|
+
private buildContextPrefix;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/executors/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAOrB,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,QAAQ,YAAY;IAEvB,OAAO,CACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,cAAc,CAAC;IA4FpB,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAcvF,OAAO,CAAC,kBAAkB;CAoB3B"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - OpenAI Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes workflow steps via the OpenAI Chat Completions API.
|
|
5
|
+
* Supports GPT-4o, o3, and other OpenAI models.
|
|
6
|
+
*
|
|
7
|
+
* Default env var: OPENAI_API_KEY
|
|
8
|
+
* Default model: gpt-4o
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_MODEL = 'gpt-4o';
|
|
11
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
12
|
+
const DEFAULT_API_KEY_ENV = 'OPENAI_API_KEY';
|
|
13
|
+
const API_BASE_URL = 'https://api.openai.com/v1';
|
|
14
|
+
export class OpenAIExecutor {
|
|
15
|
+
provider = 'openai';
|
|
16
|
+
async execute(prompt, context, config) {
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
const model = config.model || DEFAULT_MODEL;
|
|
19
|
+
const maxTokens = config.max_tokens || DEFAULT_MAX_TOKENS;
|
|
20
|
+
const apiKeyEnv = config.api_key_env || DEFAULT_API_KEY_ENV;
|
|
21
|
+
const apiKey = process.env[apiKeyEnv];
|
|
22
|
+
if (!apiKey) {
|
|
23
|
+
return {
|
|
24
|
+
output: '',
|
|
25
|
+
status: 'failure',
|
|
26
|
+
error: `API key not found in environment variable: ${apiKeyEnv}`,
|
|
27
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Build messages
|
|
31
|
+
const messages = [];
|
|
32
|
+
if (config.system_prompt) {
|
|
33
|
+
messages.push({ role: 'system', content: config.system_prompt });
|
|
34
|
+
}
|
|
35
|
+
// Add context as system message if no custom system prompt
|
|
36
|
+
if (!config.system_prompt) {
|
|
37
|
+
const contextPrefix = this.buildContextPrefix(context);
|
|
38
|
+
if (contextPrefix) {
|
|
39
|
+
messages.push({ role: 'system', content: contextPrefix });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
messages.push({ role: 'user', content: prompt });
|
|
43
|
+
const body = {
|
|
44
|
+
model,
|
|
45
|
+
max_tokens: maxTokens,
|
|
46
|
+
messages,
|
|
47
|
+
};
|
|
48
|
+
if (config.temperature !== undefined) {
|
|
49
|
+
body.temperature = config.temperature;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const response = await fetch(`${API_BASE_URL}/chat/completions`, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: {
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
57
|
+
},
|
|
58
|
+
body: JSON.stringify(body),
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const errorBody = await response.text();
|
|
62
|
+
return {
|
|
63
|
+
output: '',
|
|
64
|
+
status: 'failure',
|
|
65
|
+
error: `OpenAI API error (${response.status}): ${errorBody}`,
|
|
66
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const data = await response.json();
|
|
70
|
+
const output = data.choices?.[0]?.message?.content || '';
|
|
71
|
+
return {
|
|
72
|
+
output,
|
|
73
|
+
status: 'success',
|
|
74
|
+
metadata: {
|
|
75
|
+
provider: this.provider,
|
|
76
|
+
model,
|
|
77
|
+
duration_ms: Date.now() - startTime,
|
|
78
|
+
tokens_used: data.usage
|
|
79
|
+
? { input: data.usage.prompt_tokens, output: data.usage.completion_tokens }
|
|
80
|
+
: undefined,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return {
|
|
86
|
+
output: '',
|
|
87
|
+
status: 'failure',
|
|
88
|
+
error: `OpenAI executor error: ${error instanceof Error ? error.message : String(error)}`,
|
|
89
|
+
metadata: { provider: this.provider, model, duration_ms: Date.now() - startTime },
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async validate(config) {
|
|
94
|
+
const apiKeyEnv = config.api_key_env || DEFAULT_API_KEY_ENV;
|
|
95
|
+
const apiKey = process.env[apiKeyEnv];
|
|
96
|
+
if (!apiKey) {
|
|
97
|
+
return {
|
|
98
|
+
valid: false,
|
|
99
|
+
error: `Environment variable '${apiKeyEnv}' is not set. Set it with your OpenAI API key.`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return { valid: true };
|
|
103
|
+
}
|
|
104
|
+
buildContextPrefix(context) {
|
|
105
|
+
const parts = [];
|
|
106
|
+
if (context.issue) {
|
|
107
|
+
parts.push(`Issue #${context.issue.number}: ${context.issue.title}`);
|
|
108
|
+
if (context.issue.body) {
|
|
109
|
+
parts.push(`Issue description: ${context.issue.body.slice(0, 2000)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (context.phase) {
|
|
113
|
+
parts.push(`Workflow phase: ${context.phase}`);
|
|
114
|
+
}
|
|
115
|
+
if (context.stepName) {
|
|
116
|
+
parts.push(`Step: ${context.stepName}`);
|
|
117
|
+
}
|
|
118
|
+
return parts.length > 0 ? parts.join('\n') : '';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/executors/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fractary/faber - Executor Registry
|
|
3
|
+
*
|
|
4
|
+
* Maps provider names to executor implementations and resolves which executor
|
|
5
|
+
* to use for a given step based on the config cascade:
|
|
6
|
+
* step.executor > phase_executors[phase] > workflow.executor > null (default)
|
|
7
|
+
*
|
|
8
|
+
* When resolution returns null, the caller should use the default behavior
|
|
9
|
+
* (Claude Code direct execution in skill mode, or Claude API in CLI mode).
|
|
10
|
+
*/
|
|
11
|
+
import type { Executor, ExecutorFactory, StepExecutorConfig } from './types.js';
|
|
12
|
+
export declare class ExecutorRegistry {
|
|
13
|
+
private executors;
|
|
14
|
+
private instances;
|
|
15
|
+
/**
|
|
16
|
+
* Register an executor factory for a provider.
|
|
17
|
+
* Factories are called lazily on first use.
|
|
18
|
+
*/
|
|
19
|
+
register(provider: string, factory: ExecutorFactory): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get an executor for a provider. Creates the instance lazily.
|
|
22
|
+
* @throws Error if provider is not registered
|
|
23
|
+
*/
|
|
24
|
+
get(provider: string): Executor;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a provider is registered.
|
|
27
|
+
*/
|
|
28
|
+
has(provider: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* List all registered provider names.
|
|
31
|
+
*/
|
|
32
|
+
listProviders(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the executor for a step, applying the config cascade.
|
|
35
|
+
*
|
|
36
|
+
* Returns the executor and merged config, or null if no executor is configured
|
|
37
|
+
* (meaning the step should use the default execution path).
|
|
38
|
+
*
|
|
39
|
+
* Cascade order (most specific wins):
|
|
40
|
+
* 1. step.executor — explicit on the step
|
|
41
|
+
* 2. phaseExecutors[phase] — workflow-level per-phase override
|
|
42
|
+
* 3. workflowExecutor — workflow-level default
|
|
43
|
+
*
|
|
44
|
+
* @param step - The workflow step to resolve
|
|
45
|
+
* @param phase - Current phase name
|
|
46
|
+
* @param workflowExecutor - Workflow-level default executor config
|
|
47
|
+
* @param phaseExecutors - Per-phase executor overrides
|
|
48
|
+
* @returns Resolved executor and config, or null if no executor applies
|
|
49
|
+
*/
|
|
50
|
+
resolveForStep(step: {
|
|
51
|
+
executor?: StepExecutorConfig;
|
|
52
|
+
}, phase: string, workflowExecutor?: StepExecutorConfig, phaseExecutors?: Partial<Record<string, StepExecutorConfig>>): {
|
|
53
|
+
executor: Executor;
|
|
54
|
+
config: StepExecutorConfig;
|
|
55
|
+
} | null;
|
|
56
|
+
/**
|
|
57
|
+
* Validate all executor configs in a resolved workflow.
|
|
58
|
+
* Returns errors for any invalid configurations (missing API keys, etc.).
|
|
59
|
+
* Useful for fast-fail at plan time before execution starts.
|
|
60
|
+
*/
|
|
61
|
+
validateWorkflow(steps: Array<{
|
|
62
|
+
executor?: StepExecutorConfig;
|
|
63
|
+
}>, workflowExecutor?: StepExecutorConfig, phaseExecutors?: Partial<Record<string, StepExecutorConfig>>): Promise<Array<{
|
|
64
|
+
stepIndex: number;
|
|
65
|
+
error: string;
|
|
66
|
+
}>>;
|
|
67
|
+
/**
|
|
68
|
+
* Create a registry with all built-in providers registered.
|
|
69
|
+
*/
|
|
70
|
+
static createDefault(): ExecutorRegistry;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/executors/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAUpB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,SAAS,CAA+B;IAEhD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAM1D;;;OAGG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ;IAiB/B;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;;;;;;;;;;;;;;;OAgBG;IACH,cAAc,CACZ,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE,EACvC,KAAK,EAAE,MAAM,EACb,gBAAgB,CAAC,EAAE,kBAAkB,EACrC,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,GAC3D;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,kBAAkB,CAAA;KAAE,GAAG,IAAI;IAc5D;;;;OAIG;IACG,gBAAgB,CACpB,KAAK,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,EAAE,kBAAkB,CAAA;KAAE,CAAC,EAC/C,gBAAgB,CAAC,EAAE,kBAAkB,EACrC,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,GAC3D,OAAO,CAAC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAkDvD;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,gBAAgB;CAUzC"}
|