@m8tes/sdk 0.1.0-alpha.1 → 0.1.0-alpha.3

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/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Normalizer, M8tesStreamEvent, ConversationState } from './protocol/index.cjs';
2
- export { APIError, Accumulator, ApiErrorFields, ApprovalRequestEvent, ApprovalResolvedEvent, AuthenticationError, BaseEvent, BillingError, CompactBoundaryEvent, CompactPart, ConflictError, ErrorFromResponseOptions, M8tesApiError, M8tesStreamEventType, MateMessage, MatePart, MateStatus, MessageEndEvent, MessageStartEvent, NotFoundError, NoticeEvent, NoticePart, PROTOCOL_VERSION, PermissionDeniedError, PlanDeltaEvent, PlanEndEvent, PlanStartEvent, ProtocolVersion, QuestionEvent, QuestionItem, QuestionOption, RateLimitError, ReasoningDeltaEvent, ReasoningEndEvent, ReasoningStartEvent, RunCancelledEvent, RunErrorCode, RunErrorEvent, RunFailedError, RunFinishEvent, RunMetricsEvent, RunNotStreamingError, RunStartEvent, RunStatus, RunStatusEvent, SandboxPart, SandboxStatusEvent, SseParserOptions, TERMINAL_EVENT_TYPES, TerminalEventType, TextDeltaEvent, TextEndEvent, TextLikeKind, TextPart, TextStartEvent, ToolInputAvailableEvent, ToolInputDeltaEvent, ToolInputStartEvent, ToolOutputAvailableEvent, ToolPart, ToolState, UnknownEvent, ValidationError, accumulate, createAccumulator, createNormalizer, createSseDecoder, errorClassForStatus, errorFromResponse, initialConversationState, isTerminalEvent, parseErrorEnvelope, parseRetryAfter, parseSse, splitConcatenatedJson } from './protocol/index.cjs';
2
+ export { APIError, Accumulator, ApiErrorFields, ApprovalRequestEvent, ApprovalResolvedEvent, AuthenticationError, BaseEvent, BillingError, CompactBoundaryEvent, CompactPart, ConflictError, ErrorFromResponseOptions, M8tesApiError, M8tesStreamEventType, MateMessage, MatePart, MateStatus, MessageEndEvent, MessageStartEvent, NotFoundError, NoticeEvent, NoticePart, PROTOCOL_VERSION, PermissionDeniedError, PlanDeltaEvent, PlanEndEvent, PlanStartEvent, ProtocolVersion, QuestionEvent, QuestionItem, QuestionOption, RateLimitError, ReasoningDeltaEvent, ReasoningEndEvent, ReasoningStartEvent, RunCancelledEvent, RunErrorCode, RunErrorEvent, RunFailedError, RunFinishEvent, RunMetricsEvent, RunNotStreamingError, RunStartEvent, RunStatus, RunStatusEvent, SandboxPart, SandboxStatusEvent, SseParserOptions, TERMINAL_EVENT_TYPES, TerminalEventType, TextDeltaEvent, TextEndEvent, TextLikeKind, TextPart, TextStartEvent, ToolInputAvailableEvent, ToolInputDeltaEvent, ToolInputStartEvent, ToolOutputAvailableEvent, ToolPart, ToolState, UnknownEvent, ValidationError, accumulate, createAccumulator, createNormalizer, createSseDecoder, errorClassForStatus, errorFromResponse, initialConversationState, isTerminalEvent, parseErrorEnvelope, parseRetryAfter, parseSse, seg, splitConcatenatedJson } from './protocol/index.cjs';
3
3
 
4
4
  /**
5
5
  * Server-side transport for the m8tes V2 API.
@@ -13,9 +13,11 @@ export { APIError, Accumulator, ApiErrorFields, ApprovalRequestEvent, ApprovalRe
13
13
  * two languages behave the same under load:
14
14
  * - 3 attempts total, 0.5s initial backoff, doubling
15
15
  * - retry only 429/500/502/503/504
16
- * - retry only idempotent methods (GET/HEAD/PUT/DELETE/OPTIONS). A POST that
17
- * timed out may already have started a billable run, so re-sending it could
18
- * double-charge; those fail immediately and let the caller decide.
16
+ * - retry GET/HEAD/PUT/DELETE/OPTIONS always, and a POST only when it carries
17
+ * an `Idempotency-Key`. Without one, a POST that timed out may already have
18
+ * started a billable run, so re-sending it could double-charge; with one, the
19
+ * server replays the run it already created, which is why the run-creating
20
+ * calls mint a key on every request.
19
21
  * - honour `Retry-After` on 429
20
22
  */
21
23
 
@@ -41,10 +43,31 @@ interface RequestOptions {
41
43
  query?: string;
42
44
  signal?: AbortSignal;
43
45
  headers?: Record<string, string>;
46
+ /**
47
+ * Send as multipart/form-data instead of JSON. Used by the file-upload route.
48
+ * `fetch` sets its own `content-type` with the boundary, so we must NOT set
49
+ * one — a hand-written header omits the boundary and the server cannot parse
50
+ * the body.
51
+ */
52
+ form?: FormData;
44
53
  }
45
54
  interface StreamRequestOptions extends RequestOptions {
46
55
  /** Reuse a normalizer across reconnects so its dedupe ledger persists. */
47
56
  normalizer?: Normalizer;
57
+ /**
58
+ * Called instead of decoding the body when the server answers a run-creating
59
+ * POST with `Idempotent-Replay: true`.
60
+ *
61
+ * A replay is JSON (the run), not SSE — a run that already exists has no fresh
62
+ * stream to emit — so the caller decides what to do with it, in practice
63
+ * joining that run's own stream. It lives here rather than in the resource
64
+ * because this is the only place the Response object exists; by the time
65
+ * `stream()` yields, the headers are gone.
66
+ */
67
+ onReplay?: (run: {
68
+ id: number;
69
+ status: string;
70
+ }) => AsyncGenerator<M8tesStreamEvent, void, unknown>;
48
71
  }
