@nuanu-ai/agentify 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,110 +1,56 @@
1
1
  /**
2
2
  * The client a merchant's engineer holds: a catalog, an order desk, and one
3
- * place to say what this process answers.
3
+ * place to say what this process answers. Every method here is one a page of
4
+ * the documentation tells a merchant to call, and the documentation's examples
5
+ * are compiled against these types by a test.
4
6
  *
5
- * The shape of it is the portal's, not this file's. Every method here exists
6
- * because a page of the documentation tells a merchant to call it, with the
7
- * arguments that page passes and answering with what that page reads — and the
8
- * examples on those pages are compiled against these types by a test, so the
9
- * code a merchant copies out of the documentation is code that builds.
7
+ * One stream carries orders, price questions and order events, so there is one
8
+ * way to register a handler, `on(kind, handler)`, and one lifecycle, `start`
9
+ * and `stop`.
10
10
  *
11
- * Three kinds travel one stream, so there is one way to register a handler for
12
- * one of them — `on(kind, handler)` — and one lifecycle, `start` and `stop`,
13
- * for the loop that carries all three. What a handler receives carries the
14
- * calls that answer it, and that is the part worth reading before changing
15
- * anything here, because two things that look alike are deliberately not.
11
+ * Two families of calls on an order look alike and are not. `delivered`,
12
+ * `refused` and `accepted` build the answer a handler returns and send
13
+ * nothing; returning it is what makes forgetting to answer, or answering
14
+ * twice, impossible. `deliver`, `refuse` and `accept` send: they are the
15
+ * asynchronous merchant's calls, made later from anywhere in their code, and
16
+ * they are on every order this client hands back, including `orders.forId`
17
+ * for a process that kept only the identifier.
16
18
  *
17
- * `order.delivered(...)`, `order.refused(...)` and `order.accepted()`
18
- * build the answer and send nothing; the handler still returns it. A bot
19
- * library lets a handler reply and forget, and forgetting there costs a
20
- * message; forgetting here is an order nobody answered — redelivered, a
21
- * delivery attempt spent, and in the asynchronous mode a debt to a buyer at
22
- * the end of it. Returning the answer is what makes forgetting impossible and
23
- * answering twice impossible.
24
- *
25
- * `order.deliver(...)`, `order.refuse(...)` and `order.accept(...)` are the
26
- * other thing: they send. They are the asynchronous merchant's closure verbs,
27
- * made hours later and from anywhere in their code, and they exist on the
28
- * order rather than beside it so that a merchant never holds an identifier of
29
- * ours. The same calls are on every order this client hands back — off the
30
- * stream, off `orders.get`, off `orders.list`, and off `orders.forId` for the
31
- * process that kept nothing but the identifier — because a process that
32
- * restarted has no object left to hold, and that is exactly the moment
33
- * juggling identifiers would come back.
34
- *
35
- * One rule runs through the whole surface and it is worth stating once. What
36
- * the contract gives a call a failure branch for is returned, never thrown,
37
- * and every one of those answers is the same envelope: `ok` says which it was,
38
- * a card that was not published comes back with its findings under `problems`,
39
- * and an order call that did not go through comes back as an error with a flag
40
- * saying whether repeating it could help. A merchant's integration code is
41
- * expected to read those and branch on them.
42
- *
43
- * What is thrown is what has no branch to be read on, and it is two kinds. A
44
- * client built wrong — no key, an address that is not one, a handler
45
- * registered twice — is a `TypeError` at the line that is wrong, before
46
- * anything leaves the process. A call that went out and produced no answer of
47
- * the kind its route promises, where the route has nowhere to put one, is a
48
- * `AgentifyError` carrying the same code vocabulary the returned failures use.
49
- *
50
- * The one place that rule needed a decision rather than a reading is a
51
- * `deliver` or a `refuse` whose answer never arrived, or arrived in words this
52
- * package cannot read. The contract has a branch for it — an error with a flag
53
- * saying whether calling again could change the outcome is exactly the shape
54
- * of "the connection dropped, call again" — so it comes back through that
55
- * branch, under a code this package produces and the gateway never sends. The
56
- * three codes and what separates them are written down beside them below.
19
+ * What the contract gives a failure branch is returned, never thrown, in one
20
+ * envelope whose `ok` says which it was. What has no branch is thrown: a client
21
+ * built wrong is a `TypeError` before anything leaves the process, and a call
22
+ * that went out and produced no answer its route can carry is an
23
+ * `AgentifyError` under the same codes.
57
24
  */
