Add Kilo SDK-backed provider adapter#3882
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Effect service review: one convention issue found in the new Kilo text-generation service. See inline comment.
Posted via Macroscope — Effect Service Conventions
| modelSelection: input.modelSelection, | ||
| prompt: `Return JSON with subject and body for this staged change.\nBranch: ${input.branch ?? "unknown"}\nSummary:\n${input.stagedSummary}\nPatch:\n${input.stagedPatch}`, | ||
| }).pipe( | ||
| Effect.flatMap((text) => |
There was a problem hiding this comment.
🟡 Medium textGeneration/KiloTextGeneration.ts:175
decodeCommitOutput and decodePrOutput are applied directly to the raw Kilo text, so when the model wraps its JSON in a Markdown code fence ( json ... ), Schema.fromJsonString rejects the string and both generateCommitMessage and generatePrContent fail. The other providers extract the JSON object before decoding, but this path does not. Strip Markdown fences or use the shared JSON extraction before decoding.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/textGeneration/KiloTextGeneration.ts around line 175:
`decodeCommitOutput` and `decodePrOutput` are applied directly to the raw Kilo text, so when the model wraps its JSON in a Markdown code fence ([code fence] [code fence]json ... [code fence] [code fence]), `Schema.fromJsonString` rejects the string and both `generateCommitMessage` and `generatePrContent` fail. The other providers extract the JSON object before decoding, but this path does not. Strip Markdown fences or use the shared JSON extraction before decoding.
| yield* runKiloSdk("session.promptAsync", () => | ||
| context.client.session.promptAsync( | ||
| { | ||
| sessionID: context.kiloSessionId, | ||
| model, | ||
| agent: input.interactionMode === "plan" ? "plan" : FIXED_AGENT, | ||
| parts: [...(text ? [{ type: "text" as const, text }] : []), ...files], | ||
| }, | ||
| { throwOnError: true }, | ||
| ), | ||
| ).pipe( | ||
| Effect.mapError( | ||
| (cause) => | ||
| new ProviderAdapterRequestError({ | ||
| provider: PROVIDER, | ||
| method: cause.operation, | ||
| detail: cause.detail, | ||
| cause, | ||
| }), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
🟠 High Layers/KiloAdapter.ts:682
When session.promptAsync rejects in sendTurn, the session stays permanently marked as running with the assigned activeTurnId instead of reverting to ready. A subsequent sendTurn sees context.activeTurnId still set, so freshTurn is false — it reuses the stale turn ID and suppresses the turn.started event. Consider resetting context.activeTurnId and updating the session status on the error path so the turn failure is fully rolled back.
).pipe(
+ Effect.catchAll((error) =>
+ Effect.gen(function* () {
+ if (freshTurn) {
+ context.activeTurnId = undefined;
+ yield* updateSession(context, { status: "ready" }, true);
+ }
+ return yield* Effect.fail(error);
+ }),
+ ),
Effect.mapError(
(cause) =>
new ProviderAdapterRequestError({
provider: PROVIDER,
method: cause.operation,
detail: cause.detail,
cause,
}),
),
);🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/KiloAdapter.ts around lines 682-702:
When `session.promptAsync` rejects in `sendTurn`, the session stays permanently marked as `running` with the assigned `activeTurnId` instead of reverting to `ready`. A subsequent `sendTurn` sees `context.activeTurnId` still set, so `freshTurn` is `false` — it reuses the stale turn ID and suppresses the `turn.started` event. Consider resetting `context.activeTurnId` and updating the session status on the error path so the turn failure is fully rolled back.
What Changed
kiloas a first-party provider backed by@kilocode/sdkand a managedkilo serveprocess./providerand stores selections asproviderID/modelIDwhile retaining one top-level Kilo provider.Why
Closes #1579.
Kilo exposes typed server, session, provider, and event APIs through
@kilocode/sdk. Using that integration surface avoids scraping CLI output and allows T3 Code to consume Kilo's live model inventory and structured session stream without exposing Kilo's internal upstream providers or agent modes as separate T3 concepts.The initial adapter intentionally uses Kilo's built-in
codeagent by default, maps plan turns toplan, and treats recovery as best effort.UI Changes
Kilo now appears in provider settings and the model picker. The UI reuses the existing generic provider settings and picker components; no new interaction surface or animation was added.
Checklist
Verification
vp checkvp run typecheckvp test run src/provider/kiloRuntime.test.ts src/provider/Layers/KiloProvider.test.ts src/provider/Layers/ProviderInstanceRegistryLive.test.ts(10 tests)kilo serveand loaded/providersuccessfully.Note
Add Kilo SDK-backed provider adapter with session lifecycle and text generation
kiloprovider driver backed by the@kilocode/sdkpackage, including a full adapter (KiloAdapter.ts) and text generation implementation (KiloTextGeneration.ts).KiloRuntimeErrorinstances.KiloSettingsto server config (enabled, binaryPath, customModels) and registerskiloin provider metadata, model defaults, display names, and the settings UI.📊 Macroscope summarized 0cd8252. 15 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.