@fleetless/contracts 4.0.0-next.1 → 5.0.0-next.1

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +35 -5
  2. package/artifacts/constants.json +4 -14
  3. package/artifacts/openapi.json +46 -13
  4. package/artifacts/routes.json +2 -2
  5. package/artifacts/schema/bridge-hello.schema.json +1 -0
  6. package/artifacts/schema/bridge-job-status.schema.json +114 -0
  7. package/artifacts/schema/bridge-job-update.schema.json +21 -0
  8. package/artifacts/schema/busy-details.schema.json +12 -2
  9. package/artifacts/schema/cloud-job-query.schema.json +29 -0
  10. package/artifacts/schema/command-result.schema.json +12 -2
  11. package/artifacts/schema/invoke-or-service-response.schema.json +12 -2
  12. package/artifacts/schema/invoke-response.schema.json +12 -2
  13. package/artifacts/schema/job-event.schema.json +12 -2
  14. package/artifacts/schema/job-response.schema.json +12 -2
  15. package/artifacts/schema/job-run-list-response.schema.json +4 -3
  16. package/artifacts/schema/job-run-query.schema.json +2 -1
  17. package/artifacts/schema/job-run.schema.json +4 -3
  18. package/artifacts/schema/job-state.schema.json +1 -0
  19. package/artifacts/schema/job.schema.json +12 -2
  20. package/artifacts/schema/robot-jobs-response.schema.json +12 -2
  21. package/artifacts/schema-outgoing/bridge-hello.schema.json +1 -0
  22. package/artifacts/schema-outgoing/bridge-job-status.schema.json +117 -0
  23. package/artifacts/schema-outgoing/bridge-job-update.schema.json +21 -0
  24. package/dist/errors.d.ts +1 -1
  25. package/dist/errors.js +39 -8
  26. package/dist/index.d.ts +4 -4
  27. package/dist/index.js +2 -2
  28. package/dist/jobs.d.ts +55 -6
  29. package/dist/jobs.js +43 -14
  30. package/dist/protocol.d.ts +165 -44
  31. package/dist/protocol.js +144 -59
  32. package/dist/realtime.d.ts +5 -0
  33. package/dist/rest.d.ts +20 -0
  34. package/dist/routes.js +6 -3
  35. package/package.json +1 -1
@@ -28,12 +28,21 @@
28
28
  "type": "string",
29
29
  "enum": [
30
30
  "running",
31
+ "unknown",
31
32
  "succeeded",
32
33
  "failed",
33
34
  "cancelled",
34
35
  "lost"
35
36
  ],
36
- "description": "Where the job stands: `running`, `succeeded`, `failed`, `cancelled` or `lost`. `lost` is a real outcome — the bridge restarted mid-job and the result is gone — stated rather than left reading `running` by default."
37
+ "description": "Where the job stands: `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`. `unknown` is not an outcome — the robot went offline or silent and the cloud does not know yet; the slug stays occupied and the bridge's next statement resolves it, `error` naming why the cloud lost sight of it. `lost` is final: the bridge stated it does not know the job and nothing else runs on its action, or the action server vanished mid-goal."
38
+ },
39
+ "origin": {
40
+ "type": "string",
41
+ "enum": [
42
+ "fleetless",
43
+ "external"
44
+ ],
45
+ "description": "Who started this job. `fleetless` for everything minted by the cloud; `external` for a goal the bridge found active on a published action without having sent it — no parameters, no starter, never written to `job_runs`."
37
46
  },
38
47
  "started_at": {
39
48
  "type": "string",
@@ -91,7 +100,7 @@
91
100
  "type": "null"
92
101
  }
93
102
  ],
94
- "description": "Why the job failed: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. `null` unless `state` is `failed`."
103
+ "description": "Why the job failed, or why the cloud does not know how it stands: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. Set on `failed` and `lost`, and on `unknown` — where `code` is `bridge_disconnected` or `bridge_timeout`, the cloud's own reason for not knowing, cleared when the bridge reports the job running again."
95
104
  }
96
105
  },
