Skip to content

Commit d288dd4

Browse files
committed
fix(api): relax request config option constraints
1 parent b616910 commit d288dd4

2 files changed

Lines changed: 39 additions & 5 deletions

File tree

src/api/providers/__tests__/request-config-builder.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ describe("RequestConfigBuilder", () => {
3131
expect(builder.getCleanup()).toBeTypeOf("function")
3232
expect(() => builder.getCleanup()()).not.toThrow()
3333
})
34+
35+
test("should ignore undefined values from defaultOptions", () => {
36+
const builder = new RequestConfigBuilder({ modelId: undefined })
37+
38+
expect(builder.build()).toBeUndefined()
39+
})
3440
})
3541

3642
describe("addAbortSignal", () => {
@@ -316,6 +322,12 @@ describe("RequestConfigBuilder", () => {
316322
expect(result.modelId).toBe("test-model")
317323
})
318324

325+
test("should treat undefined extraOptions values as absent", () => {
326+
const result = RequestConfigBuilder.fromMetadata(undefined, { signal: undefined })
327+
328+
expect(result).toBeUndefined()
329+
})
330+
319331
test("should not set signal when metadata.abortSignal is undefined", () => {
320332
const metadata: ApiHandlerCreateMessageMetadata = { taskId: "test-task" }
321333
const extraOptions = { modelId: "test-model" }
@@ -577,5 +589,21 @@ describe("RequestConfigBuilder", () => {
577589
expect(config.timeout).toBe(30000)
578590
expect(config.retryCount).toBe(3)
579591
})
592+
593+
test("should accept interface-based options without an index signature", () => {
594+
interface SdkOptions {
595+
modelId?: string
596+
signal?: AbortSignal
597+
headers?: Record<string, string>
598+
maxTokens?: number
599+
}
600+
601+
const builder = new RequestConfigBuilder<SdkOptions>({ modelId: "default-model" })
602+
builder.setOption("maxTokens", 2000)
603+
604+
const config = builder.build() as SdkOptions
605+
expect(config.modelId).toBe("default-model")
606+
expect(config.maxTokens).toBe(2000)
607+
})
580608
})
581609
})

src/api/providers/config-builder/request-config-builder.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@ import { mergeAbortSignalAndTimeout, mergeAbortSignals } from "../utils/abort-si
1111
* - Header merging
1212
* - Static factory methods
1313
*/
14-
type RequestConfigOptions = {
14+
type RequestConfigOptionsBase = object & {
1515
headers?: Record<string, string>
1616
signal?: AbortSignal
17-
} & Record<string, unknown>
17+
}
18+
19+
type RequestConfigOptions = RequestConfigOptionsBase & Record<string, unknown>
1820

19-
export class RequestConfigBuilder<TOptions extends RequestConfigOptions = RequestConfigOptions> {
21+
export class RequestConfigBuilder<TOptions extends RequestConfigOptionsBase = RequestConfigOptions> {
2022
protected options: Partial<TOptions>
2123
private cleanupFn: () => void = () => {}
2224

2325
constructor(defaultOptions?: Partial<TOptions>) {
24-
this.options = defaultOptions ? { ...defaultOptions } : {}
26+
this.options = defaultOptions
27+
? (Object.fromEntries(
28+
Object.entries(defaultOptions).filter(([, value]) => value !== undefined),
29+
) as Partial<TOptions>)
30+
: {}
2531
}
2632

2733
/**
@@ -142,7 +148,7 @@ export class RequestConfigBuilder<TOptions extends RequestConfigOptions = Reques
142148
* @param extraOptions - Additional options to merge
143149
* @returns The built configuration or undefined if empty
144150
*/
145-
static fromMetadata<TOptions extends RequestConfigOptions = RequestConfigOptions>(
151+
static fromMetadata<TOptions extends RequestConfigOptionsBase = RequestConfigOptions>(
146152
metadata?: ApiHandlerCreateMessageMetadata,
147153
extraOptions?: Partial<TOptions>,
148154
): TOptions | undefined {

0 commit comments

Comments
 (0)