fix(kiro): never send a top-level systemPrompt (400 REQUEST_BODY_INVALID)
kiro.dev rejects any body carrying a top-level systemPrompt with 400 REQUEST_BODY_INVALID. The translators stopped emitting the field in v0.5.59 (the prompt travels in the first user turn via contentPrefix), but two paths kept writing it back downstream of the translator: - rtk/systemInject.js::injectKiroSystem() appended the RTK prompt to body.systemPrompt, so every kr/ model failed whenever an RTK injector (caveman, ponytail) was active. It now appends to the first history user turn's content (else currentMessage), reusing dedupStringAppend/hasPrompt so retries stay idempotent. - executors/kiro.js::appendRepairInstruction() wrote the tool-call repair instruction to systemPrompt on the retry, turning every repair into a hard failure. It now appends to currentMessage.userInputMessage.content. isKiroBody() no longer requires a string body.systemPrompt — that marker is gone from the wire shape — and sniffs the conversation turn shape instead, keeping the stray-conversationState guard intact. Stale comments in both kiro translators corrected: the systemPrompt local is only a session-replay cache key, not a wire field. Also drops the mirror/rollback repair heuristic the injector no longer needs: net -52 lines. Fixes #3641, #3845, #2890, #2901, #2939, #3109, #3459, #3749
This commit is contained in:
@@ -242,9 +242,9 @@ export function claudeToKiroRequest(model, body, stream, credentials) {
|
||||
? (credentials?.providerSpecificData?.profileArn || "")
|
||||
: (credentials?.providerSpecificData?.profileArn || resolveDefaultProfileArn(authMethod));
|
||||
|
||||
// Kiro CLI/KAS sends system prompt as top-level `systemPrompt`. Keep a
|
||||
// content fallback too because the CodeWhisperer surface does not always
|
||||
// enforce top-level systemPrompt for direct calls.
|
||||
// The system prompt travels inside the first user turn's content (contentPrefix):
|
||||
// the CodeWhisperer surface rejects a top-level `systemPrompt` with
|
||||
// 400 REQUEST_BODY_INVALID, so the value below is only a replay cache key.
|
||||
const timestamp = new Date().toISOString();
|
||||
const systemPromptParts = [];
|
||||
if (thinkingBudget !== null && !usesNativeGptEffort) {
|
||||
|
||||
@@ -340,9 +340,9 @@ export function openaiToKiroRequest(model, body, stream, credentials) {
|
||||
|
||||
const timestamp = new Date().toISOString();
|
||||
|
||||
// Kiro CLI/KAS sends these as top-level systemPrompt. Keep a content fallback
|
||||
// too because the CodeWhisperer surface does not always enforce top-level
|
||||
// systemPrompt for direct calls.
|
||||
// The system prompt travels inside the first user turn's content (contentPrefix):
|
||||
// the CodeWhisperer surface rejects a top-level `systemPrompt` with
|
||||
// 400 REQUEST_BODY_INVALID, so the value below is only a replay cache key.
|
||||
const systemPromptParts = [];
|
||||
if (thinkingBudget !== null && !usesNativeGptEffort) {
|
||||
systemPromptParts.push(buildThinkingSystemPrefix(thinkingBudget));
|
||||
|
||||
Reference in New Issue
Block a user