refactor: simplify response language retry logic in iop-rule-loader
This commit is contained in:
parent
25b171c295
commit
82ad78754e
1 changed files with 76 additions and 14 deletions
|
|
@ -19,7 +19,15 @@ type ProviderMessage = {
|
|||
};
|
||||
|
||||
type ProviderPayload = {
|
||||
model?: unknown;
|
||||
messages?: ProviderMessage[];
|
||||
temperature?: unknown;
|
||||
top_p?: unknown;
|
||||
seed?: unknown;
|
||||
think?: unknown;
|
||||
reasoning_effort?: unknown;
|
||||
thinking_token_budget?: unknown;
|
||||
include_reasoning?: unknown;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
|
|
@ -43,6 +51,7 @@ const responseLanguageUserPrefix = `[IOP 응답 언어: 이번 요청에서 사
|
|||
|
||||
const responseLanguageUserSuffix = `[응답 전 확인: 자연어 설명이 한국어인지 확인하고, 한국어가 아니면 한국어로 다시 작성한다.]`;
|
||||
|
||||
const defaultThinkingTokenBudget = 8192;
|
||||
const nonKoreanCJKPattern = /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff]/;
|
||||
|
||||
const commonRequiredSessionRules: RuleSpec[] = [
|
||||
|
|
@ -208,8 +217,29 @@ function contentAsText(content: unknown): string {
|
|||
return "";
|
||||
}
|
||||
|
||||
function messageText(message: PiMessage): string {
|
||||
return contentAsText(message.content);
|
||||
function visibleMessageText(message: PiMessage): string {
|
||||
const content = message.content;
|
||||
if (typeof content === "string") {
|
||||
return content;
|
||||
}
|
||||
if (!Array.isArray(content)) {
|
||||
return "";
|
||||
}
|
||||
return content
|
||||
.map((item) => {
|
||||
if (typeof item === "string") {
|
||||
return item;
|
||||
}
|
||||
if (!item || typeof item !== "object") {
|
||||
return "";
|
||||
}
|
||||
const type = String((item as { type?: unknown }).type ?? "");
|
||||
if (type !== "text" || !("text" in item)) {
|
||||
return "";
|
||||
}
|
||||
return String((item as { text?: unknown }).text ?? "");
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function messageHasToolCall(message: PiMessage): boolean {
|
||||
|
|
@ -237,10 +267,49 @@ function replaceMessageText(message: PiMessage, text: string): PiMessage {
|
|||
};
|
||||
}
|
||||
|
||||
function applyIopOrnithDefaults(payload: ProviderPayload): boolean {
|
||||
if (payload.model !== "ornith:35b") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let changed = false;
|
||||
if (payload.temperature === undefined) {
|
||||
payload.temperature = 0;
|
||||
changed = true;
|
||||
}
|
||||
if (payload.top_p === undefined) {
|
||||
payload.top_p = 1;
|
||||
changed = true;
|
||||
}
|
||||
if (payload.seed === undefined) {
|
||||
payload.seed = 1;
|
||||
changed = true;
|
||||
}
|
||||
if (payload.think === undefined && payload.reasoning_effort !== "none") {
|
||||
payload.think = true;
|
||||
changed = true;
|
||||
}
|
||||
if (
|
||||
payload.thinking_token_budget === undefined &&
|
||||
payload.think !== false &&
|
||||
payload.reasoning_effort !== "none"
|
||||
) {
|
||||
payload.thinking_token_budget = defaultThinkingTokenBudget;
|
||||
changed = true;
|
||||
}
|
||||
if (payload.include_reasoning === undefined) {
|
||||
payload.include_reasoning = false;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
function injectResponseLanguagePolicy(payload: ProviderPayload): ProviderPayload | undefined {
|
||||
const messages = payload.messages;
|
||||
if (!Array.isArray(messages)) {
|
||||
return undefined;
|
||||
const changed = applyIopOrnithDefaults(payload);
|
||||
return changed ? payload : undefined;
|
||||
}
|
||||
|
||||
const systemIndex = messages.findIndex((message) => message.role === "system" || message.role === "developer");
|
||||
|
|
@ -254,7 +323,8 @@ function injectResponseLanguagePolicy(payload: ProviderPayload): ProviderPayload
|
|||
const needsUserPolicy = userIndex >= 0 && !contentHasUserPolicy(messages[userIndex].content);
|
||||
|
||||
if (!needsSystemPolicy && !needsUserPolicy) {
|
||||
return undefined;
|
||||
const changed = applyIopOrnithDefaults(payload);
|
||||
return changed ? payload : undefined;
|
||||
}
|
||||
|
||||
const nextMessages = [...messages];
|
||||
|
|
@ -287,15 +357,7 @@ function injectResponseLanguagePolicy(payload: ProviderPayload): ProviderPayload
|
|||
...payload,
|
||||
messages: nextMessages,
|
||||
};
|
||||
if (nextPayload.temperature === undefined) {
|
||||
nextPayload.temperature = 0;
|
||||
}
|
||||
if (nextPayload.top_p === undefined) {
|
||||
nextPayload.top_p = 1;
|
||||
}
|
||||
if (nextPayload.seed === undefined) {
|
||||
nextPayload.seed = 1;
|
||||
}
|
||||
applyIopOrnithDefaults(nextPayload);
|
||||
|
||||
return nextPayload;
|
||||
}
|
||||
|
|
@ -342,7 +404,7 @@ ${buildRulesPrompt(projectRoot, loadedRules)}`,
|
|||
return;
|
||||
}
|
||||
|
||||
const text = messageText(message);
|
||||
const text = visibleMessageText(message);
|
||||
if (!text || !nonKoreanCJKPattern.test(text)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue