@fractary/faber 2.4.38 → 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.
Files changed (68) hide show
  1. package/dist/cli/commands/logs.d.ts.map +1 -1
  2. package/dist/cli/commands/logs.js.map +1 -1
  3. package/dist/cli/commands/repo.d.ts.map +1 -1
  4. package/dist/cli/commands/repo.js.map +1 -1
  5. package/dist/cli/commands/spec.d.ts.map +1 -1
  6. package/dist/cli/commands/spec.js.map +1 -1
  7. package/dist/cli/commands/work.d.ts.map +1 -1
  8. package/dist/cli/commands/work.js.map +1 -1
  9. package/dist/cli/commands/workflow.d.ts.map +1 -1
  10. package/dist/cli/commands/workflow.js.map +1 -1
  11. package/dist/cli/index.js +5 -5
  12. package/dist/executors/cli-entry.d.ts +25 -0
  13. package/dist/executors/cli-entry.d.ts.map +1 -0
  14. package/dist/executors/cli-entry.js +86 -0
  15. package/dist/executors/cli-entry.js.map +1 -0
  16. package/dist/executors/index.d.ts +19 -0
  17. package/dist/executors/index.d.ts.map +1 -0
  18. package/dist/executors/index.js +22 -0
  19. package/dist/executors/index.js.map +1 -0
  20. package/dist/executors/providers/claude.d.ts +20 -0
  21. package/dist/executors/providers/claude.d.ts.map +1 -0
  22. package/dist/executors/providers/claude.js +123 -0
  23. package/dist/executors/providers/claude.js.map +1 -0
  24. package/dist/executors/providers/http.d.ts +21 -0
  25. package/dist/executors/providers/http.d.ts.map +1 -0
  26. package/dist/executors/providers/http.js +118 -0
  27. package/dist/executors/providers/http.js.map +1 -0
  28. package/dist/executors/providers/index.d.ts +10 -0
  29. package/dist/executors/providers/index.d.ts.map +1 -0
  30. package/dist/executors/providers/index.js +10 -0
  31. package/dist/executors/providers/index.js.map +1 -0
  32. package/dist/executors/providers/openai-compatible.d.ts +21 -0
  33. package/dist/executors/providers/openai-compatible.d.ts.map +1 -0
  34. package/dist/executors/providers/openai-compatible.js +136 -0
  35. package/dist/executors/providers/openai-compatible.js.map +1 -0
  36. package/dist/executors/providers/openai.d.ts +20 -0
  37. package/dist/executors/providers/openai.d.ts.map +1 -0
  38. package/dist/executors/providers/openai.js +121 -0
  39. package/dist/executors/providers/openai.js.map +1 -0
  40. package/dist/executors/registry.d.ts +72 -0
  41. package/dist/executors/registry.d.ts.map +1 -0
  42. package/dist/executors/registry.js +146 -0
  43. package/dist/executors/registry.js.map +1 -0
  44. package/dist/executors/types.d.ts +148 -0
  45. package/dist/executors/types.d.ts.map +1 -0
  46. package/dist/executors/types.js +9 -0
  47. package/dist/executors/types.js.map +1 -0
  48. package/dist/executors/workflow-executor.d.ts +92 -0
  49. package/dist/executors/workflow-executor.d.ts.map +1 -0
  50. package/dist/executors/workflow-executor.js +176 -0
  51. package/dist/executors/workflow-executor.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +3 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/workflow/__tests__/resolver.test.js +20 -20
  57. package/dist/workflow/resolver.d.ts +71 -2
  58. package/dist/workflow/resolver.d.ts.map +1 -1
  59. package/dist/workflow/resolver.js +140 -12
  60. package/dist/workflow/resolver.js.map +1 -1
  61. package/dist/workflows/__tests__/registry.test.d.ts +7 -0
  62. package/dist/workflows/__tests__/registry.test.d.ts.map +1 -0
  63. package/dist/workflows/__tests__/registry.test.js +99 -0
  64. package/dist/workflows/__tests__/registry.test.js.map +1 -0
  65. package/dist/workflows/registry.d.ts.map +1 -1
  66. package/dist/workflows/registry.js +80 -5
  67. package/dist/workflows/registry.js.map +1 -1
  68. 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":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,OAAO,YAAY;IACd,QAAQ,GAAG,MAAM,CAAC;IAE3B,KAAK,CAAC,OAAO,CACX,MAAc,EACd,OAAyB,EACzB,MAA0B;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,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,wCAAwC;gBAC/C,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;aAC3E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEhF,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,kEAAkE;YAClE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC1B,MAAM;gBACN,OAAO,EAAE;oBACP,OAAO,EAAE,OAAO,CAAC,MAAM;oBACvB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,OAAO,EAAE,OAAO,CAAC,MAAM;oBACvB,SAAS,EAAE,OAAO,CAAC,QAAQ;iBAC5B;gBACD,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;gBACpC,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI;aACL,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,eAAe,QAAQ,CAAC,MAAM,UAAU,OAAO,KAAK,SAAS,EAAE;oBACtE,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;iBAC3E,CAAC;YACJ,CAAC;YAED,0CAA0C;YAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,MAAc,CAAC;YAEnB,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;gBAC9D,+BAA+B;gBAC/B,MAAM;oBACJ,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;wBACjC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO;4BACxE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAW,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACjC,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE;oBACR,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBACpC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,SAAS;gBACjB,KAAK,EAAE,wBAAwB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACvF,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;aAC3E,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,0CAA0C;aAClD,CAAC;QACJ,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,gBAAgB,MAAM,CAAC,QAAQ,EAAE;aACzC,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;CACF"}
@@ -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":"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"}
@@ -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"}