58
25
  import type { CardInput, Delivery, HandlerAnswer, Money, Order, OrderAcceptResponse, OrderCallResponse, OrderWithStatus, PublishResult, QuoteRequest, QuoteResponse, Refusal } from "@nuanu-ai/agentify-contracts";
59
26
  import { type EventHandler, type ProblemReporter, type StreamHandlerKind } from "./worker.js";
60
27
  export interface ClientOptions {
61
28
  /**
62
- * The merchant's API key.
63
- *
64
- * It admits `undefined` because the thing a merchant actually writes is
65
- * `process.env.AGENTIFY_API_KEY`, which is `string | undefined` in every
66
- * strict TypeScript project there is. Refusing that at the type level would
67
- * teach every merchant to silence it with a non-null assertion, which turns
68
- * an unset variable into an authorisation failure much later. It is refused
69
- * here instead, at the line that is wrong, with a sentence that names what
70
- * is missing.
29
+ * The merchant's API key. `undefined` is accepted by the type, since that is
30
+ * what `process.env.AGENTIFY_API_KEY` is, and refused when the client is
31
+ * built with a `TypeError` naming what is missing.
71
32
  */
72
33
  readonly apiKey: string | undefined;
73
34
  /**
74
- * Where the gateway is: `https://test.agentify.ad` while the merchant
75
- * is building, `https://agentify.ad` once they are live.
76
- *
77
- * Optional, and there is deliberately no default behind it. Both addresses
78
- * are settled and this package still refuses to pick one, because which of
79
- * them a process talks to is not a convenience — it is the difference
80
- * between a sale and a rehearsal (ADR-0020). A default would be right for
81
- * whoever wrote it and wrong for somebody's production the first time a
82
- * deployment inherited it, and that is a mistake nothing downstream can
83
- * catch: every answer from the other site parses perfectly.
35
+ * Where the gateway is: `https://test.agentify.ad` while the merchant is
36
+ * building, `https://agentify.ad` once they are live.
84
37
  *
85
- * Leaving it out builds a client, exactly as the quickstart's first step
86
- * says it does, and every call that would have to reach the gateway fails
87
- * with a sentence naming what is missing and both addresses to choose
88
- * between. That is where the failure belongs: the documentation tells the
89
- * merchant that the first call is what checks whether they can reach us.
90
- * Giving a wrong address, on the other hand, is refused here and now — a
91
- * value that is not an address at all cannot become one later.
38
+ * There is no default on purpose: which of the two a process talks to is the
39
+ * difference between a sale and a rehearsal, and every answer from the wrong
40
+ * one parses perfectly. Left out, the client is still built, and every call
41
+ * that has to reach the gateway throws a `TypeError` naming both addresses.
42
+ * A value that is not an http or https address is refused when the client
43
+ * is built.
92
44
  */
93
45
  readonly baseUrl?: string | undefined;
94
46
  }
