crewly 1.20.274 → 1.20.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/roles/team-leader/tl-addon.md +7 -0
- package/config/skills/team-leader/propose-tier-change/SKILL.md +62 -0
- package/config/skills/team-leader/propose-tier-change/execute.sh +64 -0
- package/config/skills/team-leader/propose-tier-change/execute.test.sh +75 -0
- package/dist/backend/backend/src/constants.d.ts +46 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +53 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/request-types.d.ts +2 -0
- package/dist/backend/backend/src/controllers/request-types.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team-model-tiers.controller.d.ts +41 -0
- package/dist/backend/backend/src/controllers/team/team-model-tiers.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/team/team-model-tiers.controller.js +112 -0
- package/dist/backend/backend/src/controllers/team/team-model-tiers.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/team/team.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.controller.js +12 -0
- package/dist/backend/backend/src/controllers/team/team.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/team/team.routes.js +6 -0
- package/dist/backend/backend/src/controllers/team/team.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +5 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js +16 -0
- package/dist/backend/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/index.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/model-tiers.module.d.ts +34 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/model-tiers.module.d.ts.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/model-tiers.module.js +54 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/model-tiers.module.js.map +1 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +2 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +13 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts +2 -0
- package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/decisions/decision.service.js +1 -0
- package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/backend/backend/src/services/model-tiers/model-tier.service.d.ts +251 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.service.js +701 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.service.js.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.store.d.ts +82 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.store.js +80 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.store.js.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.wiring.d.ts +28 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.wiring.js +56 -0
- package/dist/backend/backend/src/services/model-tiers/model-tier.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/tier-quality.d.ts +102 -0
- package/dist/backend/backend/src/services/model-tiers/tier-quality.d.ts.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/tier-quality.js +116 -0
- package/dist/backend/backend/src/services/model-tiers/tier-quality.js.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/tier-usage-report.d.ts +86 -0
- package/dist/backend/backend/src/services/model-tiers/tier-usage-report.d.ts.map +1 -0
- package/dist/backend/backend/src/services/model-tiers/tier-usage-report.js +148 -0
- package/dist/backend/backend/src/services/model-tiers/tier-usage-report.js.map +1 -0
- package/dist/backend/backend/src/services/skill/skill-permission.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-permission.service.js +1 -0
- package/dist/backend/backend/src/services/skill/skill-permission.service.js.map +1 -1
- package/dist/backend/backend/src/types/decision.types.d.ts +41 -1
- package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +20 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/utils/member-default-model.utils.d.ts +24 -8
- package/dist/backend/backend/src/utils/member-default-model.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/utils/member-default-model.utils.js +33 -7
- package/dist/backend/backend/src/utils/member-default-model.utils.js.map +1 -1
- package/dist/backend/backend/src/utils/model-tier.utils.d.ts +68 -0
- package/dist/backend/backend/src/utils/model-tier.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/model-tier.utils.js +111 -0
- package/dist/backend/backend/src/utils/model-tier.utils.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +46 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +53 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-builder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-builder.service.js +16 -0
- package/dist/cli/backend/src/services/ai/prompt-builder.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/model-tiers.module.d.ts +34 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/model-tiers.module.d.ts.map +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/model-tiers.module.js +54 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/model-tiers.module.js.map +1 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js +2 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-assembly.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts +13 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/prompt-module.interface.js.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts +2 -0
- package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/decisions/decision.service.js +1 -0
- package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
- package/dist/cli/backend/src/types/decision.types.d.ts +41 -1
- package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +20 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/backend/src/utils/member-default-model.utils.d.ts +24 -8
- package/dist/cli/backend/src/utils/member-default-model.utils.d.ts.map +1 -1
- package/dist/cli/backend/src/utils/member-default-model.utils.js +33 -7
- package/dist/cli/backend/src/utils/member-default-model.utils.js.map +1 -1
- package/dist/cli/backend/src/utils/model-tier.utils.d.ts +68 -0
- package/dist/cli/backend/src/utils/model-tier.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/model-tier.utils.js +111 -0
- package/dist/cli/backend/src/utils/model-tier.utils.js.map +1 -0
- package/frontend/dist/assets/{index-7e5ebf78.js → index-368419df.js} +266 -266
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
* `modelId` always wins, and the orchestrator is never touched.
|
|
9
9
|
*
|
|
10
10
|
* `CREWLY_MEMBER_DEFAULT_MODEL` replaces `sonnet`; `''` or `off` turns the
|
|
11
|
-
* default off entirely.
|
|
11
|
+
* default off entirely. A member's tier (crewly#1173) comes before this
|
|
12
|
+
* default: explicit `modelId` > tier model > reviewed default > runtime default.
|
|
12
13
|
*
|
|
13
14
|
* @module utils/member-default-model
|
|
14
15
|
*/
|
|
15
16
|
import { MEMBER_MODEL_DEFAULT_CONSTANTS, ORCHESTRATOR_SESSION_NAME, RUNTIME_TYPES } from '../constants.js';
|
|
16
17
|
import { isTeamLead, pickTeamLead } from './team.utils.js';
|
|
18
|
+
import { resolveTierModel } from './model-tier.utils.js';
|
|
17
19
|
/**
|
|
18
20
|
* The model reviewed members get when they have none, after the env override.
|
|
19
21
|
*
|
|
@@ -78,9 +80,24 @@ export function defaultModelForMember(team, member, env = process.env) {
|
|
|
78
80
|
return null;
|
|
79
81
|
return reviewedMemberDefaultModel(env);
|
|
80
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* The model of a member's tier on a runtime (crewly#1173), or undefined when
|
|
85
|
+
* it has no tier or the runtime has no model for it.
|
|
86
|
+
*
|
|
87
|
+
* @param team - The member's team (its `tierModels` override the global map)
|
|
88
|
+
* @param member - The member
|
|
89
|
+
* @param runtime - Runtime that launches
|
|
90
|
+
* @returns Model id, or undefined
|
|
91
|
+
*/
|
|
92
|
+
export function tierModelForMember(team, member, runtime) {
|
|
93
|
+
if (member.role === 'orchestrator' || member.sessionName === ORCHESTRATOR_SESSION_NAME)
|
|
94
|
+
return undefined;
|
|
95
|
+
return resolveTierModel(runtime, member.tier, team.tierModels);
|
|
96
|
+
}
|
|
81
97
|
/**
|
|
82
98
|
* The model id a member launches with: its own `modelId` when set, else the
|
|
83
|
-
*
|
|
99
|
+
* model of its tier on its runtime (crewly#1173), else the reviewed-member
|
|
100
|
+
* default from {@link defaultModelForMember}.
|
|
84
101
|
*
|
|
85
102
|
* @param team - The member's team
|
|
86
103
|
* @param member - The member
|
|
@@ -90,6 +107,9 @@ export function defaultModelForMember(team, member, env = process.env) {
|
|
|
90
107
|
export function effectiveMemberModelId(team, member, env = process.env) {
|
|
91
108
|
if (member.modelId)
|
|
92
109
|
return member.modelId;
|
|
110
|
+
const tiered = tierModelForMember(team, member, member.runtimeType ?? RUNTIME_TYPES.CLAUDE_CODE);
|
|
111
|
+
if (tiered)
|
|
112
|
+
return tiered;
|
|
93
113
|
return defaultModelForMember(team, member, env) ?? undefined;
|
|
94
114
|
}
|
|
95
115
|
/** Model names Claude Code accepts: the aliases, or a full `claude-*` id. */
|
|
@@ -98,8 +118,10 @@ const CLAUDE_MODEL_PATTERN = /^(sonnet|opus|haiku|opusplan|default|claude-[A-Za-
|
|
|
98
118
|
* The model a member launches with when it runs on a fallback runtime (its
|
|
99
119
|
* own runtime is out of usage). The member's `modelId` is kept only when the
|
|
100
120
|
* fallback runtime can use it (a Claude alias / `claude-*` id for Claude Code;
|
|
101
|
-
* a Codex `gpt-*` id is ignored). Otherwise
|
|
102
|
-
*
|
|
121
|
+
* a Codex `gpt-*` id is ignored). Otherwise its tier's model on the fallback
|
|
122
|
+
* runtime applies (a tier is runtime-neutral, crewly#1173), then the
|
|
123
|
+
* reviewed-member default for that runtime. Other fallback runtimes without a
|
|
124
|
+
* tier model get no model (their own default).
|
|
103
125
|
*
|
|
104
126
|
* @param team - The member's team
|
|
105
127
|
* @param member - The member (its configured runtime does not matter here)
|
|
@@ -108,11 +130,15 @@ const CLAUDE_MODEL_PATTERN = /^(sonnet|opus|haiku|opusplan|default|claude-[A-Za-
|
|
|
108
130
|
* @returns Model id for the fallback runtime, or undefined for its own default
|
|
109
131
|
*/
|
|
110
132
|
export function fallbackRuntimeModelId(team, member, fallbackRuntime, env = process.env) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const own = member.modelId && CLAUDE_MODEL_PATTERN.test(member.modelId.trim()) ? member.modelId : undefined;
|
|
133
|
+
const isClaude = fallbackRuntime === RUNTIME_TYPES.CLAUDE_CODE;
|
|
134
|
+
const own = isClaude && member.modelId && CLAUDE_MODEL_PATTERN.test(member.modelId.trim()) ? member.modelId : undefined;
|
|
114
135
|
if (own)
|
|
115
136
|
return own;
|
|
137
|
+
const tiered = tierModelForMember(team, member, fallbackRuntime);
|
|
138
|
+
if (tiered)
|
|
139
|
+
return tiered;
|
|
140
|
+
if (!isClaude)
|
|
141
|
+
return undefined;
|
|
116
142
|
return defaultModelForMember(team, { ...member, modelId: undefined, runtimeType: fallbackRuntime }, env) ?? undefined;
|
|
117
143
|
}
|
|
118
144
|
//# sourceMappingURL=member-default-model.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"member-default-model.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/member-default-model.utils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"member-default-model.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/member-default-model.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model tiers (crewly#1173, specs/2026-10-08-model-tiers.md).
|
|
3
|
+
*
|
|
4
|
+
* A member may carry a tier (`strong` | `mid` | `weak`) instead of a concrete
|
|
5
|
+
* model. At launch the tier resolves to a model for the runtime that really
|
|
6
|
+
* runs: the team's own map (`Team.tierModels`) first, then the global map
|
|
7
|
+
* (`MODEL_TIER_CONSTANTS.DEFAULT_TIER_MODELS`). A runtime without a `weak`
|
|
8
|
+
* model uses its `mid` model; any other unmapped tier resolves to nothing
|
|
9
|
+
* (the runtime's own default).
|
|
10
|
+
*
|
|
11
|
+
* @module utils/model-tier
|
|
12
|
+
*/
|
|
13
|
+
import type { ModelTier, TeamTierModels } from '../types/index.js';
|
|
14
|
+
/** Tiers, strongest first. */
|
|
15
|
+
export declare const MODEL_TIERS: readonly ModelTier[];
|
|
16
|
+
/**
|
|
17
|
+
* Whether a value names a tier.
|
|
18
|
+
*
|
|
19
|
+
* @param value - Candidate
|
|
20
|
+
* @returns True for `strong`, `mid` or `weak`
|
|
21
|
+
*/
|
|
22
|
+
export declare function isModelTier(value: unknown): value is ModelTier;
|
|
23
|
+
/**
|
|
24
|
+
* Rank of a tier: 2 = strong, 1 = mid, 0 = weak.
|
|
25
|
+
*
|
|
26
|
+
* @param tier - Tier
|
|
27
|
+
* @returns Rank (higher is stronger)
|
|
28
|
+
*/
|
|
29
|
+
export declare function tierRank(tier: ModelTier): number;
|
|
30
|
+
/**
|
|
31
|
+
* The tier → model map for one runtime: the global map with the team's
|
|
32
|
+
* overrides on top. Overrides that are not shell-safe model ids are ignored.
|
|
33
|
+
*
|
|
34
|
+
* @param runtime - Runtime id (`claude-code`, `codex-cli`, …)
|
|
35
|
+
* @param overrides - The team's `tierModels`
|
|
36
|
+
* @returns Map with only the tiers that have a model
|
|
37
|
+
*/
|
|
38
|
+
export declare function tierMapFor(runtime: string, overrides?: TeamTierModels): Partial<Record<ModelTier, string>>;
|
|
39
|
+
/**
|
|
40
|
+
* The model a tier runs on for a runtime.
|
|
41
|
+
*
|
|
42
|
+
* @param runtime - Runtime that launches
|
|
43
|
+
* @param tier - The member's tier
|
|
44
|
+
* @param overrides - The team's `tierModels`
|
|
45
|
+
* @returns Model id, or undefined for the runtime's own default
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* resolveTierModel('claude-code', 'weak'); // 'haiku'
|
|
50
|
+
* resolveTierModel('codex-cli', 'weak'); // 'gpt-5.4' (no weak model: mid)
|
|
51
|
+
* resolveTierModel('crewly-agent', 'strong'); // undefined
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveTierModel(runtime: string, tier: ModelTier | undefined, overrides?: TeamTierModels): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Validate a team's `tierModels` payload.
|
|
57
|
+
*
|
|
58
|
+
* @param value - Candidate (`{ runtime: { tier: model } }`)
|
|
59
|
+
* @returns The cleaned map, or an error message
|
|
60
|
+
*/
|
|
61
|
+
export declare function parseTierModels(value: unknown): {
|
|
62
|
+
ok: true;
|
|
63
|
+
value: TeamTierModels;
|
|
64
|
+
} | {
|
|
65
|
+
ok: false;
|
|
66
|
+
error: string;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=model-tier.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-tier.utils.d.ts","sourceRoot":"","sources":["../../../../../backend/src/utils/model-tier.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGnE,8BAA8B;AAC9B,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAA+B,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEhD;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAS1G;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAM7H;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiBlH"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model tiers (crewly#1173, specs/2026-10-08-model-tiers.md).
|
|
3
|
+
*
|
|
4
|
+
* A member may carry a tier (`strong` | `mid` | `weak`) instead of a concrete
|
|
5
|
+
* model. At launch the tier resolves to a model for the runtime that really
|
|
6
|
+
* runs: the team's own map (`Team.tierModels`) first, then the global map
|
|
7
|
+
* (`MODEL_TIER_CONSTANTS.DEFAULT_TIER_MODELS`). A runtime without a `weak`
|
|
8
|
+
* model uses its `mid` model; any other unmapped tier resolves to nothing
|
|
9
|
+
* (the runtime's own default).
|
|
10
|
+
*
|
|
11
|
+
* @module utils/model-tier
|
|
12
|
+
*/
|
|
13
|
+
import { MODEL_TIER_CONSTANTS } from '../constants.js';
|
|
14
|
+
import { isSafeModelId } from './runtime-model-flags.utils.js';
|
|
15
|
+
/** Tiers, strongest first. */
|
|
16
|
+
export const MODEL_TIERS = MODEL_TIER_CONSTANTS.TIERS;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a value names a tier.
|
|
19
|
+
*
|
|
20
|
+
* @param value - Candidate
|
|
21
|
+
* @returns True for `strong`, `mid` or `weak`
|
|
22
|
+
*/
|
|
23
|
+
export function isModelTier(value) {
|
|
24
|
+
return typeof value === 'string' && MODEL_TIERS.includes(value);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Rank of a tier: 2 = strong, 1 = mid, 0 = weak.
|
|
28
|
+
*
|
|
29
|
+
* @param tier - Tier
|
|
30
|
+
* @returns Rank (higher is stronger)
|
|
31
|
+
*/
|
|
32
|
+
export function tierRank(tier) {
|
|
33
|
+
return MODEL_TIERS.length - 1 - MODEL_TIERS.indexOf(tier);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The tier → model map for one runtime: the global map with the team's
|
|
37
|
+
* overrides on top. Overrides that are not shell-safe model ids are ignored.
|
|
38
|
+
*
|
|
39
|
+
* @param runtime - Runtime id (`claude-code`, `codex-cli`, …)
|
|
40
|
+
* @param overrides - The team's `tierModels`
|
|
41
|
+
* @returns Map with only the tiers that have a model
|
|
42
|
+
*/
|
|
43
|
+
export function tierMapFor(runtime, overrides) {
|
|
44
|
+
const base = MODEL_TIER_CONSTANTS.DEFAULT_TIER_MODELS[runtime] ?? {};
|
|
45
|
+
const own = overrides?.[runtime] ?? {};
|
|
46
|
+
const out = {};
|
|
47
|
+
for (const tier of MODEL_TIERS) {
|
|
48
|
+
const candidate = typeof own[tier] === 'string' && own[tier].trim() && isSafeModelId(own[tier].trim()) ? own[tier].trim() : base[tier];
|
|
49
|
+
if (candidate)
|
|
50
|
+
out[tier] = candidate;
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The model a tier runs on for a runtime.
|
|
56
|
+
*
|
|
57
|
+
* @param runtime - Runtime that launches
|
|
58
|
+
* @param tier - The member's tier
|
|
59
|
+
* @param overrides - The team's `tierModels`
|
|
60
|
+
* @returns Model id, or undefined for the runtime's own default
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* resolveTierModel('claude-code', 'weak'); // 'haiku'
|
|
65
|
+
* resolveTierModel('codex-cli', 'weak'); // 'gpt-5.4' (no weak model: mid)
|
|
66
|
+
* resolveTierModel('crewly-agent', 'strong'); // undefined
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function resolveTierModel(runtime, tier, overrides) {
|
|
70
|
+
if (!isModelTier(tier))
|
|
71
|
+
return undefined;
|
|
72
|
+
const map = tierMapFor(runtime, overrides);
|
|
73
|
+
if (map[tier])
|
|
74
|
+
return map[tier];
|
|
75
|
+
if (tier === 'weak')
|
|
76
|
+
return map.mid;
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate a team's `tierModels` payload.
|
|
81
|
+
*
|
|
82
|
+
* @param value - Candidate (`{ runtime: { tier: model } }`)
|
|
83
|
+
* @returns The cleaned map, or an error message
|
|
84
|
+
*/
|
|
85
|
+
export function parseTierModels(value) {
|
|
86
|
+
if (value === null || value === undefined)
|
|
87
|
+
return { ok: true, value: {} };
|
|
88
|
+
if (typeof value !== 'object' || Array.isArray(value))
|
|
89
|
+
return { ok: false, error: 'tierModels must be an object: { "<runtime>": { "strong"|"mid"|"weak": "<model>" } }' };
|
|
90
|
+
const out = {};
|
|
91
|
+
for (const [runtime, tiers] of Object.entries(value)) {
|
|
92
|
+
if (!/^[a-z][a-z0-9-]{1,40}$/.test(runtime))
|
|
93
|
+
return { ok: false, error: `Unknown runtime "${runtime}"` };
|
|
94
|
+
if (tiers === null || typeof tiers !== 'object' || Array.isArray(tiers))
|
|
95
|
+
return { ok: false, error: `tierModels.${runtime} must be an object of tier → model` };
|
|
96
|
+
const entry = {};
|
|
97
|
+
for (const [tier, model] of Object.entries(tiers)) {
|
|
98
|
+
if (!isModelTier(tier))
|
|
99
|
+
return { ok: false, error: `Unknown tier "${tier}" (use strong, mid or weak)` };
|
|
100
|
+
if (model === '' || model === null || model === undefined)
|
|
101
|
+
continue;
|
|
102
|
+
if (typeof model !== 'string' || !isSafeModelId(model.trim()))
|
|
103
|
+
return { ok: false, error: `Invalid model for ${runtime}.${tier}: use the model name as the runtime expects it` };
|
|
104
|
+
entry[tier] = model.trim();
|
|
105
|
+
}
|
|
106
|
+
if (Object.keys(entry).length > 0)
|
|
107
|
+
out[runtime] = entry;
|
|
108
|
+
}
|
|
109
|
+
return { ok: true, value: out };
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=model-tier.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-tier.utils.js","sourceRoot":"","sources":["../../../../../backend/src/utils/model-tier.utils.ts"],"names":[],"mappings":"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"}
|