97
106
  "required": [
@@ -99,6 +108,7 @@
99
108
  "robot_id",
100
109
  "slug",
101
110
  "state",
111
+ "origin",
102
112
  "started_at",
103
113
  "updated_at",
104
114
  "seq",
@@ -43,12 +43,21 @@
43
43
  "type": "string",
44
44
  "enum": [
45
45
  "running",
46
+ "unknown",
46
47
  "succeeded",
47
48
  "failed",
48
49
  "cancelled",
49
50
  "lost"
50
51
  ],
51
- "description": "Where the job stands: `running`, `succeeded`, `failed`, `cancelled` or `lost`. `lost` is a real outcome — the bridge restarted mid-job and the result is gone — stated rather than left reading `running` by default."
52
+ "description": "Where the job stands: `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`. `unknown` is not an outcome — the robot went offline or silent and the cloud does not know yet; the slug stays occupied and the bridge's next statement resolves it, `error` naming why the cloud lost sight of it. `lost` is final: the bridge stated it does not know the job and nothing else runs on its action, or the action server vanished mid-goal."
53
+ },
54
+ "origin": {
55
+ "type": "string",
56
+ "enum": [
57
+ "fleetless",
58
+ "external"
59
+ ],
60
+ "description": "Who started this job. `fleetless` for everything minted by the cloud; `external` for a goal the bridge found active on a published action without having sent it — no parameters, no starter, never written to `job_runs`."
52
61
  },
53
62
  "started_at": {
54
63
  "type": "string",
@@ -105,7 +114,7 @@
105
114
  "type": "null"
106
115
  }
107
116
  ],
108
- "description": "Why the job failed: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. `null` unless `state` is `failed`."
117
+ "description": "Why the job failed, or why the cloud does not know how it stands: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. Set on `failed` and `lost`, and on `unknown` — where `code` is `bridge_disconnected` or `bridge_timeout`, the cloud's own reason for not knowing, cleared when the bridge reports the job running again."
109
118
  }
110
119
  },
111
120
  "required": [
@@ -113,6 +122,7 @@
113
122
  "robot_id",
114
123
  "slug",
115
124
  "state",
125
+ "origin",
116
126
  "started_at",
117
127
  "updated_at",
118
128
  "seq",
@@ -30,12 +30,21 @@
30
30
  "type": "string",
31
31
  "enum": [
32
32
  "running",
33
+ "unknown",
33
34
  "succeeded",
34
35
  "failed",
35
36
  "cancelled",
36
37
  "lost"
37
38
  ],
38
- "description": "Where the job stands: `running`, `succeeded`, `failed`, `cancelled` or `lost`. `lost` is a real outcome — the bridge restarted mid-job and the result is gone — stated rather than left reading `running` by default."
39
+ "description": "Where the job stands: `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`. `unknown` is not an outcome — the robot went offline or silent and the cloud does not know yet; the slug stays occupied and the bridge's next statement resolves it, `error` naming why the cloud lost sight of it. `lost` is final: the bridge stated it does not know the job and nothing else runs on its action, or the action server vanished mid-goal."
40
+ },
41
+ "origin": {
42
+ "type": "string",
43
+ "enum": [
44
+ "fleetless",
45
+ "external"
46
+ ],
47
+ "description": "Who started this job. `fleetless` for everything minted by the cloud; `external` for a goal the bridge found active on a published action without having sent it — no parameters, no starter, never written to `job_runs`."
39
48
  },
40
49
  "started_at": {
41
50
  "type": "string",
@@ -93,7 +102,7 @@
93
102
  "type": "null"
94
103
  }
95
104
  ],
96
- "description": "Why the job failed: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. `null` unless `state` is `failed`."
105
+ "description": "Why the job failed, or why the cloud does not know how it stands: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. Set on `failed` and `lost`, and on `unknown` — where `code` is `bridge_disconnected` or `bridge_timeout`, the cloud's own reason for not knowing, cleared when the bridge reports the job running again."
97
106
  }
98
107
  },
99
108
  "required": [
@@ -101,6 +110,7 @@
101
110
  "robot_id",
102
111
  "slug",
103
112
  "state",
113
+ "origin",
104
114
  "started_at",
105
115
  "updated_at",
106
116
  "seq",
@@ -38,12 +38,13 @@
38
38
  "type": "string",
39
39
  "enum": [
40
40
  "running",
41
+ "unknown",
41
42
  "succeeded",
42
43
  "failed",
43
44
  "cancelled",
44
45
  "lost"
45
46
  ],
46
- "description": "How the run ended, or `running` while it is still going. `lost` means the bridge restarted mid-run and the outcome is unknowable rather than unknown."
47
+ "description": "How the run ended, or `running` while it is still going. `unknown` while the robot has not accounted for it — offline or silent — and updated once the bridge says how it stands. `lost` is final: the bridge did not know the run and nothing else ran on its action, so the outcome is unknowable rather than unknown."
47
48
  },
48
49
  "started_at": {
49
50
  "type": "string",
@@ -62,7 +63,7 @@
62
63
  "type": "null"
63
64
  }
64
65
  ],