95
47
  /**
96
48
  * The calls every order carries, wherever the merchant got it from.
97
49
  *
98
- * The first three build an answer and send nothing: they are what a handler
99
- * returns, and the return is what this SDK posts. The last three send, and
100
- * they are the calls an asynchronous merchant makes later — after the supplier
101
- * answered, from another part of their code, from another process life.
102
- *
103
- * There are three of each because the two halves are not the same set of
104
- * choices seen twice. A synchronous handler chooses between delivering and
105
- * refusing on the spot; an asynchronous one accepts and then, eventually,
106
- * delivers or refuses. Accepting from outside a handler exists for the
107
- * merchant who decides later, in another part of their code.
50
+ * `delivered`, `refused` and `accepted` build an answer and send nothing: they
51
+ * are what a handler returns, and the SDK posts the return. `deliver`,
52
+ * `refuse` and `accept` send, and are what an asynchronous merchant calls
53
+ * later, from another part of their code or another process.
108
54
  */
109
55
  export interface OrderCalls {
110
56
  /** The goods, as the handler's answer. Building one sends nothing. */
@@ -118,44 +64,41 @@ export interface OrderCalls {
118
64
  */
119
65
  accepted(): HandlerAnswer;
120
66
  /**
121
- * The goods for an order taken on earlier. Idempotent by the order's own
122
- * identifier, so repeating it after a dropped connection does no work twice.
67
+ * The goods for an order taken on earlier. Idempotent by the order's
68
+ * identifier, so repeating it after a dropped connection delivers nothing
69
+ * twice and charges nothing twice.
123
70
  */
124
71
  deliver(delivery: Delivery): Promise<OrderCallResponse>;
125
- /** A final "this cannot be delivered" for an order already taken on. */
72
+ /**
73
+ * A final "this cannot be delivered" for an order already taken on. Unlike
74
+ * `deliver`, it is not promised to be safe to repeat: when it fails, and
75
+ * above all with `outcome_unknown`, read the order back with `orders.get`
76
+ * before sending it again.
77
+ */
126
78
  refuse(refusal: Refusal): Promise<OrderCallResponse>;
127
- /** Takes the order on from outside a handler. Repeats are ordinary. */
79
+ /** Takes the order on from outside a handler. Repeating it is harmless. */
128
80
  accept(): Promise<OrderAcceptResponse>;
129
81
  }
130
82
  /**
131
- * The least an order can be and still be answerable: its identifier, and the
132
- * calls that close it.
133
- *
134
- * It is what `orders.forId` hands back, and it is the shape a merchant's own
135
- * function should take when all it does is close an order — every richer order
136
- * below satisfies it.
83
+ * The least an order can be and still be answered: its identifier and the
84
+ * calls that close it. It is what `orders.forId` returns, and the type to take
85
+ * in a function that only closes orders.
137
86
  */
138
87
  export type OrderHandle = {
139
88
  readonly id: string;
140
89
  } & OrderCalls;
141
90
  /**
142
- * An order off the stream, with the calls that close it.
143
- *
144
- * "Live" is the whole of the difference from the plain document: this object
145
- * holds the client that produced it, so it can call home on its own and the
146
- * merchant never writes an identifier of ours as an argument.
91
+ * An order off the stream, with the calls that close it. It holds the client
92
+ * that produced it, so the merchant never passes an identifier back.
147
93
  */
148
94
  export type LiveOrder = Order & OrderCalls;
149
- /** The same, read back from our record, so it also says where the order stands. */
95
+ /** An order read back from Agentify, with where it stands and the calls that close it. */
150
96
  export type LiveOrderWithStatus = OrderWithStatus & OrderCalls;
151
97
  /**
152
- * The two answers a price question has, built from the question itself.
153
- *
154
- * `as_of` is what separates "I went and looked" from "here is what was in the
155
- * cache", and the gateway reads it to decide how far it trusts the answer. Left
156
- * out, it is the moment the answer is built — which is the truth for a price
157
- * computed on the spot, and is why a merchant answering from a cache passes the
158
- * moment that cache was filled instead.
98
+ * The two answers a price question has. `asOf` is when the answer was true,
99
+ * which separates "I went and looked" from "here is what was in the cache";
100
+ * left out, it is the moment the answer is built, so a merchant answering
101
+ * from a cache passes the moment that cache was filled.
159
102
  */
160
103
  export interface QuoteCalls {
161
104
  available(price: Money, asOf?: string): QuoteResponse;
@@ -168,22 +111,9 @@ export type OrderHandler = (order: LiveOrder) => HandlerAnswer | Promise<Handler
168
111
  /** What the merchant's code answers to "how much is this and is it there". */
169
112
  export type QuoteHandler = (question: LiveQuoteRequest) => QuoteResponse | Promise<QuoteResponse>;
170
113
  /**
171
- * Everything a merchant's process can be asked to answer, by the word they
172
- * register it under.
173
- *
174
- * A map rather than four methods, because the stream is one stream and this is
175
- * the list of what travels on it. The day the contract carries a fourth kind —
176
- * the confirmation request, whose shape it does not carry yet — `REGISTERED_AS`
177
- * in `worker.ts` gains its word, and from that word every list in this file
178
- * follows: what `on` accepts, what `start` counts as an answer, and the
179
- * sentence that names a missing registration. What does not follow is what
180
- * answers it, so this map gains an entry and the worker's dispatch gains an
181
- * arm, and both refuse to compile until they do.
182
- *
183
- * `problem` is on the same list although nothing on the wire carries it. It is
184
- * one registration per process, exactly like the other three, and a second
185
- * place to register one of four things would put back the split this surface
186
- * exists to remove.
114
+ * Everything a merchant's process can be asked to answer, by the word it is
115
+ * registered under. `problem` is not on the wire; it is where the worker
116
+ * reports what went wrong, registered like the others.
187
117
  */
188
118
  export interface Handlers {
189
119
  order: OrderHandler;
@@ -191,15 +121,12 @@ export interface Handlers {
191
121
  event: EventHandler;
192
122
  problem: ProblemReporter;
193
123
  }
194
- /** The word for the reporter, which nothing on the wire carries. */
195
124
  declare const PROBLEM = "problem";
196
125
  export type HandlerKind = StreamHandlerKind | typeof PROBLEM;
197
126
  /**
198
- * Whether a type is a union of more than one thing.
199
- *
200
- * Here for one purpose, at `on` below: to tell a kind that is one kind from a
201
- * kind that is any of several, because only the first can say which handler is
202
- * the right one.
127
+ * Whether a type is a union of more than one thing. `on` uses it to refuse a
128
+ * kind that could be any of several, since only one kind says which handler
129
+ * is right.
203
130
  */
204
131
  type IsUnion<Kind, Each = Kind> = Kind extends unknown ? [Each] extends [Kind] ? false : true : never;
205
132
  export interface CatalogNamespace {
@@ -207,50 +134,38 @@ export interface CatalogNamespace {
207
134
  * Publishes one product, or says what is wrong with the card.
208
135
  *
209
136
  * Publishing again under the same `merchant_item_id` changes that card
210
- * rather than adding a second one, so a publish script can be run as often
211
- * as a merchant likes.
137
+ * rather than adding a second, so a publish script can be run as often as
138
+ * a merchant likes. A refused card comes back as `ok: false` with every
139
+ * finding under `error.problems`.
212
140
  *
213
- * The card is taken as it may be written rather than as it is stored, which
214
- * is what `CardInput` is: the price as one string or as two fields, a
215
- * declared field as its type word or written out, the fulfillment mode left
216
- * off a card that delivers in the answer to the purchase. Every one of those
217
- * is opened out when the card is accepted, so a card read back afterwards is
218
- * in the one canonical form.
141
+ * The card may use the short forms `CardInput` allows: the price as one
142
+ * string, a declared field as its type word, the fulfillment mode left off.
143
+ * They are opened out on acceptance, so a card read back is in the
144
+ * canonical form. Throws `AgentifyError` when the call fails without a
145
+ * publish result, such as a refused key or an answer that could not be read.
219
146
  */
220
147
  publish(card: CardInput): Promise<PublishResult>;
221
148
  }
222
149
  export interface OrdersNamespace {
223
150
  /**
224
- * The calls for an order named by its identifier, without asking us
225
- * anything.
226
- *
227
- * This is the one place an identifier of ours is written by a merchant, and
228
- * it is here for the process that kept nothing else: a job queued against
229
- * our identifier, a row in their own database. It reaches no gateway, which
230
- * is the point — `get` below would tell them more about the order, and
231
- * during an outage it cannot tell them anything at all, while a delivery
232
- * that comes back as "the network failed, call again" is exactly the answer
233
- * they need to keep retrying.
151
+ * The calls for an order named by its identifier, without asking Agentify
152
+ * anything. It is for a process that kept only the identifier, such as a job
153
+ * queued against it. Because it makes no call, it works during an outage,
154
+ * when a delivery that comes back as "call again" is the answer needed.
234
155
  */
235
156
  forId(orderId: string): OrderHandle;
236
157
  /**
237
- * One order and the state it is in, with the calls that close it.
238
- *
239
- * A round trip, and what it buys is the order itself: its parameters, what
240
- * it was sold for, and where it stands.
158
+ * One order and the state it is in, with the calls that close it. Throws
159
+ * `AgentifyError` when the call fails, including an unknown order.
241
160
  */
242
161
  get(orderId: string): Promise<LiveOrderWithStatus>;
243
162
  /**
244
- * Orders and the states they are in; with `open`, only the ones this worker
245
- * should walk.
246
- *
247
- * The list is what a process reads after a restart: the orders it was handed
248
- * and has not finished, each able to be delivered or refused on the spot,
249
- * together with the two that stay open once the purchase itself is over — an
250
- * order owing a refund, and one delivered that was never paid for. An order
251
- * that was priced and never paid is not on it. That one never reached the
252
- * handler, and making the goods for it would be making them for a purchase
253
- * that did not happen; it stays readable by its identifier through `get`.
163
+ * Orders and the states they are in. With `open: true`, only the ones a
164
+ * restarted worker should walk: orders it was handed and has not finished,
165
+ * an order owing a refund, and one delivered but never paid for. An order
166
+ * that was priced and never paid never reached the handler, so it is not on
167
+ * that list; `get` still reads it. Throws `AgentifyError` when the call
168
+ * fails.
254
169
  */
255
170
  list(query?: {
256
171
  readonly open?: boolean;
@@ -260,107 +175,70 @@ export interface AgentifyClient {
260
175
  readonly catalog: CatalogNamespace;
261
176
  readonly orders: OrdersNamespace;
262
177
  /**
263
- * Registers what this process answers for one kind.
178
+ * Registers what this process answers for one kind: `'order'`, `'quote'`,
179
+ * `'event'` or `'problem'`.
264
180
  *
265
- * Once per kind: a second registration is refused rather than replacing the
266
- * first, because one message goes to one handler and a silently replaced
267
- * handler is a process that has stopped answering without saying so.
181
+ * Once per kind: a second registration throws a `TypeError` rather than
182
+ * silently replacing the first. Handlers may be registered before or after
183
+ * `start`, and survive `stop`.
268
184
  *
269
- * Handlers may be registered before or after `start`; the loop reads them
270
- * when an envelope arrives, not when it begins.
271
- *
272
- * The condition on the second parameter is what makes the two halves agree,
273
- * and it is worth the sentence it costs. Written plainly as
274
- * `(kind: Kind, handler: Handlers[Kind])`, a call whose kind is not a
275
- * literal — a loop over `['order', 'quote']`, a kind held in a variable —
276
- * infers `Kind` as the union, and `Handlers[Kind]` is then the union of
277
- * handlers, so an order handler registered under `'quote'` type-checks. It
278
- * fails at the first price question, where the handler calls a method the
279
- * question does not have, and every sale of that card quietly falls back to
280
- * the card's own price. So a kind that is not one kind admits no handler at
281
- * all, and the call has to be narrowed to one of them first.
185
+ * The kind must be one literal kind. A kind held in a variable or a loop
186
+ * over several admits no handler, because a union would let an order handler
187
+ * type-check under `'quote'` and fail at the first price question.
282
188
  */
283
189
  on<Kind extends HandlerKind>(kind: Kind, handler: IsUnion<Kind> extends true ? never : Handlers[Kind]): void;
284
190
  /**
285
- * Opens the subscription and returns once it is running.
191
+ * Opens the subscription and returns once it is running. It is outgoing, so
192
+ * nothing of the merchant's has to be reachable from outside, and one
193
+ * subscription carries orders, price questions and order events together.
286
194
  *
287
- * The subscription is outgoing — this side opens it, and nothing of the
288
- * merchant's has to be reachable from outside. It carries the orders, the
289
- * price questions and the order events together, so a process needs one of
290
- * these and not three.
195
+ * Throws a `TypeError` when no gateway address was given, when the client is
196
+ * already started or still stopping, or when nothing is registered to
197
+ * answer.
291
198
  */
292
199
  start(): Promise<void>;
293
200
  /**
294
- * Stops the subscription and waits for it to finish. Safe to call twice, and
295
- * safe to call on a client that was never started.
296
- *
297
- * Two things are abandoned rather than finished, and they are not abandoned
298
- * on the same terms. A poll parked at the gateway is dropped, and the
299
- * gateway stops it and keeps whatever arrives for the next poll; only
300
- * something taken in the instant before the drop is lost, and that is an
301
- * order, which comes again, or an event, which is sent once — the list of
302
- * open orders is what finds a refund owed whose event went missing.
303
- * An answer already on its way — a delivery the handler produced a moment
304
- * ago — is dropped too, and there the honest thing to say is that nobody on
305
- * this side knows whether it arrived first: the order may already be closed
306
- * by it, or may come back. The merchant is told which of their orders that
307
- * happened to, because on their side the work happened.
201
+ /**
202
+ * Stops the subscription and waits for it to finish. Safe to call twice,
203
+ * and on a client that was never started. Handlers stay registered.
308
204
  *
309
- * Stopping does not drain. The contract has a word for a poll that asks for
310
- * whatever is queued right now and comes straight back, and it is not what a
311
- * worker shutting down wants: draining pulls more work into a process that
312
- * is going away.
205
+ * A poll parked at the gateway is dropped; anything taken in the instant
206
+ * before is an order, which comes again, or an event, which is sent once.
207
+ * An answer already on its way is dropped too, and nobody on this side knows
208
+ * whether it arrived: the order may be closed by it or may come back. The
209
+ * merchant's problem reporter is told which orders that happened to.
313
210
  *
314
- * The handlers survive it. A supervisor that stops a client and starts it
315
- * again is running the same process, and having to register everything a
316
- * second time would be a second place for the two to disagree.
211
+ * Stopping does not drain the queue, which would pull more work into a
212
+ * process that is going away.
317
213
  */
318
214
  stop(): Promise<void>;
319
215
  }
320
216
  /**
321
- * The three codes an order call comes back under when the gateway produced no
322
- * answer this package can read.
217
+ * The codes an order call or an `AgentifyError` carries when the gateway
218
+ * produced no answer this package can read. The SDK produces them; the
219
+ * gateway never sends them.
323
220
  *
324
- * The contract's list of error codes is open exactly so that a case nobody
325
- * anticipated reaches the merchant in its own words instead of being flattened
326
- * into the nearest of three. These are three of those, and they are produced
327
- * here rather than on the wire.
328
- *
329
- * Three and not one because the difference is the whole of what a merchant
330
- * needs at that moment, and they are about their own books. A call that never
331
- * arrived certainly changed nothing. A call answered in words we could not
332
- * read reached us and may well have done its work; what is missing is what it
333
- * said. And a call that was sent into silence — the connection broke, the
334
- * worker was shut down mid-flight — is neither of those, and saying it did not
335
- * arrive would be inventing the one fact the merchant came here for.
221
+ * `call_did_not_reach_us`: the call certainly changed nothing.
222
+ * `answer_not_understood`: the call reached the gateway and may have done its
223
+ * work; what it said could not be read. `outcome_unknown`: the call was sent
224
+ * into silence, such as a dropped connection or a worker shut down
225
+ * mid-flight, and nobody on this side knows whether it arrived.
336
226
  */
337
227
  export declare const CALL_DID_NOT_REACH_US = "call_did_not_reach_us";
338
228
  export declare const ANSWER_NOT_UNDERSTOOD = "answer_not_understood";
339
229
  export declare const OUTCOME_UNKNOWN = "outcome_unknown";
340
230
  /**
341
- * What is thrown where a route has no failure branch to hand a merchant back.
342
- *
343
- * Three of this client's calls answer with a document or with nothing at all —
344
- * publishing a card, reading one order, listing them — so a call that produced
345
- * no document has nowhere in the contract to be returned. It is thrown, and
346
- * this is what it is thrown as.
231
+ * What is thrown where a call has no failure branch to return: publishing a
232
+ * card, reading one order, listing orders.
347
233
  *
348
- * It carries what the returned failures carry, because the two are the same
349
- * facts about the same calls and a merchant should not have to learn a second
350
- * vocabulary for the half of them that throws. `code` is the gateway's own word
351
- * where the gateway refused in words we recognise, and otherwise one of the
352
- * three this package produces — `call_did_not_reach_us`, `answer_not_understood`,
353
- * `outcome_unknown`. `failedCall` below makes that same choice for the order
354
- * calls, so a refusal has one name on both roads. `route` is the call it
355
- * happened on, under the name the
356
- * contract's own table gives it, so a `catch` can say which of three it was
357
- * without reading the sentence.
234
+ * `code` is the gateway's own code where it refused in words this package
235
+ * recognises, and otherwise `call_did_not_reach_us`, `answer_not_understood`
236
+ * or `outcome_unknown`. `route` names the call as the contract's route table
237
+ * does, so a `catch` can tell the calls apart without reading the message.
358
238
  *
359
- * What is not this: a client built wrong. A missing key, a `baseUrl` that is
360
- * not an address, a handler registered twice and a kind nothing delivers are
361
- * mistakes in the merchant's own code, made before anything left the process,
362
- * and they stay `TypeError`. A merchant catching this class is catching calls
363
- * that went out.
239
+ * A client built wrong (a missing key, a `baseUrl` that is not an address, a
240
+ * handler registered twice) throws `TypeError` instead, before anything leaves
241
+ * the process.
364
242
  */
365
243
  export declare class AgentifyError extends Error {
366
244
  /** Why the call did not go through, for the code that branches on it. */
@@ -368,15 +246,9 @@ export declare class AgentifyError extends Error {
368
246
  /** The call it happened on, named as the contract's route table names it. */
369
247
  readonly route: string;
370
248
  /**
371
- * Whether making the same call again could get past this.
372
- *
373
- * Here for the same reason the code is: the calls that throw and the calls
374
- * that return are the same calls failing the same ways, and a merchant who
375
- * had to work out from a `catch` what a returned error would have told them
376
- * outright is being charged twice for one lesson. The gateway's own answer
377
- * where the gateway refused in words, and true where nothing readable came
378
- * back — which is a statement about what this package knows, not a promise
379
- * that the call will work.
249
+ * Whether making the same call again could get past this: the gateway's own
250
+ * answer where it refused in words, and true where nothing readable came
251
+ * back, which says what this package knows, not that the call will work.
380
252
  */
381
253
  readonly retryable: boolean;
382
254
  constructor(code: string, route: string, message: string, retryable: boolean);