@shapeshift-labs/frontier-swarm 0.5.28 → 0.5.29

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/dist/index.js CHANGED
@@ -403,6 +403,7 @@ export function createSwarmPlan(manifestInput, taskInput, options = {}) {
403
403
  id,
404
404
  runId: options.runId ?? id.replace(/^swarm-plan:/, 'swarm-run:'),
405
405
  manifestId: compiled.manifest.id,
406
+ manifest: compiled.manifest,
406
407
  createdAt: options.now ?? Date.now(),
407
408
  filters: {
408
409
  lanes: options.lanes ? [...options.lanes] : undefined,
@@ -8936,6 +8937,251 @@ function normalizeRouterPolicy(input) {
8936
8937
  }
8937
8938
  return createSwarmModelRoutingPolicy(input);
8938
8939
  }
8940
+ function normalizeSwarmTelemetryRecords(records) {
8941
+ return records.map(normalizeSwarmTelemetryRecord).filter((record) => !!(record.jobId || record.computeId || record.model));
8942
+ }
8943
+ function normalizeSwarmTelemetryRecord(input) {
8944
+ const metadata = toJsonObject(input.metadata);
8945
+ const computeId = normalizeOptionalString(input.computeId) ?? normalizeOptionalString(input.compute);
8946
+ const model = normalizeOptionalString(input.model);
8947
+ const workKind = normalizeOptionalString(input.workKind);
8948
+ const taskKind = normalizeOptionalString(input.taskKind);
8949
+ const lane = normalizeOptionalString(input.lane);
8950
+ return {
8951
+ ...(normalizeOptionalString(input.id) ? { id: normalizeOptionalString(input.id) } : {}),
8952
+ ...(readNonNegativeNumber(input.generatedAt) !== undefined ? { generatedAt: readNonNegativeNumber(input.generatedAt) } : {}),
8953
+ ...(normalizeOptionalString(input.runId) ? { runId: normalizeOptionalString(input.runId) } : {}),
8954
+ ...(normalizeOptionalString(input.planId) ? { planId: normalizeOptionalString(input.planId) } : {}),
8955
+ ...(normalizeOptionalString(input.jobId) ? { jobId: normalizeOptionalString(input.jobId) } : {}),
8956
+ ...(normalizeOptionalString(input.taskId) ? { taskId: normalizeOptionalString(input.taskId) } : {}),
8957
+ ...(lane ? { lane } : {}),
8958
+ ...(normalizeOptionalString(input.layer) ? { layer: normalizeOptionalString(input.layer) } : {}),
8959
+ ...(workKind ? { workKind } : {}),
8960
+ ...(taskKind ? { taskKind } : {}),
8961
+ ...(computeId ? { computeId } : {}),
8962
+ ...(normalizeOptionalString(input.computeKind) ? { computeKind: normalizeOptionalString(input.computeKind) } : {}),
8963
+ ...(model ? { model } : {}),
8964
+ ...(normalizeOptionalString(input.modelTier) ? { modelTier: normalizeOptionalString(input.modelTier) } : {}),
8965
+ ...(normalizeOptionalString(input.reasoningEffort) ? { reasoningEffort: normalizeOptionalString(input.reasoningEffort) } : {}),
8966
+ ...(normalizeOptionalString(input.serviceTier) ? { serviceTier: normalizeOptionalString(input.serviceTier) } : {}),
8967
+ ...(normalizeOptionalString(input.status) ? { status: normalizeOptionalString(input.status) } : {}),
8968
+ ...(normalizeOptionalString(input.mergeReadiness) ? { mergeReadiness: normalizeOptionalString(input.mergeReadiness) } : {}),
8969
+ ...(normalizeOptionalString(input.mergeDisposition) ? { mergeDisposition: normalizeOptionalString(input.mergeDisposition) } : {}),
8970
+ durationMs: readNonNegativeNumber(input.durationMs) ?? 0,
8971
+ estimatedCostUsd: readNonNegativeNumber(input.estimatedCostUsd) ?? 0,
8972
+ estimatedInputCostUsd: readNonNegativeNumber(input.estimatedInputCostUsd) ?? 0,
8973
+ estimatedOutputCostUsd: readNonNegativeNumber(input.estimatedOutputCostUsd) ?? 0,
8974
+ billableInputTokens: readNonNegativeNumber(input.billableInputTokens) ?? 0,
8975
+ outputTokens: readNonNegativeNumber(input.outputTokens) ?? 0,
8976
+ priceKnown: input.priceKnown === true,
8977
+ costEstimateInputOnly: input.costEstimateInputOnly === true,
8978
+ costEstimateMissingOutputTokens: input.costEstimateMissingOutputTokens === true,
8979
+ verificationTotal: readNonNegativeNumber(input.verificationTotal) ?? 0,
8980
+ verificationPassed: readNonNegativeNumber(input.verificationPassed) ?? 0,
8981
+ verificationFailed: readNonNegativeNumber(input.verificationFailed) ?? 0,
8982
+ verificationRequiredFailed: readNonNegativeNumber(input.verificationRequiredFailed) ?? 0,
8983
+ ownershipViolationCount: readNonNegativeNumber(input.ownershipViolationCount) ?? 0,
8984
+ changedPathCount: readNonNegativeNumber(input.changedPathCount) ?? 0,
8985
+ evidencePathCount: readNonNegativeNumber(input.evidencePathCount) ?? 0,
8986
+ humanActionCount: readNonNegativeNumber(input.humanActionCount) ?? 0,
8987
+ openHumanActionCount: readNonNegativeNumber(input.openHumanActionCount) ?? 0,
8988
+ semanticImportPresent: input.semanticImportPresent === true,
8989
+ ...(metadata ? { metadata } : {})
8990
+ };
8991
+ }
8992
+ function telemetryRecordToRoutingFeedback(record, generatedAt) {
8993
+ const evidenceScore = telemetryEvidenceScore(record);
8994
+ return createSwarmModelRoutingFeedback({
8995
+ scope: record.taskId ? 'task' : record.lane ? 'lane' : 'global',
8996
+ runId: record.runId,
8997
+ planId: record.planId,
8998
+ jobId: record.jobId,
8999
+ taskId: record.taskId,
9000
+ lane: record.lane,
9001
+ layer: record.layer,
9002
+ workKind: record.workKind,
9003
+ taskKind: record.taskKind ?? record.workKind,
9004
+ computeId: record.computeId,
9005
+ computeKind: record.computeKind,
9006
+ model: record.model,
9007
+ modelTier: record.modelTier,
9008
+ reasoningEffort: record.reasoningEffort,
9009
+ serviceTier: record.serviceTier,
9010
+ resultStatus: record.status,
9011
+ mergeReadiness: record.mergeReadiness,
9012
+ mergeDisposition: record.mergeDisposition,
9013
+ evidenceQuality: {
9014
+ band: evidenceScore >= 0.85 ? 'strong' : evidenceScore >= 0.6 ? 'adequate' : evidenceScore > 0 ? 'weak' : 'missing',
9015
+ score: evidenceScore,
9016
+ confidence: telemetryConfidence(record)
9017
+ },
9018
+ selected: true,
9019
+ tags: uniqueStrings([
9020
+ record.status,
9021
+ record.mergeReadiness,
9022
+ record.mergeDisposition,
9023
+ record.priceKnown === false ? 'unknown-price' : undefined,
9024
+ (record.verificationRequiredFailed ?? 0) > 0 ? 'required-verification-failed' : undefined,
9025
+ (record.openHumanActionCount ?? 0) > 0 ? 'open-human-action' : undefined
9026
+ ]),
9027
+ generatedAt: record.generatedAt ?? generatedAt,
9028
+ metadata: {
9029
+ telemetryRecordId: record.id,
9030
+ durationMs: record.durationMs,
9031
+ estimatedCostUsd: record.estimatedCostUsd,
9032
+ estimatedInputCostUsd: record.estimatedInputCostUsd,
9033
+ estimatedOutputCostUsd: record.estimatedOutputCostUsd,
9034
+ billableInputTokens: record.billableInputTokens,
9035
+ outputTokens: record.outputTokens,
9036
+ priceKnown: record.priceKnown,
9037
+ costEstimateInputOnly: record.costEstimateInputOnly,
9038
+ costEstimateMissingOutputTokens: record.costEstimateMissingOutputTokens,
9039
+ verificationTotal: record.verificationTotal,
9040
+ verificationPassed: record.verificationPassed,
9041
+ verificationFailed: record.verificationFailed,
9042
+ verificationRequiredFailed: record.verificationRequiredFailed,
9043
+ humanActionCount: record.humanActionCount,
9044
+ openHumanActionCount: record.openHumanActionCount,
9045
+ semanticImportPresent: record.semanticImportPresent
9046
+ }
9047
+ });
9048
+ }
9049
+ function createTelemetryRoutingSignals(records, input, generatedAt) {
9050
+ const minSamples = Math.max(1, Math.floor(input.minSamples ?? 1));
9051
+ const preferSuccessRate = clamp01(input.preferSuccessRate ?? 0.82);
9052
+ const avoidSuccessRate = clamp01(input.avoidSuccessRate ?? 0.45);
9053
+ const highCostUsd = readNonNegativeNumber(input.highCostUsd);
9054
+ const byCompute = new Map();
9055
+ for (const record of records) {
9056
+ const key = record.computeId ?? record.model;
9057
+ if (!key)
9058
+ continue;
9059
+ byCompute.set(key, [...(byCompute.get(key) ?? []), record]);
9060
+ }
9061
+ const signals = [];
9062
+ for (const [computeId, group] of byCompute) {
9063
+ if (group.length < minSamples)
9064
+ continue;
9065
+ const scores = group.map(telemetrySuccessScore);
9066
+ const successRate = scores.reduce((sum, score) => sum + score, 0) / Math.max(1, scores.length);
9067
+ const requiredFailed = group.reduce((sum, record) => sum + (record.verificationRequiredFailed ?? 0), 0);
9068
+ const openHumanActions = group.reduce((sum, record) => sum + (record.openHumanActionCount ?? 0), 0);
9069
+ const knownCosts = group.map((record) => record.estimatedCostUsd).filter((value) => value !== undefined && value > 0);
9070
+ const averageCostUsd = knownCosts.length ? knownCosts.reduce((sum, value) => sum + value, 0) / knownCosts.length : undefined;
9071
+ const confidence = group.length >= 5 ? 'high' : group.length >= 2 ? 'medium' : 'low';
9072
+ const common = {
9073
+ computeId,
9074
+ confidence: confidence,
9075
+ metadata: {
9076
+ source: 'frontier-swarm-routing-controller',
9077
+ sampleCount: group.length,
9078
+ successRate: roundScore(successRate),
9079
+ requiredFailed,
9080
+ openHumanActions,
9081
+ generatedAt,
9082
+ ...(averageCostUsd !== undefined ? { averageCostUsd } : {})
9083
+ }
9084
+ };
9085
+ if (successRate <= avoidSuccessRate || requiredFailed > 0 || openHumanActions > 0) {
9086
+ signals.push({
9087
+ ...common,
9088
+ mode: 'avoid',
9089
+ reason: requiredFailed > 0
9090
+ ? 'telemetry-required-verification-failed'
9091
+ : openHumanActions > 0
9092
+ ? 'telemetry-human-action-open'
9093
+ : 'telemetry-low-success-rate'
9094
+ });
9095
+ }
9096
+ else if (successRate >= preferSuccessRate && (highCostUsd === undefined || averageCostUsd === undefined || averageCostUsd <= highCostUsd)) {
9097
+ signals.push({
9098
+ ...common,
9099
+ mode: 'prefer',
9100
+ reason: 'telemetry-high-success-rate'
9101
+ });
9102
+ }
9103
+ else {
9104
+ signals.push({
9105
+ ...common,
9106
+ mode: 'observe',
9107
+ reason: averageCostUsd !== undefined && highCostUsd !== undefined && averageCostUsd > highCostUsd
9108
+ ? 'telemetry-high-cost-observed'
9109
+ : 'telemetry-insufficient-routing-pressure'
9110
+ });
9111
+ }
9112
+ }
9113
+ return signals;
9114
+ }
9115
+ function dedupeModelRoutingPolicySignals(signals) {
9116
+ const byKey = new Map();
9117
+ for (const signal of signals) {
9118
+ const key = [
9119
+ signal.mode ?? 'observe',
9120
+ signal.lane ?? '',
9121
+ signal.layer ?? '',
9122
+ signal.workKind ?? signal.taskKind ?? '',
9123
+ signal.computeId ?? '',
9124
+ signal.model ?? '',
9125
+ signal.modelTier ?? ''
9126
+ ].join('\u0000');
9127
+ byKey.set(key, { ...signal });
9128
+ }
9129
+ return Array.from(byKey.values());
9130
+ }
9131
+ function routingSignalToControllerDecision(signal, generatedAt) {
9132
+ const action = signal.mode === 'prefer' || signal.mode === 'avoid' ? signal.mode : 'observe';
9133
+ const metadata = toJsonObject(signal.metadata);
9134
+ return {
9135
+ id: `routing-controller-decision:${action}:${stableHash([signal, generatedAt])}`,
9136
+ action,
9137
+ ...(signal.computeId ? { computeId: signal.computeId } : {}),
9138
+ ...(signal.model ? { model: signal.model } : {}),
9139
+ ...(signal.lane ? { lane: signal.lane } : {}),
9140
+ ...(signal.workKind ? { workKind: signal.workKind } : {}),
9141
+ ...(signal.taskKind ? { taskKind: signal.taskKind } : {}),
9142
+ confidence: signal.confidence ?? 'low',
9143
+ reason: signal.reason ?? `routing ${action} signal`,
9144
+ ...(readNonNegativeNumber(metadata?.successRate) !== undefined ? { score: readNonNegativeNumber(metadata?.successRate) } : {}),
9145
+ ...(metadata ? { metadata } : {})
9146
+ };
9147
+ }
9148
+ function telemetrySuccessScore(record) {
9149
+ if ((record.verificationRequiredFailed ?? 0) > 0)
9150
+ return 0;
9151
+ if ((record.openHumanActionCount ?? 0) > 0)
9152
+ return 0.2;
9153
+ const status = slug(record.status ?? '');
9154
+ const disposition = slug(record.mergeDisposition ?? '');
9155
+ const readiness = slug(record.mergeReadiness ?? '');
9156
+ if (['completed', 'verified', 'passed', 'success'].includes(status))
9157
+ return 1;
9158
+ if (['applied', 'committed', 'checked', 'auto-mergeable'].includes(disposition) || readiness === 'patch-candidate')
9159
+ return 0.9;
9160
+ if (['blocked', 'failed', 'failure', 'rejected', 'conflict-blocked'].includes(status) || ['rejected', 'blocked', 'stale-against-head'].includes(disposition))
9161
+ return 0;
9162
+ if (readiness === 'discovery-only' || disposition === 'discovery-only')
9163
+ return 0.55;
9164
+ if ((record.verificationTotal ?? 0) > 0) {
9165
+ const passed = record.verificationPassed ?? 0;
9166
+ return clamp01(passed / Math.max(1, record.verificationTotal ?? 1));
9167
+ }
9168
+ return 0.5;
9169
+ }
9170
+ function telemetryEvidenceScore(record) {
9171
+ const verificationTotal = record.verificationTotal ?? 0;
9172
+ const verificationPassed = record.verificationPassed ?? 0;
9173
+ const verificationScore = verificationTotal > 0 ? verificationPassed / Math.max(1, verificationTotal) : undefined;
9174
+ const evidenceScore = (record.evidencePathCount ?? 0) > 0 ? 0.2 : 0;
9175
+ const semanticScore = record.semanticImportPresent ? 0.1 : 0;
9176
+ return clamp01(Math.max(telemetrySuccessScore(record), verificationScore ?? 0) + evidenceScore + semanticScore);
9177
+ }
9178
+ function telemetryConfidence(record) {
9179
+ if ((record.verificationTotal ?? 0) > 0 && (record.evidencePathCount ?? 0) > 0)
9180
+ return 'high';
9181
+ if ((record.verificationTotal ?? 0) > 0 || (record.evidencePathCount ?? 0) > 0 || record.semanticImportPresent)
9182
+ return 'medium';
9183
+ return 'low';
9184
+ }
8939
9185
  function routingFeedbackForTask(feedback, task) {
8940
9186
  return feedback.filter((entry) => routingFeedbackMatchesTask(entry, task));
8941
9187
  }
@@ -10322,6 +10568,157 @@ export function createSwarmModelRoutingPolicy(input = {}) {
10322
10568
  ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
10323
10569
  };
10324
10570
  }