65
- "description": "When the run finished, as an ISO 8601 timestamp. `null` while it is still `running` — a run has an end only once it has one."
66
+ "description": "When the run finished, as an ISO 8601 timestamp. `null` while it is still `running` or `unknown` — a run has an end only once it has one."
66
67
  },
67
68
  "duration_ms": {
68
69
  "anyOf": [
@@ -75,7 +76,7 @@
75
76
  "type": "null"
76
77
  }
77
78
  ],
78
- "description": "How long the run took, in milliseconds. `null` while it is still `running`, never `0` standing in for \"nothing so far\"."
79
+ "description": "How long the run took, in milliseconds. `null` while it is still `running` or `unknown`, never `0` standing in for \"nothing so far\"."
79
80
  },
80
81
  "result": {
81
82
  "anyOf": [
@@ -44,10 +44,11 @@
44
44
  "pattern": "^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$"
45
45
  },
46
46
  "state": {
47
- "description": "Only runs in this state — `running`, `succeeded`, `failed`, `cancelled` or `lost`.",
47
+ "description": "Only runs in this state — `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`.",
48
48
  "type": "string",
49
49
  "enum": [
50
50
  "running",
51
+ "unknown",
51
52
  "succeeded",
52
53
  "failed",
53
54
  "cancelled",
@@ -33,12 +33,13 @@
33
33
  "type": "string",
34
34
  "enum": [
35
35
  "running",
36
+ "unknown",
36
37
  "succeeded",
37
38
  "failed",
38
39
  "cancelled",
39
40
  "lost"
40
41
  ],
41
- "description": "How the run ended, or `running` while it is still going. `lost` means the bridge restarted mid-run and the outcome is unknowable rather than unknown."
42
+ "description": "How the run ended, or `running` while it is still going. `unknown` while the robot has not accounted for it — offline or silent — and updated once the bridge says how it stands. `lost` is final: the bridge did not know the run and nothing else ran on its action, so the outcome is unknowable rather than unknown."
42
43
  },
43
44
  "started_at": {
44
45
  "type": "string",
@@ -57,7 +58,7 @@
57
58
  "type": "null"
58
59
  }
59
60
  ],
60
- "description": "When the run finished, as an ISO 8601 timestamp. `null` while it is still `running` — a run has an end only once it has one."
61
+ "description": "When the run finished, as an ISO 8601 timestamp. `null` while it is still `running` or `unknown` — a run has an end only once it has one."
61
62
  },
62
63
  "duration_ms": {
63
64
  "anyOf": [
@@ -70,7 +71,7 @@
70
71
  "type": "null"
71
72
  }
72
73
  ],
73
- "description": "How long the run took, in milliseconds. `null` while it is still `running`, never `0` standing in for \"nothing so far\"."
74
+ "description": "How long the run took, in milliseconds. `null` while it is still `running` or `unknown`, never `0` standing in for \"nothing so far\"."
74
75
  },
75
76
  "result": {
76
77
  "anyOf": [
@@ -3,6 +3,7 @@
3
3
  "type": "string",
4
4
  "enum": [
5
5
  "running",
6
+ "unknown",
6
7
  "succeeded",
7
8
  "failed",
8
9
  "cancelled",
@@ -25,12 +25,21 @@
25
25
  "type": "string",
26
26
  "enum": [
27
27
  "running",
28
+ "unknown",
28
29
  "succeeded",
29
30
  "failed",
30
31
  "cancelled",
31
32
  "lost"
32
33
  ],
33
- "description": "Where the job stands: `running`, `succeeded`, `failed`, `cancelled` or `lost`. `lost` is a real outcome — the bridge restarted mid-job and the result is gone — stated rather than left reading `running` by default."
34
+ "description": "Where the job stands: `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`. `unknown` is not an outcome — the robot went offline or silent and the cloud does not know yet; the slug stays occupied and the bridge's next statement resolves it, `error` naming why the cloud lost sight of it. `lost` is final: the bridge stated it does not know the job and nothing else runs on its action, or the action server vanished mid-goal."
35
+ },
36
+ "origin": {
37
+ "type": "string",
38
+ "enum": [
39
+ "fleetless",
40
+ "external"
41
+ ],
42
+ "description": "Who started this job. `fleetless` for everything minted by the cloud; `external` for a goal the bridge found active on a published action without having sent it — no parameters, no starter, never written to `job_runs`."
34
43
  },
35
44
  "started_at": {
36
45
  "type": "string",
@@ -88,7 +97,7 @@
88
97
  "type": "null"
89
98
  }
90
99
  ],
91
- "description": "Why the job failed: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. `null` unless `state` is `failed`."
100
+ "description": "Why the job failed, or why the cloud does not know how it stands: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. Set on `failed` and `lost`, and on `unknown` — where `code` is `bridge_disconnected` or `bridge_timeout`, the cloud's own reason for not knowing, cleared when the bridge reports the job running again."
92
101
  }
