@tscircuit/capacity-autorouter 0.0.190 → 0.0.192

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.d.ts CHANGED
@@ -42,6 +42,7 @@ interface SimpleRouteJson {
42
42
  traces?: SimplifiedPcbTraces;
43
43
  }
44
44
  interface Obstacle {
45
+ obstacleId?: string;
45
46
  type: "rect";
46
47
  layers: string[];
47
48
  zLayers?: number[];
@@ -107,6 +108,8 @@ interface CapacityMeshNode {
107
108
  _isVirtualOffboard?: boolean;
108
109
  _offboardNetName?: string;
109
110
  _adjacentNodeIds?: CapacityMeshNodeId[];
111
+ _offBoardConnectionId?: string;
112
+ _offBoardConnectedCapacityMeshNodeIds?: CapacityMeshNodeId[];
110
113
  _parent?: CapacityMeshNode;
111
114
  }
112
115
  interface CapacityMeshEdge {
@@ -1094,9 +1097,15 @@ interface PortPointPathingHyperParameters {
1094
1097
  GREEDY_MULTIPLIER?: number;
1095
1098
  NODE_PF_FACTOR?: number;
1096
1099
  RANDOM_COST_MAGNITUDE?: number;
1100
+ NODE_PF_MAX_PENALTY?: number;
1097
1101
  MEMORY_PF_FACTOR?: number;
1098
1102
  BASE_CANDIDATE_COST?: number;
1103
+ MIN_ALLOWED_BOARD_SCORE?: number;
1099
1104
  MAX_ITERATIONS_PER_PATH?: number;
1105
+ FORCE_CENTER_FIRST?: boolean;
1106
+ RANDOM_WALK_DISTANCE?: number;
1107
+ FORCE_OFF_BOARD_FREQUENCY?: number;
1108
+ FORCE_OFF_BOARD_SEED?: number;
1100
1109
  }
1101
1110
  /**
1102
1111
  * An input port point without connectionName assigned yet.
@@ -1111,6 +1120,7 @@ interface InputPortPoint {
1111
1120
  connectionNodeIds: [CapacityMeshNodeId, CapacityMeshNodeId];
1112
1121
  /** XY distance to the centermost port on this Z level (centermost port has distance 0) */
1113
1122
  distToCentermostPortOnZ: number;
1123
+ connectsToOffBoardNode?: boolean;
1114
1124
  }
1115
1125
  /**
1116
1126
  * A node with pre-computed port points (without connectionName assigned).
@@ -1131,6 +1141,8 @@ interface InputNodeWithPortPoints {
1131
1141
  _containsTarget?: boolean;
1132
1142
  /** If true, this node contains an obstacle */
1133
1143
  _containsObstacle?: boolean;
1144
+ _offBoardConnectionId?: string;
1145
+ _offBoardConnectedCapacityMeshNodeIds?: CapacityMeshNodeId[];
1134
1146
  }
1135
1147
  /**
1136
1148
  * A candidate in the A* search. Represents being at a port point,
@@ -1152,6 +1164,11 @@ interface PortPointCandidate {
1152
1164
  f: number;
1153
1165
  g: number;
1154
1166
  h: number;
1167
+ /** Total distance traveled from start to this candidate */
1168
+ distanceTraveled: number;
1169
+ /** Whether this candidate has ever crossed through an off-board node */
1170
+ hasTouchedOffBoardNode?: boolean;
1171
+ lastMoveWasOffBoard?: boolean;
1155
1172
  }
