@solvice/routing 0.18.2-beta.0 → 0.19.1-beta.0

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/runs.d.ts CHANGED
@@ -210,7 +210,7 @@ export interface components {
210
210
  * Format: int64
211
211
  * @description Trigger threshold in seconds (strict `>` — the break fires when the
212
212
  * accumulator exceeds this). EU 561/2006 drive rule: `16200` (4 h 30).
213
- * Must be `> 0` and fit in 32 bits.
213
+ * Must be `> 0` and at most 2,147,483,647.
214
214
  * @example 14400
215
215
  */
216
216
  threshold_s: number;
@@ -239,7 +239,7 @@ export interface components {
239
239
  /**
240
240
  * @description Not supported on V3: a windowed break is taken wherever the
241
241
  * vehicle is when it starts, so a `location` here is rejected with
242
- * HTTP 400 `not_supported`. Set only by the V2 compatibility mapper.
242
+ * HTTP 400 `not_supported`.
243
243
  */
244
244
  location?: null | components["schemas"]["Place"];
245
245
  /** @description The window bounding the break's **start**. */
@@ -330,7 +330,7 @@ export interface components {
330
330
  * shifts only `per_route`. Default `0`. Use it to minimise distinct
331
331
  * vehicles; use `per_route` to price each working day. Not accepted on
332
332
  * `shifts[].costs`. When any vehicle has a non-zero rate and any vehicle
333
- * has several shifts, the problem solves without decomposition.
333
+ * has several shifts, the request is solved as a whole rather than split into parts, which can make a large request slower.
334
334
  * @example 400
335
335
  */
336
336
  per_used_vehicle?: number | null;
@@ -375,7 +375,7 @@ export interface components {
375
375
  * cannot see — typically the driver labour for the unload itself
376
376
  * (`service_duration_s` × the hourly rate). Without it, a reload that
377
377
  * consumes only *slack* is free in the objective: it adds no route
378
- * duration, so the solver will happily insert one to displace time that
378
+ * duration, so the solver may insert one to displace time that
379
379
  * `objective.costs.per_wait_hour` would otherwise charge as idle, parking
380
380
  * the vehicle at a depot for no capacity benefit.
381
381
  * @example 38.66
@@ -467,8 +467,8 @@ export interface components {
467
467
  * each other. The solver adds `per_entry` to the objective each time a
468
468
  * route enters a group from a job outside it, the first entry included;
469
469
  * entering from the shift's start or from a reload is free. Keeping each
470
- * group in one visit minimises the "passing-waypoint" / area re-entry count
471
- * last-mile fleets track. Presence of this object enables the feature; omit
470
+ * group in one visit minimises how often a route comes back to an area it
471
+ * already served. Presence of this object enables the feature; omit
472
472
  * it to disable.
473
473
  * @example {
474
474
  * "distance_metric": "straight_line",
@@ -542,7 +542,7 @@ export interface components {
542
542
  * this prices the vehicle that did, so a task rated badly everywhere is
543
543
  * the first one dropped when capacity runs out. It lives in the cost tier,
544
544
  * below `priority`, and adds to `preferences`, `drop_cost` and travel.
545
- * Not applied by decomposition: a problem that sets it solves monolithically.
545
+ * A request that sets it is solved as a whole rather than split into parts, which can make a large request slower.
546
546
  */
547
547
  assignment_costs?: components["schemas"]["AssignmentCost"][] | null;
548
548
  /**
@@ -705,10 +705,8 @@ export interface components {
705
705
  * - `osm`: OpenStreetMap free-flow times. No traffic, so
706
706
  * `travel.departure_time` is rejected with 400.
707
707
  * - `tomtom_real_time`: TomTom live traffic at the moment of the request.
708
- * **Not yet enabled: currently always rejected with 403 `feature_not_enabled`.** Once enabled:
709
- * `travel.departure_time` is rejected; every vehicle must use the `car`
710
- * profile; at most 100 distinct locations; up to ~25 s of matrix fetch at
711
- * 100 locations.
708
+ * **Not available:** a request that sets it is rejected with 403
709
+ * `feature_not_enabled`. Use `tomtom`.
712
710
  * - `straight_line`: great-circle distance at `travel.speed_kmh`, no road
713
711
  * network. `travel.departure_time`, `options.polyline` and any vehicle
714
712
  * `profile` other than `car` are rejected with 400.
@@ -758,8 +756,8 @@ export interface components {
758
756
  * rank, and a date with no shift adds none. Unserved tasks pay nothing;
759
757
  * the charge never outranks `priority` and cannot be combined with
760
758
  * `drop_cost`. Absent or `0` = off; a single-date request is charged
761
- * nothing. A problem that sets it, even on one date, solves without
762
- * decomposition, like `assignment_costs`. Reported as `score.components.delay`. A positive
759
+ * nothing. Like `assignment_costs`, a request that sets it, even on one
760
+ * date, is solved as a whole rather than split into parts. Reported as `score.components.delay`. A positive
763
761
  * rate below `0.00001` is rejected, as is a rate whose total over the
764
762
  * later workdays exceeds `21474.83647` (`out_of_range`).
765
763
  * @example 5
@@ -942,7 +940,9 @@ export interface components {
942
940
  };
943
941
  /**
944
942
  * PlanStopReload
945
- * @description A reload at a depot: the next trip starts there.
943
+ * @description A reload at a depot: the next trip starts there. It sits between two
944
+ * task stops, or first on a shift with a non-zero `initial_load`: the unload
945
+ * before the first job.
946
946
  */
947
947
  PlanStopReload: {
948
948
  /**
@@ -1133,8 +1133,8 @@ export interface components {
1133
1133
  };
1134
1134
  /**
1135
1135
  * @description A hard constraint between tasks, selected by `type`: `sequence`,
1136
- * `tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,
1137
- * `time_lag`, `compatible_vehicles` or `all_or_none`.
1136
+ * `consecutive`, `tag_order`, `same_vehicle`, `same_day`, `same_route`,
1137
+ * `synchronized`, `time_lag`, `compatible_vehicles` or `all_or_none`.
1138
1138
  * Each type carries only its own fields; any other `type` is rejected with
1139
1139
  * HTTP 400.
1140
1140
  *
@@ -1351,8 +1351,8 @@ export interface components {
1351
1351
  /**
1352
1352
  * Format: int64
1353
1353
  * @description Maximum spread between the synchronized instants in seconds
1354
- * (`0` = exact simultaneity). Required. A negative value, or one that
1355
- * does not fit in 32 bits, is rejected with HTTP 400 `out_of_range`.
1354
+ * (`0` = exact simultaneity). Required. A negative value, or one above
1355
+ * 2,147,483,647, is rejected with HTTP 400 `out_of_range`.
1356
1356
  */
1357
1357
  max_spread_s: number;
1358
1358
  /**
@@ -1381,7 +1381,7 @@ export interface components {
1381
1381
  *
1382
1382
  * Jobs only: if a tag named here selects a **shipment**, the request is
1383
1383
  * rejected with HTTP 400 (a shipment's two legs already carry their own
1384
- * hard precedence, which tag ordering cannot compose with yet). Drop the
1384
+ * hard precedence, which tag ordering does not combine with). Drop the
1385
1385
  * tag from the shipment.
1386
1386
  */
1387
1387
  RelationTagOrder: {
@@ -1413,13 +1413,14 @@ export interface components {
1413
1413
  /**
1414
1414
  * Format: int64
1415
1415
  * @description Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.
1416
- * Must fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).
1416
+ * From −2,147,483,648 to 2,147,483,647 and `>= min_s` (HTTP 400
1417
+ * otherwise).
1417
1418
  */
1418
1419
  max_s?: number | null;
1419
1420
  /**
1420
1421
  * Format: int64
1421
- * @description Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit
1422
- * in 32 bits.
1422
+ * @description Lower bound on `t(to) − t(from)` in seconds. Default `0`. From
1423
+ * −2,147,483,648 to 2,147,483,647.
1423
1424
  * @default 0
1424
1425
  */
1425
1426
  min_s?: number | null;
@@ -1768,7 +1769,7 @@ export interface components {
1768
1769
  load_after?: null | components["schemas"]["Quantities"];
1769
1770
  /**
1770
1771
  * @description Stop location `[longitude, latitude]` (GeoJSON order). Absent on
1771
- * every `break` stop, including a break with a pinned location, and on
1772
+ * every `break` stop, and on
1772
1773
  * `start`/`end` stops for a genuinely open end (no configured
1773
1774
  * coordinate for that end of the shift). A virtual (location-less) job
1774
1775
  * has no coordinate of its own and reports its nearest located
@@ -2272,8 +2273,8 @@ export interface components {
2272
2273
  ScoreComponents: {
2273
2274
  /**
2274
2275
  * Format: double
2275
- * @description Cost of the serving vehicle's `assignment_costs[].cost` (or the task's
2276
- * default assignment cost), in currency units.
2276
+ * @description Cost of the serving vehicle's `assignment_costs[].cost`, in currency
2277
+ * units.
2277
2278
  */
2278
2279
  assignment: number;
2279
2280
  /**
@@ -2365,7 +2366,7 @@ export interface components {
2365
2366
  /**
2366
2367
  * Format: double
2367
2368
  * @description The price of the time window each task was served in, in currency
2368
- * units (`time_windows[].cost`).
2369
+ * units (`time_windows[].choice_cost`).
2369
2370
  */
2370
2371
  window_choice: number;
2371
2372
  /**
@@ -2437,9 +2438,9 @@ export interface components {
2437
2438
  * no-op. It multiplies the vehicle's own rate (the shift's
2438
2439
  * `service_factor` if set, else the vehicle's): effective service time =
2439
2440
  * `service_duration_s / (shift_or_vehicle_factor * factor)`. Same
2440
- * direction and `[0.001, 5]` range as `vehicles[].service_factor`. V2's
2441
- * `proficiency.durationModifier` multiplied duration instead; the V2
2442
- * compatibility layer sends its inverse (`1 / durationModifier`) here.
2441
+ * direction and `[0.001, 5]` range as `vehicles[].service_factor`.
2442
+ * Migrating from V2: `proficiency.durationModifier` multiplied duration
2443
+ * instead, so send `1 / durationModifier` here.
2443
2444
  * @example 1.25
2444
2445
  */
2445
2446
  factor: number;
@@ -2523,12 +2524,14 @@ export interface components {
2523
2524
  * @description Load already on the vehicle at shift start (pre-loaded), per
2524
2525
  * dimension. Occupies capacity on the first trip only — flushed at the
2525
2526
  * first reload — so it reduces first-trip room per dimension, enforced
2526
- * by the per-trip capacity constraint. Not validated against
2527
- * `capacity` at request time: a value at or beyond capacity is
2528
- * accepted and surfaces as a solve-time result (jobs left unassigned,
2529
- * or deferred until the vehicle's first reload flushes it), not an
2530
- * HTTP 400. A dimension named here but absent from `capacity` behaves
2531
- * the same as capacity `0` in that dimension.
2527
+ * by the per-trip capacity constraint. A value above the capacity in that
2528
+ * dimension is rejected with HTTP 400 (`out_of_range`). The capacity is
2529
+ * resolved per dimension: the shift's capacity when it defines the
2530
+ * dimension, otherwise the vehicle's. If the vehicle has a capacity map
2531
+ * that omits the dimension, the capacity is `0`; if the vehicle has no
2532
+ * capacity map and the shift does not define the dimension, it is
2533
+ * unlimited. At capacity, the vehicle has no room until it unloads, so
2534
+ * the solver may start the route with a reload at one of `reloads`.
2532
2535
  */
2533
2536
  initial_load?: null | components["schemas"]["Quantities"];
2534
2537
  /**
@@ -2604,6 +2607,19 @@ export interface components {
2604
2607
  skills?: components["schemas"]["VehicleSkill"][] | null;
2605
2608
  /** @description Where the shift starts. Absent = open start. */
2606
2609
  start?: null | components["schemas"]["ShiftPlace"];
2610
+ /**
2611
+ * @description When `true`, the shift starts at its first task: travel from `start`
2612
+ * to the first task takes no time, so the first arrival is `from`
2613
+ * plus the `start` handling, and waiting there counts from `from`.
2614
+ * That travel's distance is still charged at `per_travel_km` and reported, so
2615
+ * vehicles that start closer to their work stay cheaper; its time is not
2616
+ * charged and counts toward no duration, break or leg limit.
2617
+ * `free_start_travel` instead makes the travel free altogether. `true`
2618
+ * without `start`, or together with `free_start_travel`, is rejected with
2619
+ * HTTP 400 `conflicting_fields`. Default `false`.
2620
+ * @example false
2621
+ */
2622
+ start_at_first_task?: boolean | null;
2607
2623
  /**
2608
2624
  * Format: date-time
2609
2625
  * @description Shift end (RFC 3339 instant, UTC offset required; hard unless `max_overtime_s` set). The
@@ -2757,7 +2773,7 @@ export interface components {
2757
2773
  * this prices the vehicle that did, so a task rated badly everywhere is
2758
2774
  * the first one dropped when capacity runs out. It lives in the cost tier,
2759
2775
  * below `priority`, and adds to `preferences`, `drop_cost` and travel.
2760
- * Not applied by decomposition: a problem that sets it solves monolithically.
2776
+ * A request that sets it is solved as a whole rather than split into parts, which can make a large request slower.
2761
2777
  */
2762
2778
  assignment_costs?: components["schemas"]["AssignmentCost"][] | null;
2763
2779
  /** @description Delivery leg (load off). */
@@ -3106,10 +3122,10 @@ export interface components {
3106
3122
  /**
3107
3123
  * @description How the best plan improved during the search, oldest first: the
3108
3124
  * starting plan, every improvement (thinned to at most 500 entries), and
3109
- * the final plan, which equals `summary.score` (it can equal, or after
3110
- * the final repair be slightly worse than, the entry before it). Present on
3111
- * every solve; absent on evaluate, which does not search. A large solve
3112
- * the solver splits into clusters has the final entry alone.
3125
+ * the final plan, which equals `summary.score` (it can equal, or be
3126
+ * slightly worse than, the entry before it). Present on every solve;
3127
+ * absent on evaluate, which does not search. A large request that is
3128
+ * solved in parts has the final entry alone.
3113
3129
  */
3114
3130
  search_progress?: components["schemas"]["SearchProgressPoint"][] | null;
3115
3131
  /** @description Aggregate statistics for the solve run. */
@@ -3462,8 +3478,8 @@ export interface components {
3462
3478
  /**
3463
3479
  * Format: date-time
3464
3480
  * @description Latest allowed start of service (RFC 3339 instant, UTC offset
3465
- * required), measured from arrival plus any windowed break taken first
3466
- * (#1750 D1). Hard unless `per_late_hour` prices lateness.
3481
+ * required). Service starts after any windowed break taken on arrival.
3482
+ * Hard unless `per_late_hour` prices lateness.
3467
3483
  * @example 2026-07-01T12:00:00+02:00
3468
3484
  */
3469
3485
  to: string;
@@ -3567,7 +3583,7 @@ export interface components {
3567
3583
  * @description The constraint that refused the task on at least one vehicle (or
3568
3584
  * `all_or_none`, for a task its group holds back), in the vocabulary of
3569
3585
  * the evaluate violations' `code`. A task lists one reason
3570
- * per constraint, once each, in [`ConstraintCode`] order. Absent on the
3586
+ * per constraint, once each, in the order the `code` values are listed. Absent on the
3571
3587
  * single reason of a `time_limit` or `priced_out` task, which names no
3572
3588
  * constraint.
3573
3589
  */
@@ -3609,7 +3625,9 @@ export interface components {
3609
3625
  * vehicle, named in `constraint`, once each, `unreachable` first
3610
3626
  * (`unknown` when no constraint was recorded); a task that fits but
3611
3627
  * whose `all_or_none` group holds it back has the one reason
3612
- * `all_or_none`. Otherwise there is one reason with no `constraint`.
3628
+ * `all_or_none`, and one whose all-or-none `synchronized`/`time_lag`
3629
+ * group cannot be placed together has `synchronized` and/or `time_lag`.
3630
+ * Otherwise there is one reason with no `constraint`.
3613
3631
  */
3614
3632
  reasons: components["schemas"]["UnassignedReason"][];
3615
3633
  /**
@@ -3624,7 +3642,7 @@ export interface components {
3624
3642
  task: string;
3625
3643
  };
3626
3644
  /**
3627
- * @description A vehicle type available to serve tasks.
3645
+ * @description A vehicle available to serve tasks.
3628
3646
  * @example {
3629
3647
  * "capacity": {
3630
3648
  * "volume": 20,
@@ -3724,9 +3742,9 @@ export interface components {
3724
3742
  * this vehicle multiplies whichever applies: effective service time =
3725
3743
  * `service_duration_s / (shift_or_vehicle_factor * task_factor)`.
3726
3744
  *
3727
- * V2's `durationModifier` went the other way (it MULTIPLIED duration,
3728
- * `0.8` = 20% faster); the V2 compatibility layer inverts it and sends it
3729
- * as the task's `service_factors[].factor = 1 / durationModifier`.
3745
+ * Migrating from V2: `durationModifier` went the other way (it multiplied
3746
+ * duration, `0.8` = 20% faster), so send `1 / durationModifier` as the
3747
+ * task's `service_factors[].factor`.
3730
3748
  * @default 1
3731
3749
  */
3732
3750
  service_factor?: number | null;
@@ -3812,7 +3830,7 @@ export interface components {
3812
3830
  * `free_start_travel`/`free_end_travel`, or absent on an open start or
3813
3831
  * end, is exempt. Absent = no cap. Must be > 0: `0` would make every
3814
3832
  * leg too long rather than mean "no cap", so it is rejected with HTTP
3815
- * 400 `out_of_range`, as is a value that does not fit in 32 bits. A
3833
+ * 400 `out_of_range`, as is a value above 2,147,483,647. A
3816
3834
  * breach is reported as `max_leg_travel`.
3817
3835
  * @example 3600
3818
3836
  */
@@ -3869,7 +3887,7 @@ export interface components {
3869
3887
  /**
3870
3888
  * @description A capability a vehicle or shift provides, at a proficiency level:
3871
3889
  * `{ "name": "gas", "level": 3 }`. Always an object; a bare string is
3872
- * rejected at parse.
3890
+ * rejected with HTTP 400.
3873
3891
  * @example {
3874
3892
  * "level": 3,
3875
3893
  * "name": "gas"
@@ -3908,7 +3926,7 @@ export interface components {
3908
3926
  * `period_limit` and `quota` are route-level; `sequence` and `shipment`
3909
3927
  * are on the stop; `unreachable`, `max_leg_travel` and `capacity` can be
3910
3928
  * either. `unknown`
3911
- * means the insertion check refused a stop without naming a constraint
3929
+ * means a stop was refused without a specific constraint being named
3912
3930
  * (not expected in practice).
3913
3931
  */
3914
3932
  code: components["schemas"]["ConstraintCode"];
@@ -3952,8 +3970,8 @@ export interface components {
3952
3970
  * shift is charged on its own part. An empty, non-exempt shift pays for its whole share, so pair the
3953
3971
  * term with `costs.per_route` or `per_used_vehicle` only when both are meant.
3954
3972
  * See `vehicles[].workload_weight` to give a part-time vehicle a smaller
3955
- * share. A problem that sets the term solves without decomposition, like
3956
- * `assignment_costs`.
3973
+ * share. Like `assignment_costs`, a request that sets the term is solved as
3974
+ * a whole rather than split into parts.
3957
3975
  */
3958
3976
  WorkloadShare: {
3959
3977
  /**
package/dist/v3.d.ts CHANGED
@@ -34,7 +34,7 @@ export interface paths {
34
34
  put?: never;
35
35
  /**
36
36
  * Solve a vehicle routing problem
37
- * @description Assigns the jobs and shipments in `problem` to the vehicles' shifts and returns the routes, the `plan` they follow and any tasks left unassigned, each with the reasons. The request is validated first: an invalid one is rejected with a 400 whose `errors[]` says what to fix. Travel times and distances for the request's locations are then looked up, and the search runs for up to `options.time_limit_s` seconds (default 150 ms plus 4 ms per task; maximum 60). Send a previous result's `plan` to re-optimize starting from it. `POST /v3/routing/evaluate` and `POST /v3/routing/suggest` take the same `problem`.
37
+ * @description Assigns the jobs and shipments in `problem` to the vehicles' shifts and returns the routes, the `plan` they follow and any tasks left unassigned, each with the reasons. The request is validated first: an invalid one is rejected with a 400 whose `errors[]` says what to fix. Travel times and distances for the request's locations are then looked up, and the search runs for up to `options.time_limit_s` seconds (default 150 ms plus 4 ms per task; maximum 60). A problem of more than 400 tasks (jobs and shipments together) is a 400: submit one of up to 10,000 tasks to `POST /v3/routing/runs`, which takes the same body. Send a previous result's `plan` to re-optimize starting from it. `POST /v3/routing/evaluate` and `POST /v3/routing/suggest` take the same `problem`.
38
38
  */
39
39
  post: operations["solve"];
40
40
  delete?: never;
@@ -248,7 +248,7 @@ export interface components {
248
248
  * Format: int64
249
249
  * @description Trigger threshold in seconds (strict `>` — the break fires when the
250
250
  * accumulator exceeds this). EU 561/2006 drive rule: `16200` (4 h 30).
251
- * Must be `> 0` and fit in 32 bits.
251
+ * Must be `> 0` and at most 2,147,483,647.
252
252
  * @example 14400
253
253
  */
254
254
  threshold_s: number;
@@ -277,7 +277,7 @@ export interface components {
277
277
  /**
278
278
  * @description Not supported on V3: a windowed break is taken wherever the
279
279
  * vehicle is when it starts, so a `location` here is rejected with
280
- * HTTP 400 `not_supported`. Set only by the V2 compatibility mapper.
280
+ * HTTP 400 `not_supported`.
281
281
  */
282
282
  location?: null | components["schemas"]["Place"];
283
283
  /** @description The window bounding the break's **start**. */
@@ -368,7 +368,7 @@ export interface components {
368
368
  * shifts only `per_route`. Default `0`. Use it to minimise distinct
369
369
  * vehicles; use `per_route` to price each working day. Not accepted on
370
370
  * `shifts[].costs`. When any vehicle has a non-zero rate and any vehicle
371
- * has several shifts, the problem solves without decomposition.
371
+ * has several shifts, the request is solved as a whole rather than split into parts, which can make a large request slower.
372
372
  * @example 400
373
373
  */
374
374
  per_used_vehicle?: number | null;
@@ -413,7 +413,7 @@ export interface components {
413
413
  * cannot see — typically the driver labour for the unload itself
414
414
  * (`service_duration_s` × the hourly rate). Without it, a reload that
415
415
  * consumes only *slack* is free in the objective: it adds no route
416
- * duration, so the solver will happily insert one to displace time that
416
+ * duration, so the solver may insert one to displace time that
417
417
  * `objective.costs.per_wait_hour` would otherwise charge as idle, parking
418
418
  * the vehicle at a depot for no capacity benefit.
419
419
  * @example 38.66
@@ -564,8 +564,8 @@ export interface components {
564
564
  * each other. The solver adds `per_entry` to the objective each time a
565
565
  * route enters a group from a job outside it, the first entry included;
566
566
  * entering from the shift's start or from a reload is free. Keeping each
567
- * group in one visit minimises the "passing-waypoint" / area re-entry count
568
- * last-mile fleets track. Presence of this object enables the feature; omit
567
+ * group in one visit minimises how often a route comes back to an area it
568
+ * already served. Presence of this object enables the feature; omit
569
569
  * it to disable.
570
570
  * @example {
571
571
  * "distance_metric": "straight_line",
@@ -728,7 +728,7 @@ export interface components {
728
728
  * this prices the vehicle that did, so a task rated badly everywhere is
729
729
  * the first one dropped when capacity runs out. It lives in the cost tier,
730
730
  * below `priority`, and adds to `preferences`, `drop_cost` and travel.
731
- * Not applied by decomposition: a problem that sets it solves monolithically.
731
+ * A request that sets it is solved as a whole rather than split into parts, which can make a large request slower.
732
732
  */
733
733
  assignment_costs?: components["schemas"]["AssignmentCost"][] | null;
734
734
  /**
@@ -891,10 +891,8 @@ export interface components {
891
891
  * - `osm`: OpenStreetMap free-flow times. No traffic, so
892
892
  * `travel.departure_time` is rejected with 400.
893
893
  * - `tomtom_real_time`: TomTom live traffic at the moment of the request.
894
- * **Not yet enabled: currently always rejected with 403 `feature_not_enabled`.** Once enabled:
895
- * `travel.departure_time` is rejected; every vehicle must use the `car`
896
- * profile; at most 100 distinct locations; up to ~25 s of matrix fetch at
897
- * 100 locations.
894
+ * **Not available:** a request that sets it is rejected with 403
895
+ * `feature_not_enabled`. Use `tomtom`.
898
896
  * - `straight_line`: great-circle distance at `travel.speed_kmh`, no road
899
897
  * network. `travel.departure_time`, `options.polyline` and any vehicle
900
898
  * `profile` other than `car` are rejected with 400.
@@ -944,8 +942,8 @@ export interface components {
944
942
  * rank, and a date with no shift adds none. Unserved tasks pay nothing;
945
943
  * the charge never outranks `priority` and cannot be combined with
946
944
  * `drop_cost`. Absent or `0` = off; a single-date request is charged
947
- * nothing. A problem that sets it, even on one date, solves without
948
- * decomposition, like `assignment_costs`. Reported as `score.components.delay`. A positive
945
+ * nothing. Like `assignment_costs`, a request that sets it, even on one
946
+ * date, is solved as a whole rather than split into parts. Reported as `score.components.delay`. A positive
949
947
  * rate below `0.00001` is rejected, as is a rate whose total over the
950
948
  * later workdays exceeds `21474.83647` (`out_of_range`).
951
949
  * @example 5
@@ -1169,7 +1167,9 @@ export interface components {
1169
1167
  };
1170
1168
  /**
1171
1169
  * PlanStopReload
1172
- * @description A reload at a depot: the next trip starts there.
1170
+ * @description A reload at a depot: the next trip starts there. It sits between two
1171
+ * task stops, or first on a shift with a non-zero `initial_load`: the unload
1172
+ * before the first job.
1173
1173
  */
1174
1174
  PlanStopReload: {
1175
1175
  /**
@@ -1366,8 +1366,8 @@ export interface components {
1366
1366
  };
1367
1367
  /**
1368
1368
  * @description A hard constraint between tasks, selected by `type`: `sequence`,
1369
- * `tag_order`, `same_vehicle`, `same_day`, `same_route`, `synchronized`,
1370
- * `time_lag`, `compatible_vehicles` or `all_or_none`.
1369
+ * `consecutive`, `tag_order`, `same_vehicle`, `same_day`, `same_route`,
1370
+ * `synchronized`, `time_lag`, `compatible_vehicles` or `all_or_none`.
1371
1371
  * Each type carries only its own fields; any other `type` is rejected with
1372
1372
  * HTTP 400.
1373
1373
  *
@@ -1584,8 +1584,8 @@ export interface components {
1584
1584
  /**
1585
1585
  * Format: int64
1586
1586
  * @description Maximum spread between the synchronized instants in seconds
1587
- * (`0` = exact simultaneity). Required. A negative value, or one that
1588
- * does not fit in 32 bits, is rejected with HTTP 400 `out_of_range`.
1587
+ * (`0` = exact simultaneity). Required. A negative value, or one above
1588
+ * 2,147,483,647, is rejected with HTTP 400 `out_of_range`.
1589
1589
  */
1590
1590
  max_spread_s: number;
1591
1591
  /**
@@ -1614,7 +1614,7 @@ export interface components {
1614
1614
  *
1615
1615
  * Jobs only: if a tag named here selects a **shipment**, the request is
1616
1616
  * rejected with HTTP 400 (a shipment's two legs already carry their own
1617
- * hard precedence, which tag ordering cannot compose with yet). Drop the
1617
+ * hard precedence, which tag ordering does not combine with). Drop the
1618
1618
  * tag from the shipment.
1619
1619
  */
1620
1620
  RelationTagOrder: {
@@ -1646,13 +1646,14 @@ export interface components {
1646
1646
  /**
1647
1647
  * Format: int64
1648
1648
  * @description Upper bound on `t(to) − t(from)` in seconds. Absent = unbounded.
1649
- * Must fit in 32 bits and be `>= min_s` (HTTP 400 otherwise).
1649
+ * From −2,147,483,648 to 2,147,483,647 and `>= min_s` (HTTP 400
1650
+ * otherwise).
1650
1651
  */
1651
1652
  max_s?: number | null;
1652
1653
  /**
1653
1654
  * Format: int64
1654
- * @description Lower bound on `t(to) − t(from)` in seconds. Default `0`. Must fit
1655
- * in 32 bits.
1655
+ * @description Lower bound on `t(to) − t(from)` in seconds. Default `0`. From
1656
+ * −2,147,483,648 to 2,147,483,647.
1656
1657
  * @default 0
1657
1658
  */
1658
1659
  min_s?: number | null;
@@ -2001,7 +2002,7 @@ export interface components {
2001
2002
  load_after?: null | components["schemas"]["Quantities"];
2002
2003
  /**
2003
2004
  * @description Stop location `[longitude, latitude]` (GeoJSON order). Absent on
2004
- * every `break` stop, including a break with a pinned location, and on
2005
+ * every `break` stop, and on
2005
2006
  * `start`/`end` stops for a genuinely open end (no configured
2006
2007
  * coordinate for that end of the shift). A virtual (location-less) job
2007
2008
  * has no coordinate of its own and reports its nearest located
@@ -2173,8 +2174,8 @@ export interface components {
2173
2174
  ScoreComponents: {
2174
2175
  /**
2175
2176
  * Format: double
2176
- * @description Cost of the serving vehicle's `assignment_costs[].cost` (or the task's
2177
- * default assignment cost), in currency units.
2177
+ * @description Cost of the serving vehicle's `assignment_costs[].cost`, in currency
2178
+ * units.
2178
2179
  */
2179
2180
  assignment: number;
2180
2181
  /**
@@ -2266,7 +2267,7 @@ export interface components {
2266
2267
  /**
2267
2268
  * Format: double
2268
2269
  * @description The price of the time window each task was served in, in currency
2269
- * units (`time_windows[].cost`).
2270
+ * units (`time_windows[].choice_cost`).
2270
2271
  */
2271
2272
  window_choice: number;
2272
2273
  /**
@@ -2338,9 +2339,9 @@ export interface components {
2338
2339
  * no-op. It multiplies the vehicle's own rate (the shift's
2339
2340
  * `service_factor` if set, else the vehicle's): effective service time =
2340
2341
  * `service_duration_s / (shift_or_vehicle_factor * factor)`. Same
2341
- * direction and `[0.001, 5]` range as `vehicles[].service_factor`. V2's
2342
- * `proficiency.durationModifier` multiplied duration instead; the V2
2343
- * compatibility layer sends its inverse (`1 / durationModifier`) here.
2342
+ * direction and `[0.001, 5]` range as `vehicles[].service_factor`.
2343
+ * Migrating from V2: `proficiency.durationModifier` multiplied duration
2344
+ * instead, so send `1 / durationModifier` here.
2344
2345
  * @example 1.25
2345
2346
  */
2346
2347
  factor: number;
@@ -2424,12 +2425,14 @@ export interface components {
2424
2425
  * @description Load already on the vehicle at shift start (pre-loaded), per
2425
2426
  * dimension. Occupies capacity on the first trip only — flushed at the
2426
2427
  * first reload — so it reduces first-trip room per dimension, enforced
2427
- * by the per-trip capacity constraint. Not validated against
2428
- * `capacity` at request time: a value at or beyond capacity is
2429
- * accepted and surfaces as a solve-time result (jobs left unassigned,
2430
- * or deferred until the vehicle's first reload flushes it), not an
2431
- * HTTP 400. A dimension named here but absent from `capacity` behaves
2432
- * the same as capacity `0` in that dimension.
2428
+ * by the per-trip capacity constraint. A value above the capacity in that
2429
+ * dimension is rejected with HTTP 400 (`out_of_range`). The capacity is
2430
+ * resolved per dimension: the shift's capacity when it defines the
2431
+ * dimension, otherwise the vehicle's. If the vehicle has a capacity map
2432
+ * that omits the dimension, the capacity is `0`; if the vehicle has no
2433
+ * capacity map and the shift does not define the dimension, it is
2434
+ * unlimited. At capacity, the vehicle has no room until it unloads, so
2435
+ * the solver may start the route with a reload at one of `reloads`.
2433
2436
  */
2434
2437
  initial_load?: null | components["schemas"]["Quantities"];
2435
2438
  /**
@@ -2505,6 +2508,19 @@ export interface components {
2505
2508
  skills?: components["schemas"]["VehicleSkill"][] | null;
2506
2509
  /** @description Where the shift starts. Absent = open start. */
2507
2510
  start?: null | components["schemas"]["ShiftPlace"];
2511
+ /**
2512
+ * @description When `true`, the shift starts at its first task: travel from `start`
2513
+ * to the first task takes no time, so the first arrival is `from`
2514
+ * plus the `start` handling, and waiting there counts from `from`.
2515
+ * That travel's distance is still charged at `per_travel_km` and reported, so
2516
+ * vehicles that start closer to their work stay cheaper; its time is not
2517
+ * charged and counts toward no duration, break or leg limit.
2518
+ * `free_start_travel` instead makes the travel free altogether. `true`
2519
+ * without `start`, or together with `free_start_travel`, is rejected with
2520
+ * HTTP 400 `conflicting_fields`. Default `false`.
2521
+ * @example false
2522
+ */
2523
+ start_at_first_task?: boolean | null;
2508
2524
  /**
2509
2525
  * Format: date-time
2510
2526
  * @description Shift end (RFC 3339 instant, UTC offset required; hard unless `max_overtime_s` set). The
@@ -2671,7 +2687,7 @@ export interface components {
2671
2687
  * this prices the vehicle that did, so a task rated badly everywhere is
2672
2688
  * the first one dropped when capacity runs out. It lives in the cost tier,
2673
2689
  * below `priority`, and adds to `preferences`, `drop_cost` and travel.
2674
- * Not applied by decomposition: a problem that sets it solves monolithically.
2690
+ * A request that sets it is solved as a whole rather than split into parts, which can make a large request slower.
2675
2691
  */
2676
2692
  assignment_costs?: components["schemas"]["AssignmentCost"][] | null;
2677
2693
  /** @description Delivery leg (load off). */
@@ -3173,10 +3189,10 @@ export interface components {
3173
3189
  /**
3174
3190
  * @description How the best plan improved during the search, oldest first: the
3175
3191
  * starting plan, every improvement (thinned to at most 500 entries), and
3176
- * the final plan, which equals `summary.score` (it can equal, or after
3177
- * the final repair be slightly worse than, the entry before it). Present on
3178
- * every solve; absent on evaluate, which does not search. A large solve
3179
- * the solver splits into clusters has the final entry alone.
3192
+ * the final plan, which equals `summary.score` (it can equal, or be
3193
+ * slightly worse than, the entry before it). Present on every solve;
3194
+ * absent on evaluate, which does not search. A large request that is
3195
+ * solved in parts has the final entry alone.
3180
3196
  */
3181
3197
  search_progress?: components["schemas"]["SearchProgressPoint"][] | null;
3182
3198
  /** @description Aggregate statistics for the solve run. */
@@ -3215,10 +3231,10 @@ export interface components {
3215
3231
  * @description Max ranked `insertions` in each `suggestions[]` entry, `1` to `10`;
3216
3232
  * default 5. It caps the insertions per entry, not the number of
3217
3233
  * entries: every task outside `plan` still gets its entry. Values outside
3218
- * the range are a 400, never clamped. It also sets the search's beam
3219
- * width, `max(8, 4 × max_insertions)`: for a unit of several stops, which
3220
- * is never searched exhaustively, each stop after the unit's first keeps
3221
- * at most that many partial placements. A single-stop task has every
3234
+ * the range are a 400, never clamped. It also sets how widely a unit of
3235
+ * several stops is searched (such a unit is never searched exhaustively):
3236
+ * each stop after the unit's first keeps at most
3237
+ * `max(8, 4 × max_insertions)` partial placements. A single-stop task has every
3222
3238
  * feasible position considered unless `time_limit_s` runs out first.
3223
3239
  * @default 5
3224
3240
  * @example 5
@@ -3245,7 +3261,7 @@ export interface components {
3245
3261
  * }
3246
3262
  */
3247
3263
  SuggestReason: {
3248
- /** @description Branch on this. Open set; see [`SuggestReasonCode`]. */
3264
+ /** @description Branch on this. Open set: accept values you do not know. */
3249
3265
  code: components["schemas"]["SuggestReasonCode"];
3250
3266
  /**
3251
3267
  * @description `code` as an English sentence, for people and logs. Do not parse it.
@@ -3825,8 +3841,8 @@ export interface components {
3825
3841
  /**
3826
3842
  * Format: date-time
3827
3843
  * @description Latest allowed start of service (RFC 3339 instant, UTC offset
3828
- * required), measured from arrival plus any windowed break taken first
3829
- * (#1750 D1). Hard unless `per_late_hour` prices lateness.
3844
+ * required). Service starts after any windowed break taken on arrival.
3845
+ * Hard unless `per_late_hour` prices lateness.
3830
3846
  * @example 2026-07-01T12:00:00+02:00
3831
3847
  */
3832
3848
  to: string;
@@ -3930,7 +3946,7 @@ export interface components {
3930
3946
  * @description The constraint that refused the task on at least one vehicle (or
3931
3947
  * `all_or_none`, for a task its group holds back), in the vocabulary of
3932
3948
  * the evaluate violations' `code`. A task lists one reason
3933
- * per constraint, once each, in [`ConstraintCode`] order. Absent on the
3949
+ * per constraint, once each, in the order the `code` values are listed. Absent on the
3934
3950
  * single reason of a `time_limit` or `priced_out` task, which names no
3935
3951
  * constraint.
3936
3952
  */
@@ -3972,7 +3988,9 @@ export interface components {
3972
3988
  * vehicle, named in `constraint`, once each, `unreachable` first
3973
3989
  * (`unknown` when no constraint was recorded); a task that fits but
3974
3990
  * whose `all_or_none` group holds it back has the one reason
3975
- * `all_or_none`. Otherwise there is one reason with no `constraint`.
3991
+ * `all_or_none`, and one whose all-or-none `synchronized`/`time_lag`
3992
+ * group cannot be placed together has `synchronized` and/or `time_lag`.
3993
+ * Otherwise there is one reason with no `constraint`.
3976
3994
  */
3977
3995
  reasons: components["schemas"]["UnassignedReason"][];
3978
3996
  /**
@@ -4001,7 +4019,7 @@ export interface components {
4001
4019
  warnings: components["schemas"]["RequestIssue"][];
4002
4020
  };
4003
4021
  /**
4004
- * @description A vehicle type available to serve tasks.
4022
+ * @description A vehicle available to serve tasks.
4005
4023
  * @example {
4006
4024
  * "capacity": {
4007
4025
  * "volume": 20,
@@ -4101,9 +4119,9 @@ export interface components {
4101
4119
  * this vehicle multiplies whichever applies: effective service time =
4102
4120
  * `service_duration_s / (shift_or_vehicle_factor * task_factor)`.
4103
4121
  *
4104
- * V2's `durationModifier` went the other way (it MULTIPLIED duration,
4105
- * `0.8` = 20% faster); the V2 compatibility layer inverts it and sends it
4106
- * as the task's `service_factors[].factor = 1 / durationModifier`.
4122
+ * Migrating from V2: `durationModifier` went the other way (it multiplied
4123
+ * duration, `0.8` = 20% faster), so send `1 / durationModifier` as the
4124
+ * task's `service_factors[].factor`.
4107
4125
  * @default 1
4108
4126
  */
4109
4127
  service_factor?: number | null;
@@ -4189,7 +4207,7 @@ export interface components {
4189
4207
  * `free_start_travel`/`free_end_travel`, or absent on an open start or
4190
4208
  * end, is exempt. Absent = no cap. Must be > 0: `0` would make every
4191
4209
  * leg too long rather than mean "no cap", so it is rejected with HTTP
4192
- * 400 `out_of_range`, as is a value that does not fit in 32 bits. A
4210
+ * 400 `out_of_range`, as is a value above 2,147,483,647. A
4193
4211
  * breach is reported as `max_leg_travel`.
4194
4212
  * @example 3600
4195
4213
  */
@@ -4246,7 +4264,7 @@ export interface components {
4246
4264
  /**
4247
4265
  * @description A capability a vehicle or shift provides, at a proficiency level:
4248
4266
  * `{ "name": "gas", "level": 3 }`. Always an object; a bare string is
4249
- * rejected at parse.
4267
+ * rejected with HTTP 400.
4250
4268
  * @example {
4251
4269
  * "level": 3,
4252
4270
  * "name": "gas"
@@ -4285,7 +4303,7 @@ export interface components {
4285
4303
  * `period_limit` and `quota` are route-level; `sequence` and `shipment`
4286
4304
  * are on the stop; `unreachable`, `max_leg_travel` and `capacity` can be
4287
4305
  * either. `unknown`
4288
- * means the insertion check refused a stop without naming a constraint
4306
+ * means a stop was refused without a specific constraint being named
4289
4307
  * (not expected in practice).
4290
4308
  */
4291
4309
  code: components["schemas"]["ConstraintCode"];
@@ -4329,8 +4347,8 @@ export interface components {
4329
4347
  * shift is charged on its own part. An empty, non-exempt shift pays for its whole share, so pair the
4330
4348
  * term with `costs.per_route` or `per_used_vehicle` only when both are meant.
4331
4349
  * See `vehicles[].workload_weight` to give a part-time vehicle a smaller
4332
- * share. A problem that sets the term solves without decomposition, like
4333
- * `assignment_costs`.
4350
+ * share. Like `assignment_costs`, a request that sets the term is solved as
4351
+ * a whole rather than split into parts.
4334
4352
  */
4335
4353
  WorkloadShare: {
4336
4354
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solvice/routing",
3
- "version": "0.18.2-beta.0",
3
+ "version": "0.19.1-beta.0",
4
4
  "description": "TypeScript client for the Solvice V3 routing API, generated from its OpenAPI spec.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://docs.solvice.io/guides/platform/sdks/typescript",