93
102
  },
94
103
  "required": [
@@ -96,6 +105,7 @@
96
105
  "robot_id",
97
106
  "slug",
98
107
  "state",
108
+ "origin",
99
109
  "started_at",
100
110
  "updated_at",
101
111
  "seq",
@@ -30,12 +30,21 @@
30
30
  "type": "string",
31
31
  "enum": [
32
32
  "running",
33
+ "unknown",
33
34
  "succeeded",
34
35
  "failed",
35
36
  "cancelled",
36
37
  "lost"
37
38
  ],
38
- "description": "Where the job stands: `running`, `succeeded`, `failed`, `cancelled` or `lost`. `lost` is a real outcome — the bridge restarted mid-job and the result is gone — stated rather than left reading `running` by default."
39
+ "description": "Where the job stands: `running`, `unknown`, `succeeded`, `failed`, `cancelled` or `lost`. `unknown` is not an outcome — the robot went offline or silent and the cloud does not know yet; the slug stays occupied and the bridge's next statement resolves it, `error` naming why the cloud lost sight of it. `lost` is final: the bridge stated it does not know the job and nothing else runs on its action, or the action server vanished mid-goal."
40
+ },
41
+ "origin": {
42
+ "type": "string",
43
+ "enum": [
44
+ "fleetless",
45
+ "external"
46
+ ],
47
+ "description": "Who started this job. `fleetless` for everything minted by the cloud; `external` for a goal the bridge found active on a published action without having sent it — no parameters, no starter, never written to `job_runs`."
39
48
  },
40
49
  "started_at": {
41
50
  "type": "string",
@@ -93,7 +102,7 @@
93
102
  "type": "null"
94
103
  }
95
104
  ],
96
- "description": "Why the job failed: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. `null` unless `state` is `failed`."
105
+ "description": "Why the job failed, or why the cloud does not know how it stands: a human `message`, a `code` where one exists, and `details` for the codes that carry a documented payload. Set on `failed` and `lost`, and on `unknown` — where `code` is `bridge_disconnected` or `bridge_timeout`, the cloud's own reason for not knowing, cleared when the bridge reports the job running again."
97
106
  }
98
107
  },
99
108
  "required": [
@@ -101,6 +110,7 @@
101
110
  "robot_id",
102
111
  "slug",
103
112
  "state",
113
+ "origin",
104
114
  "started_at",
105
115
  "updated_at",
106
116
  "seq",
@@ -41,6 +41,7 @@
41
41
  "type": "string",
42
42
  "enum": [
43
43
  "running",
44
+ "unknown",
44
45
  "succeeded",
45
46
  "failed",
46
47
  "cancelled",
@@ -0,0 +1,117 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "type": {
6
+ "type": "string",
7
+ "const": "job_status"
8
+ },
9
+ "request_id": {
10
+ "type": "string",
11
+ "minLength": 1,
12
+ "maxLength": 64
13
+ },
14
+ "jobs": {
15
+ "type": "array",
16
+ "items": {
17
+ "type": "object",
18
+ "properties": {
19
+ "job_id": {
20
+ "type": "string",
21
+ "format": "uuid",
22
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
23
+ },
24
+ "state": {
25
+ "type": "string",
26
+ "enum": [
27
+ "running",
28
+ "unknown",
29
+ "succeeded",
30
+ "failed",
31
+ "cancelled",
32
+ "lost"
33
+ ]
34
+ },
35
+ "feedback": {
36
+ "anyOf": [
37
+ {},
38
+ {
39
+ "type": "null"
40
+ }
41
+ ]
42
+ },
43
+ "progress": {
44
+ "anyOf": [
45
+ {
46
+ "type": "number",
47
+ "minimum": 0,
48
+ "maximum": 1
49
+ },
50
+ {
51
+ "type": "null"
52
+ }
53
+ ]
54
+ },
55
+ "result": {
56
+ "anyOf": [
57
+ {},
58
+ {
59
+ "type": "null"
60
+ }
61
+ ]
62
+ },
63
+ "error": {
64
+ "anyOf": [
65
+ {
66
+ "type": "object",
67
+ "properties": {
68
+ "code": {
69
+ "type": "string",
70
+ "minLength": 1
71
+ },
72
+ "message": {
73
+ "type": "string",
74
+ "minLength": 1
75
+ },
76
+ "details": {}
77
+ },
78
+ "required": [
79
+ "code",
80
+ "message"
81
+ ],
82
+ "additionalProperties": false
83
+ },
84
+ {
85
+ "type": "null"
86
+ }
87
+ ]
88
+ }
89
+ },
90
+ "required": [
91
+ "job_id",
92
+ "state",
93
+ "feedback",
94
+ "progress",
95
+ "result",
96
+ "error"
97
+ ],
98
+ "additionalProperties": false
99
+ }
100
+ },
101
+ "unknown_job_ids": {
102
+ "type": "array",
103
+ "items": {
104
+ "type": "string",
105
+ "format": "uuid",
106
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
107
+ }
108
+ }
109
+ },
110
+ "required": [
111
+ "type",
112
+ "request_id",
113
+ "jobs",
114
+ "unknown_job_ids"
115
+ ],
116
+ "additionalProperties": false
117
+ }
@@ -21,12 +21,31 @@
21
21
  "type": "string",
