@contentful/experience-design-system-generation 2.34.5-dev-build-3e657f24.0 → 2.34.5-dev-build-b70b5f29.0
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/package.json +1 -1
- package/dist/src/generate/adapters/local/local-agent-invoker.d.ts +7 -0
- package/dist/src/{agent-invoker.js → generate/adapters/local/local-agent-invoker.js} +2 -2
- package/dist/src/generate/adapters/local/local-agent-process.d.ts +6 -0
- package/dist/src/generate/adapters/local/local-agent-process.js +75 -0
- package/dist/src/generate/controller/generate-endpoint.d.ts +27 -0
- package/dist/src/generate/controller/generate-endpoint.js +52 -0
- package/dist/src/generate/model/endpoint.d.ts +30 -0
- package/dist/src/generate/model/endpoint.js +1 -0
- package/dist/src/generate/model/errors.d.ts +8 -0
- package/dist/src/generate/model/errors.js +11 -0
- package/dist/src/generate/model/invocation.d.ts +18 -0
- package/dist/src/generate/model/invocation.js +1 -0
- package/dist/src/generate/model/progress.d.ts +5 -0
- package/dist/src/generate/model/progress.js +1 -0
- package/dist/src/{prompt-builder.d.ts → generate/model/prompt.d.ts} +9 -22
- package/dist/src/generate/model/prompt.js +1 -0
- package/dist/src/generate/model/protocol.d.ts +91 -0
- package/dist/src/generate/model/protocol.js +1 -0
- package/dist/src/generate/services/agent-auth-service.d.ts +3 -0
- package/dist/src/generate/services/agent-auth-service.js +51 -0
- package/dist/src/generate/services/agent-configuration-service.d.ts +12 -0
- package/dist/src/generate/services/agent-configuration-service.js +98 -0
- package/dist/src/generate/services/failure-diagnostics-service.d.ts +2 -0
- package/dist/src/generate/services/failure-diagnostics-service.js +5 -0
- package/dist/src/generate/services/ports/agent-invoker.d.ts +9 -0
- package/dist/src/generate/services/ports/agent-invoker.js +1 -0
- package/dist/src/generate/services/preambles/components.d.ts +1 -0
- package/dist/src/generate/services/preambles/components.js +45 -0
- package/dist/src/generate/services/preambles/index.d.ts +4 -0
- package/dist/src/generate/services/preambles/index.js +4 -0
- package/dist/src/generate/services/preambles/map-tokens.d.ts +1 -0
- package/dist/src/generate/services/preambles/map-tokens.js +25 -0
- package/dist/src/generate/services/preambles/select.d.ts +1 -0
- package/dist/src/generate/services/preambles/select.js +26 -0
- package/dist/src/generate/services/preambles/tokens.d.ts +1 -0
- package/dist/src/generate/services/preambles/tokens.js +29 -0
- package/dist/src/generate/services/progress-service.d.ts +2 -0
- package/dist/src/generate/services/progress-service.js +4 -0
- package/dist/src/generate/services/prompt-context-service.d.ts +3 -0
- package/dist/src/generate/services/prompt-context-service.js +148 -0
- package/dist/src/generate/services/prompt-service.d.ts +9 -0
- package/dist/src/generate/services/prompt-service.js +33 -0
- package/dist/src/generate/services/protocol-parser-service.d.ts +7 -0
- package/dist/src/generate/services/protocol-parser-service.js +278 -0
- package/dist/src/generate/services/skill-loader.d.ts +3 -0
- package/dist/src/generate/services/skill-loader.js +45 -0
- package/dist/src/index.d.ts +22 -9
- package/dist/src/index.js +13 -5
- package/package.json +2 -2
- package/dist/src/agent-invoker.d.ts +0 -25
- package/dist/src/agent-runner.d.ts +0 -144
- package/dist/src/agent-runner.js +0 -564
- package/dist/src/progress.d.ts +0 -9
- package/dist/src/progress.js +0 -11
- package/dist/src/prompt-builder.js +0 -344
- /package/dist/src/{agent-names.d.ts → generate/model/agent.d.ts} +0 -0
- /package/dist/src/{agent-names.js → generate/model/agent.js} +0 -0
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-generation",
|
|
3
|
-
"version": "2.34.5-dev-build-
|
|
3
|
+
"version": "2.34.5-dev-build-b70b5f29.0",
|
|
4
4
|
"description": "Agent-invocation and skill-prompt engine for the Contentful Experience Design System SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentDebugEvent } from '../../model/invocation.js';
|
|
2
|
+
import type { AgentInvoker } from '../../services/ports/agent-invoker.js';
|
|
3
|
+
export interface CreateLocalCliAgentInvokerOptions {
|
|
4
|
+
/** Wire in a debug-event sink (e.g. the CLI's own debug logger). No-op by default. */
|
|
5
|
+
onDebugEvent?: AgentDebugEvent;
|
|
6
|
+
}
|
|
7
|
+
export declare function createLocalCliAgentInvoker(options?: CreateLocalCliAgentInvokerOptions): AgentInvoker;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { checkAgentAuth
|
|
2
|
-
|
|
1
|
+
import { checkAgentAuth } from '../../services/agent-auth-service.js';
|
|
2
|
+
import { runAgent } from './local-agent-process.js';
|
|
3
3
|
export function createLocalCliAgentInvoker(options = {}) {
|
|
4
4
|
const { onDebugEvent } = options;
|
|
5
5
|
return {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentInvocationOptions, AgentDebugEvent, AgentRunResult } from '../../model/invocation.js';
|
|
2
|
+
export interface LocalAgentRunOptions extends AgentInvocationOptions {
|
|
3
|
+
prompt: string;
|
|
4
|
+
onDebugEvent?: AgentDebugEvent;
|
|
5
|
+
}
|
|
6
|
+
export declare function runAgent(options: LocalAgentRunOptions): Promise<AgentRunResult>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { buildArgs, resolveAgentEnvironment, resolveBinary } from '../../services/agent-configuration-service.js';
|
|
3
|
+
export async function runAgent(options) {
|
|
4
|
+
const { agent, prompt, timeoutMs, model, onOutput, promptViaStdin, onDebugEvent } = options;
|
|
5
|
+
const bedrock = options.bedrock ?? process.env.EDS_BEDROCK === '1';
|
|
6
|
+
const binary = resolveBinary(agent);
|
|
7
|
+
const useStdin = !!promptViaStdin;
|
|
8
|
+
const args = buildArgs(agent, prompt, model, useStdin, bedrock);
|
|
9
|
+
const startedAt = Date.now();
|
|
10
|
+
onDebugEvent?.('run.start', {
|
|
11
|
+
agent,
|
|
12
|
+
binary,
|
|
13
|
+
model,
|
|
14
|
+
bedrock: !!bedrock,
|
|
15
|
+
timeoutMs,
|
|
16
|
+
promptLen: prompt.length,
|
|
17
|
+
promptHead: prompt.slice(0, 500),
|
|
18
|
+
});
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const bedrockEnv = resolveAgentEnvironment(agent, bedrock);
|
|
21
|
+
const child = spawn(binary, args, {
|
|
22
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
23
|
+
...(bedrockEnv ? { env: { ...process.env, ...bedrockEnv } } : {}),
|
|
24
|
+
});
|
|
25
|
+
if (useStdin && child.stdin) {
|
|
26
|
+
child.stdin.on('error', () => { });
|
|
27
|
+
child.stdin.write(prompt, () => {
|
|
28
|
+
child.stdin?.end();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
child.stdin?.end();
|
|
33
|
+
}
|
|
34
|
+
let stdout = '';
|
|
35
|
+
let stderr = '';
|
|
36
|
+
let timedOut = false;
|
|
37
|
+
let spawnError;
|
|
38
|
+
const timer = setTimeout(() => {
|
|
39
|
+
timedOut = true;
|
|
40
|
+
child.kill('SIGTERM');
|
|
41
|
+
}, timeoutMs);
|
|
42
|
+
child.stdout?.on('data', (chunk) => {
|
|
43
|
+
const text = chunk.toString();
|
|
44
|
+
stdout += text;
|
|
45
|
+
onOutput?.(text);
|
|
46
|
+
});
|
|
47
|
+
child.stderr?.on('data', (chunk) => {
|
|
48
|
+
stderr += chunk.toString();
|
|
49
|
+
});
|
|
50
|
+
child.on('error', (error) => {
|
|
51
|
+
spawnError = error;
|
|
52
|
+
});
|
|
53
|
+
child.on('close', (code, signal) => {
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
const result = {
|
|
56
|
+
exitCode: spawnError || signal ? 1 : (code ?? 1),
|
|
57
|
+
stdout,
|
|
58
|
+
stderr: spawnError ? `${stderr}${spawnError.message}` : stderr,
|
|
59
|
+
timedOut,
|
|
60
|
+
};
|
|
61
|
+
onDebugEvent?.('run.end', {
|
|
62
|
+
agent,
|
|
63
|
+
model,
|
|
64
|
+
durationMs: Date.now() - startedAt,
|
|
65
|
+
exitCode: result.exitCode,
|
|
66
|
+
signal,
|
|
67
|
+
timedOut,
|
|
68
|
+
stdoutLen: stdout.length,
|
|
69
|
+
stderrLen: stderr.length,
|
|
70
|
+
stderrTail: stderr.slice(-1000),
|
|
71
|
+
});
|
|
72
|
+
resolve(result);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GenerateEndpointRequest, GenerateEndpointResponse, GeneratePreviewRequest, GeneratePreviewResponse } from '../model/endpoint.js';
|
|
2
|
+
import type { AgentRunResult } from '../model/invocation.js';
|
|
3
|
+
import type { PromptOptions, Skill } from '../model/prompt.js';
|
|
4
|
+
import type { ParsedMapTokenPropToolCalls, ParsedSelectToolCalls, ParsedTokenToolCalls, ParsedToolCalls } from '../model/protocol.js';
|
|
5
|
+
import type { AgentInvoker } from '../services/ports/agent-invoker.js';
|
|
6
|
+
export interface GeneratePromptService {
|
|
7
|
+
buildPrompt(options: PromptOptions): Promise<string>;
|
|
8
|
+
}
|
|
9
|
+
export interface GenerateProtocolParser {
|
|
10
|
+
parseComponents(stdout: string): ParsedToolCalls;
|
|
11
|
+
parseTokens(stdout: string): ParsedTokenToolCalls;
|
|
12
|
+
parseSelect(stdout: string): ParsedSelectToolCalls;
|
|
13
|
+
parseMapTokens(stdout: string): ParsedMapTokenPropToolCalls;
|
|
14
|
+
}
|
|
15
|
+
export interface GenerateEndpointDependencies {
|
|
16
|
+
invoker: AgentInvoker;
|
|
17
|
+
promptService?: GeneratePromptService;
|
|
18
|
+
protocolParser?: GenerateProtocolParser;
|
|
19
|
+
describeFailure?: (run: AgentRunResult) => string;
|
|
20
|
+
}
|
|
21
|
+
export interface GenerateEndpoint {
|
|
22
|
+
/** Builds the prompt, invokes the agent once, and parses the stage's protocol from its output. */
|
|
23
|
+
execute<Stage extends Skill>(request: GenerateEndpointRequest<Stage>): Promise<GenerateEndpointResponse<Stage>>;
|
|
24
|
+
/** Builds the prompt only, without invoking an agent. */
|
|
25
|
+
preview<Stage extends Skill>(request: GeneratePreviewRequest<Stage>): Promise<GeneratePreviewResponse<Stage>>;
|
|
26
|
+
}
|
|
27
|
+
export declare function createGenerateEndpoint(dependencies: GenerateEndpointDependencies): GenerateEndpoint;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { GenerateRequestError } from '../model/errors.js';
|
|
2
|
+
import { describeAgentFailure } from '../services/failure-diagnostics-service.js';
|
|
3
|
+
import { buildPrompt } from '../services/prompt-service.js';
|
|
4
|
+
import { parseMapTokenPropToolCallLines, parseSelectToolCallLines, parseTokenToolCallLines, parseToolCallLines, } from '../services/protocol-parser-service.js';
|
|
5
|
+
const defaultPromptService = { buildPrompt };
|
|
6
|
+
const defaultProtocolParser = {
|
|
7
|
+
parseComponents: parseToolCallLines,
|
|
8
|
+
parseTokens: parseTokenToolCallLines,
|
|
9
|
+
parseSelect: parseSelectToolCallLines,
|
|
10
|
+
parseMapTokens: parseMapTokenPropToolCallLines,
|
|
11
|
+
};
|
|
12
|
+
const STAGES_WITH_OPTIONAL_CALLS = new Set(['map-tokens']);
|
|
13
|
+
export function createGenerateEndpoint(dependencies) {
|
|
14
|
+
const promptService = dependencies.promptService ?? defaultPromptService;
|
|
15
|
+
const protocolParser = dependencies.protocolParser ?? defaultProtocolParser;
|
|
16
|
+
const getFailure = dependencies.describeFailure ?? describeAgentFailure;
|
|
17
|
+
const stageParsers = {
|
|
18
|
+
components: protocolParser.parseComponents,
|
|
19
|
+
tokens: protocolParser.parseTokens,
|
|
20
|
+
select: protocolParser.parseSelect,
|
|
21
|
+
'map-tokens': protocolParser.parseMapTokens,
|
|
22
|
+
};
|
|
23
|
+
function requireStage(request) {
|
|
24
|
+
const stage = request.prompt.skill;
|
|
25
|
+
if (!Object.hasOwn(stageParsers, stage))
|
|
26
|
+
throw new GenerateRequestError('unknown-stage', stage);
|
|
27
|
+
return stage;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
async execute(request) {
|
|
31
|
+
const stage = requireStage(request);
|
|
32
|
+
const prompt = await promptService.buildPrompt(request.prompt);
|
|
33
|
+
const run = await dependencies.invoker.invoke({ ...request.invocation, prompt });
|
|
34
|
+
const { calls, warnings } = stageParsers[stage](run.stdout);
|
|
35
|
+
const failure = getRunFailure(run, stage, calls.length, getFailure);
|
|
36
|
+
return { stage, prompt, run, calls, warnings, ...(failure ? { failure } : {}) };
|
|
37
|
+
},
|
|
38
|
+
async preview(request) {
|
|
39
|
+
const stage = requireStage(request);
|
|
40
|
+
return { stage, prompt: await promptService.buildPrompt(request.prompt) };
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function getRunFailure(run, stage, callCount, describeFailure) {
|
|
45
|
+
if (run.timedOut)
|
|
46
|
+
return 'agent timed out';
|
|
47
|
+
if (run.exitCode !== 0)
|
|
48
|
+
return describeFailure(run);
|
|
49
|
+
if (callCount === 0 && !STAGES_WITH_OPTIONAL_CALLS.has(stage))
|
|
50
|
+
return describeFailure(run);
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AgentInvocationOptions, AgentRunResult } from './invocation.js';
|
|
2
|
+
import type { MapTokenPropCall, SelectToolCall, TokenToolCall, ToolCall } from './protocol.js';
|
|
3
|
+
import type { PromptOptions, Skill } from './prompt.js';
|
|
4
|
+
/** The tool calls each generation stage's agent is allowed to emit. */
|
|
5
|
+
export interface StageToolCalls {
|
|
6
|
+
components: ToolCall;
|
|
7
|
+
tokens: TokenToolCall;
|
|
8
|
+
select: SelectToolCall;
|
|
9
|
+
'map-tokens': MapTokenPropCall;
|
|
10
|
+
}
|
|
11
|
+
/** A request for one generation attempt. The stage is the prompt's skill, so the two cannot disagree. */
|
|
12
|
+
export interface GenerateEndpointRequest<Stage extends Skill = Skill> {
|
|
13
|
+
prompt: PromptOptions & {
|
|
14
|
+
skill: Stage;
|
|
15
|
+
};
|
|
16
|
+
invocation: AgentInvocationOptions;
|
|
17
|
+
}
|
|
18
|
+
export type GeneratePreviewRequest<Stage extends Skill = Skill> = Pick<GenerateEndpointRequest<Stage>, 'prompt'>;
|
|
19
|
+
export interface GenerateEndpointResponse<Stage extends Skill = Skill> {
|
|
20
|
+
stage: Stage;
|
|
21
|
+
prompt: string;
|
|
22
|
+
run: AgentRunResult;
|
|
23
|
+
calls: Array<StageToolCalls[Stage]>;
|
|
24
|
+
warnings: string[];
|
|
25
|
+
failure?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface GeneratePreviewResponse<Stage extends Skill = Skill> {
|
|
28
|
+
stage: Stage;
|
|
29
|
+
prompt: string;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Skill } from './prompt.js';
|
|
2
|
+
export type GenerateRequestErrorReason = 'unknown-stage';
|
|
3
|
+
/** A generation request the endpoint rejects before building a prompt or invoking an agent. */
|
|
4
|
+
export declare class GenerateRequestError extends Error {
|
|
5
|
+
readonly reason: GenerateRequestErrorReason;
|
|
6
|
+
readonly stage: Skill | string;
|
|
7
|
+
constructor(reason: GenerateRequestErrorReason, stage: Skill | string);
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** A generation request the endpoint rejects before building a prompt or invoking an agent. */
|
|
2
|
+
export class GenerateRequestError extends Error {
|
|
3
|
+
reason;
|
|
4
|
+
stage;
|
|
5
|
+
constructor(reason, stage) {
|
|
6
|
+
super(`unsupported generation stage '${String(stage)}'`);
|
|
7
|
+
this.name = 'GenerateRequestError';
|
|
8
|
+
this.reason = reason;
|
|
9
|
+
this.stage = stage;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentName } from './agent.js';
|
|
2
|
+
export interface AgentRunResult {
|
|
3
|
+
exitCode: number;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
timedOut: boolean;
|
|
7
|
+
}
|
|
8
|
+
export type AgentDebugEvent = (name: string, payload?: Record<string, unknown>) => void;
|
|
9
|
+
export type AgentAuthStatus = 'ok' | 'unauthenticated' | 'not-found';
|
|
10
|
+
/** Transport-neutral options for one agent invocation attempt. */
|
|
11
|
+
export interface AgentInvocationOptions {
|
|
12
|
+
agent: AgentName;
|
|
13
|
+
model?: string;
|
|
14
|
+
bedrock?: boolean;
|
|
15
|
+
timeoutMs: number;
|
|
16
|
+
onOutput?: (chunk: string) => void;
|
|
17
|
+
promptViaStdin?: boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CDFComponentEntry } from '@contentful/experience-design-system-types';
|
|
2
2
|
/** `components` — classify component props; `tokens` — classify design tokens; `select` — decide whether a component belongs in Contentful Experience Orchestration; `map-tokens` — suggest `$token.allowed` restrictions for design-category token props */
|
|
3
3
|
export type Skill = 'components' | 'tokens' | 'select' | 'map-tokens';
|
|
4
4
|
export type Mode = 'autonomous';
|
|
@@ -8,8 +8,8 @@ export type Mode = 'autonomous';
|
|
|
8
8
|
* MAX_COMPONENT_SOURCE_CHARS) — this pipeline is agent-fs-free by design (see
|
|
9
9
|
* generate-components.md's "you do not write any files"), so the caller must
|
|
10
10
|
* read the file itself and inline the text here rather than handing the
|
|
11
|
-
* agent a path and expecting it to open
|
|
12
|
-
*
|
|
11
|
+
* agent a path and expecting it to open it. `null` when the file
|
|
12
|
+
* could not be read (moved/deleted since extraction) — callers fall back to
|
|
13
13
|
* inferring from the prop name and $token.kind alone in that case.
|
|
14
14
|
* `siblingFiles` carries the content of files the source file relatively
|
|
15
15
|
* imports (e.g. a co-located `.styles.ts`) — token-resolution logic often
|
|
@@ -36,12 +36,6 @@ export interface ComponentSourceRef {
|
|
|
36
36
|
}
|
|
37
37
|
/** Plain-data shape of the CDF generated so far — component name -> component entry. */
|
|
38
38
|
export type GeneratedCdf = Record<string, CDFComponentEntry>;
|
|
39
|
-
/**
|
|
40
|
-
* Render the warning banner shown when a custom skill prompt is active.
|
|
41
|
-
* Always cites the bundled invariants that the override bypasses so the
|
|
42
|
-
* operator cannot miss it.
|
|
43
|
-
*/
|
|
44
|
-
export declare function formatCustomPromptBanner(skill: 'components' | 'select', path: string): string;
|
|
45
39
|
export interface PromptOptions {
|
|
46
40
|
skill: Skill;
|
|
47
41
|
mode: Mode;
|
|
@@ -51,31 +45,24 @@ export interface PromptOptions {
|
|
|
51
45
|
rawTokensFilename?: string;
|
|
52
46
|
tokensInline?: string;
|
|
53
47
|
tokenMapInline?: string;
|
|
48
|
+
/** Retained for source compatibility; prompt services do not read or write this path. */
|
|
54
49
|
outDir: string;
|
|
55
50
|
/** For components skill only: the single component's name (used in error messages). */
|
|
56
51
|
componentName?: string;
|
|
57
|
-
/**
|
|
52
|
+
/** Generated CDF so far — used by map-tokens to show the agent what is already classified. */
|
|
58
53
|
generatedCdf?: GeneratedCdf;
|
|
59
|
-
/**
|
|
54
|
+
/** DTCG token tree — used by map-tokens to give the agent a candidate path index. */
|
|
60
55
|
tokenTree?: Record<string, unknown>;
|
|
61
56
|
/** Component source file references — consumption evidence for the components skill, explicit-restriction evidence (comments, allowlists) for map-tokens. */
|
|
62
57
|
componentSourceRefs?: ComponentSourceRef[];
|
|
63
|
-
/**
|
|
64
|
-
* Feature 8: custom prompt path override. When set, this absolute or relative
|
|
65
|
-
* `.md` path is read in place of the bundled skill file. The bundled-prompt
|
|
66
|
-
* invariants (utility-wrapper rejection, description content rules, etc.) do
|
|
67
|
-
* NOT apply under an override — callers are responsible for showing the
|
|
68
|
-
* appropriate warning banner.
|
|
69
|
-
*/
|
|
58
|
+
/** Feature 8: custom prompt path override. */
|
|
70
59
|
skillPathOverride?: string;
|
|
71
60
|
/** Inline prompt instructions, taking precedence over the bundled skill or path override. */
|
|
72
61
|
skillContentOverride?: string;
|
|
73
|
-
/** JSON-serialized summary of existing space Components.
|
|
62
|
+
/** JSON-serialized summary of existing space Components. */
|
|
74
63
|
existingComponentsInline?: string;
|
|
75
|
-
/** JSON-serialized summary of existing space DesignTokens.
|
|
64
|
+
/** JSON-serialized summary of existing space DesignTokens. */
|
|
76
65
|
existingTokensInline?: string;
|
|
77
66
|
/** JSON-serialized hard allowlist for generated slot allowed-components references. */
|
|
78
67
|
componentAllowlistInline?: string;
|
|
79
68
|
}
|
|
80
|
-
export declare function buildPrompt(options: PromptOptions): Promise<string>;
|
|
81
|
-
export declare function resolveSkillPath(skill: Skill): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export interface ClassifyPropCall {
|
|
2
|
+
tool: 'classify_prop';
|
|
3
|
+
prop: string;
|
|
4
|
+
cdf_type: string;
|
|
5
|
+
cdf_category: 'content' | 'design' | 'state';
|
|
6
|
+
values?: string[];
|
|
7
|
+
token_kind?: string;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
description?: string;
|
|
10
|
+
default?: string | boolean;
|
|
11
|
+
/** Internal LLM rationale; not customer-facing. Persisted to raw_props.rationale. */
|
|
12
|
+
reason?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ExcludePropCall {
|
|
15
|
+
tool: 'exclude_prop';
|
|
16
|
+
prop: string;
|
|
17
|
+
reason: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ClassifyComponentCall {
|
|
20
|
+
tool: 'classify_component';
|
|
21
|
+
description?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Component-level rationale strings. Surfaced by the `I` ComponentRationalePanel.
|
|
24
|
+
* Each field is optional; missing fields leave existing DB values untouched
|
|
25
|
+
* (sparse update semantics in applyToolCalls).
|
|
26
|
+
*/
|
|
27
|
+
rationale?: {
|
|
28
|
+
description?: string;
|
|
29
|
+
props?: string;
|
|
30
|
+
slots?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface ClassifySlotCall {
|
|
34
|
+
tool: 'classify_slot';
|
|
35
|
+
slot: string;
|
|
36
|
+
required?: boolean;
|
|
37
|
+
allowed_components?: string[];
|
|
38
|
+
description?: string;
|
|
39
|
+
/** Per-slot rationale; persisted to raw_slots.rationale. */
|
|
40
|
+
rationale?: string;
|
|
41
|
+
}
|
|
42
|
+
export type ToolCall = ClassifyPropCall | ExcludePropCall | ClassifyComponentCall | ClassifySlotCall;
|
|
43
|
+
export interface SelectComponentCall {
|
|
44
|
+
tool: 'select_component';
|
|
45
|
+
name: string;
|
|
46
|
+
reason?: string;
|
|
47
|
+
confidence?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface RejectComponentCall {
|
|
50
|
+
tool: 'reject_component';
|
|
51
|
+
name: string;
|
|
52
|
+
reason?: string;
|
|
53
|
+
confidence?: number;
|
|
54
|
+
}
|
|
55
|
+
export type SelectToolCall = SelectComponentCall | RejectComponentCall;
|
|
56
|
+
export interface ParsedSelectToolCalls {
|
|
57
|
+
calls: SelectToolCall[];
|
|
58
|
+
warnings: string[];
|
|
59
|
+
}
|
|
60
|
+
export interface SetTokenCall {
|
|
61
|
+
tool: 'set_token';
|
|
62
|
+
path: string;
|
|
63
|
+
type: string;
|
|
64
|
+
value: unknown;
|
|
65
|
+
description?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface SetGroupCall {
|
|
68
|
+
tool: 'set_group';
|
|
69
|
+
path: string;
|
|
70
|
+
description?: string;
|
|
71
|
+
}
|
|
72
|
+
export type TokenToolCall = SetTokenCall | SetGroupCall;
|
|
73
|
+
export interface ParsedTokenToolCalls {
|
|
74
|
+
calls: TokenToolCall[];
|
|
75
|
+
warnings: string[];
|
|
76
|
+
}
|
|
77
|
+
export interface ParsedToolCalls {
|
|
78
|
+
calls: ToolCall[];
|
|
79
|
+
warnings: string[];
|
|
80
|
+
}
|
|
81
|
+
export interface MapTokenPropCall {
|
|
82
|
+
tool: 'map_token_prop';
|
|
83
|
+
component: string;
|
|
84
|
+
prop: string;
|
|
85
|
+
/** Narrowed subset of tokens the prop may draw from. Required and non-empty. */
|
|
86
|
+
token_allowed: string[];
|
|
87
|
+
}
|
|
88
|
+
export interface ParsedMapTokenPropToolCalls {
|
|
89
|
+
calls: MapTokenPropCall[];
|
|
90
|
+
warnings: string[];
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { resolveBinary } from './agent-configuration-service.js';
|
|
3
|
+
export async function checkAgentAuth(agent) {
|
|
4
|
+
const binary = resolveBinary(agent);
|
|
5
|
+
const binaryExists = await new Promise((resolve) => {
|
|
6
|
+
if (binary.startsWith('/')) {
|
|
7
|
+
import('node:fs/promises').then((fs) => fs.access(binary).then(() => resolve(true), () => resolve(false)));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const child = spawn(process.platform === 'win32' ? 'where' : 'which', [binary], { stdio: 'ignore' });
|
|
11
|
+
child.on('close', (code) => resolve(code === 0));
|
|
12
|
+
});
|
|
13
|
+
if (!binaryExists)
|
|
14
|
+
return 'not-found';
|
|
15
|
+
if (agent !== 'claude')
|
|
16
|
+
return 'ok';
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
const child = spawn(binary, ['auth', 'status', '--json'], {
|
|
19
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
20
|
+
});
|
|
21
|
+
let stdout = '';
|
|
22
|
+
let done = false;
|
|
23
|
+
const timer = setTimeout(() => {
|
|
24
|
+
if (!done) {
|
|
25
|
+
done = true;
|
|
26
|
+
child.kill('SIGTERM');
|
|
27
|
+
resolve('unauthenticated');
|
|
28
|
+
}
|
|
29
|
+
}, 5000);
|
|
30
|
+
child.stdout?.on('data', (chunk) => {
|
|
31
|
+
stdout += chunk.toString();
|
|
32
|
+
});
|
|
33
|
+
child.on('close', (code) => {
|
|
34
|
+
if (done)
|
|
35
|
+
return;
|
|
36
|
+
done = true;
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
if (code !== 0) {
|
|
39
|
+
resolve('unauthenticated');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const status = JSON.parse(stdout);
|
|
44
|
+
resolve(status.loggedIn ? 'ok' : 'unauthenticated');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
resolve('unauthenticated');
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentName } from '../model/agent.js';
|
|
2
|
+
export declare function resolveBinary(agent: AgentName): string;
|
|
3
|
+
export declare function resolveAgentEnvironment(agent: AgentName, bedrock: boolean): Record<string, string> | undefined;
|
|
4
|
+
export declare function agentSupportsBedrock(agent: AgentName): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the model for an agent. Explicit flag/creds value wins, then a
|
|
7
|
+
* per-agent `EDS_AGENT_MODEL_<AGENT>` env override, otherwise the lightweight
|
|
8
|
+
* default for that agent. `bedrock` only affects the fallback default for
|
|
9
|
+
* agents whose model id changes shape under Bedrock.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveAgentModel(agent: AgentName, explicit?: string, bedrock?: boolean): string | undefined;
|
|
12
|
+
export declare function buildArgs(agent: AgentName, prompt: string, model?: string, promptViaStdin?: boolean, bedrock?: boolean): string[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const AGENT_BINARIES = {
|
|
2
|
+
claude: 'claude',
|
|
3
|
+
codex: 'codex',
|
|
4
|
+
opencode: 'opencode',
|
|
5
|
+
cursor: 'cursor-agent',
|
|
6
|
+
copilot: 'copilot',
|
|
7
|
+
};
|
|
8
|
+
export function resolveBinary(agent) {
|
|
9
|
+
const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
|
|
10
|
+
const override = process.env[envKey];
|
|
11
|
+
if (override && override.trim())
|
|
12
|
+
return override.trim();
|
|
13
|
+
return AGENT_BINARIES[agent];
|
|
14
|
+
}
|
|
15
|
+
/** Per-agent env vars that switch model calls to AWS Bedrock. */
|
|
16
|
+
const BEDROCK_ENV_BY_AGENT = {
|
|
17
|
+
claude: { CLAUDE_CODE_USE_BEDROCK: '1' },
|
|
18
|
+
};
|
|
19
|
+
export function resolveAgentEnvironment(agent, bedrock) {
|
|
20
|
+
return bedrock ? BEDROCK_ENV_BY_AGENT[agent] : undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Agents with a working Bedrock routing mechanism, of any shape (env var,
|
|
24
|
+
* argv config override, or a provider-prefixed model string) — not just the
|
|
25
|
+
* env-var agents in BEDROCK_ENV_BY_AGENT. cursor is excluded: its own Bedrock
|
|
26
|
+
* support is currently broken for non-interactive/CI use.
|
|
27
|
+
*/
|
|
28
|
+
const BEDROCK_CAPABLE_AGENTS = new Set(['claude', 'codex', 'opencode']);
|
|
29
|
+
export function agentSupportsBedrock(agent) {
|
|
30
|
+
return BEDROCK_CAPABLE_AGENTS.has(agent);
|
|
31
|
+
}
|
|
32
|
+
const DEFAULT_CODEX_BEDROCK_REGION = 'us-east-1';
|
|
33
|
+
const DEFAULT_OPENCODE_MODEL = 'claude-haiku-4-5';
|
|
34
|
+
/**
|
|
35
|
+
* Default models per agent — lightweight/fast picks to control cost when no
|
|
36
|
+
* explicit model is configured. cursor uses `gpt-mini` (verified alias from
|
|
37
|
+
* GetUsableModels; haiku is not available in cursor's model catalog).
|
|
38
|
+
*
|
|
39
|
+
* codex is deliberately absent: with no entry here it gets no `--model` at
|
|
40
|
+
* all, so the installed Codex CLI picks whatever its account supports. On
|
|
41
|
+
* Bedrock it still needs an explicit id, since the model id there carries an
|
|
42
|
+
* `openai.` prefix required by the Bedrock provider and absent from the
|
|
43
|
+
* direct api.openai.com id — see DEFAULT_CODEX_BEDROCK_MODEL.
|
|
44
|
+
*/
|
|
45
|
+
const DEFAULT_MODELS = {
|
|
46
|
+
claude: 'haiku',
|
|
47
|
+
opencode: DEFAULT_OPENCODE_MODEL,
|
|
48
|
+
cursor: 'gpt-mini',
|
|
49
|
+
copilot: 'Auto',
|
|
50
|
+
};
|
|
51
|
+
const DEFAULT_CODEX_BEDROCK_MODEL = 'openai.gpt-5.6-luna';
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the model for an agent. Explicit flag/creds value wins, then a
|
|
54
|
+
* per-agent `EDS_AGENT_MODEL_<AGENT>` env override, otherwise the lightweight
|
|
55
|
+
* default for that agent. `bedrock` only affects the fallback default for
|
|
56
|
+
* agents whose model id changes shape under Bedrock.
|
|
57
|
+
*/
|
|
58
|
+
export function resolveAgentModel(agent, explicit, bedrock = false) {
|
|
59
|
+
if (explicit && explicit.trim())
|
|
60
|
+
return explicit.trim();
|
|
61
|
+
const override = process.env[`EDS_AGENT_MODEL_${agent.toUpperCase()}`];
|
|
62
|
+
if (override && override.trim())
|
|
63
|
+
return override.trim();
|
|
64
|
+
if (bedrock && agent === 'codex')
|
|
65
|
+
return DEFAULT_CODEX_BEDROCK_MODEL;
|
|
66
|
+
if (bedrock && agent === 'opencode')
|
|
67
|
+
return withBedrockProviderPrefix(DEFAULT_OPENCODE_MODEL);
|
|
68
|
+
return DEFAULT_MODELS[agent];
|
|
69
|
+
}
|
|
70
|
+
function withBedrockProviderPrefix(model) {
|
|
71
|
+
return model.includes('/') ? model : `amazon-bedrock/${model}`;
|
|
72
|
+
}
|
|
73
|
+
function codexBedrockConfigArgs() {
|
|
74
|
+
const region = process.env.AWS_REGION?.trim() || process.env.AWS_DEFAULT_REGION?.trim() || DEFAULT_CODEX_BEDROCK_REGION;
|
|
75
|
+
return ['-c', 'model_provider=amazon-bedrock', '-c', `model_providers.amazon-bedrock.region=${region}`];
|
|
76
|
+
}
|
|
77
|
+
export function buildArgs(agent, prompt, model, promptViaStdin = false, bedrock = false) {
|
|
78
|
+
const resolvedModel = resolveAgentModel(agent, model, bedrock);
|
|
79
|
+
const modelArg = resolvedModel ? ['--model', resolvedModel] : [];
|
|
80
|
+
const promptArg = promptViaStdin ? [] : [prompt];
|
|
81
|
+
switch (agent) {
|
|
82
|
+
case 'claude':
|
|
83
|
+
return ['--print', ...modelArg, ...promptArg];
|
|
84
|
+
case 'codex': {
|
|
85
|
+
const bedrockArgs = bedrock ? codexBedrockConfigArgs() : [];
|
|
86
|
+
return ['exec', ...bedrockArgs, ...modelArg, '--dangerously-bypass-approvals-and-sandbox', ...promptArg];
|
|
87
|
+
}
|
|
88
|
+
case 'opencode':
|
|
89
|
+
return ['run', ...modelArg, ...promptArg];
|
|
90
|
+
case 'cursor':
|
|
91
|
+
return ['--print', ...modelArg, ...promptArg];
|
|
92
|
+
case 'copilot': {
|
|
93
|
+
const copilotModel = resolveAgentModel('copilot', model);
|
|
94
|
+
const copilotModelArg = !copilotModel || copilotModel === 'Auto' ? [] : ['--model', copilotModel];
|
|
95
|
+
return ['-p', ...promptArg, ...copilotModelArg, '--allow-all-tools'];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function describeAgentFailure(result, maxDetail = 800) {
|
|
2
|
+
const base = result.exitCode !== 0 ? `agent exited with code ${result.exitCode}` : 'agent produced no tool calls';
|
|
3
|
+
const detail = (result.stderr.trim() || result.stdout.trim()).slice(-maxDetail).trim();
|
|
4
|
+
return detail ? `${base} — ${detail}` : base;
|
|
5
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentName } from '../../model/agent.js';
|
|
2
|
+
import type { AgentAuthStatus, AgentInvocationOptions, AgentRunResult } from '../../model/invocation.js';
|
|
3
|
+
export interface InvokeAgentOptions extends AgentInvocationOptions {
|
|
4
|
+
prompt: string;
|
|
5
|
+
}
|
|
6
|
+
export interface AgentInvoker {
|
|
7
|
+
invoke(options: InvokeAgentOptions): Promise<AgentRunResult>;
|
|
8
|
+
checkAuth(agent: AgentName): Promise<AgentAuthStatus>;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function buildComponentsAutonomousPreamble(inputBlock: string): string;
|