mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix: preserve unexpected provider finish reasons
This commit is contained in:
@@ -10,7 +10,7 @@ import * as Log from "@opencode-ai/core/util/log"
|
||||
import { Cause, Effect, Exit } from "effect"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { EffectBridge } from "@/effect/bridge"
|
||||
import type { LLMEvent, Usage } from "@opencode-ai/llm"
|
||||
import type { LLMEvent, ProviderMetadata, Usage } from "@opencode-ai/llm"
|
||||
import type { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { SessionRetry } from "@/session/retry"
|
||||
import { computeMetrics as computeMetricsHelper, type TokenRates } from "@/kilocode/session/metrics"
|
||||
@@ -137,6 +137,14 @@ export namespace KiloSessionProcessor {
|
||||
/** Returned shape for downstream consumers that prefer the namespace. */
|
||||
export type Metrics = TokenRates
|
||||
|
||||
export function generationID(meta: ProviderMetadata | undefined) {
|
||||
const value = meta?.gateway?.generationId
|
||||
if (typeof value !== "string") return
|
||||
const id = value.trim()
|
||||
if (!/^gen_[A-Za-z0-9_-]{1,200}$/.test(id)) return
|
||||
return id
|
||||
}
|
||||
|
||||
/**
|
||||
* Effect-based offline handler for the retry schedule.
|
||||
* Shows offline status, waits for network reconnection or user rejection.
|
||||
|
||||
@@ -869,6 +869,7 @@ export const layer = Layer.effect(
|
||||
modelID: ctx.model.id,
|
||||
selected: ctx.assistantMessage.modelID,
|
||||
})
|
||||
const generationID = KiloSessionProcessor.generationID(value.providerMetadata)
|
||||
// kilocode_change end
|
||||
// kilocode_change start - guard against finish-step without start-step:
|
||||
// ctx.stepStart is 0 until `start-step` fires, which would feed a
|
||||
@@ -922,6 +923,7 @@ export const layer = Layer.effect(
|
||||
type: "step-finish",
|
||||
time: { start: startDate, end: endDate, elapsed: elapsedMs }, // kilocode_change
|
||||
...(model ? { model } : {}), // kilocode_change
|
||||
...(generationID ? { generationID } : {}), // kilocode_change
|
||||
...(metrics ? { metrics } : {}), // kilocode_change
|
||||
tokens: usage.tokens,
|
||||
cost: usage.cost,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { KiloSessionProcessor } from "../../src/kilocode/session/processor"
|
||||
|
||||
describe("session generation id", () => {
|
||||
test("extracts a bounded Gateway generation id", () => {
|
||||
expect(
|
||||
KiloSessionProcessor.generationID({
|
||||
gateway: {
|
||||
generationId: " gen_test-123 ",
|
||||
routing: { finalProvider: "novita" },
|
||||
marketCost: "0.1",
|
||||
},
|
||||
}),
|
||||
).toBe("gen_test-123")
|
||||
})
|
||||
|
||||
test("rejects arbitrary or oversized metadata values", () => {
|
||||
expect(KiloSessionProcessor.generationID({ gateway: { generationId: "request-secret" } })).toBeUndefined()
|
||||
expect(KiloSessionProcessor.generationID({ gateway: { generationId: `gen_${"a".repeat(201)}` } })).toBeUndefined()
|
||||
expect(KiloSessionProcessor.generationID({ gateway: { generationId: 42 } })).toBeUndefined()
|
||||
expect(KiloSessionProcessor.generationID({ openai: { responseId: "gen_response" } })).toBeUndefined()
|
||||
})
|
||||
})
|
||||
@@ -577,7 +577,14 @@ describe("session processor empty tool-calls", () => {
|
||||
index: 0,
|
||||
reason: "stop",
|
||||
usage: usage(),
|
||||
providerMetadata: { kilocode: { routedModelID: "openai/gpt-5.5-20260423" } },
|
||||
providerMetadata: {
|
||||
kilocode: { routedModelID: "openai/gpt-5.5-20260423" },
|
||||
gateway: {
|
||||
generationId: "gen_test",
|
||||
routing: { finalProvider: "openai" },
|
||||
marketCost: "0.1",
|
||||
},
|
||||
},
|
||||
}),
|
||||
LLMEvent.finish({ reason: "stop", usage: usage() }),
|
||||
)
|
||||
@@ -632,6 +639,9 @@ describe("session processor empty tool-calls", () => {
|
||||
providerID: selection.providerID,
|
||||
modelID: ModelV2.ID.make("openai/gpt-5.5-20260423"),
|
||||
})
|
||||
expect(part?.generationID).toBe("gen_test")
|
||||
expect(part).not.toHaveProperty("providerMetadata")
|
||||
expect(part).not.toHaveProperty("gateway")
|
||||
}),
|
||||
{ git: true },
|
||||
),
|
||||
|
||||
@@ -281,7 +281,7 @@ describe("session.llm.ai-sdk adapter", () => {
|
||||
{
|
||||
type: "step-finish",
|
||||
index: 0,
|
||||
reason: "unknown",
|
||||
reason: "other", // kilocode_change
|
||||
usage: {
|
||||
inputTokens: 10,
|
||||
outputTokens: 5,
|
||||
@@ -294,7 +294,7 @@ describe("session.llm.ai-sdk adapter", () => {
|
||||
},
|
||||
{
|
||||
type: "finish",
|
||||
reason: "unknown",
|
||||
reason: "other", // kilocode_change
|
||||
usage: {
|
||||
inputTokens: 11,
|
||||
outputTokens: 6,
|
||||
|
||||
Reference in New Issue
Block a user