opencode-selection.ts 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import {
  2. pickBestModel,
  3. pickPrimaryAndSupport,
  4. type ScoreFunction,
  5. } from './model-selection';
  6. import type { OpenCodeFreeModel } from './types';
  7. const scoreOpenCodePrimaryForCoding: ScoreFunction<OpenCodeFreeModel> = (
  8. model,
  9. ) => {
  10. return (
  11. (model.reasoning ? 100 : 0) +
  12. (model.toolcall ? 80 : 0) +
  13. (model.attachment ? 20 : 0) +
  14. Math.min(model.contextLimit, 1_000_000) / 10_000 +
  15. Math.min(model.outputLimit, 300_000) / 10_000 +
  16. (model.status === 'active' ? 10 : 0)
  17. );
  18. };
  19. function speedBonus(modelName: string): number {
  20. const lower = modelName.toLowerCase();
  21. let score = 0;
  22. if (lower.includes('nano')) score += 60;
  23. if (lower.includes('flash')) score += 45;
  24. if (lower.includes('mini')) score += 25;
  25. if (lower.includes('preview')) score += 10;
  26. return score;
  27. }
  28. const scoreOpenCodeSupportForCoding: ScoreFunction<OpenCodeFreeModel> = (
  29. model,
  30. ) => {
  31. return (
  32. (model.toolcall ? 90 : 0) +
  33. (model.reasoning ? 50 : 0) +
  34. speedBonus(model.model) +
  35. Math.min(model.contextLimit, 400_000) / 20_000 +
  36. (model.status === 'active' ? 5 : 0)
  37. );
  38. };
  39. export function pickBestCodingOpenCodeModel(
  40. models: OpenCodeFreeModel[],
  41. ): OpenCodeFreeModel | null {
  42. return pickBestModel(models, scoreOpenCodePrimaryForCoding);
  43. }
  44. export function pickSupportOpenCodeModel(
  45. models: OpenCodeFreeModel[],
  46. primaryModel?: string,
  47. ): OpenCodeFreeModel | null {
  48. const { support } = pickPrimaryAndSupport(
  49. models,
  50. {
  51. primary: scoreOpenCodePrimaryForCoding,
  52. support: scoreOpenCodeSupportForCoding,
  53. },
  54. primaryModel,
  55. );
  56. return support;
  57. }