10571
+ export function createSwarmRoutingController(input = {}) {
10572
+ const generatedAt = input.generatedAt ?? Date.now();
10573
+ const records = normalizeSwarmTelemetryRecords([
10574
+ ...(input.records ?? []),
10575
+ ...(input.telemetry?.records ?? [])
10576
+ ]);
10577
+ const summary = input.summary ?? input.telemetry?.summary;
10578
+ const basePolicy = normalizeRouterPolicy(input.basePolicy);
10579
+ const feedback = records.map((record) => telemetryRecordToRoutingFeedback(record, generatedAt));
10580
+ const telemetrySignals = createTelemetryRoutingSignals(records, input, generatedAt);
10581
+ const baseSignals = basePolicy?.signals ?? [];
10582
+ const policy = createSwarmModelRoutingPolicy({
10583
+ id: input.id ? `${input.id}:policy` : undefined,
10584
+ ...(basePolicy ?? {}),
10585
+ defaultMode: input.routingMode ?? input.defaultMode ?? basePolicy?.defaultMode ?? 'fill',
10586
+ signals: dedupeModelRoutingPolicySignals([...baseSignals, ...telemetrySignals]),
10587
+ feedback: [...(basePolicy?.feedback ?? []), ...feedback],
10588
+ generatedAt,
10589
+ metadata: {
10590
+ ...(basePolicy?.metadata ?? {}),
10591
+ source: 'frontier-swarm-routing-controller',
10592
+ telemetryRecordCount: records.length,
10593
+ ...(summary ? { telemetrySummary: cloneJsonValue(summary) } : {}),
10594
+ ...(toJsonObject(input.metadata) ? { input: toJsonObject(input.metadata) } : {})
10595
+ }
10596
+ });
10597
+ const routedPlan = input.plan
10598
+ ? rerouteSwarmPlan({
10599
+ plan: input.plan,
10600
+ routingPolicy: policy,
10601
+ routingMode: input.routingMode ?? policy.defaultMode,
10602
+ protectedJobIds: input.protectedJobIds,
10603
+ runningJobIds: input.runningJobIds,
10604
+ completedJobIds: input.completedJobIds,
10605
+ generatedAt,
10606
+ metadata: { source: 'frontier-swarm-routing-controller' }
10607
+ })
10608
+ : undefined;
10609
+ const changedComputeCount = routedPlan && input.plan
10610
+ ? input.plan.jobs.filter((job) => routedPlan.jobs.find((entry) => entry.id === job.id)?.compute.id !== job.compute.id).length
10611
+ : 0;
10612
+ const protectedJobCount = uniqueStrings([
10613
+ ...(input.protectedJobIds ?? []),
10614
+ ...(input.runningJobIds ?? []),
10615
+ ...(input.completedJobIds ?? [])
10616
+ ]).length;
10617
+ const decisions = [
10618
+ ...telemetrySignals.map((signal) => routingSignalToControllerDecision(signal, generatedAt)),
10619
+ ...(changedComputeCount > 0 ? [{
10620
+ id: `routing-controller-decision:reroute:${stableHash([input.plan?.id, changedComputeCount, generatedAt])}`,
10621
+ action: 'reroute',
10622
+ confidence: 'medium',
10623
+ reason: `rerouted ${changedComputeCount} pending jobs from telemetry policy`,
10624
+ metadata: { changedComputeCount }
10625
+ }] : [])
10626
+ ];
10627
+ const signalCounts = countBy(telemetrySignals.map((signal) => signal.mode ?? 'observe'));
10628
+ return {
10629
+ kind: 'frontier.swarm.routing-controller',
10630
+ version: 1,
10631
+ id: input.id ?? 'swarm-routing-controller:' + stableHash([input.plan?.id, records.map((record) => record.id ?? record.jobId), generatedAt]),
10632
+ generatedAt,
10633
+ routingMode: input.routingMode ?? policy.defaultMode,
10634
+ policy,
10635
+ decisions,
10636
+ ...(routedPlan ? { routedPlan } : {}),
10637
+ summary: {
10638
+ telemetryRecordCount: records.length,
10639
+ telemetryJobCount: new Set(records.map((record) => record.jobId).filter(Boolean)).size,
10640
+ feedbackCount: feedback.length,
10641
+ signalCount: telemetrySignals.length,
10642
+ preferCount: signalCounts.prefer ?? 0,
10643
+ avoidCount: signalCounts.avoid ?? 0,
10644
+ observeCount: signalCounts.observe ?? 0,
10645
+ decisionCount: decisions.length,
10646
+ reroutedJobCount: changedComputeCount,
10647
+ changedComputeCount,
10648
+ protectedJobCount,
10649
+ missingPlanManifest: !!input.plan && !input.plan.manifest,
10650
+ ...(summary?.recordCount !== undefined ? { summaryRecordCount: summary.recordCount } : {}),
10651
+ ...(summary?.estimatedCostUsd !== undefined ? { summaryEstimatedCostUsd: summary.estimatedCostUsd } : {})
10652
+ },
10653
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
10654
+ };
10655
+ }
10656
+ export function rerouteSwarmPlan(input) {
10657
+ const plan = input.plan;
10658
+ const protectedJobIds = new Set(uniqueStrings([
10659
+ ...(input.protectedJobIds ?? []),
10660
+ ...(input.runningJobIds ?? []),
10661
+ ...(input.completedJobIds ?? [])
10662
+ ]));
10663
+ const routingPolicy = normalizeRouterPolicy(input.routingPolicy);
10664
+ if (!plan.manifest || !routingPolicy) {
10665
+ return {
10666
+ ...plan,
10667
+ metadata: mergeSwarmMetadata([plan.metadata, {
10668
+ routingController: {
10669
+ rerouteSkipped: !plan.manifest ? 'missing-plan-manifest' : 'missing-routing-policy',
10670
+ protectedJobCount: protectedJobIds.size,
10671
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
10672
+ }
10673
+ }])
10674
+ };
10675
+ }
10676
+ const routed = createSwarmPlan(plan.manifest, plan.jobs.map((job) => job.task), {
10677
+ ...plan.filters,
10678
+ id: plan.id,
10679
+ runId: plan.runId,
10680
+ now: input.generatedAt ?? plan.createdAt,
10681
+ maxReadyJobs: plan.limits.maxReadyJobs,
10682
+ maxLaneConcurrency: plan.limits.maxLaneConcurrency,
10683
+ maxConcurrencyKeyConcurrency: plan.limits.maxConcurrencyKeyConcurrency,
10684
+ maxComputeConcurrency: plan.limits.maxComputeConcurrency,
10685
+ resourceQuotas: plan.limits.resourceQuotas,
10686
+ routingPolicy,
10687
+ routingMode: input.routingMode ?? routingPolicy.defaultMode,
10688
+ routingContext: plan.routingContext,
10689
+ metadata: mergeSwarmMetadata([plan.metadata, input.metadata])
10690
+ });
10691
+ const routedById = new Map(routed.jobs.map((job) => [job.id, job]));
10692
+ let changedComputeCount = 0;
10693
+ const jobs = plan.jobs.map((job) => {
10694
+ if (protectedJobIds.has(job.id))
10695
+ return job;
10696
+ const next = routedById.get(job.id);
10697
+ if (!next)
10698
+ return job;
10699
+ if (next.compute.id !== job.compute.id)
10700
+ changedComputeCount += 1;
10701
+ return { ...next, status: job.status };
10702
+ });
10703
+ return {
10704
+ ...routed,
10705
+ id: plan.id,
10706
+ runId: plan.runId,
10707
+ createdAt: plan.createdAt,
10708
+ jobs,
10709
+ summary: summarizeJobs(jobs),
10710
+ metadata: mergeSwarmMetadata([routed.metadata, {
10711
+ routingController: {
10712
+ mode: input.routingMode ?? routingPolicy.defaultMode,
10713
+ policyId: routingPolicy.id,
10714
+ protectedJobCount: protectedJobIds.size,
10715
+ changedComputeCount,
10716
+ generatedAt: input.generatedAt ?? Date.now(),
10717
+ ...(toJsonObject(input.metadata) ? { metadata: toJsonObject(input.metadata) } : {})
10718
+ }
10719
+ }])
10720
+ };
10721
+ }
10325
10722
  export function createSwarmModelRoutingFeedbackFromBoard(input = {}) {
10326
10723
  return createSwarmModelRoutingFeedback({ scope: 'lane', resultStatus: 'board-observed', generatedAt: input.generatedAt, metadata: input.metadata });
10327
10724
  }