@mantyx/sdk 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ### Added
9
9
 
10
+ - Update protocol
11
+
12
+ ## [0.10.0] — 2026-05-13
13
+
14
+ ### Added
15
+
10
16
  - Oauth2 support
11
17
 
12
18
  ## [0.9.1] — 2026-05-11
@@ -80,7 +86,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
80
86
 
81
87
  ## [0.1.0] — 2026-05-02
82
88
 
83
- [unreleased]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.1..HEAD
89
+ [unreleased]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.10.1..HEAD
90
+ [0.10.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.1..v0.10.0
84
91
  [0.9.1]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.9.0..v0.9.1
85
92
  [0.9.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.8.0..v0.9.0
86
93
  [0.8.0]: https://github.com/mantyx-io/mantyx-sdk/compare/v0.7.0..v0.8.0
package/README.md CHANGED
@@ -555,58 +555,64 @@ All thrown errors extend `MantyxError`. Common subclasses:
555
555
 
556
556
  ### OAuth 2.0 refresh
557
557
 
558
- For long-running services, hand the SDK a `TokenSource` instead of a
559
- static `accessToken` the client refreshes proactively before
560
- expiry and again on 401, retrying the original request exactly once.
561
- Refresh tokens are **persistent and non-rotating** per
562
- [`docs/oauth.md`](./docs/oauth.md): the caller persists the
563
- `refreshToken` once at first sign-in (treat it as long-lived,
564
- encrypted at rest) and the SDK re-mints access tokens from it
565
- transparently.
558
+ The SDK ships a **refresh-only** OAuth client. It assumes the calling
559
+ app already obtained a refresh token through its own sign-in flow
560
+ (browser PKCE redirect, native auth, server-side exchange whatever
561
+ fits the host). The library does not drive consent and does not
562
+ initiate authorization-code or client-credentials grants. Once you
563
+ have the refresh token, hand it to the SDK and the rest is
564
+ transparent:
565
+
566
+ - Refresh tokens are **persistent and non-rotating** per
567
+ [`docs/oauth.md`](./docs/oauth.md): store them once at first
568
+ sign-in (treat them as long-lived, encrypted at rest) and the SDK
569
+ re-mints access tokens from the same value on demand.
570
+ - A `TokenSource` is called before every request and again on `401`,
571
+ with single-flight collapse on concurrent refreshes.
572
+ - `400 invalid_grant` from the token endpoint is surfaced as
573
+ `MantyxOAuthError` — that means the refresh has been revoked and
574
+ the caller has to drive a fresh sign-in.
566
575
 
567
576
  ```ts
568
577
  import { MantyxClient, MantyxOAuthClient } from "@mantyx/sdk";
569
578
 
570
579
  const oauth = new MantyxOAuthClient({
571
- clientId: process.env.MANTYX_OAUTH_CLIENT_ID!, // mantyx_oa_…
580
+ clientId: process.env.MANTYX_OAUTH_CLIENT_ID!, // mantyx_oa_…
572
581
  clientSecret: process.env.MANTYX_OAUTH_CLIENT_SECRET!, // mantyx_oas_…
573
582
  });
574
583
 
575
- // (1) Authorization-code: swap a `code` for the initial token pair, persist
576
- // the refresh token against the user record. See docs/oauth.md for the
577
- // full PKCE redirect dance the calling app is responsible for.
578
- const initial = await oauth.exchangeAuthorizationCode({
579
- code: authCode,
580
- redirectUri: "https://app.example.com/cb",
581
- codeVerifier: storedVerifier,
582
- });
583
- await db.users.update(userId, { mantyxRefreshToken: initial.refreshToken });
584
-
585
- // (2) End-user clients: build a refresh-driven TokenSource from the
586
- // persisted refresh token. The SDK calls it before every request and on
587
- // 401s; concurrent requests collapse onto one refresh.
584
+ // (1) Hand the SDK a stored refresh token — it caches the access token in
585
+ // memory, refreshes proactively before expiry, and retries the original
586
+ // request once on a 401.
588
587
  const client = new MantyxClient({
589
588
  tokenSource: oauth.refreshTokenSource({
590
- refreshToken: initial.refreshToken!,
591
- initialToken: initial,
589
+ refreshToken: storedRefreshToken, // mantyx_rt_…
592
590
  }),
593
591
  workspaceSlug: "acme",
594
592
  });
595
593
 
596
- // (3) Service-to-service: client_credentials sources never hold a refresh
597
- // token; they re-mint access tokens on demand.
598
- const svcClient = new MantyxClient({
599
- tokenSource: oauth.clientCredentialsTokenSource({ scope: ["agents:invoke"] }),
594
+ // (2) If the calling app already has a non-expired access token in hand
595
+ // (e.g. straight out of its sign-in flow), pass it as `initialToken` to
596
+ // skip the first /token round-trip.
597
+ const seeded = new MantyxClient({
598
+ tokenSource: oauth.refreshTokenSource({
599
+ refreshToken: storedRefreshToken,
600
+ initialToken: tokenFromSignIn,
601
+ }),
600
602
  workspaceSlug: "acme",
601
603
  });
602
604
 
603
- // (4) Manual override is still supported for short-lived access tokens that
604
- // the caller already manages.
605
+ // (3) Manual override for short-lived access tokens the caller manages
606
+ // itself no refresh, no retry, no OAuth client needed.
605
607
  const oneShot = new MantyxClient({ accessToken: "mantyx_at_…", workspaceSlug: "acme" });
608
+
609
+ // Optional: revoke a refresh token at sign-out — this kills the refresh and
610
+ // every live access token tied to its grant.
611
+ await oauth.revoke({ token: storedRefreshToken });
606
612
  ```
607
613
 
608
614
  See [`docs/oauth.md`](./docs/oauth.md) for grant types, token formats,
609
- and revocation.
615
+ scope catalog, and revocation semantics.
610
616
 
611
617
  ## Examples
612
618
 
@@ -59,6 +59,12 @@ var MantyxRunError = class extends MantyxError {
59
59
  partialText;
60
60
  /** See {@link MantyxRunErrorInit.retryable}. */
61
61
  retryable;
62
+ /** See {@link MantyxRunErrorInit.tokens}. */
63
+ tokens;
64
+ /** See {@link MantyxRunErrorInit.turns}. */
65
+ turns;
66
+ /** See {@link MantyxRunErrorInit.model}. */
67
+ model;
62
68
  constructor(runId, subtype, message, init = {}) {
63
69
  super(message, { code: subtype });
64
70
  this.name = "MantyxRunError";
@@ -68,6 +74,9 @@ var MantyxRunError = class extends MantyxError {
68
74
  this.finishReason = init.finishReason;
69
75
  this.partialText = init.partialText;
70
76
  this.retryable = init.retryable;
77
+ this.tokens = init.tokens;
78
+ this.turns = init.turns;
79
+ this.model = init.model;
71
80
  }
72
81
  };
73
82