mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 18:17:36 +00:00
fix(agent): recognize node-launched Qwen Code on Windows (#33461)
Detect Qwen Code on Windows: exact node entrypoint identities for the npm (@qwen-code/qwen-code cli-entry/cli) and standalone (qwen-code/lib) layouts, and comparablePath now collapses . / .. segments so shim paths like .bin\..\ match. Fixes #17326 Supersedes #17382 Co-authored-by: Baojiang Lee <101562714+libaojiang@users.noreply.github.com>
This commit is contained in:
@@ -124,9 +124,23 @@ export function findInterpreterEntrypointToken(
|
||||
}
|
||||
|
||||
export function comparablePath(token: string): string {
|
||||
return token
|
||||
const path = token
|
||||
.trim()
|
||||
.replace(/^["']|["']$/g, '')
|
||||
.replace(/\\/g, '/')
|
||||
.toLowerCase()
|
||||
// Why: npm's local `.bin` shims and Qwen's standalone launcher run `<dir>/../<script>` paths.
|
||||
const prefix = /^\/*/.exec(path)?.[0] ?? ''
|
||||
const segments: string[] = []
|
||||
for (const segment of path.slice(prefix.length).split('/')) {
|
||||
if (segment === '' || segment === '.') {
|
||||
continue
|
||||
}
|
||||
if (segment === '..' && segments.length > 0 && segments.at(-1) !== '..') {
|
||||
segments.pop()
|
||||
continue
|
||||
}
|
||||
segments.push(segment)
|
||||
}
|
||||
return prefix + segments.join('/')
|
||||
}
|
||||
|
||||
@@ -41,5 +41,13 @@ export const EXACT_NODE_ENTRYPOINT_IDENTITIES: readonly {
|
||||
pattern: /(?:^|\/)node_modules\/@deepseek-ai\/dsh\/lib\/bin\.js$/,
|
||||
agent: 'dsh',
|
||||
processName: 'dsh'
|
||||
},
|
||||
// Why: Qwen's npm bin is a generic `cli-entry` script that re-runs `cli` in a child node on
|
||||
// Windows; the standalone installer ships the same pair under `qwen-code/lib/`.
|
||||
{
|
||||
pattern:
|
||||
/(?:^|\/)(?:node_modules\/@qwen-code\/qwen-code\/(?:cli-entry|cli|scripts\/cli-entry|dist\/cli)|qwen-code\/lib\/cli(?:-entry)?)\.js$/,
|
||||
agent: 'qwen-code',
|
||||
processName: 'qwen'
|
||||
}
|
||||
]
|
||||
|
||||
@@ -426,6 +426,29 @@ describe('agent process recognition', () => {
|
||||
expect(recognizeAgentProcessFromCommandLine(command)).toBeNull()
|
||||
})
|
||||
|
||||
// Command lines captured from a live Windows Qwen Code 0.26.1 session (#17326).
|
||||
it.each([
|
||||
String.raw`"node" "C:\Users\dev\AppData\Local\Temp\q\node_modules\.bin\\..\@qwen-code\qwen-code\cli-entry.js"`,
|
||||
String.raw`"node" "C:\Users\dev\AppData\Roaming\npm\\node_modules\@qwen-code\qwen-code\cli-entry.js"`,
|
||||
String.raw`"C:\Program Files\nodejs\node.exe" --expose-gc C:\Users\dev\AppData\Roaming\npm\node_modules\@qwen-code\qwen-code\cli.js`,
|
||||
String.raw`"C:\Users\dev\AppData\Local\qwen-code\qwen-code\node\node.exe" "C:\Users\dev\AppData\Local\qwen-code\qwen-code\bin\..\lib\cli-entry.js"`,
|
||||
String.raw`C:\Users\dev\AppData\Local\qwen-code\qwen-code\node\node.exe --expose-gc C:\Users\dev\AppData\Local\qwen-code\qwen-code\lib\cli.js`,
|
||||
'node /usr/local/lib/node_modules/@qwen-code/qwen-code/cli.js'
|
||||
])('recognizes a node-launched Qwen Code entrypoint: %s', (command) => {
|
||||
expect(recognizeAgentProcessFromCommandLine(command)).toEqual({
|
||||
agent: 'qwen-code',
|
||||
processName: 'qwen'
|
||||
})
|
||||
})
|
||||
|
||||
it.each([
|
||||
'node /tmp/node_modules/@qwen-code/qwen-code/fzfWorker.js',
|
||||
'node /tmp/node_modules/@other/qwen-code/cli.js',
|
||||
'node /tmp/not-qwen-code/lib/cli.js'
|
||||
])('does not recognize a Qwen Code entrypoint lookalike: %s', (command) => {
|
||||
expect(recognizeAgentProcessFromCommandLine(command)).toBeNull()
|
||||
})
|
||||
|
||||
it('recognizes Prime Agent by its binary and npm entrypoint', () => {
|
||||
expect(recognizeAgentProcess('prime-agent')).toEqual({
|
||||
agent: 'prime-agent',
|
||||
|
||||
Reference in New Issue
Block a user