@north-light/api 0.0.0 → 0.3.414
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/LICENSE +18 -0
- package/README.md +66 -2
- package/dist/api/__tests__/error-codes.test.d.ts +1 -0
- package/dist/api/__tests__/error-codes.test.js +79 -0
- package/dist/api/__tests__/integration/client.test.d.ts +1 -0
- package/dist/api/__tests__/integration/client.test.js +276 -0
- package/dist/api/client.d.ts +501 -0
- package/dist/api/client.js +1281 -0
- package/dist/api/command-manifest/index.d.ts +3 -0
- package/dist/api/command-manifest/index.js +3 -0
- package/dist/api/command-manifest/manifest.d.ts +51 -0
- package/dist/api/command-manifest/manifest.js +332 -0
- package/dist/api/command-manifest/result.d.ts +25 -0
- package/dist/api/command-manifest/result.js +97 -0
- package/dist/api/command-manifest/schema.d.ts +28 -0
- package/dist/api/command-manifest/schema.js +856 -0
- package/dist/api/dto/analytics.d.ts +184 -0
- package/dist/api/dto/analytics.js +3 -0
- package/dist/api/dto/attach.d.ts +22 -0
- package/dist/api/dto/attach.js +13 -0
- package/dist/api/dto/bash-jobs.d.ts +24 -0
- package/dist/api/dto/bash-jobs.js +9 -0
- package/dist/api/dto/bash.d.ts +17 -0
- package/dist/api/dto/bash.js +1 -0
- package/dist/api/dto/broker-ops.d.ts +187 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/broker-signals.d.ts +25 -0
- package/dist/api/dto/broker-signals.js +1 -0
- package/dist/api/dto/broker.d.ts +86 -0
- package/dist/api/dto/broker.js +20 -0
- package/dist/api/dto/canvas.d.ts +359 -0
- package/dist/api/dto/canvas.js +2 -0
- package/dist/api/dto/chat-inventory.d.ts +56 -0
- package/dist/api/dto/chat-inventory.js +11 -0
- package/dist/api/dto/common.d.ts +29 -0
- package/dist/api/dto/common.js +15 -0
- package/dist/api/dto/config.d.ts +46 -0
- package/dist/api/dto/config.js +3 -0
- package/dist/api/dto/crons.d.ts +158 -0
- package/dist/api/dto/crons.js +10 -0
- package/dist/api/dto/custom-objects.d.ts +66 -0
- package/dist/api/dto/custom-objects.js +1 -0
- package/dist/api/dto/delivery.d.ts +71 -0
- package/dist/api/dto/delivery.js +7 -0
- package/dist/api/dto/docs.d.ts +135 -0
- package/dist/api/dto/docs.js +8 -0
- package/dist/api/dto/files.d.ts +21 -0
- package/dist/api/dto/files.js +1 -0
- package/dist/api/dto/focus.d.ts +24 -0
- package/dist/api/dto/focus.js +10 -0
- package/dist/api/dto/grants.d.ts +28 -0
- package/dist/api/dto/grants.js +1 -0
- package/dist/api/dto/health.d.ts +116 -0
- package/dist/api/dto/health.js +2 -0
- package/dist/api/dto/human-requests.d.ts +113 -0
- package/dist/api/dto/human-requests.js +4 -0
- package/dist/api/dto/human.d.ts +28 -0
- package/dist/api/dto/human.js +4 -0
- package/dist/api/dto/inbox.d.ts +273 -0
- package/dist/api/dto/inbox.js +4 -0
- package/dist/api/dto/lifecycle.d.ts +88 -0
- package/dist/api/dto/lifecycle.js +3 -0
- package/dist/api/dto/limits.d.ts +29 -0
- package/dist/api/dto/limits.js +2 -0
- package/dist/api/dto/mail.d.ts +44 -0
- package/dist/api/dto/mail.js +1 -0
- package/dist/api/dto/messages.d.ts +104 -0
- package/dist/api/dto/messages.js +2 -0
- package/dist/api/dto/model-config.d.ts +25 -0
- package/dist/api/dto/model-config.js +1 -0
- package/dist/api/dto/modelauth.d.ts +132 -0
- package/dist/api/dto/modelauth.js +4 -0
- package/dist/api/dto/node-events.d.ts +65 -0
- package/dist/api/dto/node-events.js +4 -0
- package/dist/api/dto/node-outcomes.d.ts +88 -0
- package/dist/api/dto/node-outcomes.js +2 -0
- package/dist/api/dto/node-records.d.ts +35 -0
- package/dist/api/dto/node-records.js +5 -0
- package/dist/api/dto/nodes.d.ts +371 -0
- package/dist/api/dto/nodes.js +3 -0
- package/dist/api/dto/objects.d.ts +172 -0
- package/dist/api/dto/objects.js +5 -0
- package/dist/api/dto/profiles.d.ts +117 -0
- package/dist/api/dto/profiles.js +4 -0
- package/dist/api/dto/recovery.d.ts +104 -0
- package/dist/api/dto/recovery.js +1 -0
- package/dist/api/dto/reports.d.ts +95 -0
- package/dist/api/dto/reports.js +2 -0
- package/dist/api/dto/review-comments.d.ts +146 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +113 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/dto/run-events.d.ts +295 -0
- package/dist/api/dto/run-events.js +6 -0
- package/dist/api/dto/structured-requests.d.ts +64 -0
- package/dist/api/dto/structured-requests.js +5 -0
- package/dist/api/dto/subscriptions.d.ts +14 -0
- package/dist/api/dto/subscriptions.js +2 -0
- package/dist/api/dto/worktree.d.ts +55 -0
- package/dist/api/dto/worktree.js +6 -0
- package/dist/api/error-codes.d.ts +259 -0
- package/dist/api/error-codes.js +56 -0
- package/dist/api/errors.d.ts +47 -0
- package/dist/api/errors.js +66 -0
- package/dist/api/index.d.ts +48 -0
- package/dist/api/index.js +45 -0
- package/dist/api/long-poll.d.ts +59 -0
- package/dist/api/long-poll.js +67 -0
- package/dist/api/node-transport.d.ts +18 -0
- package/dist/api/node-transport.js +105 -0
- package/dist/api/plugin-manifest-schema.d.ts +233 -0
- package/dist/api/plugin-manifest-schema.js +23 -0
- package/dist/api/routes.d.ts +164 -0
- package/dist/api/routes.js +197 -0
- package/dist/api/runtime-version.d.ts +31 -0
- package/dist/api/runtime-version.js +50 -0
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/canvas/boot-id.d.ts +6 -0
- package/dist/core/canvas/boot-id.js +26 -0
- package/dist/core/canvas/paths.d.ts +72 -0
- package/dist/core/canvas/paths.js +163 -0
- package/dist/core/canvas/pid.d.ts +391 -0
- package/dist/core/canvas/pid.js +948 -0
- package/dist/core/command-plugins/bundle.d.ts +149 -0
- package/dist/core/command-plugins/bundle.js +588 -0
- package/dist/core/command-plugins/endpoint.d.ts +24 -0
- package/dist/core/command-plugins/endpoint.js +51 -0
- package/dist/core/config.d.ts +233 -0
- package/dist/core/config.js +1120 -0
- package/dist/core/env-name.d.ts +6 -0
- package/dist/core/env-name.js +9 -0
- package/dist/core/errors.d.ts +38 -0
- package/dist/core/errors.js +90 -0
- package/dist/core/events/emit.d.ts +6 -0
- package/dist/core/events/emit.js +42 -0
- package/dist/core/events/envelope.d.ts +2 -0
- package/dist/core/events/envelope.js +84 -0
- package/dist/core/events/errors.d.ts +4 -0
- package/dist/core/events/errors.js +69 -0
- package/dist/core/events/operation-id.d.ts +4 -0
- package/dist/core/events/operation-id.js +24 -0
- package/dist/core/events/serialize.d.ts +4 -0
- package/dist/core/events/serialize.js +199 -0
- package/dist/core/events/source.d.ts +16 -0
- package/dist/core/events/source.js +31 -0
- package/dist/core/events/types.d.ts +68 -0
- package/dist/core/events/types.js +11 -0
- package/dist/core/exclusive-lock.d.ts +34 -0
- package/dist/core/exclusive-lock.js +197 -0
- package/dist/core/fs-utils.d.ts +44 -0
- package/dist/core/fs-utils.js +208 -0
- package/dist/core/help.d.ts +309 -0
- package/dist/core/help.js +406 -0
- package/dist/core/human/page-catalog.d.ts +57 -0
- package/dist/core/human/page-catalog.js +172 -0
- package/dist/core/installed-plugins.d.ts +2 -0
- package/dist/core/installed-plugins.js +79 -0
- package/dist/core/io.d.ts +122 -0
- package/dist/core/io.js +373 -0
- package/dist/core/keybindings/attach-control.d.ts +49 -0
- package/dist/core/keybindings/attach-control.js +42 -0
- package/dist/core/keybindings/catalog.d.ts +18 -0
- package/dist/core/keybindings/catalog.js +257 -0
- package/dist/core/keybindings/types.d.ts +42 -0
- package/dist/core/keybindings/types.js +1 -0
- package/dist/core/layout.d.ts +34 -0
- package/dist/core/layout.js +106 -0
- package/dist/core/locked-file.d.ts +27 -0
- package/dist/core/locked-file.js +118 -0
- package/dist/core/log.d.ts +9 -0
- package/dist/core/log.js +89 -0
- package/dist/core/manifest.d.ts +5 -0
- package/dist/core/manifest.js +15 -0
- package/dist/core/plugin-env.d.ts +8 -0
- package/dist/core/plugin-env.js +31 -0
- package/dist/core/plugin-extensions.d.ts +29 -0
- package/dist/core/plugin-extensions.js +191 -0
- package/dist/core/plugin-swap-lock.d.ts +9 -0
- package/dist/core/plugin-swap-lock.js +31 -0
- package/dist/core/preview-result-path.d.ts +4 -0
- package/dist/core/preview-result-path.js +26 -0
- package/dist/core/profiles/env-store.d.ts +22 -0
- package/dist/core/profiles/env-store.js +163 -0
- package/dist/core/profiles/fuzzy-match.d.ts +19 -0
- package/dist/core/profiles/fuzzy-match.js +92 -0
- package/dist/core/profiles/manifest.d.ts +120 -0
- package/dist/core/profiles/manifest.js +529 -0
- package/dist/core/rate-limit-scope.d.ts +25 -0
- package/dist/core/rate-limit-scope.js +64 -0
- package/dist/core/render.d.ts +12 -0
- package/dist/core/render.js +138 -0
- package/dist/core/resolver.d.ts +14 -0
- package/dist/core/resolver.js +111 -0
- package/dist/core/runtime/branded-host.d.ts +55 -0
- package/dist/core/runtime/branded-host.js +485 -0
- package/dist/core/runtime/broker/daemon-ops.d.ts +65 -0
- package/dist/core/runtime/broker/daemon-ops.js +177 -0
- package/dist/core/runtime/broker/signal-stream.d.ts +30 -0
- package/dist/core/runtime/broker/signal-stream.js +149 -0
- package/dist/core/scope.d.ts +32 -0
- package/dist/core/scope.js +184 -0
- package/dist/core/scoped-state/db.d.ts +17 -0
- package/dist/core/scoped-state/db.js +247 -0
- package/dist/core/scoped-state/migrate.d.ts +8 -0
- package/dist/core/scoped-state/migrate.js +187 -0
- package/dist/core/scoped-state/paths.d.ts +9 -0
- package/dist/core/scoped-state/paths.js +27 -0
- package/dist/core/scoped-state/profiles.d.ts +27 -0
- package/dist/core/scoped-state/profiles.js +93 -0
- package/dist/core/scoped-state/providers.d.ts +24 -0
- package/dist/core/scoped-state/providers.js +19 -0
- package/dist/core/scoped-state/schema.d.ts +6 -0
- package/dist/core/scoped-state/schema.js +43 -0
- package/dist/core/scoped-state/settings.d.ts +28 -0
- package/dist/core/scoped-state/settings.js +83 -0
- package/dist/core/spaces/open-beneath.d.ts +71 -0
- package/dist/core/spaces/open-beneath.js +581 -0
- package/dist/core/sqlite-statements.d.ts +4 -0
- package/dist/core/sqlite-statements.js +17 -0
- package/dist/core/subscription-state.d.ts +121 -0
- package/dist/core/subscription-state.js +287 -0
- package/dist/core/user-settings.d.ts +377 -0
- package/dist/core/user-settings.js +458 -0
- package/dist/daemon/broker-signals/bus.d.ts +30 -0
- package/dist/daemon/broker-signals/bus.js +87 -0
- package/dist/daemon/manage.d.ts +176 -0
- package/dist/daemon/manage.js +664 -0
- package/dist/daemon/pidfile.d.ts +8 -0
- package/dist/daemon/pidfile.js +37 -0
- package/dist/daemon/startup-policy.d.ts +1 -0
- package/dist/daemon/startup-policy.js +1 -0
- package/dist/native/linux.d.ts +29 -0
- package/dist/native/linux.js +20 -0
- package/dist/shared/env.d.ts +116 -0
- package/dist/shared/env.js +271 -0
- package/dist/shared/generated-context.d.ts +83 -0
- package/dist/shared/generated-context.js +235 -0
- package/dist/shared/inbox-entry-body.d.ts +22 -0
- package/dist/shared/inbox-entry-body.js +116 -0
- package/dist/shared/predicates.d.ts +2 -0
- package/dist/shared/predicates.js +4 -0
- package/dist/shared/working-activity.d.ts +9 -0
- package/dist/shared/working-activity.js +27 -0
- package/dist/types.d.ts +562 -0
- package/dist/types.js +186 -0
- package/package.json +46 -5
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
export declare const errorCodes: {
|
|
2
|
+
readonly unauthorized: {
|
|
3
|
+
readonly type: "authentication_error";
|
|
4
|
+
readonly status: 401;
|
|
5
|
+
readonly retryable: false;
|
|
6
|
+
};
|
|
7
|
+
readonly grant_revoked: {
|
|
8
|
+
readonly type: "authentication_error";
|
|
9
|
+
readonly status: 401;
|
|
10
|
+
readonly retryable: false;
|
|
11
|
+
};
|
|
12
|
+
readonly grant_removed: {
|
|
13
|
+
readonly type: "authentication_error";
|
|
14
|
+
readonly status: 401;
|
|
15
|
+
readonly retryable: false;
|
|
16
|
+
};
|
|
17
|
+
readonly grant_suspended: {
|
|
18
|
+
readonly type: "authentication_error";
|
|
19
|
+
readonly status: 401;
|
|
20
|
+
readonly retryable: false;
|
|
21
|
+
};
|
|
22
|
+
readonly refresh_token_expired: {
|
|
23
|
+
readonly type: "authentication_error";
|
|
24
|
+
readonly status: 401;
|
|
25
|
+
readonly retryable: false;
|
|
26
|
+
};
|
|
27
|
+
readonly refresh_token_reused: {
|
|
28
|
+
readonly type: "authentication_error";
|
|
29
|
+
readonly status: 401;
|
|
30
|
+
readonly retryable: false;
|
|
31
|
+
};
|
|
32
|
+
readonly scope_missing: {
|
|
33
|
+
readonly type: "permission_error";
|
|
34
|
+
readonly status: 403;
|
|
35
|
+
readonly retryable: false;
|
|
36
|
+
};
|
|
37
|
+
readonly owner_only: {
|
|
38
|
+
readonly type: "permission_error";
|
|
39
|
+
readonly status: 403;
|
|
40
|
+
readonly retryable: false;
|
|
41
|
+
};
|
|
42
|
+
readonly other_app_run: {
|
|
43
|
+
readonly type: "permission_error";
|
|
44
|
+
readonly status: 403;
|
|
45
|
+
readonly retryable: false;
|
|
46
|
+
};
|
|
47
|
+
readonly payer_not_app: {
|
|
48
|
+
readonly type: "permission_error";
|
|
49
|
+
readonly status: 403;
|
|
50
|
+
readonly retryable: false;
|
|
51
|
+
};
|
|
52
|
+
readonly approval_pending: {
|
|
53
|
+
readonly type: "permission_error";
|
|
54
|
+
readonly status: 403;
|
|
55
|
+
readonly retryable: false;
|
|
56
|
+
};
|
|
57
|
+
readonly user_denied: {
|
|
58
|
+
readonly type: "permission_error";
|
|
59
|
+
readonly status: 403;
|
|
60
|
+
readonly retryable: false;
|
|
61
|
+
};
|
|
62
|
+
readonly provider_refused: {
|
|
63
|
+
readonly type: "permission_error";
|
|
64
|
+
readonly status: 403;
|
|
65
|
+
readonly retryable: false;
|
|
66
|
+
};
|
|
67
|
+
readonly provider_not_connected: {
|
|
68
|
+
readonly type: "permission_error";
|
|
69
|
+
readonly status: 403;
|
|
70
|
+
readonly retryable: false;
|
|
71
|
+
};
|
|
72
|
+
readonly provider_setup_pending: {
|
|
73
|
+
readonly type: "permission_error";
|
|
74
|
+
readonly status: 403;
|
|
75
|
+
readonly retryable: false;
|
|
76
|
+
};
|
|
77
|
+
readonly question_pages_off: {
|
|
78
|
+
readonly type: "permission_error";
|
|
79
|
+
readonly status: 403;
|
|
80
|
+
readonly retryable: false;
|
|
81
|
+
};
|
|
82
|
+
readonly isolated_run: {
|
|
83
|
+
readonly type: "permission_error";
|
|
84
|
+
readonly status: 403;
|
|
85
|
+
readonly retryable: false;
|
|
86
|
+
};
|
|
87
|
+
readonly provider_version_retired: {
|
|
88
|
+
readonly type: "permission_error";
|
|
89
|
+
readonly status: 403;
|
|
90
|
+
readonly retryable: false;
|
|
91
|
+
};
|
|
92
|
+
readonly invalid_scope: {
|
|
93
|
+
readonly type: "invalid_request_error";
|
|
94
|
+
readonly status: 400;
|
|
95
|
+
readonly retryable: false;
|
|
96
|
+
};
|
|
97
|
+
readonly invalid_request: {
|
|
98
|
+
readonly type: "invalid_request_error";
|
|
99
|
+
readonly status: 400;
|
|
100
|
+
readonly retryable: false;
|
|
101
|
+
};
|
|
102
|
+
readonly range_not_satisfiable: {
|
|
103
|
+
readonly type: "invalid_request_error";
|
|
104
|
+
readonly status: 416;
|
|
105
|
+
readonly retryable: false;
|
|
106
|
+
};
|
|
107
|
+
readonly conflict: {
|
|
108
|
+
readonly type: "invalid_request_error";
|
|
109
|
+
readonly status: 409;
|
|
110
|
+
readonly retryable: false;
|
|
111
|
+
};
|
|
112
|
+
readonly not_found: {
|
|
113
|
+
readonly type: "invalid_request_error";
|
|
114
|
+
readonly status: 404;
|
|
115
|
+
readonly retryable: false;
|
|
116
|
+
};
|
|
117
|
+
readonly model_unavailable: {
|
|
118
|
+
readonly type: "invalid_request_error";
|
|
119
|
+
readonly status: 404;
|
|
120
|
+
readonly retryable: false;
|
|
121
|
+
};
|
|
122
|
+
readonly upstream_model_unavailable: {
|
|
123
|
+
readonly type: "server_error";
|
|
124
|
+
readonly status: 503;
|
|
125
|
+
readonly retryable: true;
|
|
126
|
+
};
|
|
127
|
+
readonly substitution_refused: {
|
|
128
|
+
readonly type: "invalid_request_error";
|
|
129
|
+
readonly status: 400;
|
|
130
|
+
readonly retryable: false;
|
|
131
|
+
};
|
|
132
|
+
readonly idempotency_conflict: {
|
|
133
|
+
readonly type: "invalid_request_error";
|
|
134
|
+
readonly status: 409;
|
|
135
|
+
readonly retryable: false;
|
|
136
|
+
};
|
|
137
|
+
readonly run_settled: {
|
|
138
|
+
readonly type: "invalid_request_error";
|
|
139
|
+
readonly status: 409;
|
|
140
|
+
readonly retryable: false;
|
|
141
|
+
};
|
|
142
|
+
readonly cap_exhausted: {
|
|
143
|
+
readonly type: "rate_limit_error";
|
|
144
|
+
readonly status: 402;
|
|
145
|
+
readonly retryable: false;
|
|
146
|
+
};
|
|
147
|
+
readonly concurrency_limit: {
|
|
148
|
+
readonly type: "rate_limit_error";
|
|
149
|
+
readonly status: 429;
|
|
150
|
+
readonly retryable: true;
|
|
151
|
+
};
|
|
152
|
+
readonly all_routes_exhausted: {
|
|
153
|
+
readonly type: "rate_limit_error";
|
|
154
|
+
readonly status: 429;
|
|
155
|
+
readonly retryable: true;
|
|
156
|
+
};
|
|
157
|
+
readonly provider_rate_limited: {
|
|
158
|
+
readonly type: "rate_limit_error";
|
|
159
|
+
readonly status: 429;
|
|
160
|
+
readonly retryable: true;
|
|
161
|
+
};
|
|
162
|
+
readonly rate_limited: {
|
|
163
|
+
readonly type: "rate_limit_error";
|
|
164
|
+
readonly status: 429;
|
|
165
|
+
readonly retryable: true;
|
|
166
|
+
};
|
|
167
|
+
readonly runtime_unreachable: {
|
|
168
|
+
readonly type: "server_error";
|
|
169
|
+
readonly status: 503;
|
|
170
|
+
readonly retryable: true;
|
|
171
|
+
};
|
|
172
|
+
readonly isolated_unavailable: {
|
|
173
|
+
readonly type: "server_error";
|
|
174
|
+
readonly status: 503;
|
|
175
|
+
readonly retryable: true;
|
|
176
|
+
};
|
|
177
|
+
readonly runtime_starting: {
|
|
178
|
+
readonly type: "server_error";
|
|
179
|
+
readonly status: 503;
|
|
180
|
+
readonly retryable: true;
|
|
181
|
+
};
|
|
182
|
+
readonly runtime_provisioning: {
|
|
183
|
+
readonly type: "server_error";
|
|
184
|
+
readonly status: 503;
|
|
185
|
+
readonly retryable: true;
|
|
186
|
+
};
|
|
187
|
+
readonly provider_unavailable: {
|
|
188
|
+
readonly type: "server_error";
|
|
189
|
+
readonly status: 503;
|
|
190
|
+
readonly retryable: true;
|
|
191
|
+
};
|
|
192
|
+
readonly upstream_refused: {
|
|
193
|
+
readonly type: "server_error";
|
|
194
|
+
readonly status: 502;
|
|
195
|
+
readonly retryable: false;
|
|
196
|
+
};
|
|
197
|
+
readonly provider_bad_response: {
|
|
198
|
+
readonly type: "server_error";
|
|
199
|
+
readonly status: 502;
|
|
200
|
+
readonly retryable: false;
|
|
201
|
+
};
|
|
202
|
+
readonly service_unavailable: {
|
|
203
|
+
readonly type: "server_error";
|
|
204
|
+
readonly status: 503;
|
|
205
|
+
readonly retryable: true;
|
|
206
|
+
};
|
|
207
|
+
readonly not_implemented: {
|
|
208
|
+
readonly type: "server_error";
|
|
209
|
+
readonly status: 501;
|
|
210
|
+
readonly retryable: false;
|
|
211
|
+
};
|
|
212
|
+
readonly permission_error: {
|
|
213
|
+
readonly type: "permission_error";
|
|
214
|
+
readonly status: 403;
|
|
215
|
+
readonly retryable: false;
|
|
216
|
+
};
|
|
217
|
+
readonly storage_unavailable: {
|
|
218
|
+
readonly type: "server_error";
|
|
219
|
+
readonly status: 503;
|
|
220
|
+
readonly retryable: true;
|
|
221
|
+
};
|
|
222
|
+
readonly server_error: {
|
|
223
|
+
readonly type: "server_error";
|
|
224
|
+
readonly status: 500;
|
|
225
|
+
readonly retryable: true;
|
|
226
|
+
};
|
|
227
|
+
readonly server_failure: {
|
|
228
|
+
readonly type: "server_error";
|
|
229
|
+
readonly status: 500;
|
|
230
|
+
readonly retryable: false;
|
|
231
|
+
};
|
|
232
|
+
readonly wake_timeout: {
|
|
233
|
+
readonly type: "server_error";
|
|
234
|
+
readonly status: 504;
|
|
235
|
+
readonly retryable: true;
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
export type ErrorCode = keyof typeof errorCodes;
|
|
239
|
+
export type ErrorType = (typeof errorCodes)[ErrorCode]['type'];
|
|
240
|
+
export type ErrorOrigin = 'directory' | 'router' | 'runtime' | 'provider' | 'app';
|
|
241
|
+
/** Full app-facing HTTP error body; the HTTP status is in the status line. */
|
|
242
|
+
export interface ErrorEnvelope {
|
|
243
|
+
error: {
|
|
244
|
+
code: string;
|
|
245
|
+
message: string;
|
|
246
|
+
details?: unknown;
|
|
247
|
+
type: ErrorType;
|
|
248
|
+
param?: string;
|
|
249
|
+
origin: ErrorOrigin;
|
|
250
|
+
retryable: boolean;
|
|
251
|
+
retry_after_s?: number;
|
|
252
|
+
reset_at?: string;
|
|
253
|
+
request_id: string;
|
|
254
|
+
run_id?: string;
|
|
255
|
+
question_id?: string;
|
|
256
|
+
user_action?: string;
|
|
257
|
+
scope?: string;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Contract 2, "Error envelope". This is the fixed-tuple subset of the
|
|
2
|
+
// app-facing code table; codes with a variable status or a transport-specific
|
|
3
|
+
// shape (provider_error, usage, stream_*) do not have a fixed tuple.
|
|
4
|
+
export const errorCodes = {
|
|
5
|
+
unauthorized: { type: 'authentication_error', status: 401, retryable: false },
|
|
6
|
+
// A refusal that names no reason (runtime validation step 5, or the directory's bare invalid_grant). Not deprecated.
|
|
7
|
+
grant_revoked: { type: 'authentication_error', status: 401, retryable: false },
|
|
8
|
+
// The directory's reasons for refusing a refresh token (D2-ERR-49..51), carried in its invalid_grant error_description.
|
|
9
|
+
grant_removed: { type: 'authentication_error', status: 401, retryable: false },
|
|
10
|
+
grant_suspended: { type: 'authentication_error', status: 401, retryable: false },
|
|
11
|
+
refresh_token_expired: { type: 'authentication_error', status: 401, retryable: false },
|
|
12
|
+
refresh_token_reused: { type: 'authentication_error', status: 401, retryable: false },
|
|
13
|
+
scope_missing: { type: 'permission_error', status: 403, retryable: false },
|
|
14
|
+
owner_only: { type: 'permission_error', status: 403, retryable: false },
|
|
15
|
+
other_app_run: { type: 'permission_error', status: 403, retryable: false },
|
|
16
|
+
payer_not_app: { type: 'permission_error', status: 403, retryable: false },
|
|
17
|
+
approval_pending: { type: 'permission_error', status: 403, retryable: false },
|
|
18
|
+
user_denied: { type: 'permission_error', status: 403, retryable: false },
|
|
19
|
+
provider_refused: { type: 'permission_error', status: 403, retryable: false },
|
|
20
|
+
provider_not_connected: { type: 'permission_error', status: 403, retryable: false },
|
|
21
|
+
// An app refusing its own operation because a provider in its `requires` is not `ready`; details `{ provider, state, message?, next }`, copied from `grant.get`'s `dependencies[provider]` entry (`next` = `<issuer>/connect/setup/<provider>?client_id=<grantee>`). The daemon never raises it (it only carries `dependencies`).
|
|
22
|
+
provider_setup_pending: { type: 'permission_error', status: 403, retryable: false },
|
|
23
|
+
question_pages_off: { type: 'permission_error', status: 403, retryable: false },
|
|
24
|
+
isolated_run: { type: 'permission_error', status: 403, retryable: false },
|
|
25
|
+
provider_version_retired: { type: 'permission_error', status: 403, retryable: false },
|
|
26
|
+
invalid_scope: { type: 'invalid_request_error', status: 400, retryable: false },
|
|
27
|
+
invalid_request: { type: 'invalid_request_error', status: 400, retryable: false },
|
|
28
|
+
range_not_satisfiable: { type: 'invalid_request_error', status: 416, retryable: false },
|
|
29
|
+
conflict: { type: 'invalid_request_error', status: 409, retryable: false },
|
|
30
|
+
not_found: { type: 'invalid_request_error', status: 404, retryable: false },
|
|
31
|
+
model_unavailable: { type: 'invalid_request_error', status: 404, retryable: false },
|
|
32
|
+
upstream_model_unavailable: { type: 'server_error', status: 503, retryable: true },
|
|
33
|
+
substitution_refused: { type: 'invalid_request_error', status: 400, retryable: false },
|
|
34
|
+
idempotency_conflict: { type: 'invalid_request_error', status: 409, retryable: false },
|
|
35
|
+
run_settled: { type: 'invalid_request_error', status: 409, retryable: false },
|
|
36
|
+
cap_exhausted: { type: 'rate_limit_error', status: 402, retryable: false },
|
|
37
|
+
concurrency_limit: { type: 'rate_limit_error', status: 429, retryable: true },
|
|
38
|
+
all_routes_exhausted: { type: 'rate_limit_error', status: 429, retryable: true },
|
|
39
|
+
provider_rate_limited: { type: 'rate_limit_error', status: 429, retryable: true },
|
|
40
|
+
rate_limited: { type: 'rate_limit_error', status: 429, retryable: true },
|
|
41
|
+
runtime_unreachable: { type: 'server_error', status: 503, retryable: true },
|
|
42
|
+
isolated_unavailable: { type: 'server_error', status: 503, retryable: true },
|
|
43
|
+
runtime_starting: { type: 'server_error', status: 503, retryable: true },
|
|
44
|
+
runtime_provisioning: { type: 'server_error', status: 503, retryable: true },
|
|
45
|
+
provider_unavailable: { type: 'server_error', status: 503, retryable: true },
|
|
46
|
+
upstream_refused: { type: 'server_error', status: 502, retryable: false },
|
|
47
|
+
provider_bad_response: { type: 'server_error', status: 502, retryable: false },
|
|
48
|
+
service_unavailable: { type: 'server_error', status: 503, retryable: true },
|
|
49
|
+
not_implemented: { type: 'server_error', status: 501, retryable: false },
|
|
50
|
+
permission_error: { type: 'permission_error', status: 403, retryable: false },
|
|
51
|
+
storage_unavailable: { type: 'server_error', status: 503, retryable: true },
|
|
52
|
+
server_error: { type: 'server_error', status: 500, retryable: true },
|
|
53
|
+
server_failure: { type: 'server_error', status: 500, retryable: false },
|
|
54
|
+
// Hosted router sleep/wake stage, not emitted by the always-on v1 runtime.
|
|
55
|
+
wake_timeout: { type: 'server_error', status: 504, retryable: true },
|
|
56
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** The uniform JSON body crtrd returns on any non-2xx response. */
|
|
2
|
+
export interface ErrorBody {
|
|
3
|
+
error: {
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
details?: unknown;
|
|
7
|
+
type?: string;
|
|
8
|
+
param?: string;
|
|
9
|
+
origin?: string;
|
|
10
|
+
retryable?: boolean;
|
|
11
|
+
retry_after_s?: number;
|
|
12
|
+
reset_at?: string;
|
|
13
|
+
request_id?: string;
|
|
14
|
+
run_id?: string;
|
|
15
|
+
question_id?: string;
|
|
16
|
+
scope?: string;
|
|
17
|
+
user_action?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Thrown by `CrtrClient` on a non-2xx response (or a synthesized transport
|
|
21
|
+
* failure such as an unreachable daemon). Carries the HTTP status, the stable
|
|
22
|
+
* machine `code` from the `ErrorBody`, and optional structured `details`. */
|
|
23
|
+
export declare class APIError extends Error {
|
|
24
|
+
readonly status: number;
|
|
25
|
+
readonly code: string;
|
|
26
|
+
readonly details?: unknown;
|
|
27
|
+
readonly headers: Headers;
|
|
28
|
+
readonly type?: string;
|
|
29
|
+
readonly param?: string;
|
|
30
|
+
readonly origin?: string;
|
|
31
|
+
readonly retryable?: boolean;
|
|
32
|
+
readonly retryAfterS?: number;
|
|
33
|
+
readonly resetAt?: string;
|
|
34
|
+
readonly requestId?: string;
|
|
35
|
+
readonly runId?: string;
|
|
36
|
+
readonly questionId?: string;
|
|
37
|
+
readonly scope?: string;
|
|
38
|
+
readonly userAction?: string;
|
|
39
|
+
constructor(status: number, code: string, message: string, details?: unknown, headers?: HeadersInit, envelope?: Partial<ErrorBody['error']>);
|
|
40
|
+
}
|
|
41
|
+
/** @deprecated Use APIError. Kept as the in-repo compatibility alias. */
|
|
42
|
+
export { APIError as ApiError };
|
|
43
|
+
/** A local API transport failure has stable status/code identity, independent
|
|
44
|
+
* of message prose. */
|
|
45
|
+
export declare function isDaemonTransportApiError(error: unknown): error is APIError;
|
|
46
|
+
/** Type guard for an `ErrorBody`-shaped parsed payload. */
|
|
47
|
+
export declare function isErrorBody(value: unknown): value is ErrorBody;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// API error contract (spec §8). Uniform JSON error body on any non-2xx; the
|
|
2
|
+
// client parses it and throws `ApiError`.
|
|
3
|
+
//
|
|
4
|
+
// PURITY (spec §3.1): Node built-ins + `src/api/*` only.
|
|
5
|
+
/** Thrown by `CrtrClient` on a non-2xx response (or a synthesized transport
|
|
6
|
+
* failure such as an unreachable daemon). Carries the HTTP status, the stable
|
|
7
|
+
* machine `code` from the `ErrorBody`, and optional structured `details`. */
|
|
8
|
+
export class APIError extends Error {
|
|
9
|
+
status;
|
|
10
|
+
code;
|
|
11
|
+
details;
|
|
12
|
+
headers;
|
|
13
|
+
type;
|
|
14
|
+
param;
|
|
15
|
+
origin;
|
|
16
|
+
retryable;
|
|
17
|
+
retryAfterS;
|
|
18
|
+
resetAt;
|
|
19
|
+
requestId;
|
|
20
|
+
runId;
|
|
21
|
+
questionId;
|
|
22
|
+
scope;
|
|
23
|
+
userAction;
|
|
24
|
+
constructor(status, code, message, details, headers, envelope) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = 'APIError';
|
|
27
|
+
this.status = status;
|
|
28
|
+
this.code = code;
|
|
29
|
+
this.headers = new Headers(headers);
|
|
30
|
+
if (details !== undefined)
|
|
31
|
+
this.details = details;
|
|
32
|
+
this.type = envelope?.type;
|
|
33
|
+
this.param = envelope?.param;
|
|
34
|
+
this.origin = envelope?.origin;
|
|
35
|
+
this.retryable = envelope?.retryable;
|
|
36
|
+
this.retryAfterS = envelope?.retry_after_s;
|
|
37
|
+
this.resetAt = envelope?.reset_at;
|
|
38
|
+
this.requestId = envelope?.request_id ?? this.headers.get('Request-Id') ?? undefined;
|
|
39
|
+
this.runId = envelope?.run_id;
|
|
40
|
+
this.questionId = envelope?.question_id;
|
|
41
|
+
this.scope = envelope?.scope;
|
|
42
|
+
this.userAction = envelope?.user_action;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** @deprecated Use APIError. Kept as the in-repo compatibility alias. */
|
|
46
|
+
export { APIError as ApiError };
|
|
47
|
+
/** A local API transport failure has stable status/code identity, independent
|
|
48
|
+
* of message prose. */
|
|
49
|
+
export function isDaemonTransportApiError(error) {
|
|
50
|
+
if (!(error instanceof APIError))
|
|
51
|
+
return false;
|
|
52
|
+
return (error.status === 503 && (error.code === 'daemon_unavailable'
|
|
53
|
+
|| error.code === 'transport_error'
|
|
54
|
+
|| error.code === 'daemon_request_interrupted')) || (error.status === 504 && error.code === 'request_timeout')
|
|
55
|
+
|| (error.status >= 500 && error.code === 'daemon_health_unavailable');
|
|
56
|
+
}
|
|
57
|
+
/** Type guard for an `ErrorBody`-shaped parsed payload. */
|
|
58
|
+
export function isErrorBody(value) {
|
|
59
|
+
if (typeof value !== 'object' || value === null)
|
|
60
|
+
return false;
|
|
61
|
+
const err = value.error;
|
|
62
|
+
if (typeof err !== 'object' || err === null)
|
|
63
|
+
return false;
|
|
64
|
+
const { code, message } = err;
|
|
65
|
+
return typeof code === 'string' && typeof message === 'string';
|
|
66
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export { CrtrClient, waitForDaemonAvailability } from './client.js';
|
|
2
|
+
export type { CrtrClientOptions, CrtrRequestOptions } from './client.js';
|
|
3
|
+
export { APIError, ApiError, isErrorBody } from './errors.js';
|
|
4
|
+
export type { ErrorBody } from './errors.js';
|
|
5
|
+
export { errorCodes } from './error-codes.js';
|
|
6
|
+
export type { ErrorCode, ErrorEnvelope, ErrorOrigin, ErrorType } from './error-codes.js';
|
|
7
|
+
export { API_VERSION, routes } from './routes.js';
|
|
8
|
+
export { RUNTIME_VERSION_HEADER, MINIMUM_RUNTIME_VERSION_HEADER, compareReleaseVersions, minimumRuntimeRefusal } from './runtime-version.js';
|
|
9
|
+
export type { MinimumRuntimeRefusal } from './runtime-version.js';
|
|
10
|
+
export { LONG_POLL_MAX_WAIT_SECONDS, LONG_POLL_ROUTES, longPollHoldSeconds, longPollRoute, requestedWait } from './long-poll.js';
|
|
11
|
+
export type { LongPollName, LongPollRoute } from './long-poll.js';
|
|
12
|
+
export * from '../shared/generated-context.js';
|
|
13
|
+
export * from './dto/common.js';
|
|
14
|
+
export * from './dto/health.js';
|
|
15
|
+
export * from './dto/limits.js';
|
|
16
|
+
export * from './dto/grants.js';
|
|
17
|
+
export * from './dto/nodes.js';
|
|
18
|
+
export * from './dto/node-outcomes.js';
|
|
19
|
+
export * from './dto/node-events.js';
|
|
20
|
+
export * from './dto/run-events.js';
|
|
21
|
+
export * from './dto/broker-signals.js';
|
|
22
|
+
export * from './dto/bash-jobs.js';
|
|
23
|
+
export * from './dto/messages.js';
|
|
24
|
+
export * from './dto/reports.js';
|
|
25
|
+
export * from './dto/structured-requests.js';
|
|
26
|
+
export * from './dto/lifecycle.js';
|
|
27
|
+
export * from './dto/subscriptions.js';
|
|
28
|
+
export * from './dto/focus.js';
|
|
29
|
+
export * from './dto/crons.js';
|
|
30
|
+
export * from './dto/config.js';
|
|
31
|
+
export * from './dto/attach.js';
|
|
32
|
+
export * from './dto/broker.js';
|
|
33
|
+
export * from './dto/profiles.js';
|
|
34
|
+
export * from './dto/modelauth.js';
|
|
35
|
+
export * from './dto/model-config.js';
|
|
36
|
+
export * from './dto/canvas.js';
|
|
37
|
+
export * from './dto/worktree.js';
|
|
38
|
+
export * from './dto/human.js';
|
|
39
|
+
export * from './dto/files.js';
|
|
40
|
+
export * from './dto/bash.js';
|
|
41
|
+
export * from './dto/inbox.js';
|
|
42
|
+
export * from './dto/human-requests.js';
|
|
43
|
+
export * from './dto/reviews.js';
|
|
44
|
+
export * from './dto/review-comments.js';
|
|
45
|
+
export * from './dto/chat-inventory.js';
|
|
46
|
+
export * from './dto/analytics.js';
|
|
47
|
+
export * from './dto/custom-objects.js';
|
|
48
|
+
export type { WatchRequest, WatchResultDTO, UnwatchQuery, UnwatchResultDTO } from './dto/objects.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// `crouter/api` — the single source of truth for crtrd's API DTOs,
|
|
2
|
+
// route constants, error contract, and the typed `CrtrClient`. Dependency-light
|
|
3
|
+
// by design (spec §3.1): Node built-ins + `src/api/*` only.
|
|
4
|
+
export { CrtrClient, waitForDaemonAvailability } from './client.js';
|
|
5
|
+
export { APIError, ApiError, isErrorBody } from './errors.js';
|
|
6
|
+
export { errorCodes } from './error-codes.js';
|
|
7
|
+
export { API_VERSION, routes } from './routes.js';
|
|
8
|
+
export { RUNTIME_VERSION_HEADER, MINIMUM_RUNTIME_VERSION_HEADER, compareReleaseVersions, minimumRuntimeRefusal } from './runtime-version.js';
|
|
9
|
+
export { LONG_POLL_MAX_WAIT_SECONDS, LONG_POLL_ROUTES, longPollHoldSeconds, longPollRoute, requestedWait } from './long-poll.js';
|
|
10
|
+
export * from '../shared/generated-context.js';
|
|
11
|
+
export * from './dto/common.js';
|
|
12
|
+
export * from './dto/health.js';
|
|
13
|
+
export * from './dto/limits.js';
|
|
14
|
+
export * from './dto/grants.js';
|
|
15
|
+
export * from './dto/nodes.js';
|
|
16
|
+
export * from './dto/node-outcomes.js';
|
|
17
|
+
export * from './dto/node-events.js';
|
|
18
|
+
export * from './dto/run-events.js';
|
|
19
|
+
export * from './dto/broker-signals.js';
|
|
20
|
+
export * from './dto/bash-jobs.js';
|
|
21
|
+
export * from './dto/messages.js';
|
|
22
|
+
export * from './dto/reports.js';
|
|
23
|
+
export * from './dto/structured-requests.js';
|
|
24
|
+
export * from './dto/lifecycle.js';
|
|
25
|
+
export * from './dto/subscriptions.js';
|
|
26
|
+
export * from './dto/focus.js';
|
|
27
|
+
export * from './dto/crons.js';
|
|
28
|
+
export * from './dto/config.js';
|
|
29
|
+
export * from './dto/attach.js';
|
|
30
|
+
export * from './dto/broker.js';
|
|
31
|
+
export * from './dto/profiles.js';
|
|
32
|
+
export * from './dto/modelauth.js';
|
|
33
|
+
export * from './dto/model-config.js';
|
|
34
|
+
export * from './dto/canvas.js';
|
|
35
|
+
export * from './dto/worktree.js';
|
|
36
|
+
export * from './dto/human.js';
|
|
37
|
+
export * from './dto/files.js';
|
|
38
|
+
export * from './dto/bash.js';
|
|
39
|
+
export * from './dto/inbox.js';
|
|
40
|
+
export * from './dto/human-requests.js';
|
|
41
|
+
export * from './dto/reviews.js';
|
|
42
|
+
export * from './dto/review-comments.js';
|
|
43
|
+
export * from './dto/chat-inventory.js';
|
|
44
|
+
export * from './dto/analytics.js';
|
|
45
|
+
export * from './dto/custom-objects.js';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** The longest any long-poll holds a request, in seconds. */
|
|
2
|
+
export declare const LONG_POLL_MAX_WAIT_SECONDS = 25;
|
|
3
|
+
export interface LongPollRoute {
|
|
4
|
+
/** The daemon operation this route is (its operation-table name), or, for a route outside `/v1`, a stable label. */
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly method: 'GET';
|
|
7
|
+
/** `:name`-style path pattern, matched segment by segment like the daemon's router. */
|
|
8
|
+
readonly path: string;
|
|
9
|
+
/** The smallest `?wait=` the route accepts: the caller asks for an integer from this through
|
|
10
|
+
* {@link LONG_POLL_MAX_WAIT_SECONDS} seconds, absent meaning 0 (answer at once). Without it the route takes no
|
|
11
|
+
* `wait` and always holds up to {@link LONG_POLL_MAX_WAIT_SECONDS}. */
|
|
12
|
+
readonly minWait?: 0 | 1;
|
|
13
|
+
}
|
|
14
|
+
export declare const LONG_POLL_ROUTES: readonly [{
|
|
15
|
+
readonly name: "run.get";
|
|
16
|
+
readonly method: "GET";
|
|
17
|
+
readonly path: "/v1/runs/:run_id";
|
|
18
|
+
readonly minWait: 1;
|
|
19
|
+
}, {
|
|
20
|
+
readonly name: "grant.get";
|
|
21
|
+
readonly method: "GET";
|
|
22
|
+
readonly path: "/v1/grant";
|
|
23
|
+
readonly minWait: 1;
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "model_auth.get";
|
|
26
|
+
readonly method: "GET";
|
|
27
|
+
readonly path: "/v1/model-auth/flows/:flow_id";
|
|
28
|
+
readonly minWait: 1;
|
|
29
|
+
}, {
|
|
30
|
+
readonly name: "structured-request.get";
|
|
31
|
+
readonly method: "GET";
|
|
32
|
+
readonly path: "/v1/structured-requests/:request_id";
|
|
33
|
+
readonly minWait: 0;
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "node-outcomes.get.119";
|
|
36
|
+
readonly method: "GET";
|
|
37
|
+
readonly path: "/v1/nodes/:id/outcome";
|
|
38
|
+
readonly minWait: 0;
|
|
39
|
+
}, {
|
|
40
|
+
readonly name: "vendor-signin.wait";
|
|
41
|
+
readonly method: "GET";
|
|
42
|
+
readonly path: "/signin/vendor/:flow_id/wait";
|
|
43
|
+
}];
|
|
44
|
+
export type LongPollName = (typeof LONG_POLL_ROUTES)[number]['name'];
|
|
45
|
+
/** The long-poll route a request path is, or `undefined`. `pathname` is the URL's path without its query. */
|
|
46
|
+
export declare function longPollRoute(method: string, pathname: string): LongPollRoute | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* The seconds a long-poll request asks to be held, from its first `wait` value: 0 when it carries none or an empty
|
|
49
|
+
* one (it answers at once), the requested seconds when `wait` is a decimal integer (no sign, no leading zero) in the
|
|
50
|
+
* route's range, and `null` when the daemon refuses it with 400 `invalid_request`. A route without `minWait` ignores
|
|
51
|
+
* the query and always holds up to {@link LONG_POLL_MAX_WAIT_SECONDS}.
|
|
52
|
+
*/
|
|
53
|
+
export declare function requestedWait(route: LongPollRoute, query: URLSearchParams): number | null;
|
|
54
|
+
/**
|
|
55
|
+
* How long the daemon may hold this request before it starts answering, in seconds — or `undefined` when it answers
|
|
56
|
+
* at once: not a long-poll route, no `wait` or `wait=0`, or a `wait` it refuses. A proxy adds its own answer deadline
|
|
57
|
+
* on top. `url` is the request target (`/v1/runs/r1?wait=25`) or a parsed URL.
|
|
58
|
+
*/
|
|
59
|
+
export declare function longPollHoldSeconds(method: string, url: string | URL): number | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// The daemon's long-polls: the routes that may hold a request open before
|
|
2
|
+
// answering, and how long. This table is the one declaration of them — the
|
|
3
|
+
// daemon parses every `?wait=` through it, and a proxy in front of the daemon
|
|
4
|
+
// (the hosting router) reads it to give a held request its hold plus its normal
|
|
5
|
+
// answer deadline instead of cutting it off.
|
|
6
|
+
//
|
|
7
|
+
// PURITY (spec §3.1): Node built-ins + `src/api/*` only.
|
|
8
|
+
/** The longest any long-poll holds a request, in seconds. */
|
|
9
|
+
export const LONG_POLL_MAX_WAIT_SECONDS = 25;
|
|
10
|
+
export const LONG_POLL_ROUTES = [
|
|
11
|
+
{ name: 'run.get', method: 'GET', path: '/v1/runs/:run_id', minWait: 1 },
|
|
12
|
+
{ name: 'grant.get', method: 'GET', path: '/v1/grant', minWait: 1 },
|
|
13
|
+
{ name: 'model_auth.get', method: 'GET', path: '/v1/model-auth/flows/:flow_id', minWait: 1 },
|
|
14
|
+
{ name: 'structured-request.get', method: 'GET', path: '/v1/structured-requests/:request_id', minWait: 0 },
|
|
15
|
+
{ name: 'node-outcomes.get.119', method: 'GET', path: '/v1/nodes/:id/outcome', minWait: 0 },
|
|
16
|
+
// The vendor sign-in page's wait: outside `/v1` and the operation table, always held.
|
|
17
|
+
{ name: 'vendor-signin.wait', method: 'GET', path: '/signin/vendor/:flow_id/wait' },
|
|
18
|
+
];
|
|
19
|
+
function segments(path) {
|
|
20
|
+
return path.split('/').filter((segment) => segment.length > 0);
|
|
21
|
+
}
|
|
22
|
+
/** The long-poll route a request path is, or `undefined`. `pathname` is the URL's path without its query. */
|
|
23
|
+
export function longPollRoute(method, pathname) {
|
|
24
|
+
if (method.toUpperCase() !== 'GET')
|
|
25
|
+
return undefined;
|
|
26
|
+
const actual = segments(pathname);
|
|
27
|
+
return LONG_POLL_ROUTES.find((route) => {
|
|
28
|
+
const pattern = segments(route.path);
|
|
29
|
+
return pattern.length === actual.length && pattern.every((segment, i) => segment.startsWith(':') || segment === actual[i]);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The seconds a long-poll request asks to be held, from its first `wait` value: 0 when it carries none or an empty
|
|
34
|
+
* one (it answers at once), the requested seconds when `wait` is a decimal integer (no sign, no leading zero) in the
|
|
35
|
+
* route's range, and `null` when the daemon refuses it with 400 `invalid_request`. A route without `minWait` ignores
|
|
36
|
+
* the query and always holds up to {@link LONG_POLL_MAX_WAIT_SECONDS}.
|
|
37
|
+
*/
|
|
38
|
+
export function requestedWait(route, query) {
|
|
39
|
+
if (route.minWait === undefined)
|
|
40
|
+
return LONG_POLL_MAX_WAIT_SECONDS;
|
|
41
|
+
const value = query.get('wait');
|
|
42
|
+
if (!value)
|
|
43
|
+
return 0;
|
|
44
|
+
if (!/^(0|[1-9]\d?)$/.test(value))
|
|
45
|
+
return null;
|
|
46
|
+
const seconds = Number(value);
|
|
47
|
+
return seconds >= route.minWait && seconds <= LONG_POLL_MAX_WAIT_SECONDS ? seconds : null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* How long the daemon may hold this request before it starts answering, in seconds — or `undefined` when it answers
|
|
51
|
+
* at once: not a long-poll route, no `wait` or `wait=0`, or a `wait` it refuses. A proxy adds its own answer deadline
|
|
52
|
+
* on top. `url` is the request target (`/v1/runs/r1?wait=25`) or a parsed URL.
|
|
53
|
+
*/
|
|
54
|
+
export function longPollHoldSeconds(method, url) {
|
|
55
|
+
let parsed;
|
|
56
|
+
try {
|
|
57
|
+
parsed = typeof url === 'string' ? new URL(url, 'http://daemon.localhost') : url;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const route = longPollRoute(method, parsed.pathname);
|
|
63
|
+
if (route === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
const seconds = requestedWait(route, parsed.searchParams);
|
|
66
|
+
return seconds ? seconds : undefined;
|
|
67
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CrtrClient, type CrtrClientOptions } from './client.js';
|
|
2
|
+
/** Resolve crtrd's default unix socket path the same way `apiSocketPath()` does,
|
|
3
|
+
* via Node built-ins only (no `core/canvas/paths.ts` import). */
|
|
4
|
+
export declare function defaultSocketPath(): string;
|
|
5
|
+
/** A standard `fetch` bound to one unix socket, built on `node:http` with
|
|
6
|
+
* `{ socketPath }`. The returned `Response`'s body is a live `ReadableStream`
|
|
7
|
+
* fed as bytes arrive — never buffered before the caller sees headers —
|
|
8
|
+
* which is what lets `CrtrClient` serve a streaming route (SSE) later without
|
|
9
|
+
* a second transport. Connection failures are wrapped as `TypeError('fetch
|
|
10
|
+
* failed', { cause })`, matching the shape native `fetch` throws, so
|
|
11
|
+
* `CrtrClient`'s cold-socket/interrupted-request classification (`err.cause.code`)
|
|
12
|
+
* reads identically off either transport. */
|
|
13
|
+
export declare function socketFetch(socketPath: string): typeof fetch;
|
|
14
|
+
/** Construct a client bound to the default local socket with autostart on.
|
|
15
|
+
* Without `onColdSocket`, a cold socket fails with `daemon_unavailable`. */
|
|
16
|
+
export declare function localClient(opts?: Omit<CrtrClientOptions, 'baseUrl' | 'fetch'> & {
|
|
17
|
+
socketPath?: string;
|
|
18
|
+
}): CrtrClient;
|