vibe-coding-master 0.3.0 → 0.3.1
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/README.md +9 -6
- package/dist/backend/adapters/claude-adapter.js +4 -1
- package/dist/backend/api/codex-hook-routes.js +9 -0
- package/dist/backend/api/codex-review-routes.js +4 -0
- package/dist/backend/api/translation-routes.js +2 -2
- package/dist/backend/cli/install-vcm-harness.js +14 -1
- package/dist/backend/gateway/gateway-service.js +4 -3
- package/dist/backend/server.js +10 -0
- package/dist/backend/services/app-settings-service.js +12 -4
- package/dist/backend/services/artifact-service.js +2 -1
- package/dist/backend/services/claude-hook-service.js +3 -3
- package/dist/backend/services/codex-hook-service.js +87 -0
- package/dist/backend/services/codex-review-service.js +144 -59
- package/dist/backend/services/harness-service.js +28 -1
- package/dist/backend/services/message-service.js +8 -7
- package/dist/backend/services/project-service.js +2 -2
- package/dist/backend/services/round-service.js +29 -25
- package/dist/backend/services/session-service.js +141 -12
- package/dist/backend/templates/harness/codex-review.js +37 -6
- package/dist/shared/constants.js +15 -1
- package/dist/shared/types/app-settings.js +4 -3
- package/dist/shared/types/codex-hook.js +1 -0
- package/dist/shared/types/session.js +44 -0
- package/dist-frontend/assets/index-BavJjWQY.js +92 -0
- package/dist-frontend/assets/index-CR1EOe-w.css +32 -0
- package/dist-frontend/index.html +2 -2
- package/docs/ARCHITECTURE.md +1 -0
- package/docs/TESTING.md +82 -0
- package/docs/codex-review-gates.md +83 -45
- package/docs/gateway-design.md +5 -4
- package/docs/known-issues.md +1 -0
- package/docs/product-design.md +26 -10
- package/package.json +1 -1
- package/dist-frontend/assets/index-C9l94uxA.js +0 -92
- package/dist-frontend/assets/index-D6jWo6Jd.css +0 -32
|
@@ -5,6 +5,10 @@ import { VcmError } from "../errors.js";
|
|
|
5
5
|
import { resolveRepoPath } from "../adapters/filesystem.js";
|
|
6
6
|
import { claudeTranscriptPath } from "./claude-transcript-service.js";
|
|
7
7
|
import { getTaskRuntimeRepoRoot } from "./task-service.js";
|
|
8
|
+
const CODEX_REVIEWER_ROLE = "codex-reviewer";
|
|
9
|
+
const CODEX_DIR = ".ai/codex";
|
|
10
|
+
const CODEX_REVIEW_DIR = ".ai/vcm/codex-reviews";
|
|
11
|
+
const CODEX_CONFIG_PATH = ".ai/codex/config.toml";
|
|
8
12
|
export function createSessionService(deps) {
|
|
9
13
|
const now = deps.now ?? (() => new Date().toISOString());
|
|
10
14
|
async function launchRoleSession(repoRoot, taskSlug, role, input, launchMode) {
|
|
@@ -17,29 +21,38 @@ export function createSessionService(deps) {
|
|
|
17
21
|
const taskRepoRoot = getTaskRuntimeRepoRoot(task);
|
|
18
22
|
const paths = deps.artifactService.getHandoffPaths(taskRepoRoot, task.handoffDir);
|
|
19
23
|
const persisted = await loadPersistedRoleRecord(deps.fs, taskRepoRoot, config.stateRoot, taskSlug, role);
|
|
24
|
+
const isCodexReviewer = role === CODEX_REVIEWER_ROLE;
|
|
20
25
|
const permissionMode = normalizeClaudePermissionMode(input.permissionMode ?? persisted?.permissionMode);
|
|
21
|
-
const model =
|
|
26
|
+
const model = isCodexReviewer
|
|
27
|
+
? normalizeCodexModel(input.model ?? persisted?.model)
|
|
28
|
+
: normalizeClaudeModel(input.model ?? persisted?.model);
|
|
29
|
+
const effort = normalizeSessionEffort(input.effort ?? persisted?.effort);
|
|
22
30
|
const claudeSessionId = launchMode === "resume"
|
|
23
31
|
? persisted?.claudeSessionId
|
|
24
32
|
: randomUUID();
|
|
25
33
|
if (!claudeSessionId) {
|
|
26
34
|
throw new VcmError({
|
|
27
35
|
code: "CLAUDE_SESSION_MISSING",
|
|
28
|
-
message: `${role} does not have a
|
|
36
|
+
message: `${role} does not have a session id to resume.`,
|
|
29
37
|
statusCode: 409,
|
|
30
38
|
hint: "Start the role once before using Resume."
|
|
31
39
|
});
|
|
32
40
|
}
|
|
33
41
|
const transcriptPath = launchMode === "resume" && persisted?.transcriptPath
|
|
34
42
|
? persisted.transcriptPath
|
|
35
|
-
: claudeTranscriptPath(taskRepoRoot, claudeSessionId);
|
|
36
|
-
const startCommand =
|
|
43
|
+
: isCodexReviewer ? undefined : claudeTranscriptPath(taskRepoRoot, claudeSessionId);
|
|
44
|
+
const startCommand = isCodexReviewer
|
|
45
|
+
? await buildCodexReviewerStartCommand(deps.fs, taskRepoRoot, launchMode, model, effort)
|
|
46
|
+
: {
|
|
47
|
+
...deps.claude.buildRoleStartCommand(role, config.claudeCommand, permissionMode, claudeSessionId, launchMode === "resume", model, effort),
|
|
48
|
+
cwd: taskRepoRoot
|
|
49
|
+
};
|
|
37
50
|
const runtimeSession = await deps.runtime.createSession({
|
|
38
51
|
taskSlug,
|
|
39
52
|
role,
|
|
40
53
|
command: startCommand.command,
|
|
41
54
|
args: startCommand.args,
|
|
42
|
-
cwd:
|
|
55
|
+
cwd: startCommand.cwd,
|
|
43
56
|
env: {
|
|
44
57
|
VCM_API_URL: deps.apiUrl,
|
|
45
58
|
VCM_TASK_REPO_ROOT: taskRepoRoot,
|
|
@@ -63,7 +76,8 @@ export function createSessionService(deps) {
|
|
|
63
76
|
command: startCommand.display,
|
|
64
77
|
permissionMode,
|
|
65
78
|
model,
|
|
66
|
-
|
|
79
|
+
effort,
|
|
80
|
+
cwd: startCommand.cwd,
|
|
67
81
|
terminalBackend: "node-pty",
|
|
68
82
|
pid: runtimeSession.pid,
|
|
69
83
|
logPath: paths.roleLogPaths[role],
|
|
@@ -159,15 +173,18 @@ export function createSessionService(deps) {
|
|
|
159
173
|
}
|
|
160
174
|
return sessions;
|
|
161
175
|
},
|
|
162
|
-
async
|
|
176
|
+
async recordRoleHookEvent(repoRoot, input) {
|
|
163
177
|
const current = await this.getRoleSession(repoRoot, input.taskSlug, input.role);
|
|
164
|
-
if (!current || !
|
|
178
|
+
if (!current || (!input.allowSessionMismatch && !matchesRoleHookSession(current, input))) {
|
|
165
179
|
return undefined;
|
|
166
180
|
}
|
|
167
181
|
const timestamp = now();
|
|
168
182
|
const isStop = input.eventName === "Stop";
|
|
169
183
|
const updated = {
|
|
170
184
|
...current,
|
|
185
|
+
claudeSessionId: input.sessionId ?? current.claudeSessionId,
|
|
186
|
+
transcriptPath: input.transcriptPath ?? current.transcriptPath,
|
|
187
|
+
cwd: input.cwd ?? current.cwd,
|
|
171
188
|
activityStatus: isStop ? "idle" : "running",
|
|
172
189
|
lastHookEventAt: timestamp,
|
|
173
190
|
lastTurnEndedAt: isStop ? timestamp : current.lastTurnEndedAt,
|
|
@@ -180,6 +197,16 @@ export function createSessionService(deps) {
|
|
|
180
197
|
await persistTaskSession(deps.fs, getTaskRuntimeRepoRoot(task), config.stateRoot, updated);
|
|
181
198
|
return updated;
|
|
182
199
|
},
|
|
200
|
+
recordClaudeHookEvent(repoRoot, input) {
|
|
201
|
+
return this.recordRoleHookEvent(repoRoot, {
|
|
202
|
+
taskSlug: input.taskSlug,
|
|
203
|
+
role: input.role,
|
|
204
|
+
eventName: input.eventName,
|
|
205
|
+
sessionId: input.claudeSessionId,
|
|
206
|
+
transcriptPath: input.transcriptPath,
|
|
207
|
+
cwd: input.cwd
|
|
208
|
+
});
|
|
209
|
+
},
|
|
183
210
|
async markRoleActivityRunning(repoRoot, taskSlug, role) {
|
|
184
211
|
const current = await this.getRoleSession(repoRoot, taskSlug, role);
|
|
185
212
|
if (!current) {
|
|
@@ -201,14 +228,67 @@ export function createSessionService(deps) {
|
|
|
201
228
|
}
|
|
202
229
|
};
|
|
203
230
|
}
|
|
204
|
-
function
|
|
205
|
-
|
|
231
|
+
async function buildCodexReviewerStartCommand(fs, taskRepoRoot, launchMode, selectedModel, selectedEffort) {
|
|
232
|
+
const codexDir = resolveRepoPath(taskRepoRoot, CODEX_DIR);
|
|
233
|
+
const reviewDir = resolveRepoPath(taskRepoRoot, CODEX_REVIEW_DIR);
|
|
234
|
+
if (!(await fs.pathExists(codexDir))) {
|
|
235
|
+
throw new VcmError({
|
|
236
|
+
code: "CODEX_REVIEW_CONFIG_MISSING",
|
|
237
|
+
message: `${CODEX_DIR} does not exist.`,
|
|
238
|
+
statusCode: 409,
|
|
239
|
+
hint: "Apply the VCM harness before starting Codex Reviewer."
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
await fs.ensureDir(reviewDir);
|
|
243
|
+
const config = await loadCodexSessionConfig(fs, taskRepoRoot);
|
|
244
|
+
const model = selectedModel === "default"
|
|
245
|
+
? config.model
|
|
246
|
+
: selectedModel;
|
|
247
|
+
const modelReasoningEffort = selectedEffort === "default"
|
|
248
|
+
? config.modelReasoningEffort
|
|
249
|
+
: selectedEffort;
|
|
250
|
+
const args = launchMode === "resume"
|
|
251
|
+
? ["resume", "--last"]
|
|
252
|
+
: [];
|
|
253
|
+
args.push("--cd", codexDir, "--add-dir", reviewDir, "--sandbox", "workspace-write", "--ask-for-approval", "never", "--dangerously-bypass-hook-trust");
|
|
254
|
+
if (model && model !== "default") {
|
|
255
|
+
args.push("--model", model);
|
|
256
|
+
}
|
|
257
|
+
if (modelReasoningEffort && modelReasoningEffort !== "default") {
|
|
258
|
+
args.push("--config", `model_reasoning_effort="${modelReasoningEffort}"`);
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
command: config.command,
|
|
262
|
+
args,
|
|
263
|
+
cwd: taskRepoRoot,
|
|
264
|
+
display: [config.command, ...args].map(formatDisplayArg).join(" ")
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
async function loadCodexSessionConfig(fs, taskRepoRoot) {
|
|
268
|
+
const configPath = resolveRepoPath(taskRepoRoot, CODEX_CONFIG_PATH);
|
|
269
|
+
if (!(await fs.pathExists(configPath))) {
|
|
270
|
+
return {
|
|
271
|
+
command: "codex",
|
|
272
|
+
model: "gpt-5.5",
|
|
273
|
+
modelReasoningEffort: "xhigh"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const content = await fs.readText(configPath);
|
|
277
|
+
const reviewSection = extractTomlSection(content, "vcm.codex_review");
|
|
278
|
+
return {
|
|
279
|
+
command: parseTomlString(reviewSection, "command") ?? "codex",
|
|
280
|
+
model: parseTomlString(content, "model") ?? "gpt-5.5",
|
|
281
|
+
modelReasoningEffort: parseTomlString(content, "model_reasoning_effort") ?? "xhigh"
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function matchesRoleHookSession(record, input) {
|
|
285
|
+
if (input.sessionId && record.claudeSessionId === input.sessionId) {
|
|
206
286
|
return true;
|
|
207
287
|
}
|
|
208
288
|
if (input.transcriptPath && record.transcriptPath === input.transcriptPath) {
|
|
209
289
|
return true;
|
|
210
290
|
}
|
|
211
|
-
if (!input.
|
|
291
|
+
if (!input.sessionId && !input.transcriptPath) {
|
|
212
292
|
return true;
|
|
213
293
|
}
|
|
214
294
|
return false;
|
|
@@ -249,7 +329,10 @@ async function loadPersistedRoleRecord(fs, repoRoot, stateRoot, taskSlug, role)
|
|
|
249
329
|
? legacy.lastStopAt
|
|
250
330
|
: undefined),
|
|
251
331
|
permissionMode: normalizeClaudePermissionMode(record.permissionMode),
|
|
252
|
-
model:
|
|
332
|
+
model: record.role === CODEX_REVIEWER_ROLE
|
|
333
|
+
? normalizeCodexModel(record.model)
|
|
334
|
+
: normalizeClaudeModel(record.model),
|
|
335
|
+
effort: normalizeSessionEffort(record.effort)
|
|
253
336
|
}
|
|
254
337
|
: undefined;
|
|
255
338
|
}
|
|
@@ -311,3 +394,49 @@ function normalizeClaudeModel(value) {
|
|
|
311
394
|
}
|
|
312
395
|
return "default";
|
|
313
396
|
}
|
|
397
|
+
function normalizeCodexModel(value) {
|
|
398
|
+
if (value === "default" || value === "gpt-5.5") {
|
|
399
|
+
return value;
|
|
400
|
+
}
|
|
401
|
+
return "gpt-5.5";
|
|
402
|
+
}
|
|
403
|
+
function normalizeSessionEffort(value) {
|
|
404
|
+
if (value === "low"
|
|
405
|
+
|| value === "medium"
|
|
406
|
+
|| value === "high"
|
|
407
|
+
|| value === "xhigh"
|
|
408
|
+
|| value === "max") {
|
|
409
|
+
return value;
|
|
410
|
+
}
|
|
411
|
+
return "default";
|
|
412
|
+
}
|
|
413
|
+
function extractTomlSection(content, sectionName) {
|
|
414
|
+
const lines = content.split(/\r?\n/);
|
|
415
|
+
const header = `[${sectionName}]`;
|
|
416
|
+
const start = lines.findIndex((line) => line.trim() === header);
|
|
417
|
+
if (start < 0) {
|
|
418
|
+
return "";
|
|
419
|
+
}
|
|
420
|
+
const section = [];
|
|
421
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
422
|
+
const line = lines[index];
|
|
423
|
+
if (/^\s*\[[^\]]+\]\s*$/.test(line)) {
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
section.push(line);
|
|
427
|
+
}
|
|
428
|
+
return section.join("\n");
|
|
429
|
+
}
|
|
430
|
+
function parseTomlString(content, key) {
|
|
431
|
+
const pattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*"([^"]*)"\\s*$`, "m");
|
|
432
|
+
return pattern.exec(content)?.[1];
|
|
433
|
+
}
|
|
434
|
+
function escapeRegExp(value) {
|
|
435
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
436
|
+
}
|
|
437
|
+
function formatDisplayArg(value) {
|
|
438
|
+
if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) {
|
|
439
|
+
return value;
|
|
440
|
+
}
|
|
441
|
+
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
442
|
+
}
|
|
@@ -96,12 +96,8 @@ approval_policy = "never"
|
|
|
96
96
|
default_permissions = "vcm_codex_reviewer"
|
|
97
97
|
|
|
98
98
|
[vcm.codex_review]
|
|
99
|
-
enabled =
|
|
100
|
-
required_gates = [
|
|
101
|
-
"architecture-plan",
|
|
102
|
-
"validation-adequacy",
|
|
103
|
-
"final-diff",
|
|
104
|
-
]
|
|
99
|
+
enabled = false
|
|
100
|
+
required_gates = []
|
|
105
101
|
|
|
106
102
|
[permissions.vcm_codex_reviewer.workspace_roots]
|
|
107
103
|
"../.." = true
|
|
@@ -118,6 +114,41 @@ required_gates = [
|
|
|
118
114
|
[permissions.vcm_codex_reviewer.network]
|
|
119
115
|
enabled = false`;
|
|
120
116
|
}
|
|
117
|
+
export function renderCodexCliConfigHarnessRules() {
|
|
118
|
+
return `[features]
|
|
119
|
+
hooks = true`;
|
|
120
|
+
}
|
|
121
|
+
export function renderCodexHooksHarnessRules() {
|
|
122
|
+
const eventScript = "let s=\"\";process.stdin.setEncoding(\"utf8\");process.stdin.on(\"data\",d=>s+=d);process.stdin.on(\"end\",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,event}));});";
|
|
123
|
+
const userPromptCommand = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'${eventScript}'"'"' | curl -fsS --max-time 2 -X POST "\${VCM_API_URL}/api/hooks/codex-reviewer" -H "content-type: application/json" --data-binary @- >/dev/null || true'`;
|
|
124
|
+
const stopCommand = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then printf "{}"; exit 0; fi; node -e '"'"'${eventScript}'"'"' | curl -fsS --max-time 5 -X POST "\${VCM_API_URL}/api/hooks/codex-reviewer/stop" -H "content-type: application/json" --data-binary @- || printf "{}"'`;
|
|
125
|
+
return JSON.stringify({
|
|
126
|
+
hooks: {
|
|
127
|
+
UserPromptSubmit: [
|
|
128
|
+
{
|
|
129
|
+
hooks: [
|
|
130
|
+
{
|
|
131
|
+
type: "command",
|
|
132
|
+
command: userPromptCommand,
|
|
133
|
+
timeout: 5
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
Stop: [
|
|
139
|
+
{
|
|
140
|
+
hooks: [
|
|
141
|
+
{
|
|
142
|
+
type: "command",
|
|
143
|
+
command: stopCommand,
|
|
144
|
+
timeout: 10
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}, null, 2);
|
|
151
|
+
}
|
|
121
152
|
export function renderCodexArchitecturePlanPrompt() {
|
|
122
153
|
return `# Codex Gate: architecture-plan
|
|
123
154
|
|
package/dist/shared/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const DEFAULT_BACKEND_PORT = 4173;
|
|
2
2
|
export const DEFAULT_FRONTEND_PORT = 5173;
|
|
3
|
-
export const
|
|
3
|
+
export const VCM_ROLE_DEFINITIONS = [
|
|
4
4
|
{
|
|
5
5
|
name: "project-manager",
|
|
6
6
|
label: "Project Manager",
|
|
@@ -26,6 +26,17 @@ export const ROLE_DEFINITIONS = [
|
|
|
26
26
|
dispatchable: true
|
|
27
27
|
}
|
|
28
28
|
];
|
|
29
|
+
export const CODEX_REVIEWER_ROLE_DEFINITION = {
|
|
30
|
+
name: "codex-reviewer",
|
|
31
|
+
label: "Codex Reviewer",
|
|
32
|
+
commandAgent: "codex-reviewer",
|
|
33
|
+
dispatchable: false
|
|
34
|
+
};
|
|
35
|
+
export const ROLE_DEFINITIONS = [
|
|
36
|
+
...VCM_ROLE_DEFINITIONS,
|
|
37
|
+
CODEX_REVIEWER_ROLE_DEFINITION
|
|
38
|
+
];
|
|
39
|
+
export const VCM_ROLE_NAMES = VCM_ROLE_DEFINITIONS.map((role) => role.name);
|
|
29
40
|
export const ROLE_NAMES = ROLE_DEFINITIONS.map((role) => role.name);
|
|
30
41
|
export const DISPATCHABLE_ROLES = ROLE_DEFINITIONS
|
|
31
42
|
.filter((role) => role.dispatchable)
|
|
@@ -33,6 +44,9 @@ export const DISPATCHABLE_ROLES = ROLE_DEFINITIONS
|
|
|
33
44
|
export function isRoleName(value) {
|
|
34
45
|
return ROLE_NAMES.includes(value);
|
|
35
46
|
}
|
|
47
|
+
export function isVcmRoleName(value) {
|
|
48
|
+
return VCM_ROLE_NAMES.includes(value);
|
|
49
|
+
}
|
|
36
50
|
export function isDispatchableRole(value) {
|
|
37
51
|
return DISPATCHABLE_ROLES.includes(value);
|
|
38
52
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VCM_ROLE_NAMES } from "../constants.js";
|
|
2
2
|
export const THEME_MODES = ["system", "light", "dark"];
|
|
3
3
|
export const PERMISSION_REQUEST_MODES = ["off", "allowAll"];
|
|
4
4
|
export function createDefaultLaunchTemplate() {
|
|
5
5
|
const roles = {};
|
|
6
|
-
for (const role of
|
|
6
|
+
for (const role of VCM_ROLE_NAMES) {
|
|
7
7
|
roles[role] = {
|
|
8
8
|
permissionMode: "default",
|
|
9
|
-
model: "default"
|
|
9
|
+
model: "default",
|
|
10
|
+
effort: "default"
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -35,3 +35,47 @@ export const CLAUDE_MODEL_OPTIONS = [
|
|
|
35
35
|
description: "Opus 4.8 + 1M context"
|
|
36
36
|
}
|
|
37
37
|
];
|
|
38
|
+
export const CODEX_MODEL_OPTIONS = [
|
|
39
|
+
{
|
|
40
|
+
value: "gpt-5.5",
|
|
41
|
+
label: "GPT-5.5",
|
|
42
|
+
description: "Strong Codex reviewer default"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
value: "default",
|
|
46
|
+
label: "Default",
|
|
47
|
+
description: "Codex account default"
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
export const SESSION_EFFORT_OPTIONS = [
|
|
51
|
+
{
|
|
52
|
+
value: "default",
|
|
53
|
+
label: "Default",
|
|
54
|
+
description: "CLI or project default"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
value: "low",
|
|
58
|
+
label: "Low",
|
|
59
|
+
description: "Fastest reasoning"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
value: "medium",
|
|
63
|
+
label: "Medium",
|
|
64
|
+
description: "Balanced reasoning"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
value: "high",
|
|
68
|
+
label: "High",
|
|
69
|
+
description: "Deeper reasoning"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
value: "xhigh",
|
|
73
|
+
label: "XHigh",
|
|
74
|
+
description: "Extra high reasoning"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: "max",
|
|
78
|
+
label: "Max",
|
|
79
|
+
description: "Maximum reasoning"
|
|
80
|
+
}
|
|
81
|
+
];
|