@adhdev/mesh-shared 1.0.82-rc.22 → 1.0.82-rc.24

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.
@@ -1,3 +1,4 @@
1
+ import { parseRoleLaunchSelection, type RoleLaunchSelection } from './role-launch'
1
2
  /**
2
3
  * session-launch — how a session was launched: provider, model and thinking
3
4
  * level, and WHERE each value came from.
@@ -35,11 +36,14 @@ export const MODEL_AXIS_SOURCES = [
35
36
  'user',
36
37
  /** The dashboard dialog restored it from the last launch (browser-local memory). */
37
38
  'remembered',
39
+ /** The authoritative daemon role default or host project override. */
40
+ 'stored_default',
41
+ 'project_default',
38
42
  /** A mesh capability slot supplied it (or a difficulty preset the slot outranked). */
39
43
  'mesh_slot',
40
44
  /** An explicit per-task model / thinking level on a mesh queue task. */
41
45
  'task_override',
42
- /** Nothing was requested; the provider's default is known (discovery / manifest). */
46
+ /** Nothing requested: the provider chooses; resolvedDefault records it when known. */
43
47
  'provider_default',
44
48
  /** A value was requested without saying where it came from, or nothing is known. */
45
49
  'unspecified',
@@ -102,6 +106,7 @@ export interface ModelSelection {
102
106
  }
103
107
 
