@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.
@@ -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
@@ -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;gBACzB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQ3D;AAED,4EAA4E;AAC5E,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,SAA+B;CAInD;AAED,oFAAoF;AACpF,qBAAa,qBAAsB,SAAQ,YAAY;gBACzC,OAAO,SAAsB;CAI1C;AAED,mFAAmF;AACnF,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,SAAuB;CAI3C;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;CAKtD;AAED,wCAAwC;AACxC,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;gBAC7B,OAAO,SAAwB,EAAE,iBAAiB,GAAE,MAAM,GAAG,IAAW;CAKrF;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;CAUF;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;CAYF;AAED;;;;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;gBAElB,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;CASF;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;CAOF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
@@ -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
- super(message);
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
- super(message);
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
- super(args.message);
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;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,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;IAe/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;IAyCd,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CAmDrE"}
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.CuratorError(`Failed to obtain end-user JWT: ${err.message}`, { cause: err });
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}`, { cause: err });
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}`, { cause: err });
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
- function httpError(status, body, url) {
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
- return new errors_js_1.CuratorAuthError(detail ?? "Invalid or revoked API key");
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
- return new errors_js_1.CuratorError(`HTTP ${status} from ${url}${detail ? `: ${detail}` : ""}`);
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;