


















@@ -112,6 +112,26 @@ function runCatalog(
112112});
113113}
114114115+function requireRecord(value: unknown, label: string): Record<string, unknown> {
116+expect(value, label).toBeTypeOf("object");
117+expect(value, label).not.toBeNull();
118+return value as Record<string, unknown>;
119+}
120+121+function expectProviderFields(result: unknown, fields: Record<string, unknown>) {
122+const provider = requireRecord(requireRecord(result, "catalog result").provider, "provider");
123+for (const [key, expected] of Object.entries(fields)) {
124+expect(provider[key]).toEqual(expected);
125+}
126+return provider;
127+}
128+129+function providerModelIds(provider: Record<string, unknown>): Array<unknown> {
130+const models = provider.models;
131+expect(Array.isArray(models), "provider models").toBe(true);
132+return (models as Array<{ id?: unknown }>).map((model) => model.id);
133+}
134+115135function installDiscoveryHooks(state: DiscoveryState, options: DiscoveryContractOptions) {
116136beforeAll(async () => {
117137vi.resetModules();
@@ -295,12 +315,13 @@ export function describeGithubCopilotProviderDiscoveryContract(params: {
295315models: [],
296316},
297317});
298-expect(resolveCopilotApiTokenMock).toHaveBeenCalledWith({
299-githubToken: "github-env-token",
300-env: expect.objectContaining({
301-GITHUB_TOKEN: "github-env-token",
302-}),
303-});
318+const copilotCall = requireRecord(
319+resolveCopilotApiTokenMock.mock.calls[0]?.[0],
320+"copilot token params",
321+);
322+expect(copilotCall.githubToken).toBe("github-env-token");
323+const env = requireRecord(copilotCall.env, "copilot token env");
324+expect(env.GITHUB_TOKEN).toBe("github-env-token");
304325});
305326});
306327}
@@ -420,33 +441,29 @@ export function describeMinimaxProviderDiscoveryContract(
420441installDiscoveryHooks(state, { providerIds: ["minimax"], loadMinimax: load });
421442422443it("keeps API catalog provider-owned", async () => {
423-await expect(
424-state.runProviderCatalog({
425-provider: state.minimaxProvider!,
426-config: {},
427-env: {
428-MINIMAX_API_KEY: "minimax-key",
429-} as NodeJS.ProcessEnv,
430-resolveProviderApiKey: () => ({ apiKey: "minimax-key" }),
431-resolveProviderAuth: () => ({
432-apiKey: "minimax-key",
433-discoveryApiKey: undefined,
434-mode: "api_key",
435-source: "env",
436-}),
437-}),
438-).resolves.toMatchObject({
439-provider: {
440-baseUrl: "https://api.minimax.io/anthropic",
441-api: "anthropic-messages",
442-authHeader: true,
444+const result = await state.runProviderCatalog({
445+provider: state.minimaxProvider!,
446+config: {},
447+env: {
448+MINIMAX_API_KEY: "minimax-key",
449+} as NodeJS.ProcessEnv,
450+resolveProviderApiKey: () => ({ apiKey: "minimax-key" }),
451+resolveProviderAuth: () => ({
443452apiKey: "minimax-key",
444-models: expect.arrayContaining([
445-expect.objectContaining({ id: "MiniMax-M2.7" }),
446-expect.objectContaining({ id: "MiniMax-M2.7-highspeed" }),
447-]),
448-},
453+discoveryApiKey: undefined,
454+mode: "api_key",
455+source: "env",
456+}),
457+});
458+const provider = expectProviderFields(result, {
459+baseUrl: "https://api.minimax.io/anthropic",
460+api: "anthropic-messages",
461+authHeader: true,
462+apiKey: "minimax-key",
449463});
464+const ids = providerModelIds(provider);
465+expect(ids).toContain("MiniMax-M2.7");
466+expect(ids).toContain("MiniMax-M2.7-highspeed");
450467});
451468452469it("keeps portal oauth marker fallback provider-owned", async () => {
@@ -463,60 +480,54 @@ export function describeMinimaxProviderDiscoveryContract(
463480},
464481});
465482466-await expect(
467-runCatalog(state, {
468-provider: state.minimaxPortalProvider!,
469-config: {},
470-env: {} as NodeJS.ProcessEnv,
471-resolveProviderApiKey: () => ({ apiKey: undefined }),
472-resolveProviderAuth: () => ({
473-apiKey: "minimax-oauth",
474-discoveryApiKey: "access-token",
475-mode: "oauth",
476-source: "profile",
477-profileId: "minimax-portal:default",
478-}),
479-}),
480-).resolves.toMatchObject({
481-provider: {
482-baseUrl: "https://api.minimax.io/anthropic",
483-api: "anthropic-messages",
484-authHeader: true,
483+const result = await runCatalog(state, {
484+provider: state.minimaxPortalProvider!,
485+config: {},
486+env: {} as NodeJS.ProcessEnv,
487+resolveProviderApiKey: () => ({ apiKey: undefined }),
488+resolveProviderAuth: () => ({
485489apiKey: "minimax-oauth",
486-models: expect.arrayContaining([expect.objectContaining({ id: "MiniMax-M2.7" })]),
487-},
490+discoveryApiKey: "access-token",
491+mode: "oauth",
492+source: "profile",
493+profileId: "minimax-portal:default",
494+}),
488495});
496+const provider = expectProviderFields(result, {
497+baseUrl: "https://api.minimax.io/anthropic",
498+api: "anthropic-messages",
499+authHeader: true,
500+apiKey: "minimax-oauth",
501+});
502+expect(providerModelIds(provider)).toContain("MiniMax-M2.7");
489503});
490504491505it("keeps portal explicit base URL override provider-owned", async () => {
492-await expect(
493-state.runProviderCatalog({
494-provider: state.minimaxPortalProvider!,
495-config: {
496-models: {
497-providers: {
498-"minimax-portal": {
499-baseUrl: "https://portal-proxy.example.com/anthropic",
500-apiKey: "explicit-key",
501-models: [],
502-},
506+const result = await state.runProviderCatalog({
507+provider: state.minimaxPortalProvider!,
508+config: {
509+models: {
510+providers: {
511+"minimax-portal": {
512+baseUrl: "https://portal-proxy.example.com/anthropic",
513+apiKey: "explicit-key",
514+models: [],
503515},
504516},
505517},
506-env: {} as NodeJS.ProcessEnv,
507-resolveProviderApiKey: () => ({ apiKey: undefined }),
508-resolveProviderAuth: () => ({
509-apiKey: undefined,
510-discoveryApiKey: undefined,
511-mode: "none",
512-source: "none",
513-}),
514-}),
515-).resolves.toMatchObject({
516-provider: {
517-baseUrl: "https://portal-proxy.example.com/anthropic",
518-apiKey: "explicit-key",
519518},
519+env: {} as NodeJS.ProcessEnv,
520+resolveProviderApiKey: () => ({ apiKey: undefined }),
521+resolveProviderAuth: () => ({
522+apiKey: undefined,
523+discoveryApiKey: undefined,
524+mode: "none",
525+source: "none",
526+}),
527+});
528+expectProviderFields(result, {
529+baseUrl: "https://portal-proxy.example.com/anthropic",
530+apiKey: "explicit-key",
520531});
521532});
522533});
@@ -531,42 +542,38 @@ export function describeModelStudioProviderDiscoveryContract(
531542installDiscoveryHooks(state, { providerIds: ["modelstudio"], loadModelStudio: load });
532543533544it("keeps catalog provider-owned", async () => {
534-await expect(
535-state.runProviderCatalog({
536-provider: state.modelStudioProvider!,
537-config: {
538-models: {
539-providers: {
540-modelstudio: {
541-baseUrl: "https://coding.dashscope.aliyuncs.com/v1",
542-models: [],
543-},
545+const result = await state.runProviderCatalog({
546+provider: state.modelStudioProvider!,
547+config: {
548+models: {
549+providers: {
550+modelstudio: {
551+baseUrl: "https://coding.dashscope.aliyuncs.com/v1",
552+models: [],
544553},
545554},
546555},
547-env: {
548-MODELSTUDIO_API_KEY: "modelstudio-key",
549-} as NodeJS.ProcessEnv,
550-resolveProviderApiKey: () => ({ apiKey: "modelstudio-key" }),
551-resolveProviderAuth: () => ({
552-apiKey: "modelstudio-key",
553-discoveryApiKey: undefined,
554-mode: "api_key",
555-source: "env",
556-}),
557-}),
558-).resolves.toMatchObject({
559-provider: {
560-baseUrl: "https://coding.dashscope.aliyuncs.com/v1",
561-api: "openai-completions",
562-apiKey: "modelstudio-key",
563-models: expect.arrayContaining([
564-expect.objectContaining({ id: "qwen3.5-plus" }),
565-expect.objectContaining({ id: "qwen3-max-2026-01-23" }),
566-expect.objectContaining({ id: "MiniMax-M2.5" }),
567-]),
568556},
557+env: {
558+MODELSTUDIO_API_KEY: "modelstudio-key",
559+} as NodeJS.ProcessEnv,
560+resolveProviderApiKey: () => ({ apiKey: "modelstudio-key" }),
561+resolveProviderAuth: () => ({
562+apiKey: "modelstudio-key",
563+discoveryApiKey: undefined,
564+mode: "api_key",
565+source: "env",
566+}),
567+});
568+const provider = expectProviderFields(result, {
569+baseUrl: "https://coding.dashscope.aliyuncs.com/v1",
570+api: "openai-completions",
571+apiKey: "modelstudio-key",
569572});
573+const ids = providerModelIds(provider);
574+expect(ids).toContain("qwen3.5-plus");
575+expect(ids).toContain("qwen3-max-2026-01-23");
576+expect(ids).toContain("MiniMax-M2.5");
570577});
571578});
572579}
@@ -619,29 +626,26 @@ export function describeCloudflareAiGatewayProviderDiscoveryContract(
619626},
620627});
621628622-await expect(
623-runCatalog(state, {
624-provider: state.cloudflareAiGatewayProvider!,
625-config: {},
626-env: {
627-CLOUDFLARE_AI_GATEWAY_API_KEY: "secret-value",
628-} as NodeJS.ProcessEnv,
629-resolveProviderApiKey: () => ({ apiKey: undefined }),
630-resolveProviderAuth: () => ({
631-apiKey: undefined,
632-discoveryApiKey: undefined,
633-mode: "none",
634-source: "none",
635-}),
629+const result = await runCatalog(state, {
630+provider: state.cloudflareAiGatewayProvider!,
631+config: {},
632+env: {
633+CLOUDFLARE_AI_GATEWAY_API_KEY: "secret-value",
634+} as NodeJS.ProcessEnv,
635+resolveProviderApiKey: () => ({ apiKey: undefined }),
636+resolveProviderAuth: () => ({
637+apiKey: undefined,
638+discoveryApiKey: undefined,
639+mode: "none",
640+source: "none",
636641}),
637-).resolves.toEqual({
638-provider: {
639-baseUrl: "https://gateway.ai.cloudflare.com/v1/acc-123/gw-456/anthropic",
640-api: "anthropic-messages",
641-apiKey: "CLOUDFLARE_AI_GATEWAY_API_KEY",
642-models: [expect.objectContaining({ id: "claude-sonnet-4-6" })],
643-},
644642});
643+const provider = expectProviderFields(result, {
644+baseUrl: "https://gateway.ai.cloudflare.com/v1/acc-123/gw-456/anthropic",
645+api: "anthropic-messages",
646+apiKey: "CLOUDFLARE_AI_GATEWAY_API_KEY",
647+});
648+expect(providerModelIds(provider)).toEqual(["claude-sonnet-4-6"]);
645649});
646650});
647651}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。