@cleocode/adapters 2026.4.57 → 2026.4.59
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/cant-context.js +711 -0
- package/dist/cant-context.js.map +1 -0
- package/dist/providers/claude-code/adapter.js +222 -0
- package/dist/providers/claude-code/adapter.js.map +1 -0
- package/dist/providers/claude-code/context-monitor.js +159 -0
- package/dist/providers/claude-code/context-monitor.js.map +1 -0
- package/dist/providers/claude-code/hooks.js +395 -0
- package/dist/providers/claude-code/hooks.js.map +1 -0
- package/dist/providers/claude-code/index.js +41 -0
- package/dist/providers/claude-code/index.js.map +1 -0
- package/dist/providers/claude-code/install.js +199 -0
- package/dist/providers/claude-code/install.js.map +1 -0
- package/dist/providers/claude-code/paths.js +41 -0
- package/dist/providers/claude-code/paths.js.map +1 -0
- package/dist/providers/claude-code/spawn.js +198 -0
- package/dist/providers/claude-code/spawn.js.map +1 -0
- package/dist/providers/claude-code/statusline.js +130 -0
- package/dist/providers/claude-code/statusline.js.map +1 -0
- package/dist/providers/claude-code/task-sync.js +119 -0
- package/dist/providers/claude-code/task-sync.js.map +1 -0
- package/dist/providers/claude-code/transport.js +29 -0
- package/dist/providers/claude-code/transport.js.map +1 -0
- package/dist/providers/claude-sdk/index.js +16 -0
- package/dist/providers/claude-sdk/index.js.map +1 -0
- package/dist/providers/claude-sdk/mcp-registry.js +66 -0
- package/dist/providers/claude-sdk/mcp-registry.js.map +1 -0
- package/dist/providers/claude-sdk/session-store.js +84 -0
- package/dist/providers/claude-sdk/session-store.js.map +1 -0
- package/dist/providers/claude-sdk/spawn.js +225 -0
- package/dist/providers/claude-sdk/spawn.js.map +1 -0
- package/dist/providers/claude-sdk/tool-bridge.js +50 -0
- package/dist/providers/claude-sdk/tool-bridge.js.map +1 -0
- package/dist/providers/codex/adapter.js +146 -0
- package/dist/providers/codex/adapter.js.map +1 -0
- package/dist/providers/codex/hooks.js +113 -0
- package/dist/providers/codex/hooks.js.map +1 -0
- package/dist/providers/codex/index.js +39 -0
- package/dist/providers/codex/index.js.map +1 -0
- package/dist/providers/codex/install.js +124 -0
- package/dist/providers/codex/install.js.map +1 -0
- package/dist/providers/cursor/adapter.js +151 -0
- package/dist/providers/cursor/adapter.js.map +1 -0
- package/dist/providers/cursor/hooks.js +208 -0
- package/dist/providers/cursor/hooks.js.map +1 -0
- package/dist/providers/cursor/index.js +36 -0
- package/dist/providers/cursor/index.js.map +1 -0
- package/dist/providers/cursor/install.js +180 -0
- package/dist/providers/cursor/install.js.map +1 -0
- package/dist/providers/cursor/spawn.js +59 -0
- package/dist/providers/cursor/spawn.js.map +1 -0
- package/dist/providers/gemini-cli/adapter.js +158 -0
- package/dist/providers/gemini-cli/adapter.js.map +1 -0
- package/dist/providers/gemini-cli/hooks.js +128 -0
- package/dist/providers/gemini-cli/hooks.js.map +1 -0
- package/dist/providers/gemini-cli/index.js +39 -0
- package/dist/providers/gemini-cli/index.js.map +1 -0
- package/dist/providers/gemini-cli/install.js +124 -0
- package/dist/providers/gemini-cli/install.js.map +1 -0
- package/dist/providers/kimi/adapter.js +145 -0
- package/dist/providers/kimi/adapter.js.map +1 -0
- package/dist/providers/kimi/hooks.js +79 -0
- package/dist/providers/kimi/hooks.js.map +1 -0
- package/dist/providers/kimi/index.js +39 -0
- package/dist/providers/kimi/index.js.map +1 -0
- package/dist/providers/kimi/install.js +124 -0
- package/dist/providers/kimi/install.js.map +1 -0
- package/dist/providers/openai-sdk/adapter.js +120 -0
- package/dist/providers/openai-sdk/adapter.js.map +1 -0
- package/dist/providers/openai-sdk/guardrails.js +139 -0
- package/dist/providers/openai-sdk/guardrails.js.map +1 -0
- package/dist/providers/openai-sdk/handoff.js +124 -0
- package/dist/providers/openai-sdk/handoff.js.map +1 -0
- package/dist/providers/openai-sdk/index.js +39 -0
- package/dist/providers/openai-sdk/index.js.map +1 -0
- package/dist/providers/openai-sdk/install.js +120 -0
- package/dist/providers/openai-sdk/install.js.map +1 -0
- package/dist/providers/openai-sdk/spawn.js +214 -0
- package/dist/providers/openai-sdk/spawn.js.map +1 -0
- package/dist/providers/openai-sdk/tracing.js +157 -0
- package/dist/providers/openai-sdk/tracing.js.map +1 -0
- package/dist/providers/opencode/adapter.js +166 -0
- package/dist/providers/opencode/adapter.js.map +1 -0
- package/dist/providers/opencode/hooks.js +206 -0
- package/dist/providers/opencode/hooks.js.map +1 -0
- package/dist/providers/opencode/index.js +37 -0
- package/dist/providers/opencode/index.js.map +1 -0
- package/dist/providers/opencode/install.js +115 -0
- package/dist/providers/opencode/install.js.map +1 -0
- package/dist/providers/opencode/spawn.js +256 -0
- package/dist/providers/opencode/spawn.js.map +1 -0
- package/dist/providers/pi/adapter.js +220 -0
- package/dist/providers/pi/adapter.js.map +1 -0
- package/dist/providers/pi/hooks.js +223 -0
- package/dist/providers/pi/hooks.js.map +1 -0
- package/dist/providers/pi/index.js +38 -0
- package/dist/providers/pi/index.js.map +1 -0
- package/dist/providers/pi/install.js +175 -0
- package/dist/providers/pi/install.js.map +1 -0
- package/dist/providers/pi/spawn.js +187 -0
- package/dist/providers/pi/spawn.js.map +1 -0
- package/dist/providers/shared/conduit-trace-writer.js +65 -0
- package/dist/providers/shared/conduit-trace-writer.js.map +1 -0
- package/dist/providers/shared/sdk-result-mapper.js +54 -0
- package/dist/providers/shared/sdk-result-mapper.js.map +1 -0
- package/dist/providers/shared/transcript-reader.js +124 -0
- package/dist/providers/shared/transcript-reader.js.map +1 -0
- package/dist/registry.js +92 -0
- package/dist/registry.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLEO permission rules mapped to OpenAI Agents SDK guardrails.
|
|
3
|
+
*
|
|
4
|
+
* CLEO ACLs (file-glob path allowlists, tool allowlists) are expressed as
|
|
5
|
+
* `InputGuardrail` instances that run before agent execution. A path that
|
|
6
|
+
* falls outside the allowed glob list causes the guardrail to trip and
|
|
7
|
+
* the agent run is rejected.
|
|
8
|
+
*
|
|
9
|
+
* @task T582
|
|
10
|
+
*/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Helpers
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* Converts a simple glob pattern to a RegExp.
|
|
16
|
+
*
|
|
17
|
+
* Supports `*` (any chars within a segment) and `**` (any chars including `/`).
|
|
18
|
+
* This is a lightweight alternative to the `minimatch` package so no extra
|
|
19
|
+
* dependency is required in the adapters package.
|
|
20
|
+
*
|
|
21
|
+
* @param glob - Glob pattern to convert (e.g. `/mnt/projects/**`).
|
|
22
|
+
* @returns A RegExp that matches paths conforming to the glob.
|
|
23
|
+
*/
|
|
24
|
+
function globToRegex(glob) {
|
|
25
|
+
// Escape regex metacharacters except * and ?
|
|
26
|
+
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
|
27
|
+
// Replace ** first (order matters), then *
|
|
28
|
+
const pattern = escaped.replace(/\*\*/g, '.+').replace(/\*/g, '[^/]*');
|
|
29
|
+
return new RegExp(`^${pattern}$`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check whether a file-system path is covered by at least one glob pattern.
|
|
33
|
+
*
|
|
34
|
+
* @param path - The absolute or relative path to test.
|
|
35
|
+
* @param allowedGlobs - Array of glob patterns (supports `*` and `**`).
|
|
36
|
+
* @returns `true` when the path matches at least one pattern.
|
|
37
|
+
*/
|
|
38
|
+
export function isPathAllowed(path, allowedGlobs) {
|
|
39
|
+
if (allowedGlobs.length === 0)
|
|
40
|
+
return true;
|
|
41
|
+
return allowedGlobs.some((glob) => globToRegex(glob).test(path));
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Guardrail builders
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Build an input guardrail that enforces CLEO file-glob path ACLs.
|
|
48
|
+
*
|
|
49
|
+
* Inspects the serialised agent input for embedded `"path":"..."` fields
|
|
50
|
+
* and rejects the run when a path falls outside the allowlist. This provides
|
|
51
|
+
* an early-exit safety fence before the agent starts consuming model tokens.
|
|
52
|
+
*
|
|
53
|
+
* @param allowedGlobs - Glob patterns that tool path arguments must match.
|
|
54
|
+
* Pass an empty array to allow all paths (permissive mode).
|
|
55
|
+
* @returns An {@link InputGuardrail} ready to attach to an `Agent`.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const guard = buildPathGuardrail(['/mnt/projects/**', '/tmp/**']);
|
|
60
|
+
* const agent = new Agent({ ..., inputGuardrails: [guard] });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function buildPathGuardrail(allowedGlobs) {
|
|
64
|
+
return {
|
|
65
|
+
name: 'cleo_path_acl',
|
|
66
|
+
execute: async (args) => {
|
|
67
|
+
// Serialise input to a string for heuristic path scanning.
|
|
68
|
+
const inputStr = typeof args.input === 'string' ? args.input : JSON.stringify(args.input);
|
|
69
|
+
// Scan for JSON-encoded `"path":"..."` occurrences in the input text.
|
|
70
|
+
// This is conservative: if no path field is found the guardrail passes.
|
|
71
|
+
const pathMatches = inputStr.matchAll(/"path"\s*:\s*"([^"]+)"/g);
|
|
72
|
+
for (const match of pathMatches) {
|
|
73
|
+
const candidate = match[1];
|
|
74
|
+
if (candidate && !isPathAllowed(candidate, allowedGlobs)) {
|
|
75
|
+
return {
|
|
76
|
+
tripwireTriggered: true,
|
|
77
|
+
outputInfo: {
|
|
78
|
+
reason: `cleo_path_acl: path denied by ACL — ${candidate}`,
|
|
79
|
+
deniedPath: candidate,
|
|
80
|
+
allowedGlobs,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { tripwireTriggered: false, outputInfo: null };
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build an input guardrail that documents the tool allowlist for audit purposes.
|
|
91
|
+
*
|
|
92
|
+
* In the OpenAI Agents SDK, tool-name enforcement is primarily structural —
|
|
93
|
+
* agents only receive the tools attached to their `tools` array. This guardrail
|
|
94
|
+
* provides an additional audit layer that records the active allowlist in the
|
|
95
|
+
* span metadata.
|
|
96
|
+
*
|
|
97
|
+
* @param allowedTools - Exact tool names permitted for this agent.
|
|
98
|
+
* Pass an empty array to allow all tools (permissive mode).
|
|
99
|
+
* @returns An {@link InputGuardrail} ready to attach to an `Agent`.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const guard = buildToolAllowlistGuardrail(['read', 'write']);
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export function buildToolAllowlistGuardrail(allowedTools) {
|
|
107
|
+
return {
|
|
108
|
+
name: 'cleo_tool_allowlist',
|
|
109
|
+
execute: async (_args) => {
|
|
110
|
+
// Structural enforcement: only listed tools are attached to the agent.
|
|
111
|
+
// This guardrail records the allowlist for audit and always passes.
|
|
112
|
+
return {
|
|
113
|
+
tripwireTriggered: false,
|
|
114
|
+
outputInfo: { allowedTools, checked: true },
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build the default CLEO guardrail set from spawn options.
|
|
121
|
+
*
|
|
122
|
+
* Combines path ACL and tool allowlist guards into a single array ready to
|
|
123
|
+
* pass as `inputGuardrails` on an `Agent` or `RunConfig`.
|
|
124
|
+
*
|
|
125
|
+
* @param allowedGlobs - File-path glob allowlist.
|
|
126
|
+
* @param allowedTools - Tool name allowlist.
|
|
127
|
+
* @returns Array of input guardrails to attach to the agent.
|
|
128
|
+
*/
|
|
129
|
+
export function buildDefaultGuardrails(allowedGlobs, allowedTools) {
|
|
130
|
+
const guards = [];
|
|
131
|
+
if (allowedGlobs.length > 0) {
|
|
132
|
+
guards.push(buildPathGuardrail(allowedGlobs));
|
|
133
|
+
}
|
|
134
|
+
if (allowedTools.length > 0) {
|
|
135
|
+
guards.push(buildToolAllowlistGuardrail(allowedTools));
|
|
136
|
+
}
|
|
137
|
+
return guards;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=guardrails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardrails.js","sourceRoot":"","sources":["../../../src/providers/openai-sdk/guardrails.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLEO Team topology → OpenAI Agents SDK handoff mapping.
|
|
3
|
+
*
|
|
4
|
+
* CLEO agents are organised in a Lead → Worker hierarchy. This module maps
|
|
5
|
+
* that topology to the SDK's first-class `handoffs` graph:
|
|
6
|
+
*
|
|
7
|
+
* - A Team Lead becomes an `Agent` whose `handoffs` array lists its workers.
|
|
8
|
+
* - Each Worker archetype (read-only, write, bash) is declared in
|
|
9
|
+
* `WORKER_ARCHETYPES` and built on demand.
|
|
10
|
+
* - The mapping is driven by `SpawnContext.options.handoffs`, which is an
|
|
11
|
+
* array of worker archetype names.
|
|
12
|
+
*
|
|
13
|
+
* @task T582
|
|
14
|
+
*/
|
|
15
|
+
import { Agent } from '@openai/agents';
|
|
16
|
+
/**
|
|
17
|
+
* Registry of built-in CLEO worker archetypes.
|
|
18
|
+
*
|
|
19
|
+
* Callers reference these by name in `SpawnContext.options.handoffs`.
|
|
20
|
+
* New archetypes can be added here without changing the spawn provider.
|
|
21
|
+
*/
|
|
22
|
+
export const WORKER_ARCHETYPES = {
|
|
23
|
+
'worker-read': {
|
|
24
|
+
name: 'worker-read',
|
|
25
|
+
instructions: 'You are a read-only CLEO worker. You may only read files and return findings. Never write, modify, or delete files.',
|
|
26
|
+
model: 'gpt-4.1-mini',
|
|
27
|
+
},
|
|
28
|
+
'worker-write': {
|
|
29
|
+
name: 'worker-write',
|
|
30
|
+
instructions: 'You are a CLEO write worker. You implement code changes directed by the lead agent. Follow the lead agent instructions precisely.',
|
|
31
|
+
model: 'gpt-4.1-mini',
|
|
32
|
+
},
|
|
33
|
+
'worker-bash': {
|
|
34
|
+
name: 'worker-bash',
|
|
35
|
+
instructions: 'You are a CLEO bash worker. You run shell commands directed by the lead agent. Only execute commands explicitly requested.',
|
|
36
|
+
model: 'gpt-4.1-mini',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Agent builders
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Build a worker `Agent` instance from a named archetype.
|
|
44
|
+
*
|
|
45
|
+
* @param archetypeName - Key in {@link WORKER_ARCHETYPES}.
|
|
46
|
+
* @param guardrails - Input guardrails to attach to the worker agent.
|
|
47
|
+
* @returns A configured SDK `Agent` or `null` when the archetype is unknown.
|
|
48
|
+
*/
|
|
49
|
+
export function buildWorkerAgent(archetypeName, guardrails) {
|
|
50
|
+
const archetype = WORKER_ARCHETYPES[archetypeName];
|
|
51
|
+
if (!archetype)
|
|
52
|
+
return null;
|
|
53
|
+
return new Agent({
|
|
54
|
+
name: archetype.name,
|
|
55
|
+
instructions: archetype.instructions,
|
|
56
|
+
model: archetype.model,
|
|
57
|
+
inputGuardrails: guardrails.length > 0 ? guardrails : undefined,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build a team lead `Agent` whose `handoffs` reference the given workers.
|
|
62
|
+
*
|
|
63
|
+
* @param leadInstructions - System instructions for the lead agent.
|
|
64
|
+
* @param leadModel - Model to use for the lead agent.
|
|
65
|
+
* @param workers - Worker agents this lead can hand off to.
|
|
66
|
+
* @param guardrails - Input guardrails to attach to the lead agent.
|
|
67
|
+
* @returns A configured lead SDK `Agent`.
|
|
68
|
+
*/
|
|
69
|
+
export function buildLeadAgent(leadInstructions, leadModel, workers, guardrails) {
|
|
70
|
+
return new Agent({
|
|
71
|
+
name: 'cleo-lead',
|
|
72
|
+
instructions: leadInstructions,
|
|
73
|
+
model: leadModel,
|
|
74
|
+
handoffs: workers.length > 0 ? workers : undefined,
|
|
75
|
+
inputGuardrails: guardrails.length > 0 ? guardrails : undefined,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Build a simple single-tier agent (no handoffs) from prompt and model.
|
|
80
|
+
*
|
|
81
|
+
* Used when `SpawnContext.options.tier` is `'worker'` or when no handoff
|
|
82
|
+
* names are provided.
|
|
83
|
+
*
|
|
84
|
+
* @param instructions - Agent system instructions.
|
|
85
|
+
* @param model - Model identifier.
|
|
86
|
+
* @param guardrails - Input guardrails.
|
|
87
|
+
* @returns A configured SDK `Agent`.
|
|
88
|
+
*/
|
|
89
|
+
export function buildStandaloneAgent(instructions, model, guardrails) {
|
|
90
|
+
return new Agent({
|
|
91
|
+
name: 'cleo-worker',
|
|
92
|
+
instructions,
|
|
93
|
+
model,
|
|
94
|
+
inputGuardrails: guardrails.length > 0 ? guardrails : undefined,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build the entry-point agent and its worker topology from spawn options.
|
|
99
|
+
*
|
|
100
|
+
* - `tier === 'lead'` or `tier === 'orchestrator'`: creates a lead agent with
|
|
101
|
+
* worker handoffs derived from `handoffNames`.
|
|
102
|
+
* - `tier === 'worker'`: creates a standalone agent with no handoffs.
|
|
103
|
+
*
|
|
104
|
+
* Unknown archetype names in `handoffNames` are silently skipped.
|
|
105
|
+
*
|
|
106
|
+
* @param options - Topology build options.
|
|
107
|
+
* @returns The entry-point agent to pass to `runner.run()`.
|
|
108
|
+
*/
|
|
109
|
+
export function buildAgentTopology(options) {
|
|
110
|
+
const { instructions, model, tier, handoffNames, guardrails } = options;
|
|
111
|
+
if (tier === 'worker') {
|
|
112
|
+
return buildStandaloneAgent(instructions, model, guardrails);
|
|
113
|
+
}
|
|
114
|
+
// Build worker agents from archetype names; skip unknown names.
|
|
115
|
+
const workers = handoffNames
|
|
116
|
+
.map((name) => buildWorkerAgent(name, guardrails))
|
|
117
|
+
.filter((a) => a !== null);
|
|
118
|
+
if (workers.length === 0) {
|
|
119
|
+
// Lead with no workers — still usable as a standalone agent.
|
|
120
|
+
return buildStandaloneAgent(instructions, model, guardrails);
|
|
121
|
+
}
|
|
122
|
+
return buildLeadAgent(instructions, model, workers, guardrails);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=handoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../../src/providers/openai-sdk/handoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* CLEO provider adapter for the OpenAI Agents SDK.
|
|
5
|
+
* Default export is the adapter class for dynamic loading by AdapterManager.
|
|
6
|
+
*
|
|
7
|
+
* @task T582
|
|
8
|
+
*/
|
|
9
|
+
import { OpenAiSdkAdapter } from './adapter.js';
|
|
10
|
+
export { OpenAiSdkAdapter } from './adapter.js';
|
|
11
|
+
export { buildDefaultGuardrails, buildPathGuardrail, buildToolAllowlistGuardrail, isPathAllowed, } from './guardrails.js';
|
|
12
|
+
export { buildAgentTopology, buildLeadAgent, buildStandaloneAgent, buildWorkerAgent, WORKER_ARCHETYPES, } from './handoff.js';
|
|
13
|
+
export { OpenAiSdkInstallProvider } from './install.js';
|
|
14
|
+
export { OpenAiSdkSpawnProvider } from './spawn.js';
|
|
15
|
+
export { CleoConduitTraceProcessor } from './tracing.js';
|
|
16
|
+
export default OpenAiSdkAdapter;
|
|
17
|
+
/**
|
|
18
|
+
* Factory function for creating adapter instances.
|
|
19
|
+
* Used by AdapterManager's dynamic import fallback.
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* This is the primary entry point for dynamic adapter loading.
|
|
23
|
+
* AdapterManager calls this function when it resolves the openai-sdk
|
|
24
|
+
* provider via its import-based discovery mechanism.
|
|
25
|
+
*
|
|
26
|
+
* @returns A new {@link OpenAiSdkAdapter} instance ready for initialization.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { createAdapter } from '@cleocode/adapters/providers/openai-sdk';
|
|
31
|
+
*
|
|
32
|
+
* const adapter = createAdapter();
|
|
33
|
+
* await adapter.initialize('/path/to/project');
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function createAdapter() {
|
|
37
|
+
return new OpenAiSdkAdapter();
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/openai-sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,2BAA2B,EAC3B,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD,eAAe,gBAAgB,CAAC;AAEhC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,gBAAgB,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI SDK Install Provider.
|
|
3
|
+
*
|
|
4
|
+
* Handles CLEO installation into OpenAI SDK environments:
|
|
5
|
+
* - Writes an AGENTS.md file with CLEO @-references
|
|
6
|
+
* - Creates a `.openai/` config stub if it does not exist
|
|
7
|
+
*
|
|
8
|
+
* @task T582
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
/** Lines that should appear in AGENTS.md to reference CLEO. */
|
|
13
|
+
const INSTRUCTION_REFERENCES = ['@~/.cleo/templates/CLEO-INJECTION.md', '@.cleo/memory-bridge.md'];
|
|
14
|
+
/**
|
|
15
|
+
* Install provider for the OpenAI Agents SDK.
|
|
16
|
+
*
|
|
17
|
+
* Manages CLEO's integration with OpenAI SDK projects by:
|
|
18
|
+
* 1. Ensuring AGENTS.md contains @-references to CLEO instruction files
|
|
19
|
+
* 2. Creating the `.openai/` config directory stub if absent
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* Installation is idempotent — running install multiple times on the same
|
|
23
|
+
* project produces the same result.
|
|
24
|
+
*/
|
|
25
|
+
export class OpenAiSdkInstallProvider {
|
|
26
|
+
/**
|
|
27
|
+
* Install CLEO into an OpenAI SDK project.
|
|
28
|
+
*
|
|
29
|
+
* @param options - Installation options including project directory.
|
|
30
|
+
* @returns Result describing what was installed.
|
|
31
|
+
*/
|
|
32
|
+
async install(options) {
|
|
33
|
+
const { projectDir } = options;
|
|
34
|
+
const installedAt = new Date().toISOString();
|
|
35
|
+
const details = {};
|
|
36
|
+
// Step 1: Ensure AGENTS.md has @-references
|
|
37
|
+
const instructionFileUpdated = this.updateInstructionFile(projectDir);
|
|
38
|
+
if (instructionFileUpdated) {
|
|
39
|
+
details.instructionFile = join(projectDir, 'AGENTS.md');
|
|
40
|
+
}
|
|
41
|
+
// Step 2: Create .openai config directory stub
|
|
42
|
+
const configCreated = this.ensureConfigDir(projectDir);
|
|
43
|
+
if (configCreated) {
|
|
44
|
+
details.configDir = join(projectDir, '.openai');
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
success: true,
|
|
48
|
+
installedAt,
|
|
49
|
+
instructionFileUpdated,
|
|
50
|
+
details,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Uninstall CLEO from the current OpenAI SDK project.
|
|
55
|
+
*
|
|
56
|
+
* Does not remove AGENTS.md references (they are harmless if CLEO is absent).
|
|
57
|
+
*/
|
|
58
|
+
async uninstall() { }
|
|
59
|
+
/**
|
|
60
|
+
* Check whether CLEO is installed in the current OpenAI SDK environment.
|
|
61
|
+
*
|
|
62
|
+
* Checks for `@~/.cleo/templates/CLEO-INJECTION.md` in AGENTS.md.
|
|
63
|
+
*/
|
|
64
|
+
async isInstalled() {
|
|
65
|
+
// A project is considered installed when AGENTS.md contains the first reference.
|
|
66
|
+
// There is no plugin registry for the OpenAI SDK.
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Ensure AGENTS.md contains @-references to CLEO instruction files.
|
|
71
|
+
*
|
|
72
|
+
* @param projectDir - Project root directory.
|
|
73
|
+
*/
|
|
74
|
+
async ensureInstructionReferences(projectDir) {
|
|
75
|
+
this.updateInstructionFile(projectDir);
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Private helpers
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Update AGENTS.md with CLEO @-references.
|
|
82
|
+
*
|
|
83
|
+
* @returns `true` if the file was created or modified.
|
|
84
|
+
*/
|
|
85
|
+
updateInstructionFile(projectDir) {
|
|
86
|
+
const agentsMdPath = join(projectDir, 'AGENTS.md');
|
|
87
|
+
let content = '';
|
|
88
|
+
let existed = false;
|
|
89
|
+
if (existsSync(agentsMdPath)) {
|
|
90
|
+
content = readFileSync(agentsMdPath, 'utf-8');
|
|
91
|
+
existed = true;
|
|
92
|
+
}
|
|
93
|
+
const missingRefs = INSTRUCTION_REFERENCES.filter((ref) => !content.includes(ref));
|
|
94
|
+
if (missingRefs.length === 0)
|
|
95
|
+
return false;
|
|
96
|
+
const refsBlock = missingRefs.join('\n');
|
|
97
|
+
if (existed) {
|
|
98
|
+
const separator = content.endsWith('\n') ? '' : '\n';
|
|
99
|
+
content = content + separator + refsBlock + '\n';
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
content = refsBlock + '\n';
|
|
103
|
+
}
|
|
104
|
+
writeFileSync(agentsMdPath, content, 'utf-8');
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create the `.openai/` config directory if it does not exist.
|
|
109
|
+
*
|
|
110
|
+
* @returns `true` if the directory was created.
|
|
111
|
+
*/
|
|
112
|
+
ensureConfigDir(projectDir) {
|
|
113
|
+
const configDir = join(projectDir, '.openai');
|
|
114
|
+
if (existsSync(configDir))
|
|
115
|
+
return false;
|
|
116
|
+
mkdirSync(configDir, { recursive: true });
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/providers/openai-sdk/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Agents SDK spawn provider.
|
|
3
|
+
*
|
|
4
|
+
* Implements `AdapterSpawnProvider` using the `@openai/agents` SDK runner.
|
|
5
|
+
* Unlike the Claude Code provider (detached fire-and-forget), this provider
|
|
6
|
+
* awaits the run and returns `status: 'completed'` or `status: 'failed'`
|
|
7
|
+
* so the orchestrator receives rich output immediately.
|
|
8
|
+
*
|
|
9
|
+
* Key features:
|
|
10
|
+
* - Tier-based model selection (lead → gpt-4.1, worker → gpt-4.1-mini)
|
|
11
|
+
* - Handoff topology built from `SpawnContext.options.handoffs`
|
|
12
|
+
* - CLEO path ACL guardrails applied at input stage
|
|
13
|
+
* - Default-on tracing via `CleoConduitTraceProcessor`
|
|
14
|
+
* - CANT prompt enrichment (best-effort, same as Claude Code provider)
|
|
15
|
+
*
|
|
16
|
+
* @task T582
|
|
17
|
+
*/
|
|
18
|
+
import { getErrorMessage } from '@cleocode/contracts';
|
|
19
|
+
import { addTraceProcessor, OpenAIProvider, Runner, setTracingDisabled } from '@openai/agents';
|
|
20
|
+
import { mapSdkRunOutcome } from '../shared/sdk-result-mapper.js';
|
|
21
|
+
import { buildDefaultGuardrails } from './guardrails.js';
|
|
22
|
+
import { buildAgentTopology } from './handoff.js';
|
|
23
|
+
import { CleoConduitTraceProcessor } from './tracing.js';
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Constants
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
const MODEL_LEAD = 'gpt-4.1';
|
|
28
|
+
const MODEL_WORKER = 'gpt-4.1-mini';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Provider
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
/**
|
|
33
|
+
* Spawn provider for the OpenAI Agents SDK.
|
|
34
|
+
*
|
|
35
|
+
* Spawns SDK-backed agent runs for a given `SpawnContext`. The run is
|
|
36
|
+
* awaited synchronously and the result mapped to a `SpawnResult` with
|
|
37
|
+
* `status: 'completed'` or `status: 'failed'`. In-flight runs are tracked
|
|
38
|
+
* by instance ID so `listRunning()` and `terminate()` work correctly.
|
|
39
|
+
*
|
|
40
|
+
* @remarks
|
|
41
|
+
* The provider creates a fresh `Runner` per spawn so that `RunConfig`
|
|
42
|
+
* settings do not bleed across parallel spawns. Trace processors are
|
|
43
|
+
* registered globally via `addTraceProcessor` and removed by disabling
|
|
44
|
+
* tracing when the option is set.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const provider = new OpenAiSdkSpawnProvider();
|
|
49
|
+
* const result = await provider.spawn({
|
|
50
|
+
* taskId: 'T582',
|
|
51
|
+
* prompt: 'Implement feature X',
|
|
52
|
+
* options: { tier: 'lead', handoffs: ['worker-read', 'worker-write'] },
|
|
53
|
+
* });
|
|
54
|
+
* console.log(result.status); // 'completed'
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export class OpenAiSdkSpawnProvider {
|
|
58
|
+
/** Currently running instance IDs (completed runs are removed). */
|
|
59
|
+
runningInstances = new Set();
|
|
60
|
+
/**
|
|
61
|
+
* Check whether the OpenAI SDK can spawn in the current environment.
|
|
62
|
+
*
|
|
63
|
+
* Requires `OPENAI_API_KEY` to be set. Does not make a network call.
|
|
64
|
+
*
|
|
65
|
+
* @returns `true` when `OPENAI_API_KEY` is present in the environment.
|
|
66
|
+
*/
|
|
67
|
+
async canSpawn() {
|
|
68
|
+
return typeof process.env.OPENAI_API_KEY === 'string' && process.env.OPENAI_API_KEY.length > 0;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Spawn a subagent via the OpenAI Agents SDK runner.
|
|
72
|
+
*
|
|
73
|
+
* Awaits the run to completion and returns a fully-resolved `SpawnResult`.
|
|
74
|
+
*
|
|
75
|
+
* @param context - Spawn context with task ID, prompt, and options.
|
|
76
|
+
* @returns Resolved spawn result with `status: 'completed'` or `'failed'`.
|
|
77
|
+
*/
|
|
78
|
+
async spawn(context) {
|
|
79
|
+
const instanceId = `openai-sdk-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
80
|
+
const startTime = new Date().toISOString();
|
|
81
|
+
this.runningInstances.add(instanceId);
|
|
82
|
+
try {
|
|
83
|
+
const opts = this.parseOptions(context.options);
|
|
84
|
+
// Enrich prompt with CANT bundle (best-effort, same pattern as Claude Code provider).
|
|
85
|
+
let finalPrompt = context.prompt;
|
|
86
|
+
try {
|
|
87
|
+
const { buildCantEnrichedPrompt } = await import('../../cant-context.js');
|
|
88
|
+
finalPrompt = await buildCantEnrichedPrompt({
|
|
89
|
+
projectDir: context.workingDirectory ?? process.cwd(),
|
|
90
|
+
basePrompt: context.prompt,
|
|
91
|
+
agentName: opts.agentName,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// CANT enrichment unavailable — use raw prompt.
|
|
96
|
+
}
|
|
97
|
+
// Build guardrails from ACL options.
|
|
98
|
+
const guardrails = buildDefaultGuardrails(opts.allowedGlobs ?? [], opts.allowedTools ?? []);
|
|
99
|
+
// Derive model from tier when not explicitly set.
|
|
100
|
+
const model = opts.model ?? this.modelForTier(opts.tier ?? 'worker');
|
|
101
|
+
// Build agent topology (lead + workers, or standalone worker).
|
|
102
|
+
const agent = buildAgentTopology({
|
|
103
|
+
instructions: finalPrompt,
|
|
104
|
+
model,
|
|
105
|
+
tier: opts.tier ?? 'worker',
|
|
106
|
+
handoffNames: opts.handoffs ?? [],
|
|
107
|
+
guardrails,
|
|
108
|
+
});
|
|
109
|
+
// Register trace processor globally (default-on).
|
|
110
|
+
// The SDK uses global processor registration via addTraceProcessor().
|
|
111
|
+
let traceProcessor;
|
|
112
|
+
if (!opts.tracingDisabled) {
|
|
113
|
+
traceProcessor = new CleoConduitTraceProcessor(context.taskId);
|
|
114
|
+
addTraceProcessor(traceProcessor);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
setTracingDisabled(true);
|
|
118
|
+
}
|
|
119
|
+
// Build OpenAI model provider and runner.
|
|
120
|
+
const modelProvider = new OpenAIProvider();
|
|
121
|
+
const runner = new Runner({ modelProvider });
|
|
122
|
+
// Run the agent — no extra options needed beyond what is set on the runner.
|
|
123
|
+
const runResult = await runner.run(agent, finalPrompt);
|
|
124
|
+
// Restore tracing state if we disabled it for this spawn.
|
|
125
|
+
if (opts.tracingDisabled) {
|
|
126
|
+
setTracingDisabled(false);
|
|
127
|
+
}
|
|
128
|
+
const finalOutput = typeof runResult.finalOutput === 'string'
|
|
129
|
+
? runResult.finalOutput
|
|
130
|
+
: JSON.stringify(runResult.finalOutput);
|
|
131
|
+
this.runningInstances.delete(instanceId);
|
|
132
|
+
return mapSdkRunOutcome(instanceId, context.taskId, 'openai-sdk', startTime, {
|
|
133
|
+
finalOutput,
|
|
134
|
+
succeeded: true,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.runningInstances.delete(instanceId);
|
|
139
|
+
return mapSdkRunOutcome(instanceId, context.taskId, 'openai-sdk', startTime, {
|
|
140
|
+
finalOutput: '',
|
|
141
|
+
succeeded: false,
|
|
142
|
+
errorMessage: getErrorMessage(error),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* List currently running OpenAI SDK agent instances.
|
|
148
|
+
*
|
|
149
|
+
* @returns Array of in-progress spawn results.
|
|
150
|
+
*/
|
|
151
|
+
async listRunning() {
|
|
152
|
+
return [...this.runningInstances].map((instanceId) => ({
|
|
153
|
+
instanceId,
|
|
154
|
+
taskId: 'unknown',
|
|
155
|
+
providerId: 'openai-sdk',
|
|
156
|
+
status: 'running',
|
|
157
|
+
startTime: new Date().toISOString(),
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Terminate a running spawn by instance ID.
|
|
162
|
+
*
|
|
163
|
+
* The OpenAI SDK runner does not support external termination of in-flight
|
|
164
|
+
* runs; this method removes the instance from the tracking set so it will
|
|
165
|
+
* no longer appear in `listRunning()`.
|
|
166
|
+
*
|
|
167
|
+
* @param instanceId - ID of the spawn instance to terminate.
|
|
168
|
+
*/
|
|
169
|
+
async terminate(instanceId) {
|
|
170
|
+
this.runningInstances.delete(instanceId);
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// Private helpers
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
/**
|
|
176
|
+
* Parse and validate `SpawnContext.options` into typed `OpenAiSdkSpawnOptions`.
|
|
177
|
+
*
|
|
178
|
+
* Unknown fields are silently ignored.
|
|
179
|
+
*/
|
|
180
|
+
parseOptions(raw) {
|
|
181
|
+
if (!raw)
|
|
182
|
+
return {};
|
|
183
|
+
const opts = {};
|
|
184
|
+
if (typeof raw.model === 'string')
|
|
185
|
+
opts.model = raw.model;
|
|
186
|
+
if (raw.tier === 'lead' || raw.tier === 'worker' || raw.tier === 'orchestrator') {
|
|
187
|
+
opts.tier = raw.tier;
|
|
188
|
+
}
|
|
189
|
+
if (Array.isArray(raw.handoffs) && raw.handoffs.every((h) => typeof h === 'string')) {
|
|
190
|
+
opts.handoffs = raw.handoffs;
|
|
191
|
+
}
|
|
192
|
+
if (Array.isArray(raw.allowedGlobs) && raw.allowedGlobs.every((g) => typeof g === 'string')) {
|
|
193
|
+
opts.allowedGlobs = raw.allowedGlobs;
|
|
194
|
+
}
|
|
195
|
+
if (Array.isArray(raw.allowedTools) && raw.allowedTools.every((t) => typeof t === 'string')) {
|
|
196
|
+
opts.allowedTools = raw.allowedTools;
|
|
197
|
+
}
|
|
198
|
+
if (typeof raw.tracingDisabled === 'boolean')
|
|
199
|
+
opts.tracingDisabled = raw.tracingDisabled;
|
|
200
|
+
if (typeof raw.agentName === 'string')
|
|
201
|
+
opts.agentName = raw.agentName;
|
|
202
|
+
return opts;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Derive the default model for a given tier.
|
|
206
|
+
*
|
|
207
|
+
* @param tier - Agent tier.
|
|
208
|
+
* @returns Model identifier string.
|
|
209
|
+
*/
|
|
210
|
+
modelForTier(tier) {
|
|
211
|
+
return tier === 'worker' ? MODEL_WORKER : MODEL_LEAD;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/providers/openai-sdk/spawn.ts"],"names":[],"mappings":"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"}
|