@rudra-js/anthropic 0.8.2 → 0.8.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.
Files changed (2) hide show
  1. package/README.md +93 -78
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -6,11 +6,11 @@ rudra-js is an open-source TypeScript library (MIT) you install from npm. A lang
6
6
 
7
7
  It is not a hosted platform, a visual or low-code app builder, or a workspace you sign up for.
8
8
 
9
- An Anthropic adapter for
10
- [`@rudra-js/core`](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core)'s
11
- `ComponentProvider`.
9
+ This package plugs Anthropic's models into
10
+ [`@rudra-js/core`](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core)
11
+ as a `ComponentProvider`.
12
12
 
13
- This adapter is documented at [rudrajs.com](https://rudrajs.com/docs#createAnthropicProvider).
13
+ Its docs are at [rudrajs.com](https://rudrajs.com/reference/anthropic/createAnthropicProvider).
14
14
 
15
15
  > Anthropic and Claude are trademarks of Anthropic, PBC. This package is an
16
16
  > independent adapter and is not affiliated with or endorsed by Anthropic.
@@ -21,13 +21,15 @@ This adapter is documented at [rudrajs.com](https://rudrajs.com/docs#createAnthr
21
21
  npm install @rudra-js/anthropic@latest @rudra-js/core@latest @rudra-js/attested@latest
22
22
  ```
23
23
 
24
- Run the same command in a new app, in one that already uses rudra-js, and to
25
- upgrade. If your app has `@rudra-js/react`, add it to the command with `@latest`
26
- too. If it has `@rudra-js/a2ui`, use the install line in that package's README
27
- instead, since it also names the two A2UI packages. The `@rudra-js` packages are
28
- published together, and each one's peer ranges on the others start at its own
29
- version. For a bare name npm stays inside the range your `package.json` already
30
- has, so without `@latest` an app on an older core can get an `ERESOLVE`.
24
+ Use this same command in a new app or in one that already uses rudra-js. Use it
25
+ to upgrade too. If your app has `@rudra-js/react`, add it to the command with
26
+ `@latest` too. If it has `@rudra-js/a2ui`, use the install line in that
27
+ package's README instead. That line also names the two A2UI packages.
28
+
29
+ The `@rudra-js` packages are released together. Each one's peer dependency
30
+ ranges on the others start at its own version. When you give npm a package name
31
+ with no version, it stays inside the range your `package.json` already has. So
32
+ without `@latest`, an app on an older core can get an `ERESOLVE` error.
31
33
 
32
34
  ```ts
33
35
  import { createAnthropicProvider } from '@rudra-js/anthropic';
@@ -37,38 +39,42 @@ const provider = createAnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY
37
39
  const generator = createComponentGenerator({ provider });
38
40
  ```
39
41
 
40
- `model` defaults to `claude-sonnet-5`, and `thinking` defaults to
41
- `{ type: 'disabled' }`.
42
+ `model` defaults to `claude-sonnet-5`. `thinking` defaults to
43
+ `{ type: 'disabled' }`. `maxTokens` and `baseUrl` are optional too.
42
44
 
43
- Both of those come from the same constraint. Generation runs on the request
44
- path, inside `modelTimeoutMs`, which core defaults to 1500ms. A model that
45
- reasons before it answers won't finish in time. Sonnet 5 reasons by default
46
- when `thinking` is left out, so it's the leaving out that would break the
47
- budget, not the choice of model.
45
+ Generation runs while the page request waits, inside core's `modelTimeoutMs`.
46
+ That defaults to 1500ms. A model that reasons before it answers won't finish in
47
+ that time. Sonnet 5 reasons by default when the request leaves `thinking` out.
48
+ So the `thinking` default is what keeps Sonnet 5 inside the time limit.
48
49
 
49
- Want a different model? Pass `model` to pin one, and raise `modelTimeoutMs` to
50
- match while you're there. A quick heads-up on `thinking`: some models reject an
51
- explicit `{ type: 'disabled' }` and reason whatever you do. Pass
52
- `thinking: null` for those and we'll send no `thinking` field at all. Our
53
- example shop pins `claude-opus-5` and gives `modelTimeoutMs` a full 60 seconds,
54
- which is a demo talking, not a production setting.
50
+ To use another model, pass `model`, and raise `modelTimeoutMs` to match. Some
51
+ models reject an explicit `{ type: 'disabled' }` and reason whatever you send.
52
+ For those, pass `thinking: null`, and the adapter sends no `thinking` field at
53
+ all. The example shop in this repo pins `claude-opus-5` and gives
54
+ `modelTimeoutMs` 60 seconds. That's a demo setting. Don't use it in production.
55
55
 
56
- The adapter asks the model to answer by calling its tool rather than forcing the
56
+ The adapter asks the model to answer by calling its tool. It doesn't force the
57
57
  call, because Claude Opus 5.5, Sonnet 5.5, Fable 5.1 and Mythos 5.1 reject a
58
- forced tool call. So a model can answer in plain text instead. That reply is
59
- turned down like any other that doesn't fit, you get the fallback component, and
60
- the event's `error` in `onEvent` says
61
- `anthropic returned no emit_component_spec tool use`. Those four models also
62
- reject `thinking: { type: 'disabled' }`, so pass `thinking: null` with them, and
63
- raise `modelTimeoutMs`, since they'll reason before they answer.
58
+ forced tool call. So a model can answer in plain text instead. The adapter
59
+ rejects that reply, the same as any reply that doesn't fit. You get the
60
+ fallback, which is the block core builds without a model. The event's `error`
61
+ in `onEvent` says `anthropic returned no emit_component_spec tool use`.
62
+
63
+ Those four models also reject `thinking: { type: 'disabled' }`, so pass
64
+ `thinking: null` with them.
65
+
66
+ You can pass your own `fetch`. This package's tests do that to stand in for a
67
+ network call.
64
68
 
65
- `maxTokens` and `baseUrl` are optional too.
69
+ The adapter builds the tool schema it sends the model from the `schema` on the
70
+ `ProviderRequest`. That's the schema `@rudra-js/core` defines. This package
71
+ keeps no copy of its own.
66
72
 
67
73
  ### An identity-linked key needs a workspace
68
74
 
69
- A key you made against your identity rather than inside a workspace belongs to
70
- you across several of them. The API can't tell which one a request is acting in,
71
- so it answers:
75
+ An identity-linked key is one you made against your own identity, outside any
76
+ workspace. It belongs to you across several workspaces. The API can't tell which
77
+ one a request acts in, so it answers with this error:
72
78
 
73
79
  ```
74
80
  400 invalid_request_error — anthropic-workspace-id is required when
@@ -84,58 +90,67 @@ createAnthropicProvider({
84
90
  });
85
91
  ```
86
92
 
87
- `fetch` is injectable. That's how our test suite stands in for a network call.
93
+ ## Data handling
88
94
 
89
- The tool schema we send the model is derived from the `schema` on the
90
- `ProviderRequest`, the same schema `@rudra-js/core` defines. We don't keep a
91
- copy here. A second copy would be a second vocabulary, and then the reconciler
92
- enforces one thing while the model is told another.
95
+ Each generation sends one POST to `https://api.anthropic.com/v1/messages`. Set
96
+ `baseUrl` to send it to another host instead. That can be a proxy or a gateway.
97
+ It can also be a region-specific endpoint you have.
93
98
 
94
- ## Data handling
99
+ The [`@rudra-js/core` README](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core#what-the-model-sees)
100
+ lists what goes in that request, under **What the model sees**. Read it before
101
+ you send real shopper traffic.
102
+
103
+ In cohort mode, the default, shoppers who look alike share one generated block.
104
+ Each shopper's own products are filled in per request. Per-shopper mode
105
+ generates for each shopper. Neither mode sends `user.id`.
106
+
107
+ A cohort-mode request can still be personal data. It carries:
108
+
109
+ - the name of the category that shopper leans towards most
110
+ - whether they have any history
111
+ - any `segment` you gave them, as you wrote it
112
+ - the candidate products, which you may have picked or ordered just for them
113
+
114
+ A per-shopper request also carries:
95
115
 
96
- Each generation is one POST to `https://api.anthropic.com/v1/messages`. Set
97
- `baseUrl` and it goes to that host instead, whether that's a proxy, a gateway,
98
- or a region-specific endpoint you have.
99
-
100
- What's in that request is listed under **What the model sees** in the
101
- [`@rudra-js/core` README](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core#what-the-model-sees).
102
- Read it before you send real shopper traffic. Neither mode sends `user.id`. In
103
- cohort mode, the default, the request can still be personal data: it names the
104
- category that shopper leans towards most, says whether they have any history,
105
- carries any `segment` you gave them as you wrote it, and lists candidates you
106
- may have picked or ordered just for them. In per-shopper mode it also carries
107
- the product that shopper is looking at, their current and recent searches,
108
- whether they're returning, their likes, dislikes, purchases, basket, most-viewed
109
- products, the categories they lean towards and interaction counts.
116
+ - the product that shopper is looking at
117
+ - their current and recent searches
118
+ - whether they're returning
119
+ - their likes, dislikes and purchases
120
+ - their basket
121
+ - their most-viewed products
122
+ - the categories they lean towards
123
+ - interaction counts
110
124
 
111
125
  If your shop is in the EU or the UK, or sells to shoppers there, you're the one
112
- sending personal data out. You'll need a data processing agreement with whoever
113
- receives it, and a transfer mechanism if they're outside the EU or the UK, even
114
- when your shop is outside them too.
115
-
116
- Call Anthropic with a key from your own Anthropic account and the receiver is
117
- Anthropic. Its data processing addendum is part of its Commercial Terms, makes
118
- Anthropic your processor and includes the transfer clauses. Your shop is
119
- Anthropic's customer. A proxy you run yourself that forwards to Anthropic
126
+ sending personal data out. You need a data processing agreement (DPA) with
127
+ whoever receives it. If the receiver is outside the EU or the UK, you also need a
128
+ transfer mechanism. That holds even when your shop is outside the EU and the UK.
129
+
130
+ If you call Anthropic with a key from your own Anthropic account, the receiver is
131
+ Anthropic. Anthropic's data processing addendum is part of its Commercial Terms.
132
+ It makes Anthropic your processor and includes the transfer clauses. Your shop
133
+ is Anthropic's customer. A proxy you run yourself that forwards to Anthropic
120
134
  doesn't change that.
121
135
 
122
136
  If you point `baseUrl` at a gateway or platform run by someone other than you or
123
137
  Anthropic, its operator sees every request and the `apiKey` you pass. If that's
124
- a key from your own Anthropic account, Anthropic is still your processor and the
125
- operator is another one, so you need a DPA with the operator as well. If the
126
- platform issued the key, Anthropic says the platform's terms govern that use:
127
- you're the platform's customer, and its DPA is the one that covers you.
128
-
129
- This package is a piece of code in the middle, and it _isn't_ a party to
130
- anything.
131
-
132
- When the API answers with an error, the `Error` we throw carries the status code
133
- and the vendor's error category, like `anthropic responded 400
134
- (invalid_request_error)`. We leave the vendor's own message out. It quotes the
135
- request back, and in rudra-js the request can hold a shopper's search
136
- terms, which an adopter's `console.error(error)` would then write to a log. A
137
- test in `anthropic-provider.test.ts` puts a search term in that message and
138
- asserts it does not reach the thrown error.
138
+ a key from your own Anthropic account, Anthropic is still your processor. The
139
+ operator is a second processor, so you need a DPA with the operator as well. If
140
+ the platform issued the key, Anthropic says the platform's terms govern that
141
+ use. You're the platform's customer, and the platform's DPA is the one that
142
+ covers you.
143
+
144
+ This package is a piece of code in the middle. It _isn't_ a party to anything.
145
+
146
+ When the API answers with an error, the adapter throws an `Error` that carries
147
+ the status code and Anthropic's error category, like
148
+ `anthropic responded 400 (invalid_request_error)`. It leaves out Anthropic's own
149
+ error message. That message quotes the request back. The request can hold a
150
+ shopper's search terms. If the adapter kept the message, a `console.error(error)`
151
+ in your app would write those terms to a log. A test in
152
+ `anthropic-provider.test.ts` puts a search term in that message and checks that
153
+ it doesn't reach the thrown error.
139
154
 
140
155
  ## Licence
141
156
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rudra-js/anthropic",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Anthropic adapter for rudra-js (@rudra-js/core), with no vendor SDK",
5
5
  "keywords": [
6
6
  "rudra-js",
@@ -52,10 +52,10 @@
52
52
  "zod": "^4.6.7"
53
53
  },
54
54
  "peerDependencies": {
55
- "@rudra-js/core": "^0.8.2"
55
+ "@rudra-js/core": "^0.8.3"
56
56
  },
57
57
  "devDependencies": {
58
- "@rudra-js/core": "0.8.2",
58
+ "@rudra-js/core": "0.8.3",
59
59
  "@types/node": "^26.4.1"
60
60
  }
61
61
  }