49
72
  interface Http {
50
73
  baseUrl: string;
@@ -68,14 +91,17 @@ declare function createHttp(options?: ClientOptions): Http;
68
91
  interface ListResponse<T> {
69
92
  data: T[];
70
93
  hasMore: boolean;
94
+ /** Cursor for `?starting_after=` when `hasMore` is true; mirrors the Python SDK. */
95
+ nextStartingAfter?: string | number | null;
71
96
  }
72
97
  /** A page of results. `for await (const item of page)` walks ALL pages. */
73
98
  declare class Page<T> implements ListResponse<T>, AsyncIterable<T> {
74
99
  readonly data: T[];
75
100
  readonly hasMore: boolean;
101
+ readonly nextStartingAfter?: string | number | null;
76
102
  /** Fetches the next page given a cursor. Absent on a terminal page. */
77
103
  private readonly fetchNext?;
78
- constructor(data: T[], hasMore: boolean, fetchNext?: (startingAfter: string | number) => Promise<Page<T>>);
104
+ constructor(data: T[], hasMore: boolean, fetchNext?: (startingAfter: string | number) => Promise<Page<T>>, nextStartingAfter?: string | number | null);
79
105
  /**
80
106
  * Auto-paging: yields every item across every page.
81
107
  *
@@ -166,7 +192,13 @@ interface Run {
166
192
  updated_at: string | null;
167
193
  task_id?: number | null;
168
194
  permission_mode?: string | null;
195
+ /** Reply-to address when the run's agent has an email inbox. */
196
+ email_address?: string | null;
169
197
  error_code?: string | null;
198
+ /** Credential route used for this run. */
199
+ auth_method?: string | null;
200
+ /** Provider behind an OAuth subscription route: claude, openai, xai, or gemini. */
201
+ auth_provider?: string | null;
170
202
  retryable?: boolean;
171
203
  retry_of_run_id?: number | null;
172
204
  retry_count?: number;
@@ -199,6 +231,10 @@ interface PermissionRequest {
199
231
  created_at: string;
200
232
  resolved_at: string | null;
201
233
  auto_resolved?: boolean;
234
+ /** False when the runtime would ignore an "always allow" for this tool. */
235
+ can_remember?: boolean;
236
+ /** False when the Always-allow control must start unticked (force-ask floor). */
237
+ remember_default?: boolean;
202
238
  }
203
239
  interface Task {
204
240
  id: number;
@@ -276,6 +312,18 @@ interface EndUserUsage {
276
312
  period_end: string;
277
313
  rate_per_minute?: number | null;
278
314
  }
315
+ /**
316
+ * One saved memory. `user_id` is the scope: your end-user's id, or `null` for an
317
+ * account-level memory. `source` says who wrote it — `"api"` for ones you create
318
+ * here, versus memories an agent saved for itself during a run.
319
+ */
320
+ interface Memory {
321
+ id: number;
322
+ user_id: string | null;
323
+ content: string;
324
+ source: string;
325
+ created_at: string;
326
+ }
279
327
  interface App {
280
328
  name: string;
281
329
  display_name: string;
@@ -294,6 +342,52 @@ interface AppConnectionResult {
294
342
  connected?: boolean;
295
343
  message?: string | null;
296
344
  }
345
+ /**
346
+ * USD price per MILLION tokens, from the same table that bills your runs.
347
+ *
348
+ * `cache_read_per_mtok` / `cache_write_per_mtok` are the prompt-cache rates: on
349
+ * Anthropic models cache reads are discounted and cache writes carry a premium;
350
+ * on providers without prompt caching both equal the input rate, so an estimate
351
+ * built from these numbers never under-counts.
352
+ */
353
+ interface ModelPricing {
354
+ input_per_mtok: number;
355
+ output_per_mtok: number;
356
+ cache_read_per_mtok: number;
357
+ cache_write_per_mtok: number;
358
+ currency: string;
359
+ }
360
+ /** A selectable model. Pass its `id` as `model` on an agent or a run. */
361
+ interface Model {
362
+ id: string;
363
+ name: string;
364
+ description: string;
365
+ /** Who serves it — `"anthropic"`, `"openai"`, … */
366
+ provider: string;
367
+ /** True for the model used when `model` is omitted or null. */
368
+ default: boolean;
369
+ /** Highest effort tier this model accepts (`"max"` on Claude, `"high"` on
370
+ * others). A higher requested effort is clamped, never rejected. */
371
+ max_effort: string;
372
+ /** Absent on older backends that predate pricing on this route. */
373
+ pricing?: ModelPricing | null;
374
+ /**
375
+ * At least one provider behind this model supports zero data retention.
376
+ *
377
+ * Read that precisely: it does NOT promise your particular request avoids a
378
+ * retaining provider. Routing can still land on one unless the account is
379
+ * constrained. Treat `true` as "ZDR is available here", not "ZDR is in
380
+ * effect" — see `zdr_providers` and `retention_note`, and confirm the account
381
+ * constraint before sending regulated data.
382
+ */
383
+ zdr_supported?: boolean;
384
+ /** Deprecated alias of `zdr_supported`. Still sent, so still typed. */
385
+ zdr?: boolean;
386
+ /** Which providers behind this route carry ZDR. */
387
+ zdr_providers?: string[];
388
+ /** Human-readable retention caveat, when there is one. */
389
+ retention_note?: string | null;
390
+ }
297
391
  interface Webhook {
298
392
  id: number;
299
393
  url: string;
@@ -304,6 +398,23 @@ interface Webhook {
304
398
  created_at: string;
305
399
  updated_at?: string | null;
306
400
  }
401
+ /**
402
+ * The full account data dump from `client.account.export()`.
403
+ *
404
+ * Deliberately untyped JSON: the document is a GDPR/CCPA access export whose
405
+ * shape follows whatever the account happens to hold (agents, tasks, runs,
406
+ * documents, memories, integration metadata), and the API grows it without a
407
+ * version bump. The Python SDK returns a bare `dict[str, Any]` for the same
408
+ * reason — typing fields here would invent a contract neither SDK has. Secrets
409
+ * are never included.
410
+ */
411
+ type AccountExport = JsonObject;
412
+ /**
413
+ * The status payload from `client.account.delete()`.
414
+ *
415
+ * Untyped for parity with the Python SDK, which returns the API's raw dict.
416
+ */
417
+ type AccountDeletion = JsonObject;
307
418
  interface WebhookDelivery {
308
419
  id: number;
309
420
  webhook_endpoint_id: number;
@@ -317,6 +428,119 @@ interface WebhookDelivery {
317
428
  next_retry_at: string | null;
318
429
  created_at: string;
319
430
  }
431
+ /** A standing tool permission policy: one pre-approved tool for one end-user.
432
+ * Note the asymmetry — you create it with `tool`, the API returns it as
433
+ * `tool_name`. */
434
+ interface PermissionPolicy {
435
+ id: number;
436
+ user_id: string;
437
+ tool_name: string;
438
+ created_at: string;
439
+ /** Which surface minted the grant ("run_approval" / "api"); null on legacy rows. */
440
+ source?: string | null;
441
+ }
442
+ /**
443
+ * Billing usage and limits for the current period.
444
+ *
445
+ * The overage fields describe the opt-in usage overage (see
446
+ * `client.billing.setOverage`) and are all zero/false on accounts that never
447
+ * enabled it. Cost fields are USD strings, not numbers, so they survive a round
448
+ * trip without float drift.
449
+ */
450
+ interface Usage {
451
+ plan: string;
452
+ runs_used: number;
453
+ runs_limit: number;
454
+ cost_used: string;
455
+ cost_limit: string;
456
+ period_end: string;
457
+ subscription_status: string | null;
458
+ overage_enabled: boolean;
459
+ overage_used_cents: number;
460
+ /** Ceiling on overage spend per period. Runs stop billing overage once reached. */
461
+ overage_cap_cents: number;
462
+ overage_rate_cents: number;
463
+ trial_ends_at?: string | null;
464
+ /** True when the account bypasses the included-runs meter (admin/unlimited). */
465
+ unlimited_runs?: boolean;
466
+ }
467
+ /** Token + USD totals over a usage-timeseries window. `cost_usd` is a string. */
468
+ interface UsageTotals {
469
+ input_tokens: number;
470
+ output_tokens: number;
471
+ cache_read_tokens: number;
472
+ cache_creation_tokens: number;
473
+ total_tokens: number;
474
+ cost_usd: string;
475
+ }
476
+ /** One model's share of a day bucket. `"unknown"` covers pre-attribution history. */
477
+ interface UsageModelSlice extends UsageTotals {
478
+ model: string;
479
+ }
480
+ /** One UTC-day bucket of token + USD usage. */
481
+ interface UsageBucket extends UsageTotals {
482
+ /** ISO date, e.g. `"2026-07-01"`. */
483
+ date: string;
484
+ /** Per-model slices — present only when the series was requested with
485
+ * `group_by: "model"`; `null` otherwise. */
486
+ models?: UsageModelSlice[] | null;
487
+ }
488
+ /** Daily usage buckets, zero-filled across `[start_date, end_date]` (UTC days). */
489
+ interface UsageTimeseries {
490
+ start_date: string;
491
+ end_date: string;
492
+ buckets: UsageBucket[];
493
+ totals: UsageTotals;
494
+ }
495
+ /** One prepaid top-up. `receipt_url` is `null` when the underlying Stripe
496
+ * checkout session is no longer retrievable. */
497
+ interface Receipt {
498
+ id: number;
499
+ amount_cents: number;
500
+ currency: string;
501
+ description: string | null;
502
+ receipt_url: string | null;
503
+ created_at: string;
504
+ }
505
+ /** A public (paid) plan from the canonical catalog. All prices in cents. */
506
+ interface Plan {
507
+ slug: string;
508
+ display_name: string;
509
+ included_runs: number;
510
+ monthly_price_cents: number;
511
+ annual_price_cents: number;
512
+ overage_rate_cents: number;
513
+ /** Per-period model-spend fair-use cap; `0` on servers that predate the field. */
514
+ fair_use_cost_limit_cents: number;
515
+ }
516
+ /** One prepaid token-balance ledger entry. Micro-USD; debits are negative. */
517
+ interface TokenTransaction {
518
+ type: string;
519
+ amount_micros: number;
520
+ balance_after_micros: number;
521
+ run_id: number | null;
522
+ description: string | null;
523
+ created_at: string;
524
+ }
525
+ /**
526
+ * Prepaid token balance plus a recent ledger (prepaid-billed accounts).
527
+ *
528
+ * Balances are micro-USD (1e-6 USD); `balance_usd` is a rounded display string.
529
+ * Runs debit this balance at official provider prices.
530
+ */
531
+ interface Balance {
532
+ balance_micros: number;
533
+ balance_usd: string;
534
+ currency: string;
535
+ /** Configurable low-balance warning level (micro-USD). */
536
+ low_balance_threshold_micros: number;
537
+ /** Fixed at 20% of the low threshold; depletion is 0. */
538
+ critical_balance_threshold_micros: number;
539
+ transactions: TokenTransaction[];
540
+ auto_reload_enabled: boolean;
541
+ auto_reload_threshold_cents?: number | null;
542
+ auto_reload_amount_cents?: number | null;
543
+ }
320
544
 
321
545
  /**
322
546
  * `client.agents` — the reusable agent personas runs execute as.
@@ -396,12 +620,21 @@ interface AgentsResource {
396
620
  delete(agentId: number, params?: {
397
621
  user_id?: string;
398
622
  }): Promise<void>;
399
- /** Turn on the webhook trigger; returns the URL to POST to. */
400
- enableWebhook(agentId: number): Promise<WebhookToggle>;
401
- disableWebhook(agentId: number): Promise<void>;
623
+ /** Turn on the webhook trigger; returns the URL to POST to.
624
+ * `user_id` scopes to one end-user (404 on mismatch), like get/update/delete. */
625
+ enableWebhook(agentId: number, params?: {
626
+ user_id?: string;
627
+ }): Promise<WebhookToggle>;
628
+ disableWebhook(agentId: number, params?: {
629
+ user_id?: string;
630
+ }): Promise<void>;
402
631
  /** Turn on the agent's email inbox; returns the address that starts runs. */
403
- enableEmailInbox(agentId: number): Promise<EmailInbox>;
404
- disableEmailInbox(agentId: number): Promise<void>;
632
+ enableEmailInbox(agentId: number, params?: {
633
+ user_id?: string;
634
+ }): Promise<EmailInbox>;
635
+ disableEmailInbox(agentId: number, params?: {
636
+ user_id?: string;
637
+ }): Promise<void>;
405
638
  }
406
639
 
407
640
  /**
@@ -459,6 +692,514 @@ interface AppsResource {
459
692
  }): Promise<void>;
460
693
  }
461
694
 
695
+ /**
696
+ * `client.account` — the two operations that act on the whole account rather
697
+ * than anything inside it: take your data out, and shut the account down.
698
+ *
699
+ * Both exist to satisfy the GDPR/CCPA rights to access and to erasure, so they
700
+ * are here for compliance flows you have to be able to run programmatically —
701
+ * a data-subject request you are forwarding, or an offboarding path in your own
702
+ * product. Neither takes parameters: they always apply to the account behind
703
+ * the API key you authenticated with, and there is no `user_id` scoping. To
704
+ * remove one end-user's data instead, use `client.users.delete()`.
705
+ *
706
+ * Mirrors `sdk/py/m8tes/_resources/account.py`.
707
+ */
708
+
709
+ interface AccountResource {
710
+ /**
711
+ * Hand a customer (or a regulator) everything the account holds — the
712
+ * GDPR/CCPA right to access.
713
+ *
714
+ * The document covers the account's agents, tasks, runs, documents, memories,
715
+ * and integration metadata. Credentials and other secrets are never included,
716
+ * so an export is safe to forward but is NOT a backup you can restore from.
717
+ * It is a single JSON body, not a stream: a large account produces a large
718
+ * response, so allow for it in your request timeout.
719
+ */
720
+ export(): Promise<AccountExport>;
721
+ /**
722
+ * Close the account — the GDPR/CCPA right to erasure.
723
+ *
724
+ * Soft-delete, and it takes effect at once: sessions and the API key are
725
+ * revoked, billing is canceled, and all automation stops, with the data
726
+ * erased after a grace period. In other words the key you just called this
727
+ * with is dead afterwards, so nothing else in the SDK will work.
728
+ */
729
+ delete(): Promise<AccountDeletion>;
730
+ }
731
+ declare function createAccountResource(http: Http): AccountResource;
732
+
733
+ /**
734
+ * `client.users` — your end-users, the multi-tenancy boundary.
735
+ *
736
+ * `user_id` is YOUR identifier for a customer; the platform stores it as
737
+ * `end_user_id` and isolates that person's memory, run history, and tool
738
+ * connections strictly. There is no fallback to account-level data.
739
+ *
740
+ * Registering an end-user here is optional — passing `user_id` on a run creates
741
+ * them implicitly. Do it explicitly when you want per-user budgets and rate
742
+ * limits. Mirrors `sdk/py/m8tes/_resources/users.py`.
743
+ */
744
+
745
+ interface EndUserCreateParams {
746
+ /** Your id for this person. Any stable string. */
747
+ user_id: string;
748
+ name?: string;
749
+ email?: string;
750
+ company?: string;
751
+ metadata?: JsonObject;
752
+ /** Cap this end-user's runs per billing period. */
753
+ run_limit?: number;
754
+ /** Cap this end-user's spend per billing period, in cents. */
755
+ cost_limit_cents?: number;
756
+ /** Cap this end-user's runs per minute. Exceeding it returns 429. */
757
+ rate_per_minute?: number;
758
+ }
759
+ /** `null` CLEARS a cap (inherit the account default); omitting leaves it alone. */
760
+ interface EndUserUpdateParams {
761
+ name?: string | null;
762
+ email?: string | null;
763
+ company?: string | null;
764
+ metadata?: JsonObject | null;
765
+ run_limit?: number | null;
766
+ cost_limit_cents?: number | null;
767
+ rate_per_minute?: number | null;
768
+ }
769
+ interface PageParams {
770
+ limit?: number;
771
+ starting_after?: number;
772
+ }
773
+ interface UsersResource {
774
+ create(params: EndUserCreateParams): Promise<EndUser>;
775
+ list(params?: PageParams): Promise<Page<EndUser>>;
776
+ get(userId: string): Promise<EndUser>;
777
+ update(userId: string, params: EndUserUpdateParams): Promise<EndUser>;
778
+ delete(userId: string): Promise<void>;
779
+ /** Per-end-user token, run, and cost usage against their limits. */
780
+ usage(params?: PageParams & {
781
+ user_id?: string;
782
+ }): Promise<Page<EndUserUsage>>;
783
+ }
784
+
785
+ /**
786
+ * `client.billing` — what you have spent, what you may spend, and the ceiling.
787
+ *
788
+ * This is the resource you reach for when cost is a product requirement rather
789
+ * than an afterthought: read current-period usage (runs, model spend, accrued
790
+ * overage), break spend down by day / end-user / agent / model, fetch the public
791
+ * plan catalog, and set the caps — the monthly overage cap on plan accounts, and
792
+ * on prepaid accounts the token balance, top-ups, auto-reload, and the
793
+ * low-balance alert threshold.
794
+ *
795
+ * An embed developer capping what their own customers can burn lives here: pair
796
+ * `usageTimeseries({ user_id })` with the per-end-user limits on `client.users`
797
+ * to meter each tenant, and `setOverage` / `setAutoReload` to bound the account
798
+ * as a whole.
799
+ *
800
+ * Mirrors `sdk/py/m8tes/_resources/billing.py`.
801
+ */
802
+
803
+ interface UsageTimeseriesParams {
804
+ /** Inclusive ISO date (`"2026-07-01"`), UTC days. Defaults to 30 days ago. */
805
+ start_date?: string;
806
+ /** Inclusive ISO date. Defaults to today. */
807
+ end_date?: string;
808
+ /** Scope to one end-user. */
809
+ user_id?: string;
810
+ /** Scope to one agent. */
811
+ agent_id?: number;
812
+ /** Permanent legacy alias for `agent_id` — the same wire field. */
813
+ teammate_id?: number;
814
+ /** Creation stamp: `"api"` embedding, `"platform"` first-party. Not settlement. */
815
+ surface?: "api" | "platform";
816
+ /** Where the run settled: `"wallet"` is the prepaid ledger. */
817
+ settled_meter?: "wallet" | "plan" | "released" | "own_sub";
818
+ /** `"model"` adds per-model slices to every bucket's `models`. The route
819
+ * accepts this one value only, so it is a literal rather than a string. */
820
+ group_by?: "model";
821
+ }
822
+ interface OverageParams {
823
+ enabled: boolean;
824
+ /** Hard ceiling on overage spend per period, in cents. */
825
+ monthly_cap_cents: number;
826
+ }
827
+ interface TopupParams {
828
+ /** Cents to add. $5 minimum, $1M maximum. */
829
+ amount_cents: number;
830
+ }
831
+ /**
832
+ * Enabling auto-reload REQUIRES both amounts; disabling takes neither. Modelled
833
+ * as a union so `{ enabled: true }` alone is a compile error rather than a 422.
834
+ */
835
+ type AutoReloadParams = {
836
+ enabled: true;
837
+ /** Reload when the balance drops below this, in cents. */
838
+ threshold_cents: number;
839
+ /** Cents to charge per reload. $5–$10,000. */
840
+ amount_cents: number;
841
+ } | {
842
+ enabled: false;
843
+ /** Amounts may still be updated while disabled; the API applies them. */
844
+ threshold_cents?: number;
845
+ amount_cents?: number;
846
+ };
847
+ interface AlertThresholdParams {
848
+ /** Balance (cents) at which the low-balance warning fires. `0` warns only on depletion. */
849
+ low_balance_threshold_cents: number;
850
+ }
851
+ interface BillingResource {
852
+ /** Where you stand this period: plan, runs used vs included, model spend, and overage state. */
853
+ usage(): Promise<Usage>;
854
+ /**
855
+ * Spend broken down by UTC day — the series to chart, alert on, or reconcile
856
+ * against an invoice. Buckets are zero-filled across the whole window, so the
857
+ * array is safe to plot without gap-handling. Cost matches `usage().cost_used`
858
+ * semantics, so the series always reconciles with period totals. With
859
+ * `group_by: "model"`, runs that predate model attribution fold
860
+ * into a `"unknown"` slice rather than disappearing.
861
+ */
862
+ usageTimeseries(params?: UsageTimeseriesParams): Promise<UsageTimeseries>;
863
+ /**
864
+ * Proof of payment for finance: one row per paid prepaid top-up, newest first.
865
+ * `receipt_url` can be `null` when Stripe can no longer retrieve the session.
866
+ */
867
+ receipts(params?: PageParams): Promise<Page<Receipt>>;
868
+ /** What the paid plans include and cost — for your own pricing page or upgrade
869
+ * prompt. Public (paid) plans only, straight from the canonical catalog, and
870
+ * returned as a plain array rather than a page. */
871
+ plans(): Promise<Plan[]>;
872
+ /**
873
+ * Decide whether runs may continue past your plan's included allotment, and how
874
+ * far. Off by default; once enabled, extra runs bill at the per-run overage rate
875
+ * until `monthly_cap_cents` is reached. Returns the refreshed usage so you can
876
+ * confirm the new state without a second call.
877
+ */
878
+ setOverage(params: OverageParams): Promise<Usage>;
879
+ /** How much prepaid credit is left, and where it went (prepaid-billed accounts).
880
+ * Amounts are micro-USD; `balance_usd` is a rounded display string. */
881
+ balance(): Promise<Balance>;
882
+ /**
883
+ * Add credit when a human is present to pay. Returns a Stripe Checkout URL to
884
+ * send the buyer to — nothing is credited until they complete payment.
885
+ */
886
+ topup(params: TopupParams): Promise<string>;
887
+ /**
888
+ * Keep credit topped up without a human, so runs never stop for an empty wallet:
889
+ * a balance below `threshold_cents` charges `amount_cents` to the saved card
890
+ * off-session. Enabling requires a saved payment method (any completed top-up
891
+ * Checkout saves one) — without it this throws a billing error with code
892
+ * `NO_SAVED_PAYMENT_METHOD`. Disabling needs only `enabled: false`. At most one
893
+ * reload fires per 6-hour window. Returns the refreshed balance.
894
+ */
895
+ setAutoReload(params: AutoReloadParams): Promise<Balance>;
896
+ /**
897
+ * Choose when you want to hear about a draining balance. The critical tier is
898
+ * fixed at 20% of the value you set, and `0` warns only on depletion. Warnings
899
+ * arrive by email and as `balance.low` / `balance.critical` / `balance.depleted`
900
+ * webhook events. Returns the refreshed balance.
901
+ */
902
+ setAlertThreshold(params: AlertThresholdParams): Promise<Balance>;
903
+ }
904
+ declare function createBillingResource(http: Http): BillingResource;
905
+
906
+ /**
907
+ * `client.memories` — pre-load what an agent already knows about someone.
908
+ *
909
+ * A run starts cold unless it has memories to draw on. Writing them here lets you
910
+ * seed an end-user's context from data you already hold (plan, timezone, past
911
+ * decisions, preferences) so the first run behaves like the tenth, instead of
912
+ * waiting for the agent to learn it over several conversations.
913
+ *
914
+ * `user_id` is the scope, and the scopes never mix: with it, the memory belongs to
915
+ * that one end-user and is visible only to runs carrying the same `user_id`;
916
+ * without it, the memory is account-level and visible only to runs that carry no
917
+ * `user_id`. There is no inheritance between the two — an account-level memory is
918
+ * NOT a fallback for an end-user run.
919
+ *
920
+ * Documented at `/docs/users`. Mirrors `sdk/py/m8tes/_resources/memories.py`.
921
+ */
922
+
923
+ interface MemoryCreateParams {
924
+ /** The fact to remember, in plain language. */
925
+ content: string;
926
+ /** Scope it to one end-user. Omit for an account-level memory. */
927
+ user_id?: string;
928
+ }
929
+ interface MemoryListParams {
930
+ /** Scope to read. Omit to read account-level memories. */
931
+ user_id?: string;
932
+ /**
933
+ * Keyword filter on content (case-insensitive substring). It only narrows the
934
+ * chosen scope — it never reaches across into the other one — and paging
935
+ * applies to the filtered set.
936
+ */
937
+ query?: string;
938
+ limit?: number;
939
+ starting_after?: number;
940
+ }
941
+ interface MemoryUpdateParams {
942
+ /** Replaces the stored text outright. */
943
+ content: string;
944
+ /** The scope the memory lives in. Must match, or the memory is not found. */
945
+ user_id?: string;
946
+ }
947
+ interface MemoriesResource {
948
+ /**
949
+ * Teach an agent a fact up front, before anyone runs it.
950
+ *
951
+ * Throws a `ConflictError` (409) when the scope is already at its memory
952
+ * capacity, or when identical content is already stored in it — so this is
953
+ * safe to call repeatedly only if you handle that error.
954
+ */
955
+ create(params: MemoryCreateParams): Promise<Memory>;
956
+ /** Audit or display what an agent knows about one end-user (or the account). */
957
+ list(params?: MemoryListParams): Promise<Page<Memory>>;
958
+ /** Correct a fact that changed, keeping its id — rather than delete + re-create. */
959
+ update(memoryId: number, params: MemoryUpdateParams): Promise<Memory>;
960
+ /** Make an agent forget something, e.g. on an end-user's erasure request. */
961
+ delete(memoryId: number, params?: {
962
+ user_id?: string;
963
+ }): Promise<void>;
964
+ }
965
+ declare function createMemoriesResource(http: Http): MemoriesResource;
966
+
967
+ /**
968
+ * `client.models` — find out which `model` values are actually valid, and what
969
+ * they cost, instead of guessing from the docs.
970
+ *
971
+ * `model` is a plain string everywhere in this SDK, which keeps new models
972
+ * usable the day they're enabled but means a typo is only caught by the API. Ask
973
+ * this route instead: it returns the models your account can select right now
974
+ * (Anthropic and not — the set grows without an SDK release), which one is the
975
+ * default, and the per-million-token prices the platform bills you at, so you
976
+ * can estimate spend before starting a run.
977
+ *
978
+ * Mirrors `sdk/py/m8tes/_resources/models.py`.
979
+ */
980
+
981
+ interface ModelsResource {
982
+ /**
983
+ * The models you can pass as `model` on an agent or a run, with USD pricing
984
+ * per million tokens.
985
+ *
986
+ * Omit `model` on an agent/run to get the entry flagged `default: true` — that
987
+ * flag is per-viewer, so the default you see here is the default you'd get.
988
+ *
989
+ * Takes no arguments and has no cursor: `GET /models/` returns the whole
990
+ * catalog in one response. A `Page` is still returned so `for await` works the
991
+ * same as on every other list, but it never fetches a second page.
992
+ */
993
+ /**
994
+ * The model catalog. Check `zdr_supported` before sending customer data: a
995
+ * non-ZDR model is allowed on the API but may retain inputs and outputs.
996
+ */
997
+ list(): Promise<Page<Model>>;
998
+ }
999
+ declare function createModelsResource(http: Http): ModelsResource;
1000
+
1001
+ /** Account-level OAuth subscriptions used by the Claude Code execution harness. */
1002
+
1003
+ type ModelConnectionProvider = "claude" | "openai" | "xai" | "gemini";
1004
+ type AuthorizableModelConnectionProvider = "openai" | "xai" | "gemini";
1005
+ type DeviceModelConnectionProvider = "openai" | "xai";
1006
+ type CodeModelConnectionProvider = "gemini";
1007
+ interface ModelConnection {
1008
+ provider: ModelConnectionProvider;
1009
+ display_name: string;
1010
+ connected: boolean;
1011
+ status?: string | null;
1012
+ account_label?: string | null;
1013
+ expires_at?: string | null;
1014
+ }
1015
+ interface ModelAuthorization {
1016
+ provider: AuthorizableModelConnectionProvider;
1017
+ state: string;
1018
+ status: "pending" | "connected";
1019
+ authorization_url?: string | null;
1020
+ user_code?: string | null;
1021
+ expires_at?: string | null;
1022
+ interval_seconds: number;
1023
+ }
1024
+ interface ModelConnectionsResource {
1025
+ /** List supported providers. Credential material is never returned. */
1026
+ list(): Promise<ModelConnection[]>;
1027
+ /** Start provider-native authorization; show the returned URL and device code when used. */
1028
+ authorize(provider: AuthorizableModelConnectionProvider): Promise<ModelAuthorization>;
1029
+ /** Poll once; successful device authorization is saved automatically. */
1030
+ authorizationStatus(provider: DeviceModelConnectionProvider, state: string): Promise<ModelAuthorization>;
1031
+ /** Exchange a pasted authorization code and store the connection. */
1032
+ completeAuthorization(provider: CodeModelConnectionProvider, state: string, params: {
1033
+ code: string;
1034
+ }): Promise<ModelAuthorization>;
1035
+ /** Cancel a short-lived provider authorization session. */
1036
+ cancelAuthorization(provider: AuthorizableModelConnectionProvider, state: string): Promise<void>;
1037
+ /** Delete m8tes' encrypted copy of the provider credentials. */
1038
+ disconnect(provider: ModelConnectionProvider): Promise<ModelConnection>;
1039
+ }
1040
+ declare function createModelConnectionsResource(http: Http): ModelConnectionsResource;
1041
+
1042
+ /**
1043
+ * `client.permissions` — standing tool allow-lists, one end-user at a time.
1044
+ *
1045
+ * A run pauses whenever the agent reaches for a tool that is not pre-approved,
1046
+ * and stays paused until somebody answers. That is the right default for a first
1047
+ * run and the wrong one for a tool your product has already decided is fine. A
1048
+ * policy here says "this end-user's runs may use this tool" once, so their runs
1049
+ * stop stopping.
1050
+ *
1051
+ * Scope: policies are per end-user (`user_id` is required on every call — there
1052
+ * is no account-wide policy) and outlive the run, unlike `runs.answerPermission()`
1053
+ * which unblocks a single gate. `/docs/users` documents this surface; mirrors
1054
+ * `sdk/py/m8tes/_resources/permissions.py`.
1055
+ */
1056
+
1057
+ interface PermissionCreateParams {
1058
+ /** The end-user whose runs this policy applies to. Required — policies never span end-users. */
1059
+ user_id: string;
1060
+ /** The tool to pre-approve, e.g. `"Bash"` or an `mcp__*` tool name. */
1061
+ tool: string;
1062
+ }
1063
+ interface PermissionListParams extends PageParams {
1064
+ /** Required: you list one end-user's policies, never the account's. */
1065
+ user_id: string;
1066
+ }
1067
+ interface PermissionsResource {
1068
+ /**
1069
+ * Pre-approve a tool so this end-user's runs no longer pause on it.
1070
+ * Idempotent — re-approving the same tool returns the existing policy rather
1071
+ * than erroring or duplicating. Send `tool`; the policy comes back as `tool_name`.
1072
+ */
1073
+ create(params: PermissionCreateParams): Promise<PermissionPolicy>;
1074
+ /** Audit what an end-user's runs are allowed to do without asking. */
1075
+ list(params: PermissionListParams): Promise<Page<PermissionPolicy>>;
1076
+ /**
1077
+ * Revoke a pre-approval, so the tool gates again on the next run.
1078
+ * `user_id` is required and scopes the delete — an id alone will not resolve.
1079
+ */
1080
+ delete(permissionId: number, params: {
1081
+ user_id: string;
1082
+ }): Promise<void>;
1083
+ }
1084
+ declare function createPermissionsResource(http: Http): PermissionsResource;
1085
+
1086
+ /**
1087
+ * Wait for a run to finish.
1088
+ *
1089
+ * Streaming is the good path: you see the work as it happens. But plenty of
1090
+ * integrations are a queue worker or a cron job that just wants the answer, and
1091
+ * without this every one of them hand-rolls the same loop — with its own idea of
1092
+ * which statuses are terminal, its own backoff, and usually no timeout. That is
1093
+ * the single most common thing a developer had to build themselves.
1094
+ *
1095
+ * Mirrors `sdk/py/m8tes/_resources/runs.py` (`poll`, `wait`): same terminal set,
1096
+ * same 2s interval and 300s default timeout, same "a transient API error is not
1097
+ * a failure, keep polling until the deadline" behaviour.
1098
+ */
1099
+
1100
+ /**
1101
+ * A run is done when it reaches one of these.
1102
+ *
1103
+ * Mirrors `TERMINAL_RUN_STATUSES` in `fastapi/app/models/run.py`, which is the
1104
+ * canonical set — including `"closed"` (a user-closed chat that cannot resume).
1105
+ * Both SDKs previously omitted it, so a closed run polled until the timeout.
1106
+ * The backend's own comment on that set warns these lists drift and that "a
1107
+ * 'closed' chat run burned tokens too". `archived` is deliberately NOT here:
1108
+ * it is a display state applied to already-terminal runs.
1109
+ */
1110
+ declare const TERMINAL_STATUSES: Set<string>;
1111
+ interface PollOptions {
1112
+ /** Seconds between polls. Default 2. */
1113
+ interval?: number;
1114
+ /** Seconds before giving up. Default 300. */
1115
+ timeout?: number;
1116
+ /** Abort the wait early. The in-flight request is cancelled with it. */
1117
+ signal?: AbortSignal;
1118
+ /**
1119
+ * End-user scope for each `GET /runs/{id}` poll. Required when the account
1120
+ * has strict multi-tenant mode on — without it every poll 422s.
1121
+ */
1122
+ user_id?: string;
1123
+ }
1124
+ interface WaitOptions extends PollOptions {
1125
+ /**
1126
+ * Called when a tool needs a decision. Return "allow" or "deny".
1127
+ * Without it, a run that pauses for a tool throws rather than hanging until
1128
+ * the timeout — silence would look identical to a slow run.
1129
+ */
1130
+ onApproval?: (request: PermissionRequest) => "allow" | "deny" | Promise<"allow" | "deny">;
1131
+ /**
1132
+ * Called when the agent asks a question. Return `{ [question text]: answer }`.
1133
+ * The keys must be the exact `question` strings from the request.
1134
+ */
1135
+ onQuestion?: (request: PermissionRequest) => Record<string, string> | Promise<Record<string, string>>;
1136
+ }
1137
+ /** Thrown when a run does not reach a terminal status before the deadline. */
1138
+ declare class RunTimeoutError extends Error {
1139
+ readonly runId: number;
1140
+ readonly timeoutSeconds: number;
1141
+ /** The last error seen while polling, if any. Without it a timeout hides the
1142
+ * transient failure that actually caused it. */
1143
+ readonly cause?: unknown;
1144
+ /** The run's status when the deadline hit, when one was ever observed. */
1145
+ readonly lastStatus?: string;
1146
+ constructor(runId: number, timeoutSeconds: number, cause?: unknown, lastStatus?: string);
1147
+ }
1148
+ /**
1149
+ * Thrown when a run pauses for a human and no handler was supplied. Better than
1150
+ * waiting out the full timeout, which gives the caller no idea what happened.
1151
+ */
1152
+ declare class RunPausedError extends Error {
1153
+ readonly runId: number;
1154
+ readonly request: PermissionRequest;
1155
+ constructor(runId: number, request: PermissionRequest, hint: string);
1156
+ }
1157
+ /** True for an AskUserQuestion pause carrying a plan for approval (plan mode). */
1158
+ declare function isPlanApproval(request: PermissionRequest): boolean;
1159
+ /** The proposed plan text, for a plan-approval pause. Null otherwise. */
1160
+ declare function planText(request: PermissionRequest): string | null;
1161
+ /**
1162
+ * Injected by the runs resource so this module stays free of transport concerns.
1163
+ * Every call takes the caller's `signal`, so an abort cancels the in-flight HTTP
1164
+ * request instead of only shortening the next sleep.
1165
+ */
1166
+ interface PollDeps {
1167
+ get(runId: number, signal?: AbortSignal): Promise<Run>;
1168
+ permissions(runId: number, signal?: AbortSignal): Promise<PermissionRequest[]>;
1169
+ approve(runId: number, params: {
1170
+ request_id: string;
1171
+ decision: "allow" | "deny";
1172
+ }, signal?: AbortSignal): Promise<unknown>;
1173
+ answer(runId: number, params: {
1174
+ answers: Record<string, string>;
1175
+ }, signal?: AbortSignal): Promise<unknown>;
1176
+ }
1177
+ /** Thrown when the caller aborts the wait. */
1178
+ declare class RunWaitAbortedError extends Error {
1179
+ /**
1180
+ * The run being waited on — `undefined` when the abort landed BEFORE any run
1181
+ * was created, which is the one case where there is nothing to go back to.
1182
+ * Previously this path passed a literal 0, producing "Waiting on run 0 was
1183
+ * aborted" and pointing the reader at a run that never existed.
1184
+ */
1185
+ readonly runId?: number;
1186
+ constructor(runId?: number);
1187
+ }
1188
+ /**
1189
+ * Poll until the run is terminal.
1190
+ *
1191
+ * A run that pauses for a human never becomes terminal, so this would spin until
1192
+ * the timeout — `waitForRun` handles that case. `poll` is for autonomous runs.
1193
+ */
1194
+ declare function pollRun(deps: PollDeps, runId: number, options?: PollOptions): Promise<Run>;
1195
+ /**
1196
+ * Wait for a run, answering human-in-the-loop pauses through callbacks.
1197
+ *
1198
+ * Same loop as `pollRun`, plus: on `awaiting_approval`, resolve every pending
1199
+ * request and let the run continue.
1200
+ */
1201
+ declare function waitForRun(deps: PollDeps, runId: number, options?: WaitOptions): Promise<Run>;
1202
+
462
1203
  /**
463
1204
  * `RunStream` — the developer-facing view of a streaming run.
464
1205
  *
@@ -481,6 +1222,13 @@ interface RunStreamOptions {
481
1222
  * Defaults to false, matching the Python SDK.
482
1223
  */
483
1224
  raiseOnError?: boolean;
1225
+ /**
1226
+ * Reuse this key to retry the same call safely — the server replays the run the
1227
+ * first attempt produced instead of starting (and billing) a second one. One is
1228
+ * minted per call automatically; supply your own only when a retry must survive
1229
+ * a process restart. Sent as the `Idempotency-Key` header.
1230
+ */
1231
+ idempotencyKey?: string;
484
1232
  }
485
1233
  declare class RunStream implements AsyncIterable<M8tesStreamEvent> {
486
1234
  private readonly source;
@@ -548,6 +1296,40 @@ interface RunCreateParams {
548
1296
  output_schema?: JsonObject;
549
1297
  /** Give this run's agent an email inbox. */
550
1298
  email_inbox?: boolean;
1299
+ /**
1300
+ * Reuse this key to retry the same create safely — the server returns the run
1301
+ * the first attempt made instead of starting (and billing) a second one.
1302
+ *
1303
+ * One is minted per call automatically, which is what makes the SDK's own
1304
+ * retries safe. Supply your own only when a retry must survive a process
1305
+ * restart: a job runner re-driving the same unit of work should pass its job
1306
+ * id. Sent as the `Idempotency-Key` header; never part of the request body.
1307
+ */
1308
+ idempotencyKey?: string;
1309
+ /**
1310
+ * Files the agent can read: a CSV to analyze, a PDF to summarize. Each is a
1311
+ * `{ name, data }` pair; `data` accepts anything `FormData` takes (Blob,
1312
+ * Uint8Array, ArrayBuffer, string). Sending files switches the request to the
1313
+ * multipart `/runs/with-files` endpoint; every other option behaves the same.
1314
+ *
1315
+ * Attachments require sandbox execution (the agent reads them with its file
1316
+ * tools from the run's working directory).
1317
+ */
1318
+ files?: RunFileInput[];
1319
+ }
1320
+ /** One attachment for `runs.create({ files })`. */
1321
+ interface RunFileInput {
1322
+ /** Filename the agent will see. Its extension determines the content type. */
1323
+ name: string;
1324
+ /** Contents. `Blob`/`File` pass straight through; bytes and strings are wrapped. */
1325
+ data: Blob | ArrayBuffer | ArrayBufferView | string;
1326
+ /**
1327
+ * Content type, if the extension does not imply it. The upload endpoint
1328
+ * validates against an allowlist and rejects the batch on a miss, so this is
1329
+ * inferred from `name` by default rather than defaulting to
1330
+ * `application/octet-stream` (which the server refuses).
1331
+ */
1332
+ type?: string;
551
1333
  }
552
1334
  interface RunListParams {
553
1335
  user_id?: string;
@@ -563,8 +1345,13 @@ interface ApproveParams {
563
1345
  request_id: string;
564
1346
  decision: "allow" | "deny";
565
1347
  /**
566
- * Apply the same decision to matching tool requests for the rest of THIS run.
567
- * For a policy that outlives the run, use the permissions API instead.
1348
+ * Persist beyond this single gate.
1349
+ * - `false` (default): this request only.
1350
+ * - `true` + allow: also silence matching tools for the rest of THIS run AND
1351
+ * store a cross-run always-allow policy (scoped to the run's end-user when
1352
+ * set; revoke via `/permissions`).
1353
+ * - `true` + deny: deny matching tools for the rest of THIS run only (no
1354
+ * stored policy).
568
1355
  */
569
1356
  remember?: boolean;
570
1357
  }
@@ -580,16 +1367,42 @@ interface RunsResource {
580
1367
  create(params: RunCreateParams, options?: RunStreamOptions): RunStream;
581
1368
  /** Start a run and return immediately; poll `get()` or use a webhook for the result. */
582
1369
  createAsync(params: RunCreateParams): Promise<Run>;
1370
+ /**
1371
+ * Start a run and wait for the result. The batch/cron counterpart to `create()`.
1372
+ * Pass `onApproval`/`onQuestion` to answer human-in-the-loop pauses inline;
1373
+ * without them a paused run throws `RunPausedError` rather than hanging.
1374
+ */
1375
+ createAndWait(params: RunCreateParams, options?: WaitOptions): Promise<Run>;
1376
+ /** Poll an existing run until it is terminal. Throws `RunTimeoutError` on deadline. */
1377
+ poll(runId: number, options?: PollOptions): Promise<Run>;
1378
+ /** Like `poll`, but resolves human-in-the-loop pauses through callbacks. */
1379
+ wait(runId: number, options?: WaitOptions): Promise<Run>;
1380
+ /**
1381
+ * Retry a failed or cancelled run. Returns a NEW run — poll that one's id, the
1382
+ * original stays failed. Idempotent: an in-flight retry is returned as-is.
1383
+ *
1384
+ * If the run already did something visible (sent a message, changed data), the
1385
+ * API refuses with a 409 `retry_needs_confirmation`; pass `confirm: true` to
1386
+ * proceed. Check `run.retryable` first to avoid a guaranteed conflict.
1387
+ */
1388
+ retry(runId: number, params?: {
1389
+ confirm?: boolean;
1390
+ }): Promise<Run>;
583
1391
  /** Join a run already in flight. Throws `RunNotStreamingError` if it has finished. */
584
1392
  stream(runId: number, options?: RunStreamOptions): RunStream;
585
1393
  /** Continue the conversation on an existing run, streaming the reply. */
586
1394
  reply(runId: number, message: string, options?: RunStreamOptions): RunStream;
587
- /** GET /runs/{id} takes NO query params it is already account-scoped, and
588
- * sending `user_id` returns 422 `unknown_query_parameter`. */
589
- get(runId: number): Promise<Run>;
1395
+ /** GET /runs/{id}. Pass `user_id` to scope to one end-user (required when the
1396
+ * account has strict multi-tenant mode on). */
1397
+ get(runId: number, params?: {
1398
+ user_id?: string;
1399
+ }): Promise<Run>;
590
1400
  list(params?: RunListParams): Promise<Page<Run>>;
591
- /** Cancel a running run. Returns the updated Run, like the Python SDK. */
592
- cancel(runId: number): Promise<Run>;
1401
+ /** Cancel a running run. Returns the updated Run, like the Python SDK.
1402
+ * Pass `user_id` when the account has strict multi-tenant mode on. */
1403
+ cancel(runId: number, params?: {
1404
+ user_id?: string;
1405
+ }): Promise<Run>;
593
1406
  /** Approve or deny a pending tool-permission gate. */
594
1407
  approve(runId: number, params: ApproveParams): Promise<PermissionRequest>;
595
1408
  /** Answer a pending AskUserQuestion gate, resuming the run. */
@@ -743,17 +1556,35 @@ interface TriggerCreateParams {
743
1556
  }
744
1557
  interface TriggersResource {
745
1558
  create(taskId: number, params: TriggerCreateParams): Promise<Trigger>;
746
- list(taskId: number): Promise<Trigger[]>;
1559
+ list(taskId: number, params?: {
1560
+ user_id?: string;
1561
+ }): Promise<Trigger[]>;
747
1562
  /** Only the schedule shape and the enabled flag are mutable — a trigger's
748
1563
  * `type`/`app`/`trigger_name` are fixed at creation and are silently ignored
749
- * on PATCH. Delete and recreate to change those. */
1564
+ * on PATCH. Delete and recreate to change those. `user_id` scopes to one
1565
+ * end-user (404 on mismatch). */
750
1566
  update(taskId: number, triggerId: number, params: {
751
1567
  cron?: string;
752
1568
  interval_seconds?: number;
753
1569
  timezone?: string;
754
1570
  enabled?: boolean;
1571
+ user_id?: string;
755
1572
  }): Promise<Trigger>;
756
- delete(taskId: number, triggerId: number): Promise<void>;
1573
+ delete(taskId: number, triggerId: number, params?: {
1574
+ user_id?: string;
1575
+ }): Promise<void>;
1576
+ }
1577
+ interface TaskRunParams {
1578
+ /** Run on behalf of this end-user. */
1579
+ user_id?: string;
1580
+ /**
1581
+ * Reuse this key to retry the same call safely — the server returns the run the
1582
+ * first attempt made instead of starting (and billing) a second one. One is
1583
+ * minted per call automatically; supply your own (e.g. a scheduler's job id)
1584
+ * only when a retry must survive a process restart. Sent as the
1585
+ * `Idempotency-Key` header, never in the body.
1586
+ */
1587
+ idempotencyKey?: string;
757
1588
  }
758
1589
  interface TasksResource {
759
1590
  triggers: TriggersResource;
@@ -769,67 +1600,16 @@ interface TasksResource {
769
1600
  user_id?: string;
770
1601
  }): Promise<void>;
771
1602
  /** Run the task now, streaming it. */
772
- run(taskId: number, params?: {
773
- user_id?: string;
774
- }, options?: RunStreamOptions): RunStream;
1603
+ run(taskId: number, params?: TaskRunParams, options?: RunStreamOptions): RunStream;
775
1604
  /** Run the task now without streaming; poll `runs.get()` for the result. */
776
- runAsync(taskId: number, params?: {
1605
+ runAsync(taskId: number, params?: TaskRunParams): Promise<Run>;
1606
+ /** `user_id` scopes to one end-user (404 on mismatch), like get/update/delete. */
1607
+ enableWebhook(taskId: number, params?: {
777
1608
  user_id?: string;
778
- }): Promise<Run>;
779
- enableWebhook(taskId: number): Promise<WebhookToggle>;
780
- disableWebhook(taskId: number): Promise<void>;
781
- }
782
-
783
- /**
784
- * `client.users` — your end-users, the multi-tenancy boundary.
785
- *
786
- * `user_id` is YOUR identifier for a customer; the platform stores it as
787
- * `end_user_id` and isolates that person's memory, run history, and tool
788
- * connections strictly. There is no fallback to account-level data.
789
- *
790
- * Registering an end-user here is optional — passing `user_id` on a run creates
791
- * them implicitly. Do it explicitly when you want per-user budgets and rate
792
- * limits. Mirrors `sdk/py/m8tes/_resources/users.py`.
793
- */
794
-
795
- interface EndUserCreateParams {
796
- /** Your id for this person. Any stable string. */
797
- user_id: string;
798
- name?: string;
799
- email?: string;
800
- company?: string;
801
- metadata?: JsonObject;
802
- /** Cap this end-user's runs per billing period. */
803
- run_limit?: number;
804
- /** Cap this end-user's spend per billing period, in cents. */
805
- cost_limit_cents?: number;
806
- /** Cap this end-user's runs per minute. Exceeding it returns 429. */
807
- rate_per_minute?: number;
808
- }
809
- /** `null` CLEARS a cap (inherit the account default); omitting leaves it alone. */
810
- interface EndUserUpdateParams {
811
- name?: string | null;
812
- email?: string | null;
813
- company?: string | null;
814
- metadata?: JsonObject | null;
815
- run_limit?: number | null;
816
- cost_limit_cents?: number | null;
817
- rate_per_minute?: number | null;
818
- }
819
- interface PageParams {
820
- limit?: number;
821
- starting_after?: number;
822
- }
823
- interface UsersResource {
824
- create(params: EndUserCreateParams): Promise<EndUser>;
825
- list(params?: PageParams): Promise<Page<EndUser>>;
826
- get(userId: string): Promise<EndUser>;
827
- update(userId: string, params: EndUserUpdateParams): Promise<EndUser>;
828
- delete(userId: string): Promise<void>;
829
- /** Per-end-user token, run, and cost usage against their limits. */
830
- usage(params?: PageParams & {
1609
+ }): Promise<WebhookToggle>;
1610
+ disableWebhook(taskId: number, params?: {
831
1611
  user_id?: string;
832
- }): Promise<Page<EndUserUsage>>;
1612
+ }): Promise<void>;
833
1613
  }
834
1614
 
835
1615
  /**
@@ -918,7 +1698,7 @@ interface WebhooksResource {
918
1698
  */
919
1699
 
920
1700
  /** Kept in lockstep with package.json "version" — guarded by test/version.test.ts. */
921
- declare const M8TES_SDK_VERSION = "0.1.0-alpha.1";
1701
+ declare const M8TES_SDK_VERSION = "0.1.0-alpha.3";
922
1702
  declare class M8tes {
923
1703
  readonly runs: RunsResource;
924
1704
  readonly agents: AgentsResource;
@@ -929,9 +1709,15 @@ declare class M8tes {
929
1709
  readonly apps: AppsResource;
930
1710
  readonly webhooks: WebhooksResource;
931
1711
  readonly settings: SettingsResource;
1712
+ readonly memories: MemoriesResource;
1713
+ readonly permissions: PermissionsResource;
1714
+ readonly models: ModelsResource;
1715
+ readonly modelConnections: ModelConnectionsResource;
1716
+ readonly billing: BillingResource;
1717
+ readonly account: AccountResource;
932
1718
  /** The underlying transport. Use it to call an endpoint this version does not wrap yet. */
933
1719
  readonly http: Http;
934
1720
  constructor(options?: ClientOptions);
935
1721
  }
936
1722
 
937
- export { type AccountSettings, type AccountSettingsUpdateParams, type Agent, type AgentCreateParams, type AgentListParams, type AgentUpdateParams, type AgentsResource, type App, type AppConnectionInitiation, type AppConnectionResult, type AppsResource, type ClientOptions, ConversationState, DEFAULT_BASE_URL, type EmailInbox, type EndUser, type EndUserCreateParams, type EndUserUpdateParams, type EndUserUsage, type FetchLike, type Http, type JsonObject, type ListResponse, M8TES_SDK_VERSION, M8tes, M8tesStreamEvent, Normalizer, Page, type PageParams, type PermissionMode, type PermissionRequest, type Run, type RunCreateParams, type RunFile, type RunListParams, type RunOutcome, RunStream, type RunStreamOptions, type RunUsage, type RunsResource, type SettingsResource, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TasksResource, type Teammate, type Trigger, type TriggerCreateParams, type TriggerType, type TriggersResource, type UsersResource, type VerifySignatureOptions, type Webhook, type WebhookDelivery, type WebhookToggle, type WebhooksResource, createHttp, verifySignature };
1723
+ export { type AccountDeletion, type AccountExport, type AccountResource, type AccountSettings, type AccountSettingsUpdateParams, type Agent, type AgentCreateParams, type AgentListParams, type AgentUpdateParams, type AgentsResource, type AlertThresholdParams, type App, type AppConnectionInitiation, type AppConnectionResult, type AppsResource, type AuthorizableModelConnectionProvider, type AutoReloadParams, type Balance, type BillingResource, type ClientOptions, type CodeModelConnectionProvider, ConversationState, DEFAULT_BASE_URL, type DeviceModelConnectionProvider, type EmailInbox, type EndUser, type EndUserCreateParams, type EndUserUpdateParams, type EndUserUsage, type FetchLike, type Http, type JsonObject, type ListResponse, M8TES_SDK_VERSION, M8tes, M8tesStreamEvent, type MemoriesResource, type Memory, type MemoryCreateParams, type MemoryListParams, type MemoryUpdateParams, type Model, type ModelAuthorization, type ModelConnection, type ModelConnectionProvider, type ModelConnectionsResource, type ModelPricing, type ModelsResource, Normalizer, type OverageParams, Page, type PageParams, type PermissionCreateParams, type PermissionListParams, type PermissionMode, type PermissionPolicy, type PermissionRequest, type PermissionsResource, type Plan, type PollOptions, type Receipt, type Run, type RunCreateParams, type RunFile, type RunListParams, type RunOutcome, RunPausedError, RunStream, type RunStreamOptions, RunTimeoutError, type RunUsage, RunWaitAbortedError, type RunsResource, type SettingsResource, TERMINAL_STATUSES, type Task, type TaskCreateParams, type TaskListParams, type TaskRunParams, type TaskUpdateParams, type TasksResource, type Teammate, type TokenTransaction, type TopupParams, type Trigger, type TriggerCreateParams, type TriggerType, type TriggersResource, type Usage, type UsageBucket, type UsageModelSlice, type UsageTimeseries, type UsageTimeseriesParams, type UsageTotals, type UsersResource, type VerifySignatureOptions, type WaitOptions, type Webhook, type WebhookDelivery, type WebhookToggle, type WebhooksResource, createAccountResource, createBillingResource, createHttp, createMemoriesResource, createModelConnectionsResource, createModelsResource, createPermissionsResource, isPlanApproval, planText, pollRun, verifySignature, waitForRun };