@recursiv/sdk 0.7.81 → 0.7.82

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/README.md CHANGED
@@ -98,7 +98,7 @@ for await (const chunk of r.agents.chatStream(agent.id, { message: 'Hello!' }))
98
98
  | `r.bookmarks` | `save`, `unsave`, `posts`, `list`, `keys`, `merge` — the member's saved posts, open-network posts and articles, synced across devices; `collections`: `list`, `create`, `update`, `remove`, `add`, `removeItem`, `items`, `posts` — private named collections of saves (0.7.68, where `network.getConfig()` advertises `capabilities.bookmark_collections`) |
99
99
  | `r.feeds` | `top` (what the member is most likely to engage with, rotated by what they saw, with open-network lanes and the lead story), `stories` (the story tail), `publicTop` (a visitor's top, keyless and edge-cacheable) |
100
100
  | `r.communities` | `create`, `join`, `search`, `members` |
101
- | `r.chat` | `send`, `dm`, `createGroup` (`encrypted: true` for an end-to-end encrypted group, 0.7.59), `messages` (cursor paging), `acceptRequest`, `declineRequest`, `leave`, `deleteConversation`; a private group's admin: `addMembers`, `removeMember`, `updateGroup` (0.7.59) |
101
+ | `r.chat` | `send`, `dm`, `createGroup` (`encrypted: true` for an end-to-end encrypted group, 0.7.59), `messages` (cursor paging), `acceptRequest`, `declineRequest`, `leave`, `deleteConversation`; a private group's admin: `addMembers`, `removeMember`, `updateGroup` (0.7.59); photos and voice notes: `uploadAttachment`, `signAttachments` (private chat storage, 0.7.82) |
102
102
  | `r.tags` | `create`, `list` |
103
103
  | `r.signals` | `batch` (up to 100 engagement signals, such as views, dwell and hides, for the member's own ranking; `keepalive` for a page-leave flush), `record` (one signal) (0.7.71) |
104
104
  | `r.curator` | `today` (World Today; a world story can carry `story_key` and `discussion`, its count across networks), `storyPosts` / `memberStoryPosts` (one page of a story's posts, keyless or under the member's key), `storyPostPages` (walk every page), `forYou`, `run`, `refreshIfStale`, `seedDeck` |
package/dist/index.d.ts CHANGED
@@ -165,7 +165,8 @@ export { POSTS_BATCH_MAX, PostsResource } from './resources/posts.js';
165
165
  export type { CategoryOrder, CategoryOrderMeta, CategoryOrderReason, PostBatch, PostBatchItem } from './resources/posts.js';
166
166
  export { UsersResource } from './resources/users.js';
167
167
  export { CommunitiesResource } from './resources/communities.js';
168
- export { ChatResource } from './resources/chat.js';
168
+ export { ChatResource, CHAT_ATTACHMENT_REF_PREFIX, chatAttachmentKeysIn, chatAttachmentRefsIn } from './resources/chat.js';
169
+ export type { ChatAttachmentRef, ChatAttachmentUploadInput, ChatAttachmentUploadUrl, ChatAttachmentUploadUrlInput, SignedChatAttachment, } from './resources/chat.js';
169
170
  export { E2eeResource } from './resources/e2ee.js';
170
171
  export type { E2eeAccountReset, E2eeDevice, E2eeDevicesRealtimeEvent, E2eeEnvelope, E2eeEvent, E2eeHasDependentsDetails, E2eeKeyPackageStatus, E2eeLink, E2eeLinkCancelledBy, E2eeLinkProgress, E2eeLinkRealtimeEvent, E2eeLinkState, E2eeObjectDownload, E2eeObjectUpload, E2eeRealtimeEvent, E2eeResetCodeSent, E2eeResetErrorCode, E2eeRevokeResponse, E2eeStartRequest, E2eeStatus, E2eeStatusReason, } from './resources/e2ee.js';
171
172
  export { ProjectsResource } from './resources/projects.js';
@@ -207,7 +208,7 @@ export type { AppSubscriptionBoostCredit, AppSubscriptionCheckoutResult, AppSubs
207
208
  export type { CuratorSource, CuratorPrompt, CuratorRunInput, CuratorRunResult, CuratorTodayEdition, CuratorTodayExcerpt, CuratorTodayLeadImage, CuratorTodayParams, CuratorTodayRadar, CuratorTodayReaction, CuratorTodayResponse, CuratorTodaySource, CuratorTodayStory, CuratorTodayDiscussion, CuratorStoryDiscussion, CuratorStoryLaneOutcome, CuratorStoryMindsPost, CuratorStoryPostItem, CuratorStoryPostPagesOptions, CuratorStoryPostsPage, CuratorStoryPostsParams, CuratorStoryReader, CuratorStorySocialPost, CuratorStoryVolumeLanes, CuratorStoryVolumeMeta, StoryPostNetwork, StoryPostPool, StoryPostSort, ForYouMeta, ForYouParams, ForYouSurface, ForYouWorldBlock, ForYouWorldBlockType, ForYouWorldCategoryShortcut, ForYouWorldItem, ForYouWorldMeta, ForYouWorldParams, ForYouWorldPart, ForYouWorldResponse, ForYouWorldStory, ForYouWorldStoryTarget, ForYouWorldViral, } from './resources/curator.js';
208
209
  export { STORY_POOL_MAX_POSTS, STORY_POST_NETWORKS, STORY_POSTS_PAGE_MAX } from './resources/curator.js';
209
210
  export { ReportsResource } from './resources/reports.js';
210
- export type { ReportTargetType, ReportStatus, CreateReportInput, ReportRecord, ResolveReportInput, } from './resources/reports.js';
211
+ export type { ReportTargetType, ReportStatus, CreateReportInput, ReportRecord, ResolveReportInput, ReportedMessageAttachment, ReportedMessageAttachments, } from './resources/reports.js';
211
212
  export { JudgmentsResource, isJudgmentSharedWordsError } from './resources/judgments.js';
212
213
  export type { JudgmentSubjectKind, JudgmentSource, JudgmentOverrideMethod, PostLabelsStatus, PostLabelsQuery, PostLabelsSubject, PostLabelsCategory, PostLabelsPolitics, PostJudgmentRecord, PostJudgment, PostSafetyAttribution, PostLabelsCategoryView, PostLabelsSummaryView, PostLabelsFullView, PostLabels, DisputeJudgmentInput, JudgmentDispute, ReviewJudgmentInput, JudgmentReviewUpheld, JudgmentReviewAwaitingReviewer, JudgmentReviewOverridden, JudgmentReview, JudgmentSharedWordsDetails, JudgmentSharedWordsError, } from './resources/judgments.js';
213
214
  export { ModerationResource } from './resources/moderation.js';
package/dist/index.js CHANGED
@@ -236,7 +236,7 @@ export { AuthResource } from './resources/auth.js';
236
236
  export { POSTS_BATCH_MAX, PostsResource } from './resources/posts.js';
237
237
  export { UsersResource } from './resources/users.js';
238
238
  export { CommunitiesResource } from './resources/communities.js';
239
- export { ChatResource } from './resources/chat.js';
239
+ export { ChatResource, CHAT_ATTACHMENT_REF_PREFIX, chatAttachmentKeysIn, chatAttachmentRefsIn } from './resources/chat.js';
240
240
  export { E2eeResource } from './resources/e2ee.js';
241
241
  export { ProjectsResource } from './resources/projects.js';
242
242
  export { AgentsResource, SUPPORTED_MODELS, AGENT_DIRECTORY_SORTS, AGENT_DIRECTORY_MAX_LIMIT } from './resources/agents.js';
@@ -116,7 +116,11 @@ export declare class ChatResource {
116
116
  type: string;
117
117
  };
118
118
  }>>;
119
- /** Edit a message (only the sender can edit) */
119
+ /**
120
+ * Edit a message's words (only the sender can edit). Keep each `chat-attachment:` reference it carries as it is: the
121
+ * server refuses an edit that drops, adds or swaps one (400 `attachment_refs_changed`, 0.7.82). To take an attachment
122
+ * back, delete the message.
123
+ */
120
124
  editMessage(messageId: string, input: {
121
125
  content: string;
122
126
  }): Promise<SingleResponse<Message>>;
@@ -130,4 +134,72 @@ export declare class ChatResource {
130
134
  unreadCount(conversationId: string): Promise<SingleResponse<{
131
135
  unread_count: number;
132
136
  }>>;
137
+ /**
138
+ * A PUT URL for one photo or voice note to send in a plaintext chat (0.7.82). With the server's private chat
139
+ * storage on, `private` is true, the URL writes into a private bucket and `ref` is `chat-attachment:<key>`, the text
140
+ * to send; with it off, `ref` is the upload's public URL. An end-to-end encrypted chat answers 409
141
+ * `conversation_encrypted`: its attachments go through `r.e2ee`. Most callers want `uploadAttachment`.
142
+ */
143
+ attachmentUploadUrl(conversationId: string, input: ChatAttachmentUploadUrlInput): Promise<SingleResponse<ChatAttachmentUploadUrl>>;
144
+ /**
145
+ * Upload one photo or voice note for a plaintext chat end to end and resolve the text to send for it (0.7.82): read
146
+ * the bytes, get the URL, PUT them with the matching Content-Type, and reject a failed transfer. Send `ref` as the
147
+ * message (or within it): a private reference renders through `signAttachments`, a public URL as before.
148
+ */
149
+ uploadAttachment(conversationId: string, input: ChatAttachmentUploadInput): Promise<ChatAttachmentUploadUrl>;
150
+ /**
151
+ * Short-lived URLs for a conversation's private attachments (0.7.82), at most 50 keys a call (the keys in its
152
+ * messages' `chat-attachment:` references; `chatAttachmentKeysIn` finds them). The server signs a key only for a
153
+ * member of the conversation, and only while a message its sender wrote there still carries it; any other key
154
+ * comes back with `url: null`. A URL works for about five minutes and is served `private, no-store`: ask again
155
+ * rather than keeping it.
156
+ */
157
+ signAttachments(conversationId: string, keys: string[]): Promise<SingleResponse<{
158
+ attachments: SignedChatAttachment[];
159
+ }>>;
160
+ }
161
+ export interface ChatAttachmentUploadUrlInput {
162
+ /** image/jpeg, image/png, image/webp, image/gif, audio/mpeg, audio/mp4, audio/wav, audio/ogg or audio/webm. */
163
+ content_type: string;
164
+ /** The exact byte count the PUT will send (signed into the URL; at most 50 MB). */
165
+ content_length: number;
166
+ }
167
+ export interface ChatAttachmentUploadUrl {
168
+ /** True when the attachment goes to the server's private chat storage. */
169
+ private: boolean;
170
+ /** PUT the bytes here with the same Content-Type. */
171
+ upload_url: string;
172
+ key: string;
173
+ /** The text to send for this attachment: `chat-attachment:<key>` when private, else the public URL. */
174
+ ref: string;
175
+ }
176
+ export interface ChatAttachmentUploadInput {
177
+ /** Caller-held bytes, such as a browser File or React Native Blob. */
178
+ blob?: Blob;
179
+ /** A local URI that the SDK should read into a Blob first. */
180
+ uri?: string;
181
+ /** Defaults to blob.type. */
182
+ contentType?: string;
183
+ /** Optional transport override for React Native adapters and focused tests. */
184
+ fetchImpl?: typeof fetch;
185
+ }
186
+ export interface SignedChatAttachment {
187
+ key: string;
188
+ /** A GET URL valid until `expires_at`, or null when this caller may not open the key. */
189
+ url: string | null;
190
+ expires_at: string | null;
191
+ }
192
+ /** The text a message carries before a private chat attachment's key. */
193
+ export declare const CHAT_ATTACHMENT_REF_PREFIX = "chat-attachment:";
194
+ /** One private attachment a message's text refers to. */
195
+ export interface ChatAttachmentRef {
196
+ /** The whole reference as it appears in the text (`chat-attachment:<key>`). */
197
+ ref: string;
198
+ /** The key to pass to `signAttachments`. */
199
+ key: string;
200
+ kind: 'image' | 'audio';
133
201
  }
202
+ /** The private attachments a message's text refers to, in order, each once (0.7.82). */
203
+ export declare function chatAttachmentRefsIn(content: string | null | undefined): ChatAttachmentRef[];
204
+ /** The private attachment keys a message's text refers to, for `signAttachments` (0.7.82). */
205
+ export declare function chatAttachmentKeysIn(content: string | null | undefined): string[];
@@ -1,3 +1,4 @@
1
+ import { RecursivError } from '../errors.js';
1
2
  export class ChatResource {
2
3
  client;
3
4
  constructor(client) {
@@ -127,7 +128,11 @@ export class ChatResource {
127
128
  reactToMessage(messageId, input) {
128
129
  return this.client.post(`/chat/messages/${messageId}/react`, input);
129
130
  }
130
- /** Edit a message (only the sender can edit) */
131
+ /**
132
+ * Edit a message's words (only the sender can edit). Keep each `chat-attachment:` reference it carries as it is: the
133
+ * server refuses an edit that drops, adds or swaps one (400 `attachment_refs_changed`, 0.7.82). To take an attachment
134
+ * back, delete the message.
135
+ */
131
136
  editMessage(messageId, input) {
132
137
  return this.client.put(`/chat/messages/${messageId}`, input);
133
138
  }
@@ -143,4 +148,81 @@ export class ChatResource {
143
148
  unreadCount(conversationId) {
144
149
  return this.client.get('/chat/unread-count', { conversation_id: conversationId });
145
150
  }
151
+ /**
152
+ * A PUT URL for one photo or voice note to send in a plaintext chat (0.7.82). With the server's private chat
153
+ * storage on, `private` is true, the URL writes into a private bucket and `ref` is `chat-attachment:<key>`, the text
154
+ * to send; with it off, `ref` is the upload's public URL. An end-to-end encrypted chat answers 409
155
+ * `conversation_encrypted`: its attachments go through `r.e2ee`. Most callers want `uploadAttachment`.
156
+ */
157
+ attachmentUploadUrl(conversationId, input) {
158
+ return this.client.post(`/chat/conversations/${conversationId}/attachments/upload-url`, input);
159
+ }
160
+ /**
161
+ * Upload one photo or voice note for a plaintext chat end to end and resolve the text to send for it (0.7.82): read
162
+ * the bytes, get the URL, PUT them with the matching Content-Type, and reject a failed transfer. Send `ref` as the
163
+ * message (or within it): a private reference renders through `signAttachments`, a public URL as before.
164
+ */
165
+ async uploadAttachment(conversationId, input) {
166
+ const hasBlob = input.blob !== undefined;
167
+ const hasUri = typeof input.uri === 'string' && input.uri.length > 0;
168
+ if (hasBlob === hasUri)
169
+ throw attachmentError(0, 'Provide exactly one of blob or uri.', 'invalid_upload_source');
170
+ const doFetch = input.fetchImpl ?? fetch;
171
+ let blob = input.blob;
172
+ if (!blob && input.uri) {
173
+ const source = await doFetch(input.uri);
174
+ if (!source.ok)
175
+ throw attachmentError(source.status, `Could not read upload source (HTTP ${source.status}).`, 'upload_source_failed');
176
+ blob = await source.blob();
177
+ }
178
+ if (!blob)
179
+ throw attachmentError(0, 'Upload source did not produce any bytes.', 'empty_upload_source');
180
+ const contentType = input.contentType?.trim() || blob.type?.trim();
181
+ if (!contentType)
182
+ throw attachmentError(0, 'A content type is required for chat attachments.', 'missing_content_type');
183
+ const minted = await this.attachmentUploadUrl(conversationId, { content_type: contentType, content_length: blob.size });
184
+ if (!minted?.data?.upload_url || !minted.data.ref) {
185
+ throw attachmentError(0, 'The API did not return a chat attachment upload URL.', 'missing_upload_url');
186
+ }
187
+ const response = await doFetch(minted.data.upload_url, { method: 'PUT', body: blob, headers: { 'Content-Type': contentType } });
188
+ if (!response.ok)
189
+ throw attachmentError(response.status, `Chat attachment upload failed (HTTP ${response.status}).`, 'chat_attachment_upload_failed');
190
+ return minted.data;
191
+ }
192
+ /**
193
+ * Short-lived URLs for a conversation's private attachments (0.7.82), at most 50 keys a call (the keys in its
194
+ * messages' `chat-attachment:` references; `chatAttachmentKeysIn` finds them). The server signs a key only for a
195
+ * member of the conversation, and only while a message its sender wrote there still carries it; any other key
196
+ * comes back with `url: null`. A URL works for about five minutes and is served `private, no-store`: ask again
197
+ * rather than keeping it.
198
+ */
199
+ signAttachments(conversationId, keys) {
200
+ return this.client.post(`/chat/conversations/${conversationId}/attachments/sign`, { keys });
201
+ }
202
+ }
203
+ function attachmentError(status, message, code) {
204
+ return new RecursivError(status, { type: 'upload_error', message, code });
205
+ }
206
+ /** The text a message carries before a private chat attachment's key. */
207
+ export const CHAT_ATTACHMENT_REF_PREFIX = 'chat-attachment:';
208
+ const CHAT_ATTACHMENT_REF_RE = /chat-attachment:(chat\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.([a-z0-9]{2,5}))/g;
209
+ /** The extensions the server mints a private attachment key with (and jpeg), as it parses one; anything else is text. */
210
+ const IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'webp', 'gif']);
211
+ const AUDIO_EXTENSIONS = new Set(['mp3', 'm4a', 'wav', 'ogg', 'weba']);
212
+ /** The private attachments a message's text refers to, in order, each once (0.7.82). */
213
+ export function chatAttachmentRefsIn(content) {
214
+ if (!content?.includes(CHAT_ATTACHMENT_REF_PREFIX))
215
+ return [];
216
+ const found = new Map();
217
+ for (const match of content.matchAll(CHAT_ATTACHMENT_REF_RE)) {
218
+ const extension = match[2];
219
+ const kind = AUDIO_EXTENSIONS.has(extension) ? 'audio' : IMAGE_EXTENSIONS.has(extension) ? 'image' : null;
220
+ if (kind && !found.has(match[1]))
221
+ found.set(match[1], { ref: match[0], key: match[1], kind });
222
+ }
223
+ return [...found.values()];
224
+ }
225
+ /** The private attachment keys a message's text refers to, for `signAttachments` (0.7.82). */
226
+ export function chatAttachmentKeysIn(content) {
227
+ return chatAttachmentRefsIn(content).map((attachment) => attachment.key);
146
228
  }
@@ -11,10 +11,16 @@ interface NetworkConfig {
11
11
  * `bookmark_collections` (0.7.68; absent on older servers): this server serves bookmark collections
12
12
  * (`bookmarks.collections`). Show collections only when it is true, and still treat a 503
13
13
  * `lists_unavailable` as off.
14
+ *
15
+ * `child_safety_report_category` (absent on older servers): this server files the child-safety report category's
16
+ * sub-types (`child_safety:minor_in_danger`, `:sexualised_minor`, `:grooming_enticement`, `:trafficking`) as
17
+ * urgent: top severity, an immediate staff alert, decided by a person. Offer them only when it is true; otherwise
18
+ * report child sexual abuse material as `csam`, which every server files as urgent.
14
19
  */
15
20
  capabilities: {
16
21
  ws_token: boolean;
17
22
  bookmark_collections?: boolean;
23
+ child_safety_report_category?: boolean;
18
24
  };
19
25
  auth_methods: string;
20
26
  default_template_name: string | null;
@@ -57,4 +57,28 @@ export declare class ReportsResource {
57
57
  dismiss(reportId: string): Promise<SingleResponse<{
58
58
  success: true;
59
59
  }>>;
60
+ /**
61
+ * Short-lived URLs for the private chat photos and voice notes a reported message carries (0.7.82), for the staff
62
+ * person reviewing the report. A live admin's own key only: an AI account or an agent key gets 403
63
+ * `human_required`. Only the reported message's own attachments are signed; each URL works for about five minutes
64
+ * and is served `private, no-store`, so ask again rather than keeping it. A report of anything but a message is
65
+ * 400 `not_a_message_report`. Only a recipient's report opens anything: a report you filed yourself is 403
66
+ * `own_report`, and one not filed by a person in that chat (other than the message's sender) is 403
67
+ * `reporter_not_a_recipient`.
68
+ */
69
+ signAttachments(reportId: string): Promise<SingleResponse<ReportedMessageAttachments>>;
70
+ }
71
+ export interface ReportedMessageAttachment {
72
+ key: string;
73
+ kind: 'image' | 'audio';
74
+ content_type: string;
75
+ /** A GET URL valid until `expires_at`. */
76
+ url: string;
77
+ expires_at: string;
78
+ }
79
+ export interface ReportedMessageAttachments {
80
+ report_id: string;
81
+ message_id: string;
82
+ conversation_id: string;
83
+ attachments: ReportedMessageAttachment[];
60
84
  }
@@ -27,4 +27,16 @@ export class ReportsResource {
27
27
  dismiss(reportId) {
28
28
  return this.client.post(`/reports/${encodeURIComponent(reportId)}/dismiss`);
29
29
  }
30
+ /**
31
+ * Short-lived URLs for the private chat photos and voice notes a reported message carries (0.7.82), for the staff
32
+ * person reviewing the report. A live admin's own key only: an AI account or an agent key gets 403
33
+ * `human_required`. Only the reported message's own attachments are signed; each URL works for about five minutes
34
+ * and is served `private, no-store`, so ask again rather than keeping it. A report of anything but a message is
35
+ * 400 `not_a_message_report`. Only a recipient's report opens anything: a report you filed yourself is 403
36
+ * `own_report`, and one not filed by a person in that chat (other than the message's sender) is 403
37
+ * `reporter_not_a_recipient`.
38
+ */
39
+ signAttachments(reportId) {
40
+ return this.client.post(`/reports/${encodeURIComponent(reportId)}/attachments/sign`);
41
+ }
30
42
  }
package/llm.md CHANGED
@@ -504,7 +504,9 @@ const { data: group } = await r.chat.createGroup({ name: 'Team', member_ids: ['u
504
504
  const { data: msgs } = await r.chat.messages(dm.id, { limit: 50 })
505
505
  ```
506
506
 
507
- Methods: `conversations`, `communityConversation`, `conversation`, `messages`, `send`, `dm`, `createGroup`, `addMembers`, `removeMember`, `updateGroup`, `deleteConversation`, `leave`, `acceptRequest`, `declineRequest`, `reactToMessage`, `editMessage`, `deleteMessage`, `markAsRead`, `unreadCount`
507
+ Methods: `conversations`, `communityConversation`, `conversation`, `messages`, `send`, `dm`, `createGroup`, `addMembers`, `removeMember`, `updateGroup`, `deleteConversation`, `leave`, `acceptRequest`, `declineRequest`, `reactToMessage`, `editMessage`, `deleteMessage`, `markAsRead`, `unreadCount`, `attachmentUploadUrl`, `uploadAttachment`, `signAttachments`
508
+
509
+ Chat photos and voice notes (0.7.82): `const { ref } = await r.chat.uploadAttachment(dm.id, { blob })`, then send `ref`. With the server's private chat storage on, `ref` is `chat-attachment:<key>`: render it with `(await r.chat.signAttachments(dm.id, chatAttachmentKeysIn(message.content))).data.attachments` (URLs live about five minutes, `private, no-store`; `url: null` for a key the caller may not open). `editMessage` changes a message's words only: an edit that drops, adds or swaps a `chat-attachment:` reference gets 400 `attachment_refs_changed` (delete the message instead). Otherwise `ref` is a public URL, as before. A group's chat tied to a community always gets a public URL. Staff reviewing a member's report of a message open its private attachments with `r.reports.signAttachments(reportId)` (a live admin's own key; an AI account or agent key gets 403 `human_required`; only a report filed by a person in that chat, other than the sender and the caller, opens anything: 403 `own_report` or `reporter_not_a_recipient` otherwise).
508
510
 
509
511
  Scroll back with `messages(id, { cursor: page.meta.next_cursor })`, not a growing `offset`. Conversations carry `can_delete` / `can_leave`; check them before offering Delete or Leave.
510
512
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@recursiv/sdk",
3
- "version": "0.7.81",
3
+ "version": "0.7.82",
4
4
  "description": "TypeScript SDK for the Recursiv API",
5
5
  "license": "FSL-1.1-ALv2",
6
6
  "type": "module",