@rudra-js/anthropic 0.9.0 → 0.9.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.
Files changed (2) hide show
  1. package/README.md +86 -77
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -21,15 +21,17 @@ Its docs are at [rudrajs.com](https://rudrajs.com/reference/anthropic/createAnth
21
21
  npm install @rudra-js/anthropic@latest @rudra-js/core@latest @rudra-js/attested@latest
22
22
  ```
23
23
 
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
24
+ You will need this command in a new app and in an app that already uses
25
+ rudra-js. You will also need this command to upgrade. If your app has
26
+ `@rudra-js/react`, you will need to add it to the command with `@latest` too. If
27
+ your app has `@rudra-js/a2ui`, you will need to use the install line in that
27
28
  package's README instead. That line also names the two A2UI packages.
28
29
 
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.
30
+ All of these `@rudra-js` packages are released together. Peer dependency ranges
31
+ between them start at the version of the package that has the range. If you give
32
+ npm a package name with no version, npm will stay inside the range your
33
+ `package.json` already has. This means leaving out `@latest` can give an app on
34
+ an older core an `ERESOLVE` error.
33
35
 
34
36
  ```ts
35
37
  import { createAnthropicProvider } from '@rudra-js/anthropic';
@@ -39,49 +41,53 @@ const provider = createAnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY
39
41
  const generator = createComponentGenerator({ provider });
40
42
  ```
41
43
 
42
- `model` defaults to `claude-sonnet-5`. `thinking` defaults to
43
- `{ type: 'disabled' }`. `maxTokens` and `baseUrl` are optional too.
44
-
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.
49
-
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
-
56
- The adapter asks the model to answer by calling its tool. It doesn't force the
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. 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
44
+ By default, `model` is `claude-sonnet-5` and `thinking` is
45
+ `{ type: 'disabled' }`. You can also set `maxTokens` and `baseUrl`. These are
46
+ optional too.
47
+
48
+ Your page request waits while generation runs inside core's `modelTimeoutMs`.
49
+ This is 1500ms by default. If a model reasons before it answers, it won't finish
50
+ in that time. By default Sonnet 5 will reason if the request leaves `thinking`
51
+ out. So the `thinking` default is what keeps Sonnet 5 inside the time limit.
52
+
53
+ If you want to use another model, pass `model` and raise `modelTimeoutMs` to
54
+ match. Some models reject an explicit `{ type: 'disabled' }` and reason whatever
55
+ you send. For those models you will need to pass `thinking: null` to have the
56
+ adapter send no `thinking` field at all. There is an example shop in this repo
57
+ that pins `claude-opus-5` and gives `modelTimeoutMs` 60 seconds. That's a demo
58
+ setting. Don't use it in production.
59
+
60
+ This adapter asks the model to answer by calling its tool. But the call isn't
61
+ forced, because Claude Opus 5.5, Sonnet 5.5, Fable 5.1 and Mythos 5.1 reject a
62
+ forced tool call. This means a model can answer in plain text instead. If it
63
+ does, the adapter will reject the reply like any other reply that doesn't fit.
64
+ You will then get the fallback (the block that core builds without a model). For
65
+ this reply the event's `error` in `onEvent` says
66
+ `anthropic returned no emit_component_spec tool use`.
67
+
68
+ Those four models also reject `thinking: { type: 'disabled' }`. With them you
69
+ need to pass `thinking: null`.
70
+
71
+ You can pass a custom `fetch`. This package's tests do that to stand in for a
67
72
  network call.
68
73
 
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.
74
+ This adapter builds the tool schema it sends the model from the `schema` on the
75
+ `ProviderRequest`. That's the schema defined by `@rudra-js/core`. This package
76
+ doesn't keep a copy.
72
77
 
73
78
  ### An identity-linked key needs a workspace
74
79
 
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:
80
+ If you made a key against your own identity, outside any workspace, this is an
81
+ identity-linked key. This key belongs to you across several workspaces. Because
82
+ the API can't tell which of those a request acts in, it answers with this error:
78
83
 
79
84
  ```
80
85
  400 invalid_request_error — anthropic-workspace-id is required when
81
86
  authenticating with an identity-linked API key
82
87
  ```
83
88
 
84
- Pass the workspace, or create the key from inside a workspace instead:
89
+ You need to pass the workspace or create the key from inside a workspace
90
+ instead:
85
91
 
86
92
  ```ts
87
93
  createAnthropicProvider({
@@ -92,28 +98,30 @@ createAnthropicProvider({
92
98
 
93
99
  ## Data handling
94
100
 
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.
101
+ For each generation there is a single POST to
102
+ `https://api.anthropic.com/v1/messages`. You can set `baseUrl` to send this to
103
+ another host instead, like a proxy, a gateway or a region-specific endpoint you
104
+ have.
98
105
 
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.
106
+ What goes in that request is listed in the [`@rudra-js/core` README](https://github.com/clivedsouza1010/rudra-js/tree/main/packages/core#what-the-model-sees),
107
+ under **What the model sees**. You will need to read this before you send real
108
+ shopper traffic.
102
109
 
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`.
110
+ By default, shoppers who look alike share a single generated block, but each
111
+ shopper's products are filled in per request, except a hero's. This is cohort
112
+ mode. In per-shopper mode a block is generated for each shopper. Neither mode
113
+ sends `user.id`.
106
114
 
107
- A cohort-mode request can still be personal data. It carries:
115
+ Even a cohort-mode request can be personal data. It carries:
108
116
 
109
117
  - the name of the category that shopper leans towards most
110
118
  - whether they have any history
111
119
  - any `segment` you gave them, as you wrote it
112
- - the candidate products, which you may have picked or ordered just for them
120
+ - the candidate products (you may have picked or ordered these just for them)
113
121
 
114
122
  A per-shopper request also carries:
115
123
 
116
- - the product that shopper is looking at
124
+ - which product the shopper is looking at
117
125
  - their current and recent searches
118
126
  - whether they're returning
119
127
  - their likes, dislikes and purchases
@@ -122,35 +130,36 @@ A per-shopper request also carries:
122
130
  - the categories they lean towards
123
131
  - interaction counts
124
132
 
125
- If your shop is in the EU or the UK, or sells to shoppers there, you're the one
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
134
- doesn't change that.
135
-
136
- If you point `baseUrl` at a gateway or platform run by someone other than you or
137
- Anthropic, its operator sees every request and the `apiKey` you pass. If that's
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.
133
+ If your shop is in the EU or the UK or sells to shoppers there, you are the
134
+ sender of personal data. You need a data processing agreement (DPA) with whoever
135
+ receives this data. You will also need a transfer mechanism if the receiver is
136
+ outside the EU or the UK. This is true even if your shop is outside the EU and
137
+ the UK.
138
+
139
+ For calls to Anthropic with a key from your own Anthropic account, the receiver
140
+ is Anthropic. Its data processing addendum is part of its Commercial Terms. This
141
+ addendum makes Anthropic your processor and includes the transfer clauses. Your
142
+ shop is Anthropic's customer. This doesn't change if a proxy you run yourself
143
+ forwards to Anthropic.
144
+
145
+ If `baseUrl` points at a gateway or platform run by someone other than you or
146
+ Anthropic, its operator will see all requests and your `apiKey`. If that key is
147
+ from your own Anthropic account, Anthropic will still be your processor. You
148
+ will also need a DPA with the operator, because the operator is a second
149
+ processor. If the platform issued the key, Anthropic says the platform's terms
150
+ govern this use. In this case you're the platform's customer. It is the
151
+ platform's DPA that covers you.
143
152
 
144
153
  This package is a piece of code in the middle. It _isn't_ a party to anything.
145
154
 
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.
155
+ When the API answers with an error, the adapter will throw an `Error` with the
156
+ status code and Anthropic's error category, like
157
+ `anthropic responded 400 (invalid_request_error)`. It leaves out Anthropic's
158
+ error message, because that message quotes back a request that can hold a
159
+ shopper's search terms. If the adapter kept the message, those terms would be
160
+ written to a log by a `console.error(error)` in your app. There is a test for
161
+ this in `anthropic-provider.test.ts`. It puts a search term in the message to
162
+ check that the term doesn't reach the thrown error.
154
163
 
155
164
  ## Licence
156
165
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rudra-js/anthropic",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
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.9.0"
55
+ "@rudra-js/core": "^0.9.1"
56
56
  },
57
57
  "devDependencies": {
58
- "@rudra-js/core": "0.9.0",
58
+ "@rudra-js/core": "0.9.1",
59
59
  "@types/node": "^26.4.1"
60
60
  }
61
61
  }