Skip to content

Commit c0ca4ed

Browse files
ndemiancclaude
andcommitted
docs(ai): declare label?/onRetry? in the provider-dispatch typedefs (PR #45 review)
streamChat/complete/streamAgentTurn read o.label and o.onRetry, and pass onRetry as an object literal into the openaiCompat adapters — but the @PARAM typedefs for both didn't list them. Under // @ts-check that is 9 real diagnostics: TS2339 (property does not exist) on each o.label / o.onRetry read, plus TS2353 (excess property) on each adapter literal. Added label?:string and onRetry?:(info:{attempt,retries,status})=>void to the three router typedefs, and onRetry? to the three adapter typedefs (they already carried label?). The reviewer flagged label; onRetry has the same defect (added by the retry commit) and is fixed in the same pass. Verified with a real tsc 5.6 checkJs run — and not the vacuous kind: a synthetic probe first confirmed tsc actually enforces TS2339/TS2353 here (an earlier npx form was silently not running tsc at all), then stashing the fix gave BEFORE=9 label/onRetry errors, restoring it gave AFTER=0. JSDoc-only; runtime unchanged (full gate 24 suites, 28 provider tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent a38092e commit c0ca4ed

2 files changed

Lines changed: 15 additions & 9 deletions

File tree

extensions/levelcode-ai/providers/index.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ function secretStorageKey(id) {
142142
/**
143143
* Unified streaming chat across providers. `messages` is the shared {role,content:string} shape
144144
* (valid for both Anthropic and OpenAI). Anthropic → native adapter; everything else → openaiCompat.
145-
* @param {{providerId:string, apiKey?:string, baseURL?:string, model:string, maxTokens?:number,
146-
* system:string, messages:any[], signal?:AbortSignal, onDelta:(t:string)=>void}} o
145+
* @param {{providerId:string, apiKey?:string, baseURL?:string, label?:string, model:string, maxTokens?:number,
146+
* system:string, messages:any[], signal?:AbortSignal, onDelta:(t:string)=>void,
147+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} o
147148
*/
148149
async function streamChat(o) {
149150
const p = getProvider(o.providerId);
@@ -163,8 +164,9 @@ async function streamChat(o) {
163164

164165
/**
165166
* Unified one-shot completion across providers (inline ghost-text / edit). Returns full text.
166-
* @param {{providerId:string, apiKey?:string, baseURL?:string, model:string, maxTokens?:number,
167-
* system:string, messages:any[], stop?:string[], signal?:AbortSignal}} o
167+
* @param {{providerId:string, apiKey?:string, baseURL?:string, label?:string, model:string, maxTokens?:number,
168+
* system:string, messages:any[], stop?:string[], signal?:AbortSignal,
169+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} o
168170
* @returns {Promise<string>}
169171
*/
170172
async function complete(o) {
@@ -195,9 +197,10 @@ function supportsTools(id) {
195197
* translation); every other provider → the OpenAI adapter, which translates the Anthropic-shaped
196198
* transcript/tools in and the streamed tool-calls back out. Returns the SAME
197199
* {content, stop_reason, usage, malformed} shape for both, so agent.js is provider-agnostic.
198-
* @param {{providerId:string, apiKey?:string, baseURL?:string, model:string, maxTokens?:number,
200+
* @param {{providerId:string, apiKey?:string, baseURL?:string, label?:string, model:string, maxTokens?:number,
199201
* system:string, messages:any[], tools?:any[], signal?:AbortSignal,
200-
* onText?:(t:string)=>void, onToolStart?:(name:string)=>void}} o
202+
* onText?:(t:string)=>void, onToolStart?:(name:string)=>void,
203+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} o
201204
*/
202205
async function streamAgentTurn(o) {
203206
const p = getProvider(o.providerId);

extensions/levelcode-ai/providers/openaiCompat.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ async function postChat(opts, body) {
174174
* Streaming chat over /v1/chat/completions. opts.onDelta(text) per chunk; resolves at end.
175175
* @param {{baseURL:string, apiKey?:string, headers?:object, label?:string, model:string,
176176
* maxTokens?:number, system?:string, messages:any[], stop?:string[],
177-
* signal?:AbortSignal, onDelta:(t:string)=>void}} opts
177+
* signal?:AbortSignal, onDelta:(t:string)=>void,
178+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} opts
178179
*/
179180
async function streamOpenAI(opts) {
180181
const label = opts.label || 'OpenAI-compatible';
@@ -196,7 +197,8 @@ async function streamOpenAI(opts) {
196197
/**
197198
* Non-streaming single completion (inline ghost-text / edit). Returns the full text.
198199
* @param {{baseURL:string, apiKey?:string, headers?:object, label?:string, model:string,
199-
* maxTokens?:number, system?:string, messages:any[], stop?:string[], signal?:AbortSignal}} opts
200+
* maxTokens?:number, system?:string, messages:any[], stop?:string[], signal?:AbortSignal,
201+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} opts
200202
* @returns {Promise<string>}
201203
*/
202204
async function completeOpenAI(opts) {
@@ -248,7 +250,8 @@ async function listOpenAIModels(opts) {
248250
* to {type:'text'} / {type:'tool_use', id, name, input} blocks.
249251
* @param {{baseURL:string, apiKey?:string, headers?:object, label?:string, model:string,
250252
* maxTokens?:number, system:string, messages:any[], tools?:any[], signal?:AbortSignal,
251-
* onText?:(t:string)=>void, onToolStart?:(name:string)=>void}} opts
253+
* onText?:(t:string)=>void, onToolStart?:(name:string)=>void,
254+
* onRetry?:(info:{attempt:number,retries:number,status:number})=>void}} opts
252255
* @returns {Promise<{content:any[], stop_reason:string, usage:any, malformed:Set<string>}>}
253256
*/
254257
async function streamOpenAIAgentTurn(opts) {

0 commit comments

Comments
 (0)