1156
1173
  interface ConnectionPathResult {
1157
1174
  connection: SimpleRouteConnection;
@@ -1196,8 +1213,14 @@ declare class PortPointPathingSolver extends BaseSolver {
1196
1213
  nodeAssignedPortPoints: Map<CapacityMeshNodeId, PortPoint[]>;
1197
1214
  /** Factor applied to port point reuse penalty */
1198
1215
  PORT_POINT_REUSE_FACTOR: number;
1216
+ /**
1217
+ * Cost when a node doesn't go off board when it's supposed to w/ the
1218
+ * FORCE_OFF_BOARD_FREQUENCY setting.
1219
+ */
1220
+ BASE_COST_FOR_NOT_GOING_OFF_BOARD: number;
1199
1221
  /** Multiplied by Pf delta cost (in -log(1-pf) space) */
1200
1222
  get NODE_PF_FACTOR(): number;
1223
+ get RANDOM_WALK_DISTANCE(): number;
1201
1224
  /** Used only in heuristic (h) to "look ahead" into known-congested regions */
1202
1225
  get MEMORY_PF_FACTOR(): number;
1203
1226
  get CENTER_OFFSET_FOCUS_SHIFT(): number;
@@ -1205,14 +1228,18 @@ declare class PortPointPathingSolver extends BaseSolver {
1205
1228
  get RANDOM_COST_MAGNITUDE(): number;
1206
1229
  /** Cost of adding a candidate to the path */
1207
1230
  get BASE_CANDIDATE_COST(): number;
1208
- /** Cost penalty for changing layers (used in heuristic) */
1209
- Z_DIST_COST: number;
1231
+ get NODE_PF_MAX_PENALTY(): number;
1232
+ get FORCE_CENTER_FIRST(): boolean;
1233
+ get FORCE_OFF_BOARD_FREQUENCY(): number;
1234
+ get FORCE_OFF_BOARD_SEED(): number;
1235
+ get NODE_MAX_PF(): number;
1210
1236
  /** Penalty factor for port points that are far from the center of the segment */
1211
1237
  get CENTER_OFFSET_DIST_PENALTY_FACTOR(): number;
1212
1238
  colorMap: Record<string, string>;
1213
1239
  get GREEDY_MULTIPLIER(): number;
1214
1240
  MAX_CANDIDATES_IN_MEMORY: number;
1215
1241
  get MAX_ITERATIONS_PER_PATH(): number;
1242
+ get MIN_ALLOWED_BOARD_SCORE(): number;
1216
1243
  nodeMemoryPfMap: Map<CapacityMeshNodeId, number>;
1217
1244
  currentConnectionIndex: number;
1218
1245
  currentPathIterations: number;
@@ -1223,10 +1250,12 @@ declare class PortPointPathingSolver extends BaseSolver {
1223
1250
  capacityMeshNodeMap: Map<CapacityMeshNodeId, CapacityMeshNode>;
1224
1251
  /** Heuristic scaling: an estimate of "node pitch" used to estimate remaining hops */
1225
1252
  avgNodePitch: number;
1253
+ /** Whether the current connection should be forced to route off-board */
1254
+ currentConnectionShouldRouteOffBoard: boolean;
1255
+ /** Cached list of off-board nodes for computing distance to nearest off-board node */
1256
+ offBoardNodes: InputNodeWithPortPoints[];
1226
1257
  /** Cache of base node cost (cost of node in current committed state) */
1227
1258
  private baseNodeCostCache;
1228
- /** Cache of delta cost for a specific node segment (entry->exit) for a specific connection */
1229
- private segmentDeltaCostCache;
1230
1259
  constructor({ simpleRouteJson, inputNodes, capacityMeshNodes, colorMap, nodeMemoryPfMap, hyperParameters, }: {
1231
1260
  simpleRouteJson: SimpleRouteJson;
1232
1261
  capacityMeshNodes: CapacityMeshNode[];
@@ -1239,10 +1268,9 @@ declare class PortPointPathingSolver extends BaseSolver {
1239
1268
  private clampPf;
1240
1269
  /** Convert Pf into an additive "failure cost" */
1241
1270
  private pfToFailureCost;
1242
- private round3;
1243
- private pointKey;
1244
1271
  /** Base node cost with the currently-committed port points (no candidate additions) */
1245
1272
  private getBaseNodeFailureCost;
1273
+ computeBoardScore(): number;
1246
1274
  /**
1247
1275
  * Exact delta cost of routing this connection through `nodeId`
1248
1276
  * for the segment defined by entry->exit.
@@ -1285,6 +1313,13 @@ declare class PortPointPathingSolver extends BaseSolver {
1285
1313
  * This ensures the last node's segment is accounted for in g.
1286
1314
  */
1287
1315
  private computeGToEndTarget;
1316
+ /**
1317
+ * Compute distance to the nearest off-board node from a point.
1318
+ */
1319
+ computeDistanceToNearestOffBoardNode(point: {
1320
+ x: number;
1321
+ y: number;
1322
+ }): number;
1288
1323
  /**
1289
1324
  * Heuristic: approximate remaining cost.
1290
1325
  *
@@ -1293,10 +1328,7 @@ declare class PortPointPathingSolver extends BaseSolver {
1293
1328
  * - estimated remaining hops (distance / avgNodePitch)
1294
1329
  * - memoryPfMap to bias away from historically high Pf regions
1295
1330
  */
1296
- computeH(point: {
1297
- x: number;
1298
- y: number;
1299
- }, currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId, currentZ: number): number;
1331
+ computeH(point: InputPortPoint, currentNodeId: CapacityMeshNodeId, endGoalNodeId: CapacityMeshNodeId, currentZ: number, distanceTraveled: number, hasTouchedOffBoardNode?: boolean): number;
1300
1332
  getAvailableExitPortPoints(nodeId: CapacityMeshNodeId): InputPortPoint[];
1301
1333
  /**
1302
1334
  * Get available port points to exit from a node, but *do not* return all.
@@ -1307,7 +1339,10 @@ declare class PortPointPathingSolver extends BaseSolver {
1307
1339
  * unassigned offsets as backups.
1308
1340
  */
1309
1341
  getAvailableExitPortPointsWithOmissions(nodeId: CapacityMeshNodeId, _endGoalNodeId: CapacityMeshNodeId): InputPortPoint[];
1310
- canTravelThroughObstacle(node: InputNodeWithPortPoints, connectionName: string): boolean;
1342
+ getAvailableExitPortPointsForOffboardConnection(nodeId: CapacityMeshNodeId): (InputPortPoint & {
1343
+ throughNodeId: CapacityMeshNodeId;
1344
+ })[];
1345
+ canTravelThroughObstacle(node: InputNodeWithPortPoints, connectionName: string, rootConnectionName: string): boolean;
1311
1346
  /**
1312
1347
  * Check if we've reached the end goal node
1313
1348
  */
@@ -1338,6 +1373,72 @@ declare class PortPointPathingSolver extends BaseSolver {
1338
1373
  visualize(): GraphicsObject;
1339
1374
  }
1340
1375
 
1376
+ interface HyperPortPointPathingSolverParams {
1377
+ simpleRouteJson: SimpleRouteJson;
1378
+ capacityMeshNodes: CapacityMeshNode[];
1379
+ inputNodes: InputNodeWithPortPoints[];
1380
+ colorMap?: Record<string, string>;
1381
+ nodeMemoryPfMap?: Map<CapacityMeshNodeId, number>;
1382
+ numShuffleSeeds?: number;
1383
+ minAllowedBoardScore?: number;
1384
+ hyperParameters?: Partial<PortPointPathingHyperParameters>;
1385
+ }
1386
+ declare class HyperPortPointPathingSolver extends HyperParameterSupervisorSolver<PortPointPathingSolver> {
1387
+ private params;
1388
+ constructor(params: HyperPortPointPathingSolverParams);
1389
+ getHyperParameterDefs(): Array<HyperParameterDef>;
1390
+ getCombinationDefs(): Array<string[]>;
1391
+ generateSolver(hyperParameters: any): PortPointPathingSolver;
1392
+ /**
1393
+ * G measures the "cost" of this solver based on current score.
1394
+ * We use the raw board score (more negative = worse quality = higher cost).
1395
+ *
1396
+ * The key insight is that early scores (at ~25% progress) are predictive
1397
+ * of final quality. Solvers with better early scores tend to finish better.
1398
+ */
1399
+ computeG(solver: PortPointPathingSolver): number;
1400
+ /**
1401
+ * H estimates remaining "cost" based on current trajectory.
1402
+ *
1403
+ * Key insight from analysis: bad solvers have similar early scores but
1404
+ * explode later (e.g., seed 760: -0.23 @ 25% → -15.05 final).
1405
+ * Good solvers maintain low scores throughout (e.g., seed 829: -0.06 @ 25% → -2.42 final).
1406
+ *
1407
+ * We estimate remaining cost by extrapolating current score/connection rate.
1408
+ */
1409
+ computeH(solver: PortPointPathingSolver): number;
1410
+ /**
1411
+ * Get the nodes with port points from the winning solver
1412
+ */
1413
+ getNodesWithPortPoints(): NodeWithPortPoints[];
1414
+ /**
1415
+ * Get connection results from the winning solver
1416
+ */
1417
+ get connectionsWithResults(): ConnectionPathResult[];
1418
+ /**
1419
+ * Get input nodes from the winning solver
1420
+ */
1421
+ get inputNodes(): InputNodeWithPortPoints[];
1422
+ /**
1423
+ * Get node map from the winning solver
1424
+ */
1425
+ get nodeMap(): Map<CapacityMeshNodeId, InputNodeWithPortPoints>;
1426
+ /**
1427
+ * Get assigned port points from the winning solver
1428
+ */
1429
+ get assignedPortPoints(): Map<any, any>;
1430
+ /**
1431
+ * Get node assigned port points from the winning solver
1432
+ */
1433
+ get nodeAssignedPortPoints(): Map<any, any>;
1434
+ /**
1435
+ * Compute board score from the winning solver
1436
+ */
1437
+ computeBoardScore(): number;
1438
+ onSolve(solver: SupervisedSolver<PortPointPathingSolver>): void;
1439
+ visualize(): GraphicsObject;
1440
+ }
1441
+
1341
1442
  interface PortPointSectionParams {
1342
1443
  centerOfSectionCapacityNodeId: CapacityMeshNodeId;
1343
1444
  expansionDegrees: number;
@@ -1512,7 +1613,12 @@ declare class MultiSectionPortPointOptimizer extends BaseSolver {
1512
1613
  * Marks nodes containing cut path endpoints as targets so the solver can route to/from them.
1513
1614
  */
1514
1615
  prepareSectionInputNodesForCutPaths(section: PortPointSection): InputNodeWithPortPoints[];
1515
- getHyperParametersForAttempt(attempt: number): PortPointPathingHyperParameters;
1616
+ getHyperParametersForScheduleIndex(scheduleIndex: number, sectionAttempt: number): PortPointPathingHyperParameters;
1617
+ /**
1618
+ * Create a PortPointPathingSolver for the current section.
1619
+ * This centralizes the solver creation logic that was previously duplicated in 3 places.
1620
+ */
1621
+ createSectionSolver(section: PortPointSection): PortPointPathingSolver;
1516
1622
  /**
1517
1623
  * Reattach the optimized section results back to the main state.
1518
1624
  * Handles both fully contained connections AND cut paths.
@@ -1551,7 +1657,7 @@ declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
1551
1657
  deadEndSolver?: DeadEndSolver;
1552
1658
  traceSimplificationSolver?: TraceSimplificationSolver;
1553
1659
  availableSegmentPointSolver?: AvailableSegmentPointSolver;
1554
- portPointPathingSolver?: PortPointPathingSolver;
1660
+ portPointPathingSolver?: HyperPortPointPathingSolver;
1555
1661
  multiSectionPortPointOptimizer?: MultiSectionPortPointOptimizer;
1556
1662
  viaDiameter: number;
1557
1663
  minTraceWidth: number;
@@ -1564,7 +1670,7 @@ declare class AutoroutingPipelineSolver2_PortPointPathing extends BaseSolver {
1564
1670
  capacityNodes: CapacityMeshNode[] | null;
1565
1671
  capacityEdges: CapacityMeshEdge[] | null;
1566
1672
  cacheProvider: CacheProvider | null;
1567
- pipelineDef: (PipelineStep$2<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$2<typeof RectDiffPipeline> | PipelineStep$2<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$2<typeof AvailableSegmentPointSolver> | PipelineStep$2<typeof PortPointPathingSolver> | PipelineStep$2<typeof MultiSectionPortPointOptimizer> | PipelineStep$2<typeof HighDensitySolver> | PipelineStep$2<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$2<typeof TraceSimplificationSolver>)[];
1673
+ pipelineDef: (PipelineStep$2<typeof NetToPointPairsSolver2_OffBoardConnection> | PipelineStep$2<typeof RectDiffPipeline> | PipelineStep$2<typeof CapacityMeshEdgeSolver2_NodeTreeOptimization> | PipelineStep$2<typeof AvailableSegmentPointSolver> | PipelineStep$2<typeof HyperPortPointPathingSolver> | PipelineStep$2<typeof MultiSectionPortPointOptimizer> | PipelineStep$2<typeof HighDensitySolver> | PipelineStep$2<typeof MultipleHighDensityRouteStitchSolver> | PipelineStep$2<typeof TraceSimplificationSolver>)[];
1568
1674
  constructor(srj: SimpleRouteJson, opts?: CapacityMeshSolverOptions$2);
1569
1675
  currentPipelineStepIndex: number;
1570
1676
  _step(): void;
@@ -3205,10 +3311,10 @@ type AutoroutingPipelineSolverOptions = CapacityMeshSolverOptions;
3205
3311
  type PipelineStep<T extends new (...args: any[]) => BaseSolver> = {
3206
3312
  solverName: string;
3207
3313
  solverClass: T;
3208
- getConstructorParams: (instance: AssignableViaAutoroutingPipelineSolver) => ConstructorParameters<T>;
3209
- onSolved?: (instance: AssignableViaAutoroutingPipelineSolver) => void;
3314
+ getConstructorParams: (instance: AssignableAutoroutingPipeline1Solver) => ConstructorParameters<T>;
3315
+ onSolved?: (instance: AssignableAutoroutingPipeline1Solver) => void;
3210
3316
  };
3211
- declare class AssignableViaAutoroutingPipelineSolver extends BaseSolver {
3317
+ declare class AssignableAutoroutingPipeline1Solver extends BaseSolver {
3212
3318
  srj: SimpleRouteJson;
3213
3319
  opts: CapacityMeshSolverOptions;
3214
3320
  netToPointPairsSolver?: NetToPointPairsSolver;
@@ -3276,4 +3382,4 @@ declare const convertSrjToGraphicsObject: (srj: SimpleRouteJson) => {
3276
3382
  points: Point$3[];
3277
3383
  };
3278
3384
 
3279
- export { AssignableViaAutoroutingPipelineSolver, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver2_PortPointPathing as AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };
3385
+ export { AssignableAutoroutingPipeline1Solver, AutoroutingPipeline1_OriginalUnravel, AutoroutingPipelineSolver2_PortPointPathing as AutoroutingPipelineSolver, type AutoroutingPipelineSolverOptions, type CachableSolver, type CacheProvider, CapacityMeshSolver, InMemoryCache, LocalStorageCache, calculateOptimalCapacityDepth, convertSrjToGraphicsObject, getGlobalInMemoryCache, getGlobalLocalStorageCache, getTunedTotalCapacity1, setupGlobalCaches };