@darqlabs/curator-sdk 0.2.0 → 0.3.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/cjs/errors.d.ts +96 -5
- package/dist/cjs/errors.d.ts.map +1 -1
- package/dist/cjs/errors.js +181 -15
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/http.d.ts.map +1 -1
- package/dist/cjs/http.js +65 -13
- package/dist/cjs/http.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/errors.d.ts +96 -5
- package/dist/esm/errors.d.ts.map +1 -1
- package/dist/esm/errors.js +176 -14
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/http.d.ts.map +1 -1
- package/dist/esm/http.js +66 -14
- package/dist/esm/http.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/errors.d.ts
CHANGED
|
@@ -10,31 +10,99 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { AssistantMessage, ApprovalDetails, AuthorizationDetails, AgentFailureClass } from "./types.js";
|
|
12
12
|
export declare class CuratorError extends Error {
|
|
13
|
+
/**
|
|
14
|
+
* What an END USER may be shown.
|
|
15
|
+
*
|
|
16
|
+
* `message` is for developers — it can name the request, the status, and the
|
|
17
|
+
* server's own wording. That is the wrong text to put in a chat bubble, and
|
|
18
|
+
* shipping it there is not a hypothetical: a 500 rendered as
|
|
19
|
+
* `HTTP 500 from https://api.../agents/<slug>/conversations: …`, exposing the
|
|
20
|
+
* deployment's URL to whoever was chatting, and an end-user token failure
|
|
21
|
+
* rendered as "End-user JWT could not be verified", which tells the person
|
|
22
|
+
* nothing they can act on and leaks the auth mechanism.
|
|
23
|
+
*
|
|
24
|
+
* Every subclass sets this to something safe and actionable. `renderError` in
|
|
25
|
+
* the React bindings prefers it and never falls back to `message`, so a new
|
|
26
|
+
* error type is safe-by-default rather than leaky-by-default.
|
|
27
|
+
*/
|
|
28
|
+
readonly userMessage: string;
|
|
29
|
+
/** HTTP status, when this came from a response. */
|
|
30
|
+
readonly status: number | null;
|
|
31
|
+
/** Server error code (`error.code`), when present. */
|
|
32
|
+
readonly code: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Correlation id from `x-request-id` / `correlationId`. The one detail worth
|
|
35
|
+
* showing a user on an unexpected failure — it is what support can trace,
|
|
36
|
+
* and it says nothing about the system's shape.
|
|
37
|
+
*/
|
|
38
|
+
readonly requestId: string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Request URL, as a PROPERTY rather than part of `message`. Available for
|
|
41
|
+
* logs and bug reports without riding along into anything user-visible.
|
|
42
|
+
*/
|
|
43
|
+
readonly url: string | null;
|
|
13
44
|
constructor(message: string, options?: {
|
|
14
45
|
cause?: unknown;
|
|
46
|
+
userMessage?: string;
|
|
47
|
+
status?: number | null;
|
|
48
|
+
code?: string | null;
|
|
49
|
+
requestId?: string | null;
|
|
50
|
+
url?: string | null;
|
|
15
51
|
});
|
|
16
52
|
}
|
|
53
|
+
/** Last-resort user-facing text. Deliberately says nothing about the system. */
|
|
54
|
+
export declare const DEFAULT_USER_MESSAGE = "Something went wrong. Please try again.";
|
|
55
|
+
/** Appends a correlation id when there is one, so support has a handle. */
|
|
56
|
+
export declare function withRequestId(text: string, requestId: string | null): string;
|
|
57
|
+
type HttpContext = {
|
|
58
|
+
status?: number | null;
|
|
59
|
+
code?: string | null;
|
|
60
|
+
requestId?: string | null;
|
|
61
|
+
url?: string | null;
|
|
62
|
+
};
|
|
17
63
|
/** HTTP 401 from the API — your API key is missing, invalid, or revoked. */
|
|
18
64
|
export declare class CuratorAuthError extends CuratorError {
|
|
19
|
-
constructor(message?: string);
|
|
65
|
+
constructor(message?: string, ctx?: HttpContext);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* HTTP 401 specifically because the END-USER token was missing, expired, or
|
|
69
|
+
* unverifiable — distinct from `CuratorAuthError`, which is about the
|
|
70
|
+
* integrator's API key.
|
|
71
|
+
*
|
|
72
|
+
* Separate because the remediation is completely different: an API-key failure
|
|
73
|
+
* needs a developer, whereas this one is usually a stale session the user fixes
|
|
74
|
+
* by signing in again. Collapsing them produced "Authentication failed. Check
|
|
75
|
+
* your API key." in response to an expired user token, which sends the reader
|
|
76
|
+
* after the wrong thing entirely.
|
|
77
|
+
*/
|
|
78
|
+
export declare class CuratorEndUserAuthError extends CuratorError {
|
|
79
|
+
constructor(message?: string, ctx?: HttpContext);
|
|
20
80
|
}
|
|
21
81
|
/** HTTP 403 from the API — your API key doesn't have permission for this action. */
|
|
22
82
|
export declare class CuratorForbiddenError extends CuratorError {
|
|
23
|
-
constructor(message?: string);
|
|
83
|
+
constructor(message?: string, ctx?: HttpContext);
|
|
24
84
|
}
|
|
25
85
|
/** HTTP 404 from the API — the deployment slug or conversation id wasn't found. */
|
|
26
86
|
export declare class CuratorNotFoundError extends CuratorError {
|
|
27
|
-
constructor(message?: string);
|
|
87
|
+
constructor(message?: string, ctx?: HttpContext);
|
|
28
88
|
}
|
|
29
89
|
/** HTTP 410 from the API — the deployment was retired. */
|
|
30
90
|
export declare class CuratorDeploymentRetiredError extends CuratorError {
|
|
31
91
|
readonly retiredAt: string | null;
|
|
32
|
-
constructor(message: string, retiredAt: string | null);
|
|
92
|
+
constructor(message: string, retiredAt: string | null, ctx?: HttpContext);
|
|
33
93
|
}
|
|
34
94
|
/** HTTP 429 from the API — back off. */
|
|
35
95
|
export declare class CuratorRateLimitError extends CuratorError {
|
|
36
96
|
readonly retryAfterSeconds: number | null;
|
|
37
|
-
constructor(message?: string, retryAfterSeconds?: number | null);
|
|
97
|
+
constructor(message?: string, retryAfterSeconds?: number | null, ctx?: HttpContext);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* HTTP 5xx. The server already returns a generic body plus a `correlationId`
|
|
101
|
+
* for unexpected failures, so the useful thing to surface is that id — not the
|
|
102
|
+
* status line and URL the SDK used to build into `message`.
|
|
103
|
+
*/
|
|
104
|
+
export declare class CuratorServerError extends CuratorError {
|
|
105
|
+
constructor(message: string, ctx?: HttpContext);
|
|
38
106
|
}
|
|
39
107
|
/**
|
|
40
108
|
* Run paused waiting for human approval. Approval resolution is not
|
|
@@ -69,6 +137,22 @@ export declare class CuratorAuthorizationRequiredError extends CuratorError {
|
|
|
69
137
|
runId: string;
|
|
70
138
|
});
|
|
71
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Delegated-identity failure codes, mirroring the server's taxonomy in
|
|
142
|
+
* `delegationFailure.ts`. Four outcomes because each implies a DIFFERENT next
|
|
143
|
+
* action, and collapsing them is what makes "why did this fail only after the
|
|
144
|
+
* approval?" unanswerable.
|
|
145
|
+
*
|
|
146
|
+
* `AgentFailureClass` has no delegated variant, and the errored payload carries
|
|
147
|
+
* no structured code — the server prefixes the failure MESSAGE with the code
|
|
148
|
+
* instead. So this is recovered by parsing that prefix, which is a real
|
|
149
|
+
* coupling: if the server stops prefixing, `delegationCode` silently goes null
|
|
150
|
+
* and the user gets the generic agent-error text. The durable fix is a
|
|
151
|
+
* first-class field on the errored event; until then the prefix is the contract.
|
|
152
|
+
*/
|
|
153
|
+
export type DelegationFailureCode = "DELEGATED_IDENTITY_EXPIRED" | "DELEGATED_IDENTITY_REVOKED" | "DELEGATED_TOKEN_EXCHANGE_FAILED" | "DOWNSTREAM_AUTH_REJECTED" | "DELEGATED_AUTH_NOT_CONFIGURED";
|
|
154
|
+
/** Recover the delegated-failure code from a server message prefix. */
|
|
155
|
+
export declare function parseDelegationFailureCode(message: string | undefined): DelegationFailureCode | null;
|
|
72
156
|
/**
|
|
73
157
|
* The agent run reached a terminal error state (LLM quota, auth, 5xx
|
|
74
158
|
* exhausted retries, etc.). `failureClass` and `isPermanent` mirror the
|
|
@@ -80,6 +164,12 @@ export declare class CuratorAgentError extends CuratorError {
|
|
|
80
164
|
readonly conversationId: string;
|
|
81
165
|
readonly runId: string;
|
|
82
166
|
readonly stepId: string | null;
|
|
167
|
+
/**
|
|
168
|
+
* Set when the run failed on delegated identity. Distinct from
|
|
169
|
+
* `failureClass`, which has no delegated variant — see
|
|
170
|
+
* {@link DelegationFailureCode}.
|
|
171
|
+
*/
|
|
172
|
+
readonly delegationCode: DelegationFailureCode | null;
|
|
83
173
|
constructor(args: {
|
|
84
174
|
message: string;
|
|
85
175
|
failureClass: AgentFailureClass;
|
|
@@ -104,4 +194,5 @@ export declare class CuratorTimeoutError extends CuratorError {
|
|
|
104
194
|
continueWaiting: (timeoutMs?: number) => Promise<AssistantMessage>;
|
|
105
195
|
});
|
|
106
196
|
}
|
|
197
|
+
export {};
|
|
107
198
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/cjs/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,YAAY,CAAA;AAEnB,qBAAa,YAAa,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,YAAY,CAAA;AAEnB,qBAAa,YAAa,SAAQ,KAAK;IACrC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;gBAGzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACpB;CAcJ;AAED,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,4CACU,CAAA;AAE3C,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE5E;AAED,KAAK,WAAW,GAAG;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB,CAAA;AAED,4EAA4E;AAC5E,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,SAA+B,EAAE,GAAG,GAAE,WAAgB;CAM1E;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,SAAQ,YAAY;gBAC3C,OAAO,SAAyC,EAAE,GAAG,GAAE,WAAgB;CAOpF;AAED,oFAAoF;AACpF,qBAAa,qBAAsB,SAAQ,YAAY;gBACzC,OAAO,SAAsB,EAAE,GAAG,GAAE,WAAgB;CAIjE;AAED,mFAAmF;AACnF,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,SAAuB,EAAE,GAAG,GAAE,WAAgB;CAMlE;AAED,0DAA0D;AAC1D,qBAAa,6BAA8B,SAAQ,YAAY;IAC7D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;gBACrB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,GAAE,WAAgB;CAQ7E;AAED,wCAAwC;AACxC,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;gBAEvC,OAAO,SAAwB,EAC/B,iBAAiB,GAAE,MAAM,GAAG,IAAW,EACvC,GAAG,GAAE,WAAgB;CAWxB;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;gBACtC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB;CAUnD;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;gBAEV,IAAI,EAAE;QAChB,QAAQ,EAAE,eAAe,CAAA;QACzB,cAAc,EAAE,MAAM,CAAA;QACtB,KAAK,EAAE,MAAM,CAAA;KACd;CAeF;AAED;;;;;GAKG;AACH,qBAAa,iCAAkC,SAAQ,YAAY;IACjE,QAAQ,CAAC,aAAa,EAAE,oBAAoB,CAAA;IAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;gBAEV,IAAI,EAAE;QAChB,aAAa,EAAE,oBAAoB,CAAA;QACnC,cAAc,EAAE,MAAM,CAAA;QACtB,KAAK,EAAE,MAAM,CAAA;KACd;CAkBF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,qBAAqB,GAC7B,4BAA4B,GAC5B,4BAA4B,GAC5B,iCAAiC,GACjC,0BAA0B,GAC1B,+BAA+B,CAAA;AAUnC,uEAAuE;AACvE,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,qBAAqB,GAAG,IAAI,CAM9B;AA+BD;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAA;IACxC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,qBAAqB,GAAG,IAAI,CAAA;gBAEzC,IAAI,EAAE;QAChB,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,iBAAiB,CAAA;QAC/B,WAAW,EAAE,OAAO,CAAA;QACpB,cAAc,EAAE,MAAM,CAAA;QACtB,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACvB;CAuBF;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;gBAE/D,IAAI,EAAE;QAChB,cAAc,EAAE,MAAM,CAAA;QACtB,KAAK,EAAE,MAAM,CAAA;QACb,eAAe,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;KACnE;CAUF"}
|
package/dist/cjs/errors.js
CHANGED
|
@@ -10,11 +10,49 @@
|
|
|
10
10
|
* backstop.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.CuratorTimeoutError = exports.CuratorAgentError = exports.CuratorAuthorizationRequiredError = exports.CuratorApprovalRequiredError = exports.CuratorRateLimitError = exports.CuratorDeploymentRetiredError = exports.CuratorNotFoundError = exports.CuratorForbiddenError = exports.CuratorAuthError = exports.CuratorError = void 0;
|
|
13
|
+
exports.CuratorTimeoutError = exports.CuratorAgentError = exports.CuratorAuthorizationRequiredError = exports.CuratorApprovalRequiredError = exports.CuratorServerError = exports.CuratorRateLimitError = exports.CuratorDeploymentRetiredError = exports.CuratorNotFoundError = exports.CuratorForbiddenError = exports.CuratorEndUserAuthError = exports.CuratorAuthError = exports.DEFAULT_USER_MESSAGE = exports.CuratorError = void 0;
|
|
14
|
+
exports.withRequestId = withRequestId;
|
|
15
|
+
exports.parseDelegationFailureCode = parseDelegationFailureCode;
|
|
14
16
|
class CuratorError extends Error {
|
|
17
|
+
/**
|
|
18
|
+
* What an END USER may be shown.
|
|
19
|
+
*
|
|
20
|
+
* `message` is for developers — it can name the request, the status, and the
|
|
21
|
+
* server's own wording. That is the wrong text to put in a chat bubble, and
|
|
22
|
+
* shipping it there is not a hypothetical: a 500 rendered as
|
|
23
|
+
* `HTTP 500 from https://api.../agents/<slug>/conversations: …`, exposing the
|
|
24
|
+
* deployment's URL to whoever was chatting, and an end-user token failure
|
|
25
|
+
* rendered as "End-user JWT could not be verified", which tells the person
|
|
26
|
+
* nothing they can act on and leaks the auth mechanism.
|
|
27
|
+
*
|
|
28
|
+
* Every subclass sets this to something safe and actionable. `renderError` in
|
|
29
|
+
* the React bindings prefers it and never falls back to `message`, so a new
|
|
30
|
+
* error type is safe-by-default rather than leaky-by-default.
|
|
31
|
+
*/
|
|
32
|
+
userMessage;
|
|
33
|
+
/** HTTP status, when this came from a response. */
|
|
34
|
+
status;
|
|
35
|
+
/** Server error code (`error.code`), when present. */
|
|
36
|
+
code;
|
|
37
|
+
/**
|
|
38
|
+
* Correlation id from `x-request-id` / `correlationId`. The one detail worth
|
|
39
|
+
* showing a user on an unexpected failure — it is what support can trace,
|
|
40
|
+
* and it says nothing about the system's shape.
|
|
41
|
+
*/
|
|
42
|
+
requestId;
|
|
43
|
+
/**
|
|
44
|
+
* Request URL, as a PROPERTY rather than part of `message`. Available for
|
|
45
|
+
* logs and bug reports without riding along into anything user-visible.
|
|
46
|
+
*/
|
|
47
|
+
url;
|
|
15
48
|
constructor(message, options) {
|
|
16
49
|
super(message);
|
|
17
50
|
this.name = "CuratorError";
|
|
51
|
+
this.userMessage = options?.userMessage ?? exports.DEFAULT_USER_MESSAGE;
|
|
52
|
+
this.status = options?.status ?? null;
|
|
53
|
+
this.code = options?.code ?? null;
|
|
54
|
+
this.requestId = options?.requestId ?? null;
|
|
55
|
+
this.url = options?.url ?? null;
|
|
18
56
|
// Preserve the underlying error if the runtime supports it.
|
|
19
57
|
if (options?.cause !== undefined) {
|
|
20
58
|
;
|
|
@@ -23,26 +61,57 @@ class CuratorError extends Error {
|
|
|
23
61
|
}
|
|
24
62
|
}
|
|
25
63
|
exports.CuratorError = CuratorError;
|
|
64
|
+
/** Last-resort user-facing text. Deliberately says nothing about the system. */
|
|
65
|
+
exports.DEFAULT_USER_MESSAGE = "Something went wrong. Please try again.";
|
|
66
|
+
/** Appends a correlation id when there is one, so support has a handle. */
|
|
67
|
+
function withRequestId(text, requestId) {
|
|
68
|
+
return requestId ? `${text} (reference: ${requestId})` : text;
|
|
69
|
+
}
|
|
26
70
|
/** HTTP 401 from the API — your API key is missing, invalid, or revoked. */
|
|
27
71
|
class CuratorAuthError extends CuratorError {
|
|
28
|
-
constructor(message = "Invalid or revoked API key") {
|
|
29
|
-
|
|
72
|
+
constructor(message = "Invalid or revoked API key", ctx = {}) {
|
|
73
|
+
// The API key is the INTEGRATOR's credential. An end user can do nothing
|
|
74
|
+
// about it and should not be told which credential failed.
|
|
75
|
+
super(message, { ...ctx, userMessage: "This chat isn't available right now. Please try again later." });
|
|
30
76
|
this.name = "CuratorAuthError";
|
|
31
77
|
}
|
|
32
78
|
}
|
|
33
79
|
exports.CuratorAuthError = CuratorAuthError;
|
|
80
|
+
/**
|
|
81
|
+
* HTTP 401 specifically because the END-USER token was missing, expired, or
|
|
82
|
+
* unverifiable — distinct from `CuratorAuthError`, which is about the
|
|
83
|
+
* integrator's API key.
|
|
84
|
+
*
|
|
85
|
+
* Separate because the remediation is completely different: an API-key failure
|
|
86
|
+
* needs a developer, whereas this one is usually a stale session the user fixes
|
|
87
|
+
* by signing in again. Collapsing them produced "Authentication failed. Check
|
|
88
|
+
* your API key." in response to an expired user token, which sends the reader
|
|
89
|
+
* after the wrong thing entirely.
|
|
90
|
+
*/
|
|
91
|
+
class CuratorEndUserAuthError extends CuratorError {
|
|
92
|
+
constructor(message = "End-user token could not be verified", ctx = {}) {
|
|
93
|
+
super(message, {
|
|
94
|
+
...ctx,
|
|
95
|
+
userMessage: "Your session has expired. Please sign in again to continue.",
|
|
96
|
+
});
|
|
97
|
+
this.name = "CuratorEndUserAuthError";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.CuratorEndUserAuthError = CuratorEndUserAuthError;
|
|
34
101
|
/** HTTP 403 from the API — your API key doesn't have permission for this action. */
|
|
35
102
|
class CuratorForbiddenError extends CuratorError {
|
|
36
|
-
constructor(message = "Permission denied") {
|
|
37
|
-
super(message);
|
|
103
|
+
constructor(message = "Permission denied", ctx = {}) {
|
|
104
|
+
super(message, { ...ctx, userMessage: "You don't have access to this." });
|
|
38
105
|
this.name = "CuratorForbiddenError";
|
|
39
106
|
}
|
|
40
107
|
}
|
|
41
108
|
exports.CuratorForbiddenError = CuratorForbiddenError;
|
|
42
109
|
/** HTTP 404 from the API — the deployment slug or conversation id wasn't found. */
|
|
43
110
|
class CuratorNotFoundError extends CuratorError {
|
|
44
|
-
constructor(message = "Resource not found") {
|
|
45
|
-
|
|
111
|
+
constructor(message = "Resource not found", ctx = {}) {
|
|
112
|
+
// Says nothing about WHICH resource: on a 404 the slug is often the thing
|
|
113
|
+
// that is wrong, and echoing it back tells a prober they guessed close.
|
|
114
|
+
super(message, { ...ctx, userMessage: "This chat isn't available." });
|
|
46
115
|
this.name = "CuratorNotFoundError";
|
|
47
116
|
}
|
|
48
117
|
}
|
|
@@ -50,8 +119,11 @@ exports.CuratorNotFoundError = CuratorNotFoundError;
|
|
|
50
119
|
/** HTTP 410 from the API — the deployment was retired. */
|
|
51
120
|
class CuratorDeploymentRetiredError extends CuratorError {
|
|
52
121
|
retiredAt;
|
|
53
|
-
constructor(message, retiredAt) {
|
|
54
|
-
super(message
|
|
122
|
+
constructor(message, retiredAt, ctx = {}) {
|
|
123
|
+
super(message, {
|
|
124
|
+
...ctx,
|
|
125
|
+
userMessage: "This assistant is no longer available.",
|
|
126
|
+
});
|
|
55
127
|
this.name = "CuratorDeploymentRetiredError";
|
|
56
128
|
this.retiredAt = retiredAt;
|
|
57
129
|
}
|
|
@@ -60,13 +132,33 @@ exports.CuratorDeploymentRetiredError = CuratorDeploymentRetiredError;
|
|
|
60
132
|
/** HTTP 429 from the API — back off. */
|
|
61
133
|
class CuratorRateLimitError extends CuratorError {
|
|
62
134
|
retryAfterSeconds;
|
|
63
|
-
constructor(message = "Rate limit exceeded", retryAfterSeconds = null) {
|
|
64
|
-
super(message
|
|
135
|
+
constructor(message = "Rate limit exceeded", retryAfterSeconds = null, ctx = {}) {
|
|
136
|
+
super(message, {
|
|
137
|
+
...ctx,
|
|
138
|
+
userMessage: retryAfterSeconds
|
|
139
|
+
? `Too many messages. Please wait ${retryAfterSeconds} seconds and try again.`
|
|
140
|
+
: "Too many messages. Please wait a moment and try again.",
|
|
141
|
+
});
|
|
65
142
|
this.name = "CuratorRateLimitError";
|
|
66
143
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
67
144
|
}
|
|
68
145
|
}
|
|
69
146
|
exports.CuratorRateLimitError = CuratorRateLimitError;
|
|
147
|
+
/**
|
|
148
|
+
* HTTP 5xx. The server already returns a generic body plus a `correlationId`
|
|
149
|
+
* for unexpected failures, so the useful thing to surface is that id — not the
|
|
150
|
+
* status line and URL the SDK used to build into `message`.
|
|
151
|
+
*/
|
|
152
|
+
class CuratorServerError extends CuratorError {
|
|
153
|
+
constructor(message, ctx = {}) {
|
|
154
|
+
super(message, {
|
|
155
|
+
...ctx,
|
|
156
|
+
userMessage: withRequestId("Something went wrong on our end. Please try again.", ctx.requestId ?? null),
|
|
157
|
+
});
|
|
158
|
+
this.name = "CuratorServerError";
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.CuratorServerError = CuratorServerError;
|
|
70
162
|
/**
|
|
71
163
|
* Run paused waiting for human approval. Approval resolution is not
|
|
72
164
|
* exposed to API consumers — pauses are routed through the dashboard
|
|
@@ -80,7 +172,10 @@ class CuratorApprovalRequiredError extends CuratorError {
|
|
|
80
172
|
runId;
|
|
81
173
|
constructor(args) {
|
|
82
174
|
super(`Run paused for approval — the '${args.approval.tool_name}' tool needs an administrator to review it. ` +
|
|
83
|
-
"Contact your administrator to resolve this in the Curator dashboard."
|
|
175
|
+
"Contact your administrator to resolve this in the Curator dashboard.", {
|
|
176
|
+
userMessage: `That action needs administrator approval. Someone has been asked to review the ` +
|
|
177
|
+
`"${args.approval.tool_name}" request.`,
|
|
178
|
+
});
|
|
84
179
|
this.name = "CuratorApprovalRequiredError";
|
|
85
180
|
this.approval = args.approval;
|
|
86
181
|
this.conversationId = args.conversationId;
|
|
@@ -102,7 +197,11 @@ class CuratorAuthorizationRequiredError extends CuratorError {
|
|
|
102
197
|
super(`Run paused for authorization — connect ${args.authorization.provider} to continue. ` +
|
|
103
198
|
(args.authorization.connect_url
|
|
104
199
|
? `Connect at ${args.authorization.connect_url}, then resume the conversation.`
|
|
105
|
-
: "Connect the provider, then resume the conversation.")
|
|
200
|
+
: "Connect the provider, then resume the conversation."), {
|
|
201
|
+
// `reason` is authored for the end user by the integration; prefer it.
|
|
202
|
+
userMessage: args.authorization.reason ||
|
|
203
|
+
`Connect your ${args.authorization.provider} account to continue.`,
|
|
204
|
+
});
|
|
106
205
|
this.name = "CuratorAuthorizationRequiredError";
|
|
107
206
|
this.authorization = args.authorization;
|
|
108
207
|
this.conversationId = args.conversationId;
|
|
@@ -110,6 +209,51 @@ class CuratorAuthorizationRequiredError extends CuratorError {
|
|
|
110
209
|
}
|
|
111
210
|
}
|
|
112
211
|
exports.CuratorAuthorizationRequiredError = CuratorAuthorizationRequiredError;
|
|
212
|
+
const DELEGATION_CODES = [
|
|
213
|
+
"DELEGATED_IDENTITY_EXPIRED",
|
|
214
|
+
"DELEGATED_IDENTITY_REVOKED",
|
|
215
|
+
"DELEGATED_TOKEN_EXCHANGE_FAILED",
|
|
216
|
+
"DOWNSTREAM_AUTH_REJECTED",
|
|
217
|
+
"DELEGATED_AUTH_NOT_CONFIGURED",
|
|
218
|
+
];
|
|
219
|
+
/** Recover the delegated-failure code from a server message prefix. */
|
|
220
|
+
function parseDelegationFailureCode(message) {
|
|
221
|
+
if (!message)
|
|
222
|
+
return null;
|
|
223
|
+
for (const code of DELEGATION_CODES) {
|
|
224
|
+
if (message.startsWith(`${code}:`))
|
|
225
|
+
return code;
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* End-user text per delegated-failure code. The split that matters is WHO can
|
|
231
|
+
* fix it: expiry is the user's to resolve by re-authenticating, revocation and
|
|
232
|
+
* scope gaps need an administrator, and the exchange/config failures are ours
|
|
233
|
+
* and must not be phrased as the user's fault.
|
|
234
|
+
*/
|
|
235
|
+
function delegationUserMessage(code) {
|
|
236
|
+
switch (code) {
|
|
237
|
+
case "DELEGATED_IDENTITY_EXPIRED":
|
|
238
|
+
// The common one: a run paused past the assertion's lifetime. Retrying
|
|
239
|
+
// the same request is futile, so the text must ask for a NEW session
|
|
240
|
+
// rather than inviting another attempt.
|
|
241
|
+
return "Your session expired before that could finish. Please sign in again and retry.";
|
|
242
|
+
case "DELEGATED_IDENTITY_REVOKED":
|
|
243
|
+
// Server-side this pages someone — it means a context was crossed or
|
|
244
|
+
// probed. Never hint at the mechanism; the user just lacks authority.
|
|
245
|
+
return "You don't have permission to complete that action. Please contact your administrator.";
|
|
246
|
+
case "DOWNSTREAM_AUTH_REJECTED":
|
|
247
|
+
// Exchange worked; the resource server said no. A scope/permission gap on
|
|
248
|
+
// the customer's side, so an administrator is the right destination.
|
|
249
|
+
return "Your account doesn't have access to what that action needed. Please contact your administrator.";
|
|
250
|
+
case "DELEGATED_TOKEN_EXCHANGE_FAILED":
|
|
251
|
+
case "DELEGATED_AUTH_NOT_CONFIGURED":
|
|
252
|
+
// Ours to fix. Do not tell the user to sign in — it will not help, and it
|
|
253
|
+
// sends them chasing a problem they cannot see.
|
|
254
|
+
return "That action isn't available right now. Please try again later.";
|
|
255
|
+
}
|
|
256
|
+
}
|
|
113
257
|
/**
|
|
114
258
|
* The agent run reached a terminal error state (LLM quota, auth, 5xx
|
|
115
259
|
* exhausted retries, etc.). `failureClass` and `isPermanent` mirror the
|
|
@@ -121,9 +265,29 @@ class CuratorAgentError extends CuratorError {
|
|
|
121
265
|
conversationId;
|
|
122
266
|
runId;
|
|
123
267
|
stepId;
|
|
268
|
+
/**
|
|
269
|
+
* Set when the run failed on delegated identity. Distinct from
|
|
270
|
+
* `failureClass`, which has no delegated variant — see
|
|
271
|
+
* {@link DelegationFailureCode}.
|
|
272
|
+
*/
|
|
273
|
+
delegationCode;
|
|
124
274
|
constructor(args) {
|
|
125
|
-
|
|
275
|
+
const delegationCode = parseDelegationFailureCode(args.message);
|
|
276
|
+
super(args.message, {
|
|
277
|
+
// NOT `args.message`: the run's failure text is written for an operator
|
|
278
|
+
// and can name providers, quotas, or step ids. A delegated failure gets
|
|
279
|
+
// its own text because the server already told us who can fix it —
|
|
280
|
+
// throwing that away and falling back to `isPermanent` is how an expired
|
|
281
|
+
// session became "couldn't complete that request", which is true and
|
|
282
|
+
// useless when "sign in again" was the answer.
|
|
283
|
+
userMessage: delegationCode
|
|
284
|
+
? delegationUserMessage(delegationCode)
|
|
285
|
+
: args.isPermanent
|
|
286
|
+
? "The assistant couldn't complete that request. Please try rephrasing, or contact support."
|
|
287
|
+
: "The assistant hit a temporary problem. Please try again.",
|
|
288
|
+
});
|
|
126
289
|
this.name = "CuratorAgentError";
|
|
290
|
+
this.delegationCode = delegationCode;
|
|
127
291
|
this.failureClass = args.failureClass;
|
|
128
292
|
this.isPermanent = args.isPermanent;
|
|
129
293
|
this.conversationId = args.conversationId;
|
|
@@ -142,7 +306,9 @@ class CuratorTimeoutError extends CuratorError {
|
|
|
142
306
|
runId;
|
|
143
307
|
continueWaiting;
|
|
144
308
|
constructor(args) {
|
|
145
|
-
super("Timed out waiting for the agent to reply — the run is still in progress."
|
|
309
|
+
super("Timed out waiting for the agent to reply — the run is still in progress.", {
|
|
310
|
+
userMessage: "This is taking longer than usual. It may still finish — check back in a moment.",
|
|
311
|
+
});
|
|
146
312
|
this.name = "CuratorTimeoutError";
|
|
147
313
|
this.conversationId = args.conversationId;
|
|
148
314
|
this.runId = args.runId;
|
package/dist/cjs/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAwEH,sCAEC;AA6MD,gEAQC;AAtRD,MAAa,YAAa,SAAQ,KAAK;IACrC;;;;;;;;;;;;;;OAcG;IACM,WAAW,CAAQ;IAC5B,mDAAmD;IAC1C,MAAM,CAAe;IAC9B,sDAAsD;IAC7C,IAAI,CAAe;IAC5B;;;;OAIG;IACM,SAAS,CAAe;IACjC;;;OAGG;IACM,GAAG,CAAe;IAE3B,YACE,OAAe,EACf,OAOC;QAED,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;QAC1B,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,4BAAoB,CAAA;QAC/D,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,CAAA;QACrC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,IAAI,CAAA;QACjC,IAAI,CAAC,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAA;QAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,IAAI,CAAA;QAC/B,4DAA4D;QAC5D,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,CAAC;YAAC,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;QACtD,CAAC;IACH,CAAC;CACF;AAxDD,oCAwDC;AAED,gFAAgF;AACnE,QAAA,oBAAoB,GAC/B,yCAAyC,CAAA;AAE3C,2EAA2E;AAC3E,SAAgB,aAAa,CAAC,IAAY,EAAE,SAAwB;IAClE,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,gBAAgB,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,CAAA;AAC/D,CAAC;AASD,4EAA4E;AAC5E,MAAa,gBAAiB,SAAQ,YAAY;IAChD,YAAY,OAAO,GAAG,4BAA4B,EAAE,MAAmB,EAAE;QACvE,yEAAyE;QACzE,2DAA2D;QAC3D,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC,CAAA;QACvG,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,CAAC;CACF;AAPD,4CAOC;AAED;;;;;;;;;;GAUG;AACH,MAAa,uBAAwB,SAAQ,YAAY;IACvD,YAAY,OAAO,GAAG,sCAAsC,EAAE,MAAmB,EAAE;QACjF,KAAK,CAAC,OAAO,EAAE;YACb,GAAG,GAAG;YACN,WAAW,EAAE,6DAA6D;SAC3E,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AARD,0DAQC;AAED,oFAAoF;AACpF,MAAa,qBAAsB,SAAQ,YAAY;IACrD,YAAY,OAAO,GAAG,mBAAmB,EAAE,MAAmB,EAAE;QAC9D,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC,CAAA;QACzE,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;IACrC,CAAC;CACF;AALD,sDAKC;AAED,mFAAmF;AACnF,MAAa,oBAAqB,SAAQ,YAAY;IACpD,YAAY,OAAO,GAAG,oBAAoB,EAAE,MAAmB,EAAE;QAC/D,0EAA0E;QAC1E,wEAAwE;QACxE,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAA;QACrE,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAA;IACpC,CAAC;CACF;AAPD,oDAOC;AAED,0DAA0D;AAC1D,MAAa,6BAA8B,SAAQ,YAAY;IACpD,SAAS,CAAe;IACjC,YAAY,OAAe,EAAE,SAAwB,EAAE,MAAmB,EAAE;QAC1E,KAAK,CAAC,OAAO,EAAE;YACb,GAAG,GAAG;YACN,WAAW,EAAE,wCAAwC;SACtD,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;CACF;AAVD,sEAUC;AAED,wCAAwC;AACxC,MAAa,qBAAsB,SAAQ,YAAY;IAC5C,iBAAiB,CAAe;IACzC,YACE,OAAO,GAAG,qBAAqB,EAC/B,oBAAmC,IAAI,EACvC,MAAmB,EAAE;QAErB,KAAK,CAAC,OAAO,EAAE;YACb,GAAG,GAAG;YACN,WAAW,EAAE,iBAAiB;gBAC5B,CAAC,CAAC,kCAAkC,iBAAiB,yBAAyB;gBAC9E,CAAC,CAAC,wDAAwD;SAC7D,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;QACnC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;IAC5C,CAAC;CACF;AAhBD,sDAgBC;AAED;;;;GAIG;AACH,MAAa,kBAAmB,SAAQ,YAAY;IAClD,YAAY,OAAe,EAAE,MAAmB,EAAE;QAChD,KAAK,CAAC,OAAO,EAAE;YACb,GAAG,GAAG;YACN,WAAW,EAAE,aAAa,CACxB,oDAAoD,EACpD,GAAG,CAAC,SAAS,IAAI,IAAI,CACtB;SACF,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAXD,gDAWC;AAED;;;;;;GAMG;AACH,MAAa,4BAA6B,SAAQ,YAAY;IACnD,QAAQ,CAAiB;IACzB,cAAc,CAAQ;IACtB,KAAK,CAAQ;IAEtB,YAAY,IAIX;QACC,KAAK,CACH,kCAAkC,IAAI,CAAC,QAAQ,CAAC,SAAS,8CAA8C;YACrG,sEAAsE,EACxE;YACE,WAAW,EACT,iFAAiF;gBACjF,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,YAAY;SAC1C,CACF,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAA;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;CACF;AAxBD,oEAwBC;AAED;;;;;GAKG;AACH,MAAa,iCAAkC,SAAQ,YAAY;IACxD,aAAa,CAAsB;IACnC,cAAc,CAAQ;IACtB,KAAK,CAAQ;IAEtB,YAAY,IAIX;QACC,KAAK,CACH,0CAA0C,IAAI,CAAC,aAAa,CAAC,QAAQ,gBAAgB;YACnF,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW;gBAC7B,CAAC,CAAC,cAAc,IAAI,CAAC,aAAa,CAAC,WAAW,iCAAiC;gBAC/E,CAAC,CAAC,qDAAqD,CAAC,EAC5D;YACE,uEAAuE;YACvE,WAAW,EACT,IAAI,CAAC,aAAa,CAAC,MAAM;gBACzB,gBAAgB,IAAI,CAAC,aAAa,CAAC,QAAQ,uBAAuB;SACrE,CACF,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,mCAAmC,CAAA;QAC/C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAA;QACvC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;CACF;AA3BD,8EA2BC;AAsBD,MAAM,gBAAgB,GAA4B;IAChD,4BAA4B;IAC5B,4BAA4B;IAC5B,iCAAiC;IACjC,0BAA0B;IAC1B,+BAA+B;CAChC,CAAA;AAED,uEAAuE;AACvE,SAAgB,0BAA0B,CACxC,OAA2B;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;IACjD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,IAA2B;IACxD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,4BAA4B;YAC/B,uEAAuE;YACvE,qEAAqE;YACrE,wCAAwC;YACxC,OAAO,gFAAgF,CAAA;QACzF,KAAK,4BAA4B;YAC/B,qEAAqE;YACrE,sEAAsE;YACtE,OAAO,uFAAuF,CAAA;QAChG,KAAK,0BAA0B;YAC7B,0EAA0E;YAC1E,qEAAqE;YACrE,OAAO,iGAAiG,CAAA;QAC1G,KAAK,iCAAiC,CAAC;QACvC,KAAK,+BAA+B;YAClC,0EAA0E;YAC1E,gDAAgD;YAChD,OAAO,gEAAgE,CAAA;IAC3E,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAa,iBAAkB,SAAQ,YAAY;IACxC,YAAY,CAAmB;IAC/B,WAAW,CAAS;IACpB,cAAc,CAAQ;IACtB,KAAK,CAAQ;IACb,MAAM,CAAe;IAC9B;;;;OAIG;IACM,cAAc,CAA8B;IAErD,YAAY,IAOX;QACC,MAAM,cAAc,GAAG,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/D,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE;YAClB,wEAAwE;YACxE,wEAAwE;YACxE,mEAAmE;YACnE,yEAAyE;YACzE,qEAAqE;YACrE,+CAA+C;YAC/C,WAAW,EAAE,cAAc;gBACzB,CAAC,CAAC,qBAAqB,CAAC,cAAc,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,WAAW;oBAChB,CAAC,CAAC,0FAA0F;oBAC5F,CAAC,CAAC,0DAA0D;SACjE,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;QAC/B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAA;QACpC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAA;IACnC,CAAC;CACF;AA3CD,8CA2CC;AAED;;;;GAIG;AACH,MAAa,mBAAoB,SAAQ,YAAY;IAC1C,cAAc,CAAQ;IACtB,KAAK,CAAQ;IACb,eAAe,CAAmD;IAE3E,YAAY,IAIX;QACC,KAAK,CAAC,0EAA0E,EAAE;YAChF,WAAW,EACT,iFAAiF;SACpF,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACvB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAA;IAC7C,CAAC;CACF;AAnBD,kDAmBC"}
|
package/dist/cjs/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC1B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yCAAyC;IACzC,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAEvD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAA;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAoB;gBAE5C,IAAI,EAAE,iBAAiB;IAsBnC,yDAAyD;IACzD,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM;IAgB9C;;;;;;OAMG;YACW,iBAAiB;IAc/B;;;;;OAKG;IACG,UAAU,CACd,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACnF,OAAO,CAAC,QAAQ,CAAC;IAgDd,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CAuDrE"}
|
package/dist/cjs/http.js
CHANGED
|
@@ -72,7 +72,7 @@ class HttpClient {
|
|
|
72
72
|
return value || undefined;
|
|
73
73
|
}
|
|
74
74
|
catch (err) {
|
|
75
|
-
throw new errors_js_1.
|
|
75
|
+
throw new errors_js_1.CuratorEndUserAuthError(`Failed to obtain end-user JWT: ${err.message}`);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
@@ -105,15 +105,22 @@ class HttpClient {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
catch (err) {
|
|
108
|
-
throw new errors_js_1.CuratorError(`Network error talking to ${finalUrl}: ${err.message}`, {
|
|
108
|
+
throw new errors_js_1.CuratorError(`Network error talking to ${finalUrl}: ${err.message}`, {
|
|
109
|
+
cause: err,
|
|
110
|
+
url: finalUrl,
|
|
111
|
+
userMessage: "Can't reach the assistant. Check your connection and try again.",
|
|
112
|
+
});
|
|
109
113
|
}
|
|
110
114
|
if (!response.ok) {
|
|
111
115
|
const text = await response.text().catch(() => "");
|
|
112
116
|
const body = text ? safeJsonParse(text) : undefined;
|
|
113
|
-
throw httpError(response.status, body, finalUrl);
|
|
117
|
+
throw httpError(response.status, body, finalUrl, response.headers.get("x-request-id"));
|
|
114
118
|
}
|
|
115
119
|
if (!response.body) {
|
|
116
|
-
throw new errors_js_1.CuratorError(`Streaming response had no body (${finalUrl})
|
|
120
|
+
throw new errors_js_1.CuratorError(`Streaming response had no body (${finalUrl})`, {
|
|
121
|
+
url: finalUrl,
|
|
122
|
+
status: response.status,
|
|
123
|
+
});
|
|
117
124
|
}
|
|
118
125
|
return response;
|
|
119
126
|
}
|
|
@@ -145,7 +152,11 @@ class HttpClient {
|
|
|
145
152
|
});
|
|
146
153
|
}
|
|
147
154
|
catch (err) {
|
|
148
|
-
throw new errors_js_1.CuratorError(`Network error talking to ${finalUrl}: ${err.message}`, {
|
|
155
|
+
throw new errors_js_1.CuratorError(`Network error talking to ${finalUrl}: ${err.message}`, {
|
|
156
|
+
cause: err,
|
|
157
|
+
url: finalUrl,
|
|
158
|
+
userMessage: "Can't reach the assistant. Check your connection and try again.",
|
|
159
|
+
});
|
|
149
160
|
}
|
|
150
161
|
finally {
|
|
151
162
|
if (timer)
|
|
@@ -157,7 +168,7 @@ class HttpClient {
|
|
|
157
168
|
const text = await response.text();
|
|
158
169
|
const body = text ? safeJsonParse(text) : undefined;
|
|
159
170
|
if (!response.ok) {
|
|
160
|
-
throw httpError(response.status, body, finalUrl);
|
|
171
|
+
throw httpError(response.status, body, finalUrl, response.headers.get("x-request-id"));
|
|
161
172
|
}
|
|
162
173
|
return body ?? undefined;
|
|
163
174
|
}
|
|
@@ -188,32 +199,73 @@ function safeJsonParse(text) {
|
|
|
188
199
|
return text;
|
|
189
200
|
}
|
|
190
201
|
}
|
|
191
|
-
|
|
202
|
+
/** Server error codes that mean the END-USER token failed, not the API key. */
|
|
203
|
+
const END_USER_AUTH_CODES = new Set([
|
|
204
|
+
"missing_end_user_jwt",
|
|
205
|
+
"end_user_jwt_invalid",
|
|
206
|
+
"end_user_jwt_expired",
|
|
207
|
+
"end_user_jwt_internal_error",
|
|
208
|
+
"end_user_session_invalid",
|
|
209
|
+
]);
|
|
210
|
+
function httpError(status, body, url, requestId = null) {
|
|
192
211
|
const detail = readErrorMessage(body);
|
|
212
|
+
const code = readErrorCode(body);
|
|
213
|
+
// `url` rides along as a PROPERTY, never inside `message`. A message that
|
|
214
|
+
// embeds the request URL ends up in a chat bubble the moment any consumer
|
|
215
|
+
// renders `err.message`, which is exactly how a deployment URL got shown to
|
|
216
|
+
// an end user.
|
|
217
|
+
const ctx = { status, code, requestId: requestId ?? readCorrelationId(body), url };
|
|
193
218
|
switch (status) {
|
|
194
219
|
case 401:
|
|
195
|
-
|
|
220
|
+
// Two different failures share this status. Distinguished by the server's
|
|
221
|
+
// error code so the SDK can say "sign in again" instead of sending the
|
|
222
|
+
// reader after an API key they cannot see.
|
|
223
|
+
return code && END_USER_AUTH_CODES.has(code)
|
|
224
|
+
? new errors_js_1.CuratorEndUserAuthError(detail ?? undefined, ctx)
|
|
225
|
+
: new errors_js_1.CuratorAuthError(detail ?? "Invalid or revoked API key", ctx);
|
|
196
226
|
case 403:
|
|
197
|
-
return new errors_js_1.CuratorForbiddenError(detail ?? "Permission denied");
|
|
227
|
+
return new errors_js_1.CuratorForbiddenError(detail ?? "Permission denied", ctx);
|
|
198
228
|
case 404:
|
|
199
|
-
return new errors_js_1.CuratorNotFoundError(detail ?? "Resource not found");
|
|
229
|
+
return new errors_js_1.CuratorNotFoundError(detail ?? "Resource not found", ctx);
|
|
200
230
|
case 410: {
|
|
201
231
|
const retiredAt = body && typeof body === "object" && "details" in body
|
|
202
232
|
? (body.details
|
|
203
233
|
?.retired_at ?? null)
|
|
204
234
|
: null;
|
|
205
|
-
return new errors_js_1.CuratorDeploymentRetiredError(detail ?? "Deployment has been retired", retiredAt);
|
|
235
|
+
return new errors_js_1.CuratorDeploymentRetiredError(detail ?? "Deployment has been retired", retiredAt, ctx);
|
|
206
236
|
}
|
|
207
237
|
case 429: {
|
|
208
238
|
const retry = body && typeof body === "object" && "retryAfter" in body
|
|
209
239
|
? Number(body.retryAfter)
|
|
210
240
|
: null;
|
|
211
|
-
return new errors_js_1.CuratorRateLimitError(detail ?? undefined, Number.isFinite(retry) ? retry : null);
|
|
241
|
+
return new errors_js_1.CuratorRateLimitError(detail ?? undefined, Number.isFinite(retry) ? retry : null, ctx);
|
|
212
242
|
}
|
|
213
243
|
default:
|
|
214
|
-
|
|
244
|
+
if (status >= 500) {
|
|
245
|
+
return new errors_js_1.CuratorServerError(`HTTP ${status} from ${url}${detail ? `: ${detail}` : ""}`, ctx);
|
|
246
|
+
}
|
|
247
|
+
return new errors_js_1.CuratorError(`HTTP ${status} from ${url}${detail ? `: ${detail}` : ""}`, ctx);
|
|
215
248
|
}
|
|
216
249
|
}
|
|
250
|
+
function readErrorCode(body) {
|
|
251
|
+
if (!body || typeof body !== "object")
|
|
252
|
+
return null;
|
|
253
|
+
const b = body;
|
|
254
|
+
if (b.error && typeof b.error === "object") {
|
|
255
|
+
const inner = b.error;
|
|
256
|
+
if (typeof inner.code === "string")
|
|
257
|
+
return inner.code;
|
|
258
|
+
}
|
|
259
|
+
if (typeof b.code === "string")
|
|
260
|
+
return b.code;
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
function readCorrelationId(body) {
|
|
264
|
+
if (!body || typeof body !== "object")
|
|
265
|
+
return null;
|
|
266
|
+
const b = body;
|
|
267
|
+
return typeof b.correlationId === "string" ? b.correlationId : null;
|
|
268
|
+
}
|
|
217
269
|
function readErrorMessage(body) {
|
|
218
270
|
if (!body || typeof body !== "object")
|
|
219
271
|
return undefined;
|