@open-agent-toolkit/cli 0.3.1 → 0.3.2
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/assets/agents/oat-reviewer.md +7 -2
- package/assets/bundle-metadata.json +1 -1
- package/assets/config/dispatch-matrix-recommendation.json +63 -43
- package/assets/docs/cli-utilities/configuration.md +20 -8
- package/assets/docs/cli-utilities/workflow-gates.md +1 -1
- package/assets/docs/contributing/index.md +1 -0
- package/assets/docs/contributing/updating-model-guidance.md +106 -0
- package/assets/docs/contributing/verifying-cursor-pins.md +30 -18
- package/assets/docs/provider-sync/providers.md +5 -2
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/reference/oat-directory-structure.md +1 -1
- package/assets/docs/workflows/projects/artifacts.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +67 -50
- package/assets/docs/workflows/projects/evidence-layers.md +6 -2
- package/assets/docs/workflows/projects/implementation-execution.md +9 -4
- package/assets/docs/workflows/projects/lifecycle.md +8 -6
- package/assets/docs/workflows/projects/programmatic-execution.md +4 -3
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-claude.md +20 -7
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +4 -4
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +2 -0
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +82 -25
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-implement/references/phase-execution.md +16 -8
- package/assets/skills/oat-project-import-plan/SKILL.md +7 -4
- package/assets/skills/oat-project-lite/SKILL.md +5 -3
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-plan/SKILL.md +7 -4
- package/assets/skills/oat-project-plan-writing/SKILL.md +28 -16
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-quick-start/SKILL.md +7 -4
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +4 -4
- package/assets/skills/oat-project-review-provide/SKILL.md +7 -4
- package/assets/skills/subagent-orchestration/SKILL.md +1 -1
- package/assets/skills/subagent-orchestration/references/evidence-and-refresh.md +30 -29
- package/assets/skills/subagent-orchestration/references/provider-claude.md +41 -36
- package/assets/skills/subagent-orchestration/references/provider-codex.md +30 -35
- package/assets/skills/subagent-orchestration/references/provider-cursor.md +46 -38
- package/assets/templates/plan.md +5 -5
- package/dist/commands/project/dispatch/record.d.ts.map +1 -1
- package/dist/commands/project/dispatch/record.js +27 -5
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +112 -35
- package/dist/config/dispatch-matrix.d.ts.map +1 -1
- package/dist/config/dispatch-matrix.js +13 -0
- package/dist/providers/ceiling/registry.d.ts +7 -2
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +35 -11
- package/dist/providers/claude/codec/materialize.d.ts +33 -0
- package/dist/providers/claude/codec/materialize.d.ts.map +1 -0
- package/dist/providers/claude/codec/materialize.js +149 -0
- package/dist/providers/claude/codec/sync-extension.d.ts +24 -0
- package/dist/providers/claude/codec/sync-extension.d.ts.map +1 -0
- package/dist/providers/claude/codec/sync-extension.js +312 -0
- package/dist/providers/claude/dispatch-envelope.d.ts +34 -0
- package/dist/providers/claude/dispatch-envelope.d.ts.map +1 -0
- package/dist/providers/claude/dispatch-envelope.js +233 -0
- package/dist/providers/claude/targets.d.ts +48 -0
- package/dist/providers/claude/targets.d.ts.map +1 -0
- package/dist/providers/claude/targets.js +228 -0
- package/dist/providers/codex/codec/shared.d.ts +6 -0
- package/dist/providers/codex/codec/shared.d.ts.map +1 -1
- package/dist/providers/codex/codec/shared.js +8 -0
- package/dist/providers/cursor/codec/catalog.d.ts.map +1 -1
- package/dist/providers/cursor/codec/catalog.js +47 -45
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +35 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -1
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +225 -12
- package/dist/providers/shared/registry.d.ts.map +1 -1
- package/dist/providers/shared/registry.js +5 -2
- package/package.json +2 -2
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { parseGenericDispatchRecord, } from '../identity/generic-dispatch-record.js';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { readOatManagedClaudeRole } from './codec/materialize.js';
|
|
5
|
+
import { buildClaudeEffortVariantName, validateClaudeDispatchCapability, } from './targets.js';
|
|
6
|
+
const generationSchema = z.enum([
|
|
7
|
+
'fable-5-1',
|
|
8
|
+
'fable-5',
|
|
9
|
+
'opus-5-5',
|
|
10
|
+
'sonnet-5',
|
|
11
|
+
'opus-4-7',
|
|
12
|
+
'opus-4-6',
|
|
13
|
+
'sonnet-4-6',
|
|
14
|
+
]);
|
|
15
|
+
const capabilityEvidenceSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
source: z.enum([
|
|
18
|
+
'explicit-model-id',
|
|
19
|
+
'family-pin-model-id',
|
|
20
|
+
'family-pin-declaration',
|
|
21
|
+
'alias-capability-equivalence',
|
|
22
|
+
]),
|
|
23
|
+
modelReference: z.string().min(1),
|
|
24
|
+
exactModel: z.boolean(),
|
|
25
|
+
generation: generationSchema.optional(),
|
|
26
|
+
possibleGenerations: z.array(generationSchema).optional(),
|
|
27
|
+
capabilitiesSource: z.string().min(1),
|
|
28
|
+
supportedEfforts: z.array(z.string().min(1)).min(1),
|
|
29
|
+
})
|
|
30
|
+
.strict();
|
|
31
|
+
const targetSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
model: z.string().min(1),
|
|
34
|
+
effort: z.string().min(1),
|
|
35
|
+
capabilityEvidence: capabilityEvidenceSchema,
|
|
36
|
+
crossHarness: z.literal(false),
|
|
37
|
+
})
|
|
38
|
+
.passthrough();
|
|
39
|
+
const providerResolutionSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
value: z.string().min(1),
|
|
42
|
+
mode: z.literal('enforced'),
|
|
43
|
+
mechanism: z.literal('pinned-variant'),
|
|
44
|
+
dispatchArgs: z.object({ variant: z.string().min(1) }).strict(),
|
|
45
|
+
modelAxis: z.string().min(1),
|
|
46
|
+
effortAxis: z.string().min(1),
|
|
47
|
+
target: targetSchema,
|
|
48
|
+
selection: z
|
|
49
|
+
.object({
|
|
50
|
+
role: z.enum(['implementer', 'reviewer']),
|
|
51
|
+
policyMode: z.literal('managed'),
|
|
52
|
+
policy: z.string().min(1),
|
|
53
|
+
target: targetSchema,
|
|
54
|
+
})
|
|
55
|
+
.passthrough(),
|
|
56
|
+
})
|
|
57
|
+
.passthrough();
|
|
58
|
+
const resolutionSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
status: z.literal('resolved'),
|
|
61
|
+
provider: z.literal('claude'),
|
|
62
|
+
policyMode: z.literal('managed'),
|
|
63
|
+
policy: z.string().min(1),
|
|
64
|
+
providers: z.object({ claude: providerResolutionSchema }).passthrough(),
|
|
65
|
+
})
|
|
66
|
+
.passthrough();
|
|
67
|
+
const launchPayloadSchema = z
|
|
68
|
+
.object({
|
|
69
|
+
variant: z.string().min(1),
|
|
70
|
+
model: z.string().min(1).optional(),
|
|
71
|
+
})
|
|
72
|
+
.strict();
|
|
73
|
+
const PROTECTED_RECORD_FIELDS = [
|
|
74
|
+
'provider',
|
|
75
|
+
'dispatch_policy',
|
|
76
|
+
'dispatch_ceiling',
|
|
77
|
+
'role_name',
|
|
78
|
+
'role_selector',
|
|
79
|
+
'model_selector',
|
|
80
|
+
'model_selector_granularity',
|
|
81
|
+
'effort_selector',
|
|
82
|
+
'selection_source',
|
|
83
|
+
'candidates_considered',
|
|
84
|
+
'selection_reason',
|
|
85
|
+
'selected_route',
|
|
86
|
+
'payload',
|
|
87
|
+
'configured_invocation_evidence',
|
|
88
|
+
];
|
|
89
|
+
function definitionFrontmatter(content) {
|
|
90
|
+
const match = /^---\n([\s\S]*?)\n---(?:\n|$)/u.exec(content);
|
|
91
|
+
if (!match?.[1]) {
|
|
92
|
+
throw new Error('Generated Claude definition has no YAML frontmatter.');
|
|
93
|
+
}
|
|
94
|
+
const parsed = YAML.parse(match[1]);
|
|
95
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
96
|
+
throw new Error('Generated Claude definition frontmatter is not a map.');
|
|
97
|
+
}
|
|
98
|
+
return parsed;
|
|
99
|
+
}
|
|
100
|
+
function assertSameTarget(left, right) {
|
|
101
|
+
if (left.model !== right.model ||
|
|
102
|
+
left.effort !== right.effort ||
|
|
103
|
+
JSON.stringify(left.capabilityEvidence) !==
|
|
104
|
+
JSON.stringify(right.capabilityEvidence)) {
|
|
105
|
+
throw new Error('Claude resolver target and selection target disagree on model, effort, or capability evidence.');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Validate the managed resolver result against the generated provider role and
|
|
110
|
+
* the exact payload that will be launched. This is the production boundary
|
|
111
|
+
* used by the project dispatch-record producer for managed Claude dispatches.
|
|
112
|
+
*/
|
|
113
|
+
export function acceptClaudeLaunchEnvelope(input) {
|
|
114
|
+
const resolution = resolutionSchema.parse(input.resolution);
|
|
115
|
+
const provider = resolution.providers.claude;
|
|
116
|
+
const launch = launchPayloadSchema.parse(input.launch);
|
|
117
|
+
assertSameTarget(provider.target, provider.selection.target);
|
|
118
|
+
const validation = validateClaudeDispatchCapability(provider.selection.target);
|
|
119
|
+
if (!validation.valid) {
|
|
120
|
+
throw new Error(validation.reason ?? 'Resolver selected an invalid Claude target.');
|
|
121
|
+
}
|
|
122
|
+
const baseRole = provider.selection.role === 'reviewer'
|
|
123
|
+
? 'oat-reviewer'
|
|
124
|
+
: 'oat-phase-implementer';
|
|
125
|
+
const expectedVariant = buildClaudeEffortVariantName({
|
|
126
|
+
agentName: baseRole,
|
|
127
|
+
model: provider.selection.target.model,
|
|
128
|
+
effort: provider.selection.target.effort,
|
|
129
|
+
});
|
|
130
|
+
if (provider.dispatchArgs.variant !== expectedVariant) {
|
|
131
|
+
throw new Error(`Managed Claude resolver variant ${provider.dispatchArgs.variant} does not match selected target ${expectedVariant}.`);
|
|
132
|
+
}
|
|
133
|
+
if (launch.variant !== expectedVariant) {
|
|
134
|
+
throw new Error(`Claude launch variant ${launch.variant} does not match resolver-selected variant ${expectedVariant}.`);
|
|
135
|
+
}
|
|
136
|
+
const managed = readOatManagedClaudeRole(input.definition);
|
|
137
|
+
if (!managed || managed.roleName !== expectedVariant) {
|
|
138
|
+
throw new Error(`Generated Claude definition ${expectedVariant} is absent or is not the matching OAT-managed role.`);
|
|
139
|
+
}
|
|
140
|
+
if (JSON.stringify(managed.capabilityEvidence) !==
|
|
141
|
+
JSON.stringify(provider.selection.target.capabilityEvidence)) {
|
|
142
|
+
throw new Error('Generated Claude definition capability evidence does not match the resolver-selected capability.');
|
|
143
|
+
}
|
|
144
|
+
const frontmatter = definitionFrontmatter(input.definition);
|
|
145
|
+
if (frontmatter.name !== expectedVariant) {
|
|
146
|
+
throw new Error(`Generated Claude definition name does not match ${expectedVariant}.`);
|
|
147
|
+
}
|
|
148
|
+
if (frontmatter.model !== provider.selection.target.model) {
|
|
149
|
+
throw new Error(`Generated Claude definition model does not match selected model ${provider.selection.target.model}.`);
|
|
150
|
+
}
|
|
151
|
+
if (frontmatter.effort !== provider.selection.target.effort) {
|
|
152
|
+
throw new Error(`Generated Claude definition effort does not match selected effort ${provider.selection.target.effort}.`);
|
|
153
|
+
}
|
|
154
|
+
if (launch.model !== undefined &&
|
|
155
|
+
launch.model !== provider.selection.target.model) {
|
|
156
|
+
throw new Error(`Per-call Claude model ${launch.model} conflicts with generated definition model ${provider.selection.target.model}.`);
|
|
157
|
+
}
|
|
158
|
+
if (provider.modelAxis !== `selected:${provider.selection.target.model}`) {
|
|
159
|
+
throw new Error('Claude resolver model axis disagrees with its target.');
|
|
160
|
+
}
|
|
161
|
+
if (provider.effortAxis !== `selected:${provider.selection.target.effort}`) {
|
|
162
|
+
throw new Error('Claude resolver effort axis disagrees with its target.');
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
schemaVersion: 1,
|
|
166
|
+
provider: 'claude',
|
|
167
|
+
resolverRole: provider.selection.role,
|
|
168
|
+
baseRole,
|
|
169
|
+
variant: expectedVariant,
|
|
170
|
+
model: provider.selection.target.model,
|
|
171
|
+
capabilityEvidence: provider.selection.target.capabilityEvidence,
|
|
172
|
+
effort: provider.selection.target.effort,
|
|
173
|
+
policy: resolution.policy,
|
|
174
|
+
ceiling: provider.value,
|
|
175
|
+
payload: launch,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function recordBase(value) {
|
|
179
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
180
|
+
throw new Error('Managed Claude dispatch recordBase must be a JSON object.');
|
|
181
|
+
}
|
|
182
|
+
const base = value;
|
|
183
|
+
for (const field of PROTECTED_RECORD_FIELDS) {
|
|
184
|
+
if (Object.hasOwn(base, field)) {
|
|
185
|
+
throw new Error(`Managed Claude dispatch recordBase must omit derived field ${field}.`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return base;
|
|
189
|
+
}
|
|
190
|
+
/** Build configured invocation evidence only from an accepted launch envelope. */
|
|
191
|
+
export function buildClaudeDispatchRecord(input) {
|
|
192
|
+
const base = recordBase(input.recordBase);
|
|
193
|
+
const action = base.action;
|
|
194
|
+
if ((input.envelope.resolverRole === 'reviewer' && action !== 'review') ||
|
|
195
|
+
(input.envelope.resolverRole === 'implementer' &&
|
|
196
|
+
action !== 'implementation' &&
|
|
197
|
+
action !== 'fix')) {
|
|
198
|
+
throw new Error(`Managed Claude resolver role ${input.envelope.resolverRole} conflicts with record action ${String(action)}.`);
|
|
199
|
+
}
|
|
200
|
+
return parseGenericDispatchRecord({
|
|
201
|
+
...base,
|
|
202
|
+
provider: 'claude',
|
|
203
|
+
dispatch_policy: input.envelope.policy,
|
|
204
|
+
dispatch_ceiling: input.envelope.ceiling,
|
|
205
|
+
role_name: input.envelope.baseRole,
|
|
206
|
+
role_selector: input.envelope.variant,
|
|
207
|
+
model_selector: input.envelope.model,
|
|
208
|
+
model_selector_granularity: 'exact-native-model-choice',
|
|
209
|
+
effort_selector: input.envelope.effort,
|
|
210
|
+
selection_source: 'policy-resolved',
|
|
211
|
+
candidates_considered: [input.envelope.variant],
|
|
212
|
+
selection_reason: 'native-catalog',
|
|
213
|
+
selected_route: 'native',
|
|
214
|
+
payload: input.envelope.payload,
|
|
215
|
+
configured_invocation_evidence: [
|
|
216
|
+
{
|
|
217
|
+
source: 'accepted-claude-launch-envelope',
|
|
218
|
+
schemaVersion: input.envelope.schemaVersion,
|
|
219
|
+
variant: input.envelope.variant,
|
|
220
|
+
model: input.envelope.model,
|
|
221
|
+
capabilitySource: input.envelope.capabilityEvidence.source,
|
|
222
|
+
capabilityModelReference: input.envelope.capabilityEvidence.modelReference,
|
|
223
|
+
capabilityExactModel: input.envelope.capabilityEvidence.exactModel,
|
|
224
|
+
capabilityGeneration: input.envelope.capabilityEvidence.generation ?? null,
|
|
225
|
+
capabilityPossibleGenerations: input.envelope.capabilityEvidence.possibleGenerations?.join(',') ??
|
|
226
|
+
null,
|
|
227
|
+
capabilityDeclarationSource: input.envelope.capabilityEvidence.capabilitiesSource,
|
|
228
|
+
capabilitySupportedEfforts: input.envelope.capabilityEvidence.supportedEfforts.join(','),
|
|
229
|
+
effort: input.envelope.effort,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
});
|
|
233
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export declare const CLAUDE_MODEL_ORDER: readonly ['haiku', 'sonnet', 'opus', 'fable'];
|
|
2
|
+
export declare const CLAUDE_EFFORT_ORDER: readonly ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
3
|
+
declare const CLAUDE_GENERATION_EFFORTS: {
|
|
4
|
+
readonly 'fable-5-1': readonly ["low", "medium", "high", "xhigh", "max"];
|
|
5
|
+
readonly 'fable-5': readonly ["low", "medium", "high", "xhigh", "max"];
|
|
6
|
+
readonly 'opus-5-5': readonly ["low", "medium", "high", "xhigh", "max"];
|
|
7
|
+
readonly 'sonnet-5': readonly ["low", "medium", "high", "xhigh", "max"];
|
|
8
|
+
readonly 'opus-4-7': readonly ["low", "medium", "high", "xhigh", "max"];
|
|
9
|
+
readonly 'opus-4-6': readonly ["low", "medium", "high", "max"];
|
|
10
|
+
readonly 'sonnet-4-6': readonly ["low", "medium", "high", "max"];
|
|
11
|
+
};
|
|
12
|
+
export type ClaudeModelGeneration = keyof typeof CLAUDE_GENERATION_EFFORTS;
|
|
13
|
+
export type ClaudeCapabilitySource = 'explicit-model-id' | 'family-pin-model-id' | 'family-pin-declaration' | 'alias-capability-equivalence';
|
|
14
|
+
export interface ClaudeCapabilityEvidence {
|
|
15
|
+
source: ClaudeCapabilitySource;
|
|
16
|
+
modelReference: string;
|
|
17
|
+
exactModel: boolean;
|
|
18
|
+
generation?: ClaudeModelGeneration;
|
|
19
|
+
possibleGenerations?: ClaudeModelGeneration[];
|
|
20
|
+
capabilitiesSource: string;
|
|
21
|
+
supportedEfforts: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface ClaudeDispatchTarget {
|
|
24
|
+
model: string;
|
|
25
|
+
effort?: string;
|
|
26
|
+
capabilityEvidence?: ClaudeCapabilityEvidence;
|
|
27
|
+
}
|
|
28
|
+
export interface ClaudeTargetValidation {
|
|
29
|
+
valid: boolean;
|
|
30
|
+
reason?: string;
|
|
31
|
+
capabilityEvidence?: ClaudeCapabilityEvidence;
|
|
32
|
+
}
|
|
33
|
+
/** Extract a documented effort-capability generation from a provider model ID. */
|
|
34
|
+
export declare function claudeModelGeneration(model: string): ClaudeModelGeneration | null;
|
|
35
|
+
/** Resolve capability evidence without claiming an unobserved exact model. */
|
|
36
|
+
export declare function resolveClaudeCapabilityEvidence(target: Pick<ClaudeDispatchTarget, 'model' | 'capabilityEvidence'>, env?: NodeJS.ProcessEnv): ClaudeTargetValidation;
|
|
37
|
+
export declare function validateClaudeDispatchTarget(target: ClaudeDispatchTarget): ClaudeTargetValidation;
|
|
38
|
+
/** Validate an effort-pinned target against explicit capability evidence. */
|
|
39
|
+
export declare function validateClaudeDispatchCapability(target: ClaudeDispatchTarget, env?: NodeJS.ProcessEnv): ClaudeTargetValidation;
|
|
40
|
+
export declare function normalizeClaudeRoleName(input: string): string;
|
|
41
|
+
export declare function buildClaudeEffortVariantName(options: {
|
|
42
|
+
agentName: string;
|
|
43
|
+
model: string;
|
|
44
|
+
effort: string;
|
|
45
|
+
}): string;
|
|
46
|
+
export declare function claudeTargetRank(target: ClaudeDispatchTarget): [number, number];
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../../src/providers/claude/targets.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,YAAI,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAEhF,eAAO,MAAM,mBAAmB,YAC9B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,CACG,CAAC;AAEX,QAAA,MAAM,yBAAyB;;;;;;;;CAQuB,CAAC;AAGvD,MAAM,MAAM,qBAAqB,GAAG,MAAM,OAAO,yBAAyB,CAAC;AAC3E,MAAM,MAAM,sBAAsB,GAC9B,mBAAmB,GACnB,qBAAqB,GACrB,wBAAwB,GACxB,8BAA8B,CAAC;AAEnC,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mBAAmB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC9C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AASD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;CAC/C;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;CAC/C;AAkBD,kFAAkF;AAClF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,qBAAqB,GAAG,IAAI,CAc9B;AA4ID,8EAA8E;AAC9E,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,oBAAoB,CAAC,EAClE,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,sBAAsB,CAgBxB;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,oBAAoB,GAC3B,sBAAsB,CAoBxB;AAED,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,oBAAoB,EAC5B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,sBAAsB,CAexB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAeT;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,oBAAoB,GAC3B,CAAC,MAAM,EAAE,MAAM,CAAC,CAQlB"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
export const CLAUDE_MODEL_ORDER = ['haiku', 'sonnet', 'opus', 'fable'];
|
|
2
|
+
export const CLAUDE_EFFORT_ORDER = [
|
|
3
|
+
'low',
|
|
4
|
+
'medium',
|
|
5
|
+
'high',
|
|
6
|
+
'xhigh',
|
|
7
|
+
'max',
|
|
8
|
+
];
|
|
9
|
+
const CLAUDE_GENERATION_EFFORTS = {
|
|
10
|
+
'fable-5-1': CLAUDE_EFFORT_ORDER,
|
|
11
|
+
'fable-5': CLAUDE_EFFORT_ORDER,
|
|
12
|
+
'opus-5-5': CLAUDE_EFFORT_ORDER,
|
|
13
|
+
'sonnet-5': CLAUDE_EFFORT_ORDER,
|
|
14
|
+
'opus-4-7': CLAUDE_EFFORT_ORDER,
|
|
15
|
+
'opus-4-6': ['low', 'medium', 'high', 'max'],
|
|
16
|
+
'sonnet-4-6': ['low', 'medium', 'high', 'max'],
|
|
17
|
+
};
|
|
18
|
+
const ALIAS_DEFAULT_ENV = {
|
|
19
|
+
haiku: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
20
|
+
sonnet: 'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
21
|
+
opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
22
|
+
fable: 'ANTHROPIC_DEFAULT_FABLE_MODEL',
|
|
23
|
+
};
|
|
24
|
+
function modelFamily(model) {
|
|
25
|
+
const normalized = model.toLowerCase().replace(/\[1m\]$/u, '');
|
|
26
|
+
for (const family of CLAUDE_MODEL_ORDER) {
|
|
27
|
+
if (normalized === family ||
|
|
28
|
+
new RegExp(`(?:^|[./:_-])claude-${family}(?:-|$)`, 'u').test(normalized) ||
|
|
29
|
+
new RegExp(`(?:^|[./:_-])${family}(?:-|$)`, 'u').test(normalized)) {
|
|
30
|
+
return family;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/** Extract a documented effort-capability generation from a provider model ID. */
|
|
36
|
+
export function claudeModelGeneration(model) {
|
|
37
|
+
const normalized = model.toLowerCase().replace(/\[1m\]$/u, '');
|
|
38
|
+
for (const generation of Object.keys(CLAUDE_GENERATION_EFFORTS)) {
|
|
39
|
+
const [family, ...versionParts] = generation.split('-');
|
|
40
|
+
const version = versionParts.join('[-.]');
|
|
41
|
+
const pattern = new RegExp(`(?:^|[./:_-])(?:claude-)?${family}-${version}(?=$|[-@.:/[])`, 'u');
|
|
42
|
+
if (pattern.test(normalized))
|
|
43
|
+
return generation;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function generationEvidence(generation, source, modelReference, capabilitiesSource) {
|
|
48
|
+
return {
|
|
49
|
+
source,
|
|
50
|
+
modelReference,
|
|
51
|
+
exactModel: source === 'explicit-model-id',
|
|
52
|
+
generation,
|
|
53
|
+
capabilitiesSource,
|
|
54
|
+
supportedEfforts: [...CLAUDE_GENERATION_EFFORTS[generation]],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function familyPinCapabilityEvidence(family, pinName, pinnedModel, env) {
|
|
58
|
+
const generation = claudeModelGeneration(pinnedModel);
|
|
59
|
+
if (generation && modelFamily(generation) !== family) {
|
|
60
|
+
return {
|
|
61
|
+
valid: false,
|
|
62
|
+
reason: `Claude alias ${JSON.stringify(family)} is pinned by ${pinName}=${JSON.stringify(pinnedModel)}, but the pin belongs to another model family.`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const capabilityName = `${pinName}_SUPPORTED_CAPABILITIES`;
|
|
66
|
+
const declaration = env[capabilityName];
|
|
67
|
+
if (!declaration && generation) {
|
|
68
|
+
return {
|
|
69
|
+
valid: true,
|
|
70
|
+
capabilityEvidence: generationEvidence(generation, 'family-pin-model-id', pinnedModel, pinName),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (!declaration) {
|
|
74
|
+
return {
|
|
75
|
+
valid: false,
|
|
76
|
+
reason: `Claude alias ${JSON.stringify(family)} uses custom pin ${pinName}=${JSON.stringify(pinnedModel)}, but ${capabilityName} does not establish effort support.`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const capabilities = new Set(declaration
|
|
80
|
+
.split(',')
|
|
81
|
+
.map((entry) => entry.trim())
|
|
82
|
+
.filter(Boolean));
|
|
83
|
+
if (!capabilities.has('effort')) {
|
|
84
|
+
return {
|
|
85
|
+
valid: false,
|
|
86
|
+
reason: `${capabilityName} must include effort before xhigh_effort or max_effort can establish Claude effort support.`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const supportedEfforts = ['low', 'medium', 'high'];
|
|
90
|
+
if (capabilities.has('xhigh_effort'))
|
|
91
|
+
supportedEfforts.push('xhigh');
|
|
92
|
+
if (capabilities.has('max_effort'))
|
|
93
|
+
supportedEfforts.push('max');
|
|
94
|
+
return {
|
|
95
|
+
valid: true,
|
|
96
|
+
capabilityEvidence: {
|
|
97
|
+
source: 'family-pin-declaration',
|
|
98
|
+
modelReference: pinnedModel,
|
|
99
|
+
exactModel: false,
|
|
100
|
+
...(generation ? { generation } : {}),
|
|
101
|
+
capabilitiesSource: capabilityName,
|
|
102
|
+
supportedEfforts,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** Resolve capability evidence without claiming an unobserved exact model. */
|
|
107
|
+
function deriveClaudeCapabilityEvidence(model, env = process.env) {
|
|
108
|
+
const requestedFamily = modelFamily(model);
|
|
109
|
+
if (!requestedFamily) {
|
|
110
|
+
return {
|
|
111
|
+
valid: false,
|
|
112
|
+
reason: `Unsupported Claude model ${JSON.stringify(model)}. Valid aliases: ${CLAUDE_MODEL_ORDER.join(', ')}; version-pinned Claude model IDs are also accepted.`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const explicitGeneration = claudeModelGeneration(model);
|
|
116
|
+
if (explicitGeneration) {
|
|
117
|
+
return {
|
|
118
|
+
valid: true,
|
|
119
|
+
capabilityEvidence: generationEvidence(explicitGeneration, 'explicit-model-id', model, 'dispatch-target-model'),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const alias = model.toLowerCase().replace(/\[1m\]$/u, '');
|
|
123
|
+
if (alias !== requestedFamily) {
|
|
124
|
+
return {
|
|
125
|
+
valid: false,
|
|
126
|
+
reason: `Cannot establish a documented Claude effort capability for model ${JSON.stringify(model)}. Use a recognized versioned model ID.`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const pinName = ALIAS_DEFAULT_ENV[requestedFamily];
|
|
130
|
+
if (env['CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST']) {
|
|
131
|
+
return {
|
|
132
|
+
valid: false,
|
|
133
|
+
reason: `Claude alias ${JSON.stringify(alias)} has a host-managed provider-dependent generation. Host-managed model configuration takes precedence over ${pinName}; use a versioned model ID in the dispatch target to establish capability.`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const pinnedModel = env[pinName];
|
|
137
|
+
if (pinnedModel) {
|
|
138
|
+
return familyPinCapabilityEvidence(requestedFamily, pinName, pinnedModel, env);
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
valid: false,
|
|
142
|
+
reason: `Claude effort-pinned alias ${JSON.stringify(alias)} cannot establish capability because provider routing, availableModels, or organization policy may substitute another generation. Use a recognized versioned model ID or pin ${pinName} with matching capability evidence.`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Resolve capability evidence without claiming an unobserved exact model. */
|
|
146
|
+
export function resolveClaudeCapabilityEvidence(target, env = process.env) {
|
|
147
|
+
const derived = deriveClaudeCapabilityEvidence(target.model, env);
|
|
148
|
+
if (!derived.valid || !derived.capabilityEvidence)
|
|
149
|
+
return derived;
|
|
150
|
+
if (target.capabilityEvidence &&
|
|
151
|
+
JSON.stringify(target.capabilityEvidence) !==
|
|
152
|
+
JSON.stringify(derived.capabilityEvidence)) {
|
|
153
|
+
return {
|
|
154
|
+
valid: false,
|
|
155
|
+
reason: 'Provided Claude capability evidence does not match the capability derived from the model and active provider configuration.',
|
|
156
|
+
capabilityEvidence: derived.capabilityEvidence,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return derived;
|
|
160
|
+
}
|
|
161
|
+
export function validateClaudeDispatchTarget(target) {
|
|
162
|
+
if (!modelFamily(target.model)) {
|
|
163
|
+
return {
|
|
164
|
+
valid: false,
|
|
165
|
+
reason: `Unsupported Claude model ${JSON.stringify(target.model)}. Valid aliases: ${CLAUDE_MODEL_ORDER.join(', ')}; version-pinned Claude model IDs are also accepted.`,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (target.effort === undefined) {
|
|
169
|
+
return { valid: true };
|
|
170
|
+
}
|
|
171
|
+
if (!CLAUDE_EFFORT_ORDER.includes(target.effort)) {
|
|
172
|
+
return {
|
|
173
|
+
valid: false,
|
|
174
|
+
reason: `Unsupported Claude effort ${JSON.stringify(target.effort)}. Valid values: ${CLAUDE_EFFORT_ORDER.join(', ')}.`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return { valid: true };
|
|
178
|
+
}
|
|
179
|
+
/** Validate an effort-pinned target against explicit capability evidence. */
|
|
180
|
+
export function validateClaudeDispatchCapability(target, env = process.env) {
|
|
181
|
+
const route = validateClaudeDispatchTarget(target);
|
|
182
|
+
if (!route.valid || target.effort === undefined)
|
|
183
|
+
return route;
|
|
184
|
+
const resolution = resolveClaudeCapabilityEvidence(target, env);
|
|
185
|
+
if (!resolution.valid || !resolution.capabilityEvidence)
|
|
186
|
+
return resolution;
|
|
187
|
+
const evidence = resolution.capabilityEvidence;
|
|
188
|
+
if (!evidence.supportedEfforts.includes(target.effort)) {
|
|
189
|
+
return {
|
|
190
|
+
valid: false,
|
|
191
|
+
reason: `Claude capability evidence ${JSON.stringify(evidence.modelReference)} does not support effort ${JSON.stringify(target.effort)}. Supported values: ${evidence.supportedEfforts.join(', ')}.`,
|
|
192
|
+
capabilityEvidence: evidence,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return { valid: true, capabilityEvidence: evidence };
|
|
196
|
+
}
|
|
197
|
+
export function normalizeClaudeRoleName(input) {
|
|
198
|
+
return input
|
|
199
|
+
.trim()
|
|
200
|
+
.toLowerCase()
|
|
201
|
+
.replace(/\.md$/i, '')
|
|
202
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
203
|
+
.replace(/-{2,}/g, '-')
|
|
204
|
+
.replace(/^-+|-+$/g, '');
|
|
205
|
+
}
|
|
206
|
+
export function buildClaudeEffortVariantName(options) {
|
|
207
|
+
const validation = validateClaudeDispatchTarget({
|
|
208
|
+
model: options.model,
|
|
209
|
+
effort: options.effort,
|
|
210
|
+
});
|
|
211
|
+
if (!validation.valid) {
|
|
212
|
+
throw new Error(validation.reason);
|
|
213
|
+
}
|
|
214
|
+
const agentName = normalizeClaudeRoleName(options.agentName);
|
|
215
|
+
if (!agentName) {
|
|
216
|
+
throw new Error('Cannot build Claude effort variant: missing agent name.');
|
|
217
|
+
}
|
|
218
|
+
return `${agentName}-claude-${normalizeClaudeRoleName(options.model)}-${options.effort}`;
|
|
219
|
+
}
|
|
220
|
+
export function claudeTargetRank(target) {
|
|
221
|
+
const family = modelFamily(target.model);
|
|
222
|
+
return [
|
|
223
|
+
family ? CLAUDE_MODEL_ORDER.indexOf(family) : -1,
|
|
224
|
+
target.effort === undefined
|
|
225
|
+
? -1
|
|
226
|
+
: CLAUDE_EFFORT_ORDER.indexOf(target.effort),
|
|
227
|
+
];
|
|
228
|
+
}
|
|
@@ -3,6 +3,12 @@ export declare const OAT_MANAGED_ROLE_NAME_PREFIX = "# oat-role: ";
|
|
|
3
3
|
export declare const OAT_MANAGED_ROLE_OWNER_PREFIX = "# oat-owner: ";
|
|
4
4
|
export type CodexRoleOwner = 'supported-catalogue' | 'user-config' | 'project-config';
|
|
5
5
|
export declare const SUPPORTED_CODEX_ROLE_TARGETS: readonly ({
|
|
6
|
+
model: string;
|
|
7
|
+
effort: string;
|
|
8
|
+
} | {
|
|
9
|
+
model: string;
|
|
10
|
+
effort: string;
|
|
11
|
+
} | {
|
|
6
12
|
model: string;
|
|
7
13
|
effort: "high" | "low" | "medium" | "xhigh";
|
|
8
14
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/providers/codex/codec/shared.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAC7D,eAAO,MAAM,4BAA4B,iBAAiB,CAAC;AAC3D,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAE7D,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,aAAa,GACb,gBAAgB,CAAC;AAoBrB,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/providers/codex/codec/shared.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAC7D,eAAO,MAAM,4BAA4B,iBAAiB,CAAC;AAC3D,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAE7D,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,aAAa,GACb,gBAAgB,CAAC;AAoBrB,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;IAqB/B,CAAC;AAEX,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO5D;AAQD,wBAAgB,oCAAoC,CAAC,OAAO,EAAE;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAiBT;AAgDD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAOT;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,MAAM,CAER;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,IAAI,CAEvB;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,GACpB,MAAM,CAkBR;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE"}
|
|
@@ -12,6 +12,14 @@ const STANDARD_SUPPORTED_CODEX_EFFORTS = [
|
|
|
12
12
|
'xhigh',
|
|
13
13
|
];
|
|
14
14
|
export const SUPPORTED_CODEX_ROLE_TARGETS = [
|
|
15
|
+
...[...STANDARD_SUPPORTED_CODEX_EFFORTS, 'max'].map((effort) => ({
|
|
16
|
+
model: 'gpt-6-luna',
|
|
17
|
+
effort,
|
|
18
|
+
})),
|
|
19
|
+
...[...STANDARD_SUPPORTED_CODEX_EFFORTS, 'max'].map((effort) => ({
|
|
20
|
+
model: 'gpt-6-sol',
|
|
21
|
+
effort,
|
|
22
|
+
})),
|
|
15
23
|
...STANDARD_SUPPORTED_CODEX_EFFORTS.map((effort) => ({
|
|
16
24
|
model: 'gpt-5.6-luna',
|
|
17
25
|
effort,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../../src/providers/cursor/codec/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,eAAe,GACf,eAAe,GACf,kBAAkB,CAAC;AAEvB;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,KAAK,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,qBAAqB,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../../src/providers/cursor/codec/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,eAAe,GACf,eAAe,GACf,kBAAkB,CAAC;AAEvB;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,KAAK,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,qBAAqB,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;CACpB;AA+BD,eAAO,MAAM,yBAAyB,8eAsKe,CAAC;AAEtD,eAAO,MAAM,6BAA6B,yBAEzC,CAAC;AAEF,eAAO,MAAM,2BAA2B,YACtC,uBAAuB,EACvB,cAAc,CACN,CAAC;AAEX,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,GACpB,qBAAqB,GAAG,SAAS,CAInC"}
|