22
22
  "enum": [
23
23
  "running",
24
+ "unknown",
24
25
  "succeeded",
25
26
  "failed",
26
27
  "cancelled",
27
28
  "lost"
28
29
  ]
29
30
  },
31
+ "origin": {
32
+ "type": "string",
33
+ "enum": [
34
+ "fleetless",
35
+ "external"
36
+ ]
37
+ },
38
+ "goal_id": {
39
+ "anyOf": [
40
+ {
41
+ "type": "string",
42
+ "minLength": 1
43
+ },
44
+ {
45
+ "type": "null"
46
+ }
47
+ ]
48
+ },
30
49
  "feedback": {
31
50
  "anyOf": [
32
51
  {},
@@ -92,6 +111,8 @@
92
111
  "job_id",
93
112
  "slug",
94
113
  "state",
114
+ "origin",
115
+ "goal_id",
95
116
  "feedback",
96
117
  "progress",
97
118
  "result",
package/dist/errors.d.ts CHANGED
@@ -49,5 +49,5 @@ export type ParameterInvalidDetails = z.infer<typeof parameterInvalidDetails>;
49
49
  * list is the shared vocabulary, not a closed set, so a new refusal never
50
50
  * needs a contracts release before it can be reported honestly.
51
51
  */
52
- export declare const ERROR_CODES: readonly ["not_found", "validation_error", "bad_request", "unknown_datapoint", "invalid_token", "protocol_mismatch", "invalid_frame", "duplicate_slug", "reserved_slug", "unknown_slug", "unknown_field_path", "unknown_type", "unknown_topic", "invalid_rate", "invalid_range", "config_conflict", "no_data", "robot_offline", "bridge_timeout", "unauthorized", "forbidden", "invalid_credentials", "token_expired", "token_revoked", "email_taken", "identifier_taken", "weak_password", "account_blocked", "busy", "parameter_invalid", "job_lost", "action_server_lost", "action_failed", "goal_rejected", "goal_send_failed", "result_failed", "goal_uncontrollable", "bridge_disconnected", "config_changed", "publisher_busy", "unknown_command", "not_subscribable", "camera_offline", "no_snapshot_yet", "live_unavailable", "wrong_kind", "not_recorded", "not_aggregatable", "quota_exceeded", "credential_in_use", "goal_timeout", "robot_in_use", "robot_deletion_partial", "job_queue_full", "invalid_uuid", "rate_limited", "tier_required", "token_spent", "service_timeout", "asset_missing", "dynamic_registration_disabled", "client_limit_reached", "idp_unavailable", "mcp_disabled", "tool_not_available", "capability_required", "last_owner", "target_state_conflict", "signup_closed", "draft_not_a_document", "internal_error", "not_cancellable", "unsupported_media_type", "wrong_browser", "invalid_yaml", "unstorable_yaml", "registration_closed", "domain_not_allowed", "email_unverified", "origin_not_allowed", "template_invalid", "provider_disabled", "provider_misconfigured", "invalid_redirect_uri", "interaction_expired"];
52
+ export declare const ERROR_CODES: readonly ["not_found", "validation_error", "bad_request", "unknown_datapoint", "invalid_token", "protocol_mismatch", "bridge_too_old", "invalid_frame", "duplicate_slug", "reserved_slug", "unknown_slug", "unknown_field_path", "unknown_type", "unknown_topic", "invalid_rate", "invalid_range", "config_conflict", "no_data", "robot_offline", "bridge_timeout", "unauthorized", "forbidden", "invalid_credentials", "token_expired", "token_revoked", "email_taken", "identifier_taken", "weak_password", "account_blocked", "busy", "parameter_invalid", "job_lost", "job_unknown_to_bridge", "action_server_lost", "action_failed", "goal_rejected", "goal_send_failed", "result_failed", "goal_uncontrollable", "bridge_disconnected", "config_changed", "publisher_busy", "unknown_command", "not_subscribable", "camera_offline", "no_snapshot_yet", "live_unavailable", "wrong_kind", "not_recorded", "not_aggregatable", "quota_exceeded", "credential_in_use", "goal_timeout", "robot_in_use", "robot_deletion_partial", "job_queue_full", "invalid_uuid", "rate_limited", "tier_required", "token_spent", "service_timeout", "asset_missing", "dynamic_registration_disabled", "client_limit_reached", "idp_unavailable", "mcp_disabled", "tool_not_available", "capability_required", "last_owner", "target_state_conflict", "signup_closed", "draft_not_a_document", "internal_error", "not_cancellable", "unsupported_media_type", "wrong_browser", "invalid_yaml", "unstorable_yaml", "registration_closed", "domain_not_allowed", "email_unverified", "origin_not_allowed", "template_invalid", "provider_disabled", "provider_misconfigured", "invalid_redirect_uri", "interaction_expired"];
53
53
  export type ErrorCode = (typeof ERROR_CODES)[number];
package/dist/errors.js CHANGED
@@ -51,6 +51,16 @@ export const ERROR_CODES = [
51
51
  'unknown_datapoint',
52
52
  'invalid_token',
53
53
  'protocol_mismatch',
54
+ /**
55
+ * The cloud's `hello_error` for a bridge whose `protocol_version` is below
56
+ * every version it serves — since protocol 5, anything below 5. Its message
57
+ * names the bridge release to install (`LATEST_BRIDGE_VERSION`, 6.0.0 at
58
+ * the cut), because "too old" alone leaves an operator guessing how far to
59
+ * upgrade. Distinct from `protocol_mismatch`, the generic refusal for a
60
+ * version the cloud cannot place: this one says which way the gap runs and
61
+ * what closes it. Reaches the robot's detail view as `last_hello_error`.
62
+ */
63
+ 'bridge_too_old',
54
64
  'invalid_frame',
55
65
  // Configuration.
56
66
  'duplicate_slug',
@@ -74,9 +84,10 @@ export const ERROR_CODES = [
74
84
  /**
75
85
  * The cloud has heard nothing — heartbeat or real progress — from a
76
86
  * running job for longer than it tolerates while the bridge is connected:
77
- * `patience_ms` for a protocol-3 bridge, `JOB_HEARTBEAT_TIMEOUT_MS` for a
78
- * protocol-4 one once it has heard from the job at all. `job.error.code`
79
- * on `lost`.
87
+ * `patience_ms` until the first report, `JOB_HEARTBEAT_TIMEOUT_MS` after
88
+ * it. `job.error.code` on `unknown`, not `lost`: silence is the cloud's
89
+ * guess, so it asks the bridge with `job_query` and the answer resolves the
90
+ * job — running again clears this code, an end replaces it.
80
91
  */
81
92
  'bridge_timeout',
82
93
  // Identity and rights. `forbidden` is deliberately the answer both
@@ -145,8 +156,26 @@ export const ERROR_CODES = [
145
156
  'busy',
146
157
  /** A parameter failed its declared rule; details name the field and the rule. */
147
158
  'parameter_invalid',
148
- /** The bridge could not account for this job after a restart. */
159
+ /**
160
+ * The bridge's own statement, while connected, that it lost track of a job
161
+ * it still names — the vocabulary behind its `job_lost` frame. Distinct
162
+ * from `job_unknown_to_bridge`, the cloud's conclusion about a job the
163
+ * bridge does not name at all.
164
+ */
149
165
  'job_lost',
166
+ /**
167
+ * The bridge does not know this job — its `hello.active_jobs` or a
168
+ * `job_status` answer leaves it out — and, for an action, no goal the
169
+ * bridge cannot attribute is active on the job's action any more, so none
170
+ * of them can be it. A `job.error.code` on `lost`, final: how an `unknown`
171
+ * job the bridge has no word about ends. A service job, which has no goals to look
172
+ * at, gets it as soon as the bridge does not know it; so does a job whose
173
+ * persisted goal the action server no longer knows (its result expired).
174
+ * Distinct from `job_lost`, the bridge's own statement about a job it
175
+ * still names, and from `bridge_disconnected`/`bridge_timeout`, the
176
+ * cloud's guesses that make a job `unknown` in the first place.
177
+ */
178
+ 'job_unknown_to_bridge',
150
179
  /**
151
180
  * The robot's action server vanished mid-goal — the bridge's own liveness
152
181
  * check found `server_is_ready()` false for three seconds straight and
@@ -163,13 +192,15 @@ export const ERROR_CODES = [
163
192
  'goal_send_failed',
164
193
  /** Asking the action server for its result raised; `job.error.code` on `failed`. */
165
194
  'result_failed',
166
- /** A goal accepted after its own timeout could not then be cancelled; `job.error.code` on `failed`. */
195
+ /** A goal accepted after its own timeout could not then be cancelled; `job.error.code` on `lost`. */
167
196
  'goal_uncontrollable',
168
197
  /**
169
198
  * The robot stayed offline for longer than `JOB_OFFLINE_GRACE_MS` while a
170
- * job was running. A late real outcome, if the robot reconnects and the
171
- * bridge still has it, corrects this — it is not final the way a genuine
172
- * bridge report is. `job.error.code` on `lost`.
199
+ * job was running. `job.error.code` on `unknown`, not `lost`: the cloud
200
+ * does not know how the job stands, and the reconnecting bridge's
201
+ * `hello.active_jobs` resolves it — running again clears this code, an end
202
+ * replaces it, and a job the bridge does not know becomes `lost` with
203
+ * `job_unknown_to_bridge`.
173
204
  */
174
205
  'bridge_disconnected',
175
206
  /**
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@ export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, ro
3
3
  export type { ApplyErrorKind, ApplyError } from './common.js';
4
4
  export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
5
5
  export type { McpAppPaths, McpToolKind, McpExposure, McpCapabilities, McpRobotDatasheet, McpRolePreviewResponse, } from './mcp.js';
6
- export { PROTOCOL_VERSION, PROTOCOL_VERSIONS, PROTOCOL_SUNSET_DAYS, LATEST_BRIDGE_VERSION, protocolStatus, minimumProtocolVersion, sunsetOf, statusFromTable, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, bridgeLinkMode, datapointFrame, bridgeState, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, CLOSE_TOKEN_ROTATED, bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress, activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, JOB_HEARTBEAT_INTERVAL_MS, JOB_HEARTBEAT_TIMEOUT_MS, JOB_OFFLINE_GRACE_MS, } from './protocol.js';
7
- export type { ProtocolVersionEntry, ProtocolStatus, BridgeHello, CloudHelloOk, CloudHelloError, CloudPing, BridgePong, BridgeLinkMode, DatapointFrame, BridgeState, CloudConfig, BridgeConfigApplied, CloudIntrospectRequest, BridgeIntrospect, CloudTypeRequest, BridgeTypeDefinitions, CloudInvoke, CloudCancel, CloudPublish, BridgeJobUpdate, BridgeJobLost, SnapshotHeader, CloudCameraStart, CloudCameraStop, BridgeCameraState, ActiveJob, BridgeAssetsAvailable, CloudAssetRequest, BridgeAssetProgress, } from './protocol.js';
8
- export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
9
- export type { JobState, Job, JobEvent, BusyDetails, PublisherBusyDetails, JobQueueFullDetails, } from './jobs.js';
6
+ export { PROTOCOL_VERSION, PROTOCOL_VERSIONS, PROTOCOL_SUNSET_DAYS, LATEST_BRIDGE_VERSION, protocolStatus, minimumProtocolVersion, sunsetOf, statusFromTable, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, bridgeLinkMode, datapointFrame, bridgeState, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, cloudJobQuery, bridgeJobStatusEntry, bridgeJobStatus, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, CLOSE_TOKEN_ROTATED, bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress, activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, JOB_HEARTBEAT_INTERVAL_MS, JOB_HEARTBEAT_TIMEOUT_MS, JOB_OFFLINE_GRACE_MS, } from './protocol.js';
7
+ export type { ProtocolVersionEntry, ProtocolStatus, BridgeHello, CloudHelloOk, CloudHelloError, CloudPing, BridgePong, BridgeLinkMode, DatapointFrame, BridgeState, CloudConfig, BridgeConfigApplied, CloudIntrospectRequest, BridgeIntrospect, CloudTypeRequest, BridgeTypeDefinitions, CloudInvoke, CloudCancel, CloudPublish, BridgeJobUpdate, BridgeJobLost, CloudJobQuery, BridgeJobStatusEntry, BridgeJobStatus, SnapshotHeader, CloudCameraStart, CloudCameraStop, BridgeCameraState, ActiveJob, BridgeAssetsAvailable, CloudAssetRequest, BridgeAssetProgress, } from './protocol.js';
8
+ export { jobState, jobOrigin, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
9
+ export type { JobState, JobOrigin, Job, JobEvent, BusyDetails, PublisherBusyDetails, JobQueueFullDetails, } from './jobs.js';
10
10
  export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
11
11
  export type { JobActor, JobRunKind, JobRun, JobRunQuery, JobRunListResponse, JobRunSummary } from './jobs.js';
12
12
  export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, lowBandwidthSection, LOW_BANDWIDTH_DEFAULTS, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds, ALERT_SEVERITY_DEFAULT, ALERT_ENABLED_DEFAULT, RETENTION_INTERVAL_SECONDS_DEFAULT, CHART_WINDOW_MINUTES_DEFAULT, cameraSource, cameraCredentials, } from './config.js';
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  export { SLUG_RULE, ROS_NAME_RULE, ROS_TYPE_NAME_RULE, FIELD_PATH_RULE, slug, rosName, rosTypeName, fieldPath, wireSeqCursor, wireTimestampMs, applyErrorKind, applyError, } from './common.js';
3
3
  export { MCP_PROTOCOL_VERSION, MCP_ENDPOINT_PATH, mcpAppEndpointPath, MCP_APP_PATHS, MCP_TOOL_NAME_MAX, MCP_ASSET_LINK_PATH, MCP_ASSET_LINK_TTL_MS, mcpToolNamePattern, mcpToolKind, mcpExposure, mcpCapabilities, mcpRobotDatasheet, mcpRolePreviewResponse, } from './mcp.js';
4
- export { PROTOCOL_VERSION, PROTOCOL_VERSIONS, PROTOCOL_SUNSET_DAYS, LATEST_BRIDGE_VERSION, protocolStatus, minimumProtocolVersion, sunsetOf, statusFromTable, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, bridgeLinkMode, datapointFrame, bridgeState, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, CLOSE_TOKEN_ROTATED,
4
+ export { PROTOCOL_VERSION, PROTOCOL_VERSIONS, PROTOCOL_SUNSET_DAYS, LATEST_BRIDGE_VERSION, protocolStatus, minimumProtocolVersion, sunsetOf, statusFromTable, bridgeHello, cloudHelloOk, cloudHelloError, cloudPing, bridgePong, bridgeLinkMode, datapointFrame, bridgeState, cloudConfig, bridgeConfigApplied, cloudIntrospectRequest, bridgeIntrospect, cloudTypeRequest, bridgeTypeDefinitions, cloudInvoke, cloudCancel, cloudPublish, bridgeJobUpdate, bridgeJobLost, cloudJobQuery, bridgeJobStatusEntry, bridgeJobStatus, snapshotHeader, cloudCameraStart, cloudCameraStop, bridgeCameraState, SNAPSHOT_MAX_BYTES, CLOSE_ROBOT_DELETED, CLOSE_TOKEN_ROTATED,
5
5
  // Assets.
6
6
  bridgeAssetsAvailable, cloudAssetRequest, bridgeAssetProgress,
7
7
  // Addressing.
8
8
  activeJob, DEFAULT_PATIENCE_MS, MAX_PATIENCE_MS, MIN_PATIENCE_MS, JOB_HEARTBEAT_INTERVAL_MS, JOB_HEARTBEAT_TIMEOUT_MS, JOB_OFFLINE_GRACE_MS, } from './protocol.js';
9
- export { jobState, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
9
+ export { jobState, jobOrigin, job, jobEvent, busyDetails, publisherBusyDetails, jobQueueFullDetails } from './jobs.js';
10
10
  export { JOB_RUN_PAGE_MAX, JOB_RUN_RETENTION_DAYS, jobActor, jobRunKind, jobRun, jobRunQuery, jobRunListResponse, jobRunSummaryQuery, jobRunSummary, } from './jobs.js';
11
11
  export { FLEETLESS_FORMAT_VERSION, RESERVED_SLUGS, parameterType, parameterSpec, parameterMap, serviceDescription, parameterDescription, messageTemplate, messageRef, messageBody, messageMap, PLACEHOLDER_RE, placeholderNames, actionConfig, serviceConfig, publisherConfig, cameraConfig, alertCondition, datapointAlert, rateThrottleHz, datapointNumeric, datapointRetention, datapointChart, datapointConfig, lowBandwidthSection, LOW_BANDWIDTH_DEFAULTS, robotConfigDoc, validationIssue, configState, snapshotIntervalSeconds,
12
12
  // The defaults the format names, so nobody invents them twice.