mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
* fix(source-control): read the Kimi answer from stream-json Kimi Code's text mode prefixes thinking and hook output with a bullet, so the commit message arrived mixed with narration. The recipe now asks for --output-format stream-json and the answer is taken from the last assistant record, which is the commit message (#33556). A record that requests a tool is narration rather than an answer, so it clears the candidate: a stream that ends on a tool call yields no answer, which finalizeFromAgentOutput already treats as a failed run. Only a body whose every non-empty line is a record counts as stream output, so a plain answer that happens to contain a JSON line is left alone. * fix(source-control): decode Kimi output only for the selected protocol * fix(source-control): satisfy generation hook checks * Preserve Kimi generation failures and normalize options linearly * Fix Kimi argument failure messages * Bound Kimi option failure recognition * Fix Kimi generation test fixture types --------- Co-authored-by: beduldul <alkaysan07@gmail.com>
50 lines
1.6 KiB
TypeScript
50 lines
1.6 KiB
TypeScript
function matchesOption(token: string, aliases: readonly string[]): boolean {
|
|
return aliases.some(
|
|
(alias) =>
|
|
token === alias ||
|
|
(alias !== '--' && token.startsWith(`${alias}=`)) ||
|
|
(alias.startsWith('-') &&
|
|
!alias.startsWith('--') &&
|
|
token.startsWith(alias) &&
|
|
token.length > alias.length)
|
|
)
|
|
}
|
|
|
|
export function findOptionOccurrence(
|
|
tokens: readonly string[],
|
|
aliases: readonly string[],
|
|
stopAtTerminator: boolean,
|
|
valueOptions: readonly string[] = [],
|
|
startIndex = 0,
|
|
/** False keeps the next token; 'required' consumes even a dash-leading operand. */
|
|
takesValue: boolean | 'required' = true
|
|
): { index: number; consumed: number; value?: string } | null {
|
|
for (let index = startIndex; index < tokens.length; index += 1) {
|
|
const token = tokens[index]
|
|
if (stopAtTerminator && token === '--') {
|
|
break
|
|
}
|
|
if (!matchesOption(token, aliases)) {
|
|
// Required option values can look like flags, including `--`.
|
|
if (valueOptions.includes(token)) {
|
|
index += 1
|
|
}
|
|
continue
|
|
}
|
|
const nextToken = tokens[index + 1]
|
|
const consumesNext =
|
|
takesValue &&
|
|
aliases.includes(token) &&
|
|
nextToken !== undefined &&
|
|
(takesValue === 'required' || !nextToken.startsWith('-'))
|
|
const alias = aliases.find((name) => matchesOption(token, [name]))
|
|
const value = consumesNext
|
|
? nextToken
|
|
: alias && token !== alias
|
|
? token.slice(alias.length + (token[alias.length] === '=' ? 1 : 0))
|
|
: undefined
|
|
return { index, consumed: consumesNext ? 2 : 1, value }
|
|
}
|
|
return null
|
|
}
|