@agentteams/runner 0.0.113 → 0.0.114
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/api-client.d.ts +6 -0
- package/dist/api-client.js +26 -0
- package/dist/api-client.js.map +1 -1
- package/dist/api-client.test.js +23 -0
- package/dist/api-client.test.js.map +1 -1
- package/dist/executable.d.ts +19 -2
- package/dist/executable.js +144 -7
- package/dist/executable.js.map +1 -1
- package/dist/executable.test.js +70 -1
- package/dist/executable.test.js.map +1 -1
- package/dist/handlers/trigger-handler.js +3 -0
- package/dist/handlers/trigger-handler.js.map +1 -1
- package/dist/poller.d.ts +5 -1
- package/dist/poller.js +87 -0
- package/dist/poller.js.map +1 -1
- package/dist/poller.test.js +187 -0
- package/dist/poller.test.js.map +1 -1
- package/dist/runners/amp.js +3 -16
- package/dist/runners/amp.js.map +1 -1
- package/dist/runners/antigravity.js +3 -16
- package/dist/runners/antigravity.js.map +1 -1
- package/dist/runners/capabilities.d.ts +7 -1
- package/dist/runners/capabilities.js +21 -9
- package/dist/runners/capabilities.js.map +1 -1
- package/dist/runners/capabilities.test.js +12 -0
- package/dist/runners/capabilities.test.js.map +1 -1
- package/dist/runners/claude-code.js +3 -8
- package/dist/runners/claude-code.js.map +1 -1
- package/dist/runners/claude-code.test.js +10 -0
- package/dist/runners/claude-code.test.js.map +1 -1
- package/dist/runners/codex.js +3 -16
- package/dist/runners/codex.js.map +1 -1
- package/dist/runners/copilot-cli.js +2 -8
- package/dist/runners/copilot-cli.js.map +1 -1
- package/dist/runners/cursor-cli.js +2 -8
- package/dist/runners/cursor-cli.js.map +1 -1
- package/dist/runners/cursor-cli.test.js +14 -0
- package/dist/runners/cursor-cli.test.js.map +1 -1
- package/dist/runners/engine-commands.d.ts +11 -0
- package/dist/runners/engine-commands.js +27 -0
- package/dist/runners/engine-commands.js.map +1 -0
- package/dist/runners/grok-build-identity.d.ts +8 -0
- package/dist/runners/grok-build-identity.js +17 -0
- package/dist/runners/grok-build-identity.js.map +1 -0
- package/dist/runners/grok-build.d.ts +60 -0
- package/dist/runners/grok-build.js +360 -0
- package/dist/runners/grok-build.js.map +1 -0
- package/dist/runners/grok-build.test.d.ts +1 -0
- package/dist/runners/grok-build.test.js +233 -0
- package/dist/runners/grok-build.test.js.map +1 -0
- package/dist/runners/index.js +3 -0
- package/dist/runners/index.js.map +1 -1
- package/dist/runners/index.test.js +2 -0
- package/dist/runners/index.test.js.map +1 -1
- package/dist/runners/kimi-cli.js +2 -8
- package/dist/runners/kimi-cli.js.map +1 -1
- package/dist/runners/kimi-cli.test.js +8 -0
- package/dist/runners/kimi-cli.test.js.map +1 -1
- package/dist/runners/kiro-cli.js +2 -8
- package/dist/runners/kiro-cli.js.map +1 -1
- package/dist/runners/kiro-cli.test.js +1 -0
- package/dist/runners/kiro-cli.test.js.map +1 -1
- package/dist/runners/log-merger.d.ts +8 -0
- package/dist/runners/log-merger.js +33 -0
- package/dist/runners/log-merger.js.map +1 -0
- package/dist/runners/log-reporter.d.ts +2 -2
- package/dist/runners/log-reporter.js +2 -29
- package/dist/runners/log-reporter.js.map +1 -1
- package/dist/runners/opencode.js +3 -16
- package/dist/runners/opencode.js.map +1 -1
- package/dist/runners/session-env.d.ts +24 -0
- package/dist/runners/session-env.js +61 -0
- package/dist/runners/session-env.js.map +1 -0
- package/dist/runners/session-env.test.d.ts +1 -0
- package/dist/runners/session-env.test.js +78 -0
- package/dist/runners/session-env.test.js.map +1 -0
- package/dist/runners/stream-json-parser.js +45 -0
- package/dist/runners/stream-json-parser.js.map +1 -1
- package/dist/runners/types.d.ts +2 -0
- package/dist/utils/engine-probe.d.ts +15 -0
- package/dist/utils/engine-probe.js +52 -0
- package/dist/utils/engine-probe.js.map +1 -0
- package/dist/utils/engine-probe.test.d.ts +1 -0
- package/dist/utils/engine-probe.test.js +108 -0
- package/dist/utils/engine-probe.test.js.map +1 -0
- package/dist/utils/model-enumerator.d.ts +42 -0
- package/dist/utils/model-enumerator.js +223 -0
- package/dist/utils/model-enumerator.js.map +1 -0
- package/dist/utils/model-enumerator.test.d.ts +1 -0
- package/dist/utils/model-enumerator.test.js +132 -0
- package/dist/utils/model-enumerator.test.js.map +1 -0
- package/native/bin/win32-x64/agentrunner-launcher.exe +0 -0
- package/native/bin/win32-x64/manifest.json +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-probe.js","sourceRoot":"","sources":["../../src/utils/engine-probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { describe, it } from 'node:test';
|
|
3
|
+
import { probeInstalledEngines } from './engine-probe.js';
|
|
4
|
+
describe('probeInstalledEngines', () => {
|
|
5
|
+
it('returns only installed engines and resolves npm global bin once per cycle', async () => {
|
|
6
|
+
let npmGlobalBinCalls = 0;
|
|
7
|
+
const result = await probeInstalledEngines('custom-opencode', {
|
|
8
|
+
getNpmGlobalBinPathAsync: async () => {
|
|
9
|
+
npmGlobalBinCalls += 1;
|
|
10
|
+
return '/global/bin';
|
|
11
|
+
},
|
|
12
|
+
resolveExecutablePathWithPreferenceAsync: async (name, _preferredNames, deps) => {
|
|
13
|
+
assert.equal(deps?.npmGlobalBinPath, '/global/bin');
|
|
14
|
+
return name === 'codex' ? '/bin/codex' : null;
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
assert.deepEqual(result.engines, ['CODEX']);
|
|
18
|
+
assert.equal(result.reliable, true);
|
|
19
|
+
assert.equal(npmGlobalBinCalls, 1);
|
|
20
|
+
});
|
|
21
|
+
it('uses the configured OpenCode command and absorbs individual probe failures', async () => {
|
|
22
|
+
const requestedCommands = [];
|
|
23
|
+
const result = await probeInstalledEngines('custom-opencode', {
|
|
24
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
25
|
+
resolveExecutablePathWithPreferenceAsync: async (name) => {
|
|
26
|
+
requestedCommands.push(name);
|
|
27
|
+
return name === 'custom-opencode' ? '/bin/custom-opencode' : null;
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
assert.equal(requestedCommands[0], 'custom-opencode');
|
|
31
|
+
assert.deepEqual(result.engines, ['OPENCODE']);
|
|
32
|
+
});
|
|
33
|
+
// 탐지와 실제 기동이 갈리지 않도록 러너 모듈과 같은 선호 목록을 넘겨야 한다.
|
|
34
|
+
it('passes the same executable preference the runners use', async () => {
|
|
35
|
+
const preferences = new Map();
|
|
36
|
+
await probeInstalledEngines('opencode', {
|
|
37
|
+
platform: () => 'win32',
|
|
38
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
39
|
+
resolveExecutablePathWithPreferenceAsync: async (name, preferredNames) => {
|
|
40
|
+
preferences.set(name, preferredNames);
|
|
41
|
+
return null;
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
assert.deepEqual(preferences.get('claude'), ['claude.cmd', 'claude']);
|
|
45
|
+
assert.deepEqual(preferences.get('kimi'), ['kimi.cmd', 'kimi']);
|
|
46
|
+
assert.deepEqual(preferences.get('kiro-cli'), ['kiro-cli.exe', 'kiro-cli']);
|
|
47
|
+
assert.deepEqual(preferences.get('agent'), ['agent']);
|
|
48
|
+
assert.deepEqual(preferences.get('grok'), ['grok.exe', 'grok']);
|
|
49
|
+
});
|
|
50
|
+
it('accepts Cursor only when the executable identifies itself as Cursor Agent', async () => {
|
|
51
|
+
const probe = (helpText) => probeInstalledEngines('opencode', {
|
|
52
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
53
|
+
runProbeCommand: async () => helpText,
|
|
54
|
+
resolveExecutablePathWithPreferenceAsync: async (name) => (name === 'agent' ? '/bin/agent' : null),
|
|
55
|
+
});
|
|
56
|
+
assert.deepEqual((await probe('Start the Cursor Agent')).engines, ['CURSOR_CLI']);
|
|
57
|
+
assert.deepEqual((await probe('Unrelated agent utility')).engines, []);
|
|
58
|
+
// 타임아웃으로 죽은 --help는 null을 돌려주며, 오탐 대신 미설치로 취급한다.
|
|
59
|
+
assert.deepEqual((await probe(null)).engines, []);
|
|
60
|
+
});
|
|
61
|
+
// `grok`은 무관한 npm 패키지(@vibe-kit/grok-cli)도 쓰는 이름이라, 공식 help 문구가 없으면
|
|
62
|
+
// 설치된 것으로 보고하면 안 된다. 서드파티를 GROK_BUILD로 오탐하면 실행이 통째로 깨진다.
|
|
63
|
+
it('accepts Grok only when the executable identifies itself as Grok Build', async () => {
|
|
64
|
+
const probe = (helpText) => probeInstalledEngines('opencode', {
|
|
65
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
66
|
+
runProbeCommand: async () => helpText,
|
|
67
|
+
resolveExecutablePathWithPreferenceAsync: async (name) => (name === 'grok' ? '/bin/grok' : null),
|
|
68
|
+
});
|
|
69
|
+
assert.deepEqual((await probe('Grok Build TUI\n\nUsage: grok [OPTIONS] [PROMPT]')).engines, ['GROK_BUILD']);
|
|
70
|
+
// 서드파티 @vibe-kit/grok-cli의 help에는 이 문구가 없다.
|
|
71
|
+
assert.deepEqual((await probe('Grok CLI - AI assistant in your terminal')).engines, []);
|
|
72
|
+
assert.deepEqual((await probe(null)).engines, []);
|
|
73
|
+
});
|
|
74
|
+
it('skips a conflicting Grok candidate and accepts the next official installation', async () => {
|
|
75
|
+
const probed = [];
|
|
76
|
+
const result = await probeInstalledEngines('opencode', {
|
|
77
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
78
|
+
resolveExecutablePathsWithPreferenceAsync: async (name) => name === 'grok' ? ['/custom/bin/grok', '/usr/local/bin/grok'] : [],
|
|
79
|
+
resolveExecutablePathWithPreferenceAsync: async () => null,
|
|
80
|
+
runProbeCommand: async (executablePath) => {
|
|
81
|
+
probed.push(executablePath);
|
|
82
|
+
return executablePath === '/usr/local/bin/grok' ? 'Grok Build TUI' : 'Grok CLI - AI assistant';
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
assert.deepEqual(probed, ['/custom/bin/grok', '/usr/local/bin/grok']);
|
|
86
|
+
assert.deepEqual(result.engines, ['GROK_BUILD']);
|
|
87
|
+
});
|
|
88
|
+
// 빈 목록은 서버에서 "제한 없음"으로 해석되므로, 조회 자체가 불가능한 환경은 보고 대상에서 빼야 한다.
|
|
89
|
+
it('marks a zero-engine result unreliable when the lookup command cannot run', async () => {
|
|
90
|
+
const result = await probeInstalledEngines('opencode', {
|
|
91
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
92
|
+
resolveExecutablePathWithPreferenceAsync: async () => null,
|
|
93
|
+
isExecutableLookupAvailable: async () => false,
|
|
94
|
+
});
|
|
95
|
+
assert.deepEqual(result.engines, []);
|
|
96
|
+
assert.equal(result.reliable, false);
|
|
97
|
+
});
|
|
98
|
+
it('keeps a zero-engine result reliable when the lookup command works', async () => {
|
|
99
|
+
const result = await probeInstalledEngines('opencode', {
|
|
100
|
+
getNpmGlobalBinPathAsync: async () => null,
|
|
101
|
+
resolveExecutablePathWithPreferenceAsync: async () => null,
|
|
102
|
+
isExecutableLookupAvailable: async () => true,
|
|
103
|
+
});
|
|
104
|
+
assert.deepEqual(result.engines, []);
|
|
105
|
+
assert.equal(result.reliable, true);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=engine-probe.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-probe.test.js","sourceRoot":"","sources":["../../src/utils/engine-probe.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { RunnerType } from '@agentteams/core-constants';
|
|
2
|
+
export type EnumeratedModel = {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
maxInputTokens?: number;
|
|
6
|
+
};
|
|
7
|
+
export type ModelEnumerationResult = {
|
|
8
|
+
status: 'SUCCESS';
|
|
9
|
+
values: EnumeratedModel[];
|
|
10
|
+
} | {
|
|
11
|
+
status: 'UNSUPPORTED' | 'EMPTY_OUTPUT' | 'FORMAT_MISMATCH' | 'COMMAND_FAILED';
|
|
12
|
+
message?: string;
|
|
13
|
+
};
|
|
14
|
+
export type ModelEnumeratorDependencies = {
|
|
15
|
+
execute: (executablePath: string, args: string[]) => Promise<{
|
|
16
|
+
stdout: string;
|
|
17
|
+
}>;
|
|
18
|
+
platform: () => NodeJS.Platform;
|
|
19
|
+
resolveExecutable: (name: string, preferredNames: string[]) => string;
|
|
20
|
+
};
|
|
21
|
+
export declare const parseKiroModels: (output: string) => ModelEnumerationResult;
|
|
22
|
+
export declare const parseOpenCodeVerboseModels: (output: string) => ModelEnumerationResult;
|
|
23
|
+
type LineModelShape = 'tab' | 'slash';
|
|
24
|
+
export declare const parseLineModels: (output: string, shape: LineModelShape) => ModelEnumerationResult;
|
|
25
|
+
export declare const parseCursorModels: (output: string) => ModelEnumerationResult;
|
|
26
|
+
/**
|
|
27
|
+
* `grok models`는 JSON 플래그가 없고 사람이 읽는 평문만 낸다(2026-08-14 실측, grok 1.0.3):
|
|
28
|
+
*
|
|
29
|
+
* You are logged in with grok.com.
|
|
30
|
+
*
|
|
31
|
+
* Default model: grok-4.6
|
|
32
|
+
*
|
|
33
|
+
* Available models:
|
|
34
|
+
* * grok-4.6 (default)
|
|
35
|
+
*
|
|
36
|
+
* `Available models:` 헤더 뒤의 글머리 줄만 읽는다. 헤더 앞줄에는 로그인 상태와
|
|
37
|
+
* `Default model:` 같은 진단 문구가 섞여 있어, 줄 형태만으로 거르면 그것들이 모델 값으로
|
|
38
|
+
* 새어 들어간다. 값 뒤의 `(default)` 표시는 값의 일부가 아니라 기본 모델 마커라 떼어낸다.
|
|
39
|
+
*/
|
|
40
|
+
export declare const parseGrokModels: (output: string) => ModelEnumerationResult;
|
|
41
|
+
export declare const enumerateModels: (runnerType: RunnerType, dependencies?: Partial<ModelEnumeratorDependencies>) => Promise<ModelEnumerationResult>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { platform } from 'node:os';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { resolveExecutablePathWithPreference } from '../executable.js';
|
|
5
|
+
import { RUNNER_CAPABILITIES } from '../runners/capabilities.js';
|
|
6
|
+
import { getGrokExecutablePreference } from '../runners/grok-build.js';
|
|
7
|
+
import { getKiroExecutablePreference } from '../runners/kiro-cli.js';
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
const RESERVED_MODEL_PREFIX = '__fast__:';
|
|
10
|
+
const ENUMERATION_TIMEOUT_MS = 30_000;
|
|
11
|
+
const defaultDependencies = {
|
|
12
|
+
execute: async (executablePath, args) => {
|
|
13
|
+
const { stdout } = await execFileAsync(executablePath, args, {
|
|
14
|
+
encoding: 'utf8',
|
|
15
|
+
windowsHide: true,
|
|
16
|
+
timeout: ENUMERATION_TIMEOUT_MS,
|
|
17
|
+
killSignal: 'SIGKILL',
|
|
18
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
19
|
+
});
|
|
20
|
+
return { stdout: String(stdout) };
|
|
21
|
+
},
|
|
22
|
+
platform,
|
|
23
|
+
resolveExecutable: resolveExecutablePathWithPreference,
|
|
24
|
+
};
|
|
25
|
+
// API의 value/label은 255자를 넘으면 요청을 거절하므로 러너에서 먼저 자른다.
|
|
26
|
+
// 255자를 넘는 value는 모델 식별자로 볼 수 없으니 자르지 않고 버린다.
|
|
27
|
+
const MAX_FIELD_LENGTH = 255;
|
|
28
|
+
const normalizeModels = (models) => {
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
return models.filter((model) => {
|
|
31
|
+
const value = model.value.trim();
|
|
32
|
+
if (value.length === 0 || value.length > MAX_FIELD_LENGTH || value.startsWith(RESERVED_MODEL_PREFIX)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (seen.has(value)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
seen.add(value);
|
|
39
|
+
model.value = value;
|
|
40
|
+
model.label = (model.label.trim() || value).slice(0, MAX_FIELD_LENGTH);
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
const parsedResult = (output, models) => {
|
|
45
|
+
if (output.trim().length === 0) {
|
|
46
|
+
return { status: 'EMPTY_OUTPUT' };
|
|
47
|
+
}
|
|
48
|
+
const values = normalizeModels(models);
|
|
49
|
+
return values.length > 0 ? { status: 'SUCCESS', values } : { status: 'FORMAT_MISMATCH' };
|
|
50
|
+
};
|
|
51
|
+
export const parseKiroModels = (output) => {
|
|
52
|
+
if (output.trim().length === 0)
|
|
53
|
+
return { status: 'EMPTY_OUTPUT' };
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(output);
|
|
56
|
+
const models = Array.isArray(parsed.models)
|
|
57
|
+
? parsed.models.flatMap((model) => {
|
|
58
|
+
if (typeof model.model_id !== 'string')
|
|
59
|
+
return [];
|
|
60
|
+
const maxInputTokens = typeof model.context_window_tokens === 'number' &&
|
|
61
|
+
Number.isInteger(model.context_window_tokens) &&
|
|
62
|
+
model.context_window_tokens > 0
|
|
63
|
+
? model.context_window_tokens
|
|
64
|
+
: undefined;
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
value: model.model_id,
|
|
68
|
+
label: typeof model.model_name === 'string' ? model.model_name : model.model_id,
|
|
69
|
+
...(maxInputTokens ? { maxInputTokens } : {}),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
})
|
|
73
|
+
: [];
|
|
74
|
+
return parsedResult(output, models);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { status: 'FORMAT_MISMATCH' };
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
export const parseOpenCodeVerboseModels = (output) => {
|
|
81
|
+
const lines = output.split(/\r?\n/u);
|
|
82
|
+
const models = [];
|
|
83
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
84
|
+
const value = lines[index]?.trim() ?? '';
|
|
85
|
+
if (!/^[^\s{}]+\/[^\s{}]+$/u.test(value))
|
|
86
|
+
continue;
|
|
87
|
+
const jsonLines = [];
|
|
88
|
+
for (let jsonIndex = index + 1; jsonIndex < lines.length; jsonIndex += 1) {
|
|
89
|
+
const line = lines[jsonIndex] ?? '';
|
|
90
|
+
if (jsonLines.length === 0 && line.trim() !== '{')
|
|
91
|
+
break;
|
|
92
|
+
jsonLines.push(line);
|
|
93
|
+
try {
|
|
94
|
+
const metadata = JSON.parse(jsonLines.join('\n'));
|
|
95
|
+
const context = metadata.limit?.context;
|
|
96
|
+
models.push({
|
|
97
|
+
value,
|
|
98
|
+
label: typeof metadata.name === 'string' ? metadata.name : value,
|
|
99
|
+
...(typeof context === 'number' && Number.isInteger(context) && context > 0
|
|
100
|
+
? { maxInputTokens: context }
|
|
101
|
+
: {}),
|
|
102
|
+
});
|
|
103
|
+
index = jsonIndex;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// pretty-print JSON이 완성될 때까지 다음 줄을 이어 붙인다.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return parsedResult(output, models);
|
|
112
|
+
};
|
|
113
|
+
export const parseLineModels = (output, shape) => parsedResult(output, output
|
|
114
|
+
.split(/\r?\n/u)
|
|
115
|
+
.filter((line) => line.trim().length > 0 && !line.trim().startsWith('Fetching '))
|
|
116
|
+
.flatMap((line) => {
|
|
117
|
+
if (shape === 'slash') {
|
|
118
|
+
const value = line.trim();
|
|
119
|
+
return /^[^\s{}]+\/[^\s{}]+$/u.test(value) ? [{ value, label: value }] : [];
|
|
120
|
+
}
|
|
121
|
+
const separatorIndex = line.indexOf('\t');
|
|
122
|
+
if (separatorIndex < 0)
|
|
123
|
+
return [];
|
|
124
|
+
const value = line.slice(0, separatorIndex).trim();
|
|
125
|
+
const label = line.slice(separatorIndex + 1).trim();
|
|
126
|
+
return /^\S+$/u.test(value) ? [{ value, label: label || value }] : [];
|
|
127
|
+
}));
|
|
128
|
+
export const parseCursorModels = (output) => parsedResult(output, output.split(/\r?\n/u).flatMap((line) => {
|
|
129
|
+
const match = line.trim().match(/^(\S+)\s+-\s+(.+)$/u);
|
|
130
|
+
if (!match || match[1] === 'auto')
|
|
131
|
+
return [];
|
|
132
|
+
return [{ value: match[1] ?? '', label: match[2] ?? match[1] ?? '' }];
|
|
133
|
+
}));
|
|
134
|
+
/**
|
|
135
|
+
* `grok models`는 JSON 플래그가 없고 사람이 읽는 평문만 낸다(2026-08-14 실측, grok 1.0.3):
|
|
136
|
+
*
|
|
137
|
+
* You are logged in with grok.com.
|
|
138
|
+
*
|
|
139
|
+
* Default model: grok-4.6
|
|
140
|
+
*
|
|
141
|
+
* Available models:
|
|
142
|
+
* * grok-4.6 (default)
|
|
143
|
+
*
|
|
144
|
+
* `Available models:` 헤더 뒤의 글머리 줄만 읽는다. 헤더 앞줄에는 로그인 상태와
|
|
145
|
+
* `Default model:` 같은 진단 문구가 섞여 있어, 줄 형태만으로 거르면 그것들이 모델 값으로
|
|
146
|
+
* 새어 들어간다. 값 뒤의 `(default)` 표시는 값의 일부가 아니라 기본 모델 마커라 떼어낸다.
|
|
147
|
+
*/
|
|
148
|
+
export const parseGrokModels = (output) => {
|
|
149
|
+
if (output.trim().length === 0)
|
|
150
|
+
return { status: 'EMPTY_OUTPUT' };
|
|
151
|
+
const lines = output.split(/\r?\n/u);
|
|
152
|
+
const headerIndex = lines.findIndex((line) => /^available models:\s*$/iu.test(line.trim()));
|
|
153
|
+
if (headerIndex < 0)
|
|
154
|
+
return { status: 'FORMAT_MISMATCH' };
|
|
155
|
+
const models = [];
|
|
156
|
+
for (const line of lines.slice(headerIndex + 1)) {
|
|
157
|
+
const trimmed = line.trim();
|
|
158
|
+
if (trimmed.length === 0)
|
|
159
|
+
continue;
|
|
160
|
+
const match = trimmed.match(/^[*\-•]\s+(\S+)(?:\s+\((.+)\))?$/u);
|
|
161
|
+
// 글머리 형태가 아닌 줄이 나오면 목록 구획이 끝난 것으로 본다.
|
|
162
|
+
if (!match)
|
|
163
|
+
break;
|
|
164
|
+
const value = match[1] ?? '';
|
|
165
|
+
if (value.length > 0)
|
|
166
|
+
models.push({ value, label: value });
|
|
167
|
+
}
|
|
168
|
+
return parsedResult(output, models);
|
|
169
|
+
};
|
|
170
|
+
const commandFailure = (error) => ({
|
|
171
|
+
status: 'COMMAND_FAILED',
|
|
172
|
+
message: error instanceof Error ? error.message : String(error),
|
|
173
|
+
});
|
|
174
|
+
export const enumerateModels = async (runnerType, dependencies = {}) => {
|
|
175
|
+
if (!RUNNER_CAPABILITIES[runnerType].modelEnumeration) {
|
|
176
|
+
return { status: 'UNSUPPORTED' };
|
|
177
|
+
}
|
|
178
|
+
const deps = { ...defaultDependencies, ...dependencies };
|
|
179
|
+
const isWindows = deps.platform() === 'win32';
|
|
180
|
+
try {
|
|
181
|
+
switch (runnerType) {
|
|
182
|
+
case 'KIRO_CLI': {
|
|
183
|
+
const executable = deps.resolveExecutable('kiro-cli', getKiroExecutablePreference(isWindows));
|
|
184
|
+
return parseKiroModels((await deps.execute(executable, ['chat', '--list-models', '--format', 'json'])).stdout);
|
|
185
|
+
}
|
|
186
|
+
case 'OPENCODE': {
|
|
187
|
+
const executable = deps.resolveExecutable('opencode', isWindows ? ['opencode.cmd', 'opencode'] : ['opencode']);
|
|
188
|
+
try {
|
|
189
|
+
const verbose = parseOpenCodeVerboseModels((await deps.execute(executable, ['models', '--verbose'])).stdout);
|
|
190
|
+
if (verbose.status === 'SUCCESS')
|
|
191
|
+
return verbose;
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// 구버전 또는 일시 오류에서는 안정적인 줄 단위 명령으로 한 번 폴백한다.
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
return parseLineModels((await deps.execute(executable, ['models'])).stdout, 'slash');
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
return commandFailure(error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
case 'ANTIGRAVITY': {
|
|
204
|
+
const executable = deps.resolveExecutable('agy', isWindows ? ['agy.cmd', 'agy'] : ['agy']);
|
|
205
|
+
return parseLineModels((await deps.execute(executable, ['models'])).stdout, 'tab');
|
|
206
|
+
}
|
|
207
|
+
case 'CURSOR_CLI': {
|
|
208
|
+
const executable = deps.resolveExecutable('agent', isWindows ? ['agent.cmd', 'agent'] : ['agent']);
|
|
209
|
+
return parseCursorModels((await deps.execute(executable, ['models'])).stdout);
|
|
210
|
+
}
|
|
211
|
+
case 'GROK_BUILD': {
|
|
212
|
+
const executable = deps.resolveExecutable('grok', getGrokExecutablePreference(isWindows));
|
|
213
|
+
return parseGrokModels((await deps.execute(executable, ['models'])).stdout);
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
return { status: 'UNSUPPORTED' };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
return commandFailure(error);
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
//# sourceMappingURL=model-enumerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-enumerator.js","sourceRoot":"","sources":["../../src/utils/model-enumerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { describe, test } from 'node:test';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { enumerateModels, parseCursorModels, parseGrokModels, parseKiroModels, parseLineModels, parseOpenCodeVerboseModels, } from './model-enumerator.js';
|
|
6
|
+
const fixture = (name) => readFile(fileURLToPath(new URL(`../runners/fixtures/${name}`, import.meta.url)), 'utf8');
|
|
7
|
+
describe('model enumerator parsers', () => {
|
|
8
|
+
test('parses OpenCode labels and context limits while allowing a missing context', async () => {
|
|
9
|
+
const result = parseOpenCodeVerboseModels(await fixture('opencode-models-verbose.txt'));
|
|
10
|
+
assert.deepEqual(result, {
|
|
11
|
+
status: 'SUCCESS',
|
|
12
|
+
values: [
|
|
13
|
+
{ value: 'opencode/big-pickle', label: 'Big Pickle', maxInputTokens: 200000 },
|
|
14
|
+
{ value: 'opencode/deepseek-v4-flash-free', label: 'DeepSeek V4 Flash Free' },
|
|
15
|
+
],
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
test('parses Kiro model metadata', async () => {
|
|
19
|
+
const result = parseKiroModels(await fixture('kiro-models.json'));
|
|
20
|
+
assert.equal(result.status, 'SUCCESS');
|
|
21
|
+
if (result.status !== 'SUCCESS')
|
|
22
|
+
return;
|
|
23
|
+
assert.deepEqual(result.values[1], {
|
|
24
|
+
value: 'claude-sonnet-4.5',
|
|
25
|
+
label: 'claude-sonnet-4.5',
|
|
26
|
+
maxInputTokens: 200000,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
test('parses Antigravity values without treating status text or labels as ids', async () => {
|
|
30
|
+
assert.deepEqual(parseLineModels(await fixture('antigravity-models.txt'), 'tab'), {
|
|
31
|
+
status: 'SUCCESS',
|
|
32
|
+
values: [
|
|
33
|
+
{ value: 'gemini-3.7-flash-high', label: 'Gemini 3.7 Flash (High)' },
|
|
34
|
+
{ value: 'gemini-3.6-flash-medium', label: 'Gemini 3.6 Flash (Medium)' },
|
|
35
|
+
{ value: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6 (Thinking)' },
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
test('rejects diagnostic lines that carry no model shape', () => {
|
|
40
|
+
// 인증 만료·네트워크 오류로 CLI가 한 단어 진단 메시지를 내면 그대로 승인 대기 목록에 쌓였다.
|
|
41
|
+
assert.deepEqual(parseLineModels('Error\nUnauthorized\nhttps://example.com/login', 'tab'), {
|
|
42
|
+
status: 'FORMAT_MISMATCH',
|
|
43
|
+
});
|
|
44
|
+
assert.deepEqual(parseLineModels('Error\nUnauthorized\nbare-token', 'slash'), { status: 'FORMAT_MISMATCH' });
|
|
45
|
+
assert.deepEqual(parseLineModels('provider/model-a\nError', 'slash'), {
|
|
46
|
+
status: 'SUCCESS',
|
|
47
|
+
values: [{ value: 'provider/model-a', label: 'provider/model-a' }],
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
test('drops values and labels that exceed the API length limit', () => {
|
|
51
|
+
const longValue = 'a'.repeat(256);
|
|
52
|
+
const longLabel = 'b'.repeat(300);
|
|
53
|
+
assert.deepEqual(parseLineModels(`${longValue}\tlabel\nmodel-a\t${longLabel}`, 'tab'), {
|
|
54
|
+
status: 'SUCCESS',
|
|
55
|
+
values: [{ value: 'model-a', label: 'b'.repeat(255) }],
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
test('drops Cursor headers, auto, and help text', async () => {
|
|
59
|
+
assert.deepEqual(parseCursorModels(await fixture('cursor-models.txt')), {
|
|
60
|
+
status: 'SUCCESS',
|
|
61
|
+
values: [
|
|
62
|
+
{ value: 'gpt-5.3-codex-low', label: 'Codex 5.3 Low' },
|
|
63
|
+
{ value: 'composer-2.5', label: 'Composer 2.5' },
|
|
64
|
+
],
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
test('reads only the Grok bullet list under the Available models header', async () => {
|
|
68
|
+
assert.deepEqual(parseGrokModels(await fixture('grok-models.txt')), {
|
|
69
|
+
status: 'SUCCESS',
|
|
70
|
+
values: [{ value: 'grok-4.6', label: 'grok-4.6' }],
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
// 헤더 앞에는 로그인 상태와 `Default model:` 진단 줄이 있다. 줄 형태만으로 거르면
|
|
74
|
+
// 그 값들이 모델로 새어 들어간다.
|
|
75
|
+
test('does not leak Grok diagnostic lines above the header as models', () => {
|
|
76
|
+
const output = ['You are logged in with grok.com.', '', 'Default model: grok-4.6', ''].join('\n');
|
|
77
|
+
assert.deepEqual(parseGrokModels(output), { status: 'FORMAT_MISMATCH' });
|
|
78
|
+
});
|
|
79
|
+
test('stops the Grok list at the first non-bullet line and strips the default marker', () => {
|
|
80
|
+
const output = ['Available models:', ' * grok-4.6 (default)', ' * grok-mini', '', 'Notes: something else'].join('\n');
|
|
81
|
+
assert.deepEqual(parseGrokModels(output), {
|
|
82
|
+
status: 'SUCCESS',
|
|
83
|
+
values: [
|
|
84
|
+
{ value: 'grok-4.6', label: 'grok-4.6' },
|
|
85
|
+
{ value: 'grok-mini', label: 'grok-mini' },
|
|
86
|
+
],
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
test('distinguishes empty output, format mismatch, and reserved values', () => {
|
|
90
|
+
assert.deepEqual(parseLineModels('', 'tab'), { status: 'EMPTY_OUTPUT' });
|
|
91
|
+
assert.deepEqual(parseCursorModels('Available models\ninvalid'), { status: 'FORMAT_MISMATCH' });
|
|
92
|
+
assert.deepEqual(parseLineModels('__fast__:hidden\tHidden', 'tab'), { status: 'FORMAT_MISMATCH' });
|
|
93
|
+
assert.deepEqual(parseGrokModels(''), { status: 'EMPTY_OUTPUT' });
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe('enumerateModels', () => {
|
|
97
|
+
const dependencies = (execute) => ({
|
|
98
|
+
execute,
|
|
99
|
+
platform: () => 'darwin',
|
|
100
|
+
resolveExecutable: (name) => `/bin/${name}`,
|
|
101
|
+
});
|
|
102
|
+
test('falls back to line output when OpenCode verbose enumeration fails', async () => {
|
|
103
|
+
const calls = [];
|
|
104
|
+
const result = await enumerateModels('OPENCODE', dependencies(async (_executable, args) => {
|
|
105
|
+
calls.push(args);
|
|
106
|
+
if (args.includes('--verbose'))
|
|
107
|
+
throw new Error('unsupported flag');
|
|
108
|
+
return { stdout: 'provider/model-a\n' };
|
|
109
|
+
}));
|
|
110
|
+
assert.deepEqual(calls, [['models', '--verbose'], ['models']]);
|
|
111
|
+
assert.deepEqual(result, {
|
|
112
|
+
status: 'SUCCESS',
|
|
113
|
+
values: [{ value: 'provider/model-a', label: 'provider/model-a' }],
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
test('classifies command failures instead of throwing', async () => {
|
|
117
|
+
const result = await enumerateModels('KIRO_CLI', dependencies(async () => {
|
|
118
|
+
throw new Error('offline');
|
|
119
|
+
}));
|
|
120
|
+
assert.equal(result.status, 'COMMAND_FAILED');
|
|
121
|
+
});
|
|
122
|
+
test('does not enumerate unsupported runners', async () => {
|
|
123
|
+
let called = false;
|
|
124
|
+
const result = await enumerateModels('CODEX', dependencies(async () => {
|
|
125
|
+
called = true;
|
|
126
|
+
return { stdout: '' };
|
|
127
|
+
}));
|
|
128
|
+
assert.deepEqual(result, { status: 'UNSUPPORTED' });
|
|
129
|
+
assert.equal(called, false);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=model-enumerator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-enumerator.test.js","sourceRoot":"","sources":["../../src/utils/model-enumerator.test.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.114",
|
|
4
4
|
"platform": "win32",
|
|
5
5
|
"arch": "x64",
|
|
6
6
|
"fileName": "agentrunner-launcher.exe",
|
|
7
|
-
"sha256": "
|
|
7
|
+
"sha256": "57d5ee98e3f5a8cda9798b9b03e2fcd2c27cd1b86c6ce1a2226405eb4fe40b96"
|
|
8
8
|
}
|