104
108
  export interface SessionLaunchRecord {
109
+ roleLaunch?: RoleLaunchSelection
105
110
  sessionId: string
106
111
  providerType: string
107
112
  providerVersion?: string
@@ -230,7 +235,9 @@ export function parseSessionLaunchRecord(raw: unknown): SessionLaunchRecord | un
230
235
  const providerVersion = readString(record.providerVersion)
231
236
  const workspace = readString(record.workspace)
232
237
  const autoApproveModeId = readString(record.autoApproveModeId)
238
+ const roleLaunch = parseRoleLaunchSelection(record.roleLaunch)
233
239
  return {
240
+ ...(roleLaunch ? { roleLaunch } : {}),
234
241
  sessionId,
235
242
  providerType,
236
243
  ...(providerVersion ? { providerVersion } : {}),
@@ -40,6 +40,13 @@ import {
40
40
  export interface CliSlotRecipe {
41
41
  /** Optional model to pin on the slot. Best-effort at launch. */
42
42
  model?: string
43
+ /**
44
+ * Optional ordered candidate models to prefer when the provider's live
45
+ * `modelOptions` (from model discovery) is present on `DetectedCliProvider`.
46
+ * The first candidate present in `modelOptions` wins; falls back to `model`
47
+ * when `modelOptions` is absent or contains none of the candidates.
48
+ */
49
+ modelCandidates?: readonly string[]
43
50
  /** Optional thinking level, in the provider's own vocabulary. */
44
51
  thinkingLevel?: string
45
52
  /** Difficulty range this slot handles. Empty = general-purpose. */
@@ -101,11 +108,26 @@ export const CLI_SLOT_RECIPES: Readonly<Record<string, readonly CliSlotRecipe[]>
101
108
  ],
102
109
  'antigravity-cli': [
103
110
  {
104
- model: 'Gemini 3.1 Pro (High)',
111
+ model: 'Gemini 3.8 Flash (High)',
112
+ modelCandidates: ['Gemini 3.8 Flash (High)', 'Gemini 4 Argon (Low)', 'Gemini 3.7 Flash (High)', 'Gemini 3.1 Pro (High)'],
105
113
  difficulty: ['easy'],
106
114
  maxParallel: 2,
107
115
  rationale: 'Cheap capacity for easy tasks.',
108
116
  },
117
+ {
118
+ model: 'Gemini 4 Argon (Medium)',
119
+ modelCandidates: ['Gemini 4 Argon (Medium)', 'Gemini 3.8 Flash (High)', 'Gemini 3.7 Flash (High)', 'Gemini 3.1 Pro (High)'],
120
+ difficulty: ['medium'],
121
+ maxParallel: 2,
122
+ rationale: 'Balanced Argon tier for medium tasks.',
123
+ },
124
+ {
125
+ model: 'Gemini 4 Argon (High)',
126
+ modelCandidates: ['Gemini 4 Argon (High)', 'Gemini 3.8 Flash (High)', 'Gemini 3.1 Pro (High)'],
127
+ difficulty: ['difficult'],
128
+ maxParallel: 1,
129
+ rationale: 'Reserved for hard tasks; capped at 1 to bound cost.',
130
+ },
109
131
  ],
110
132
  'cursor-cli': [
111
133
  {
@@ -137,6 +159,13 @@ export interface DetectedCliProvider {
137
159
  displayName?: string
138
160
  /** Detected version, when known. Display only — never affects the mapping. */
139
161
  version?: string
162
+ /**
163
+ * Live discovered / resolved `modelOptions` for this provider on the node,
164
+ * when available on the status catalog. When present and non-empty, recipes
165
+ * prefer the first matching model from `[recipe.model, ...recipe.modelCandidates]`
166
+ * that exists in `modelOptions`.
167
+ */
168
+ modelOptions?: readonly string[]
140
169
  }
141
170
 
142
171
  /** One proposed slot plus why it was proposed. */
@@ -197,6 +226,36 @@ function dedupeDetected(detected: readonly DetectedCliProvider[]): DetectedCliPr
197
226
  return out
198
227
  }
199
228
 
229
+ /**
230
+ * Resolve a recipe's pinned model against the provider's live `modelOptions`
231
+ * (populated from the daemon's model-discovery overlay when available). If
232
+ * `modelOptions` is absent or none of the recipe's candidates appear in it,
233
+ * falls back to `recipe.model`.
234
+ */
235
+ function resolveRecipeModel(
236
+ recipe: CliSlotRecipe,
237
+ modelOptions: readonly string[] | undefined,
238
+ ): string | undefined {
239
+ if (!Array.isArray(modelOptions) || modelOptions.length === 0) {
240
+ return recipe.model
241
+ }
242
+ const available = new Set(
243
+ modelOptions
244
+ .filter((m): m is string => typeof m === 'string' && m.trim().length > 0)
245
+ .map(m => m.trim()),
246
+ )
247
+ if (available.size === 0) return recipe.model
248
+ const candidates = [
249
+ ...(recipe.model ? [recipe.model] : []),
250
+ ...(recipe.modelCandidates ?? []),
251
+ ]
252
+ for (const candidate of candidates) {
253
+ const trimmed = typeof candidate === 'string' ? candidate.trim() : ''
254
+ if (trimmed && available.has(trimmed)) return trimmed
255
+ }
256
+ return recipe.model
257
+ }
258
+
200
259
  /**
201
260
  * Build a capability-slot proposal from a node's detected CLI providers.
202
261
  *
@@ -229,7 +288,7 @@ export function buildSlotProposal(
229
288
  // a proposal can never preview a shape the write would reshape.
230
289
  const slot = normalizeNodeCapabilitySlot({
231
290
  provider: provider.type,
232
- model: recipe.model,
291
+ model: resolveRecipeModel(recipe, provider.modelOptions),
233
292
  thinkingLevel: recipe.thinkingLevel,
234
293
  difficulty: recipe.difficulty,
235
294
  maxParallel: recipe.maxParallel,
@@ -40,6 +40,10 @@ export const WORKER_TOOLS = [
40
40
  'git_status',
41
41
  'git_log',
42
42
  'git_diff',
43
+ 'driver_list',
44
+ 'driver_describe',
45
+ 'driver_invoke',
46
+ 'artifact_register',
43
47
  ] as const
44
48
 
45
49
  export type WorkerTool = typeof WORKER_TOOLS[number]