@rayrun/sdk 0.2.1 → 0.3.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/README.md CHANGED
@@ -14,8 +14,28 @@ const { items: connections } = await rayrun.connections.list();
14
14
  Create keys in **Dashboard → Settings → API keys**. The plaintext is shown once.
15
15
 
16
16
  The client covers catalog search, connection and credential setup, OAuth links, indexing, tool and
17
- client policies, activity, review queues, and webhooks. Safe reads retry rate limits, server errors,
18
- and transient network failures; writes do not retry automatically.
17
+ client policies, reusable access profiles, activity, review queues, and webhooks. Safe reads retry
18
+ rate limits, server errors, and transient network failures; writes do not retry automatically.
19
+
20
+ ## Reuse one access ceiling across clients
21
+
22
+ ```js
23
+ const { profile } = await rayrun.accessProfiles.create({
24
+ name: 'Support agents',
25
+ description: 'Read by default; sensitive tools stay blocked.',
26
+ });
27
+
28
+ await rayrun.accessProfiles.setPolicy(profile.uid, 'read-only', profile.toolPolicyVersion);
29
+ await rayrun.accessProfiles.update(profile.uid, {
30
+ description: 'Read by default; sensitive tools stay blocked.',
31
+ expectedVersion: profile.toolPolicyVersion + 1,
32
+ name: 'Support agents',
33
+ });
34
+ await rayrun.clients.setAccessProfile(clientUid, profile.uid, clientToolPolicyVersion);
35
+ ```
36
+
37
+ The effective policy is always the intersection of the workspace, profile, and client rules. A
38
+ profile can narrow access but cannot grant something blocked by the workspace or client.
19
39
 
20
40
  ## Stream code run-ahead
21
41
 
@@ -75,7 +95,9 @@ After verification, parse the body as `WebhookPayload`. Every event has a stable
75
95
  `occurredAt`; its `data` shape is narrowed by `type`. Use `id` to deduplicate retries.
76
96
  For `activity.call`, `arguments` and `result` contain the captured tool payloads, or `null` when
77
97
  capture was disabled for that connection, the webhook did not opt in with
78
- `forwardToolPayloads: true`, or no result existed.
98
+ `forwardToolPayloads: true`, or no result existed. `payloadCaptured` distinguishes a metadata-only
99
+ webhook from a call where capture was disabled. Rayrun observes MCP tool arguments and results; it
100
+ does not receive the host's full Claude or GPT prompt, assistant response, or surrounding chat.
79
101
 
80
102
  ```ts
81
103
  import type { WebhookPayload } from '@rayrun/sdk';
package/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export type JsonValue =
10
10
  export type PageQuery = { cursor?: string; limit?: number };
11
11
  export type ToolDecision = 'allow' | 'ask' | 'block';
12
12
  export type ToolAccessMode = 'read-only' | 'ask-before-changes' | 'allow-all' | 'custom';
13
+ export type AccessProfileMode = 'read-only' | 'ask-before-changes' | 'allow-all' | 'block-all';
13
14
  export type Risk = 'read' | 'change' | 'destructive' | 'unknown';
14
15
  export type Connection = {
15
16
  authorizedAt: string | null;
@@ -24,6 +25,7 @@ export type Connection = {
24
25
  slug: string;
25
26
  status: 'connected' | 'disabled' | 'error' | 'indexing' | 'needs-authorization' | 'new';
26
27
  toolAccessMode: ToolAccessMode;
28
+ toolPolicyVersion: number;
27
29
  };
28
30
  export type CatalogEntry = {
29
31
  authType: Connection['authType'];
@@ -50,15 +52,33 @@ export type Tool = {
50
52
  title: string | null;
51
53
  };
52
54
  export type Client = {
55
+ accessProfile: Pick<AccessProfile, 'name' | 'uid'> | null;
53
56
  clientName: string;
54
57
  grantedAt: string;
55
58
  lastUsedAt: string | null;
56
59
  redirectHost: string;
57
60
  revokedAt: string | null;
58
61
  toolAccessMode: ToolAccessMode;
62
+ toolPolicyVersion: number;
59
63
  uid: string;
60
64
  userName: string;
61
65
  };
66
+ export type AccessProfile = {
67
+ assignedClientCount: number;
68
+ description: string;
69
+ name: string;
70
+ toolAccessMode: AccessProfileMode;
71
+ toolPolicyVersion: number;
72
+ uid: string;
73
+ };
74
+ export type AccessProfileTool = {
75
+ available: boolean;
76
+ decision: ToolDecision | null;
77
+ name: string;
78
+ riskLevel: Risk;
79
+ serviceName: string;
80
+ uid: string;
81
+ };
62
82
  export type Activity = {
63
83
  calledAt: string;
64
84
  clientName: string | null;
@@ -111,7 +131,17 @@ export type WebhookEvent =
111
131
  | 'review.changed'
112
132
  | 'tool.definition-changed'
113
133
  | 'tool.policy-changed';
114
- export type WebhookEnvelope<T extends Exclude<WebhookEvent, '*'>, D> = {
134
+ export type WebhookDeliveryEvent = Exclude<WebhookEvent, '*'> | 'webhook.test';
135
+ export type ToolPolicyEventType =
136
+ | 'access-profile-archived'
137
+ | 'access-profile-assigned'
138
+ | 'access-profile-changed'
139
+ | 'access-profile-created'
140
+ | 'client-mode-changed'
141
+ | 'client-tool-rule-changed'
142
+ | 'workspace-mode-changed'
143
+ | 'workspace-tool-rule-changed';
144
+ export type WebhookEnvelope<T extends WebhookDeliveryEvent, D> = {
115
145
  data: D;
116
146
  id: string;
117
147
  occurredAt: string;
@@ -124,12 +154,23 @@ export type WebhookPayload =
124
154
  activityId: string;
125
155
  arguments: JsonValue;
126
156
  calledAt: string;
157
+ clientUid: string | null;
127
158
  connectionUid: string | null;
128
159
  errorCode: string | null;
160
+ payloadCaptured: boolean;
129
161
  policyDecision: ToolDecision | null;
130
162
  result: JsonValue;
163
+ sessionUid: string;
131
164
  succeeded: boolean | null;
132
165
  toolName: string;
166
+ userUid: string | null;
167
+ }
168
+ >
169
+ | WebhookEnvelope<
170
+ 'webhook.test',
171
+ {
172
+ endpointUid: string;
173
+ message: string;
133
174
  }
134
175
  >
135
176
  | WebhookEnvelope<
@@ -169,7 +210,10 @@ export type WebhookPayload =
169
210
  {
170
211
  connectionUid: string | null;
171
212
  decision: ToolDecision | null;
172
- eventType: string;
213
+ eventType: ToolPolicyEventType;
214
+ metadata: Record<string, JsonValue>;
215
+ oauthClientConsentUid: string | null;
216
+ oauthClientName: string | null;
173
217
  toolUid: string | null;
174
218
  }
175
219
  >;
@@ -208,7 +252,7 @@ export class Rayrun {
208
252
  | { kind: 'openapi'; specificationUrl: string; baseUrl?: string; name?: string },
209
253
  ): Promise<{ connection: { uid: string } }>;
210
254
  createOAuthLink(uid: string): Promise<{ authorizationUrl: string }>;
211
- delete(uid: string): Promise<void>;
255
+ delete(uid: string, expectedVersion: number): Promise<void>;
212
256
  index(uid: string): Promise<{ enqueued: boolean }>;
213
257
  list(query?: PageQuery): Promise<CursorPage<Connection>>;
214
258
  setCredential(uid: string, body: Credential): Promise<{ enqueued: boolean }>;
@@ -228,6 +272,11 @@ export class Rayrun {
228
272
  };
229
273
  clients: {
230
274
  list(query?: PageQuery): Promise<CursorPage<Client>>;
275
+ setAccessProfile(
276
+ uid: string,
277
+ profileUid: string | null,
278
+ expectedVersion: number,
279
+ ): Promise<void>;
231
280
  setPolicy(uid: string, mode: Exclude<ToolAccessMode, 'custom'>): Promise<void>;
232
281
  setToolPolicy(
233
282
  uid: string,
@@ -235,6 +284,28 @@ export class Rayrun {
235
284
  body: { decision: ToolDecision | null; riskConfirmed?: boolean },
236
285
  ): Promise<void>;
237
286
  };
287
+ accessProfiles: {
288
+ archive(uid: string, expectedVersion: number): Promise<void>;
289
+ create(body: { description: string; name: string }): Promise<{ profile: AccessProfile }>;
290
+ /** @deprecated Use archive. */
291
+ delete(uid: string, expectedVersion: number): Promise<void>;
292
+ list(query?: PageQuery): Promise<CursorPage<AccessProfile>>;
293
+ listTools(uid: string, query?: PageQuery): Promise<CursorPage<AccessProfileTool>>;
294
+ setPolicy(uid: string, mode: AccessProfileMode, expectedVersion: number): Promise<void>;
295
+ setToolPolicy(
296
+ uid: string,
297
+ toolUid: string,
298
+ body: {
299
+ decision: ToolDecision | null;
300
+ expectedVersion: number;
301
+ riskConfirmed?: boolean;
302
+ },
303
+ ): Promise<void>;
304
+ update(
305
+ uid: string,
306
+ body: { description: string; expectedVersion: number; name: string },
307
+ ): Promise<void>;
308
+ };
238
309
  activity: { list(query?: PageQuery): Promise<CursorPage<Activity>> };
239
310
  reviews: { list(query?: PageQuery): Promise<CursorPage<Review>> };
240
311
  webhooks: {
package/index.js CHANGED
@@ -114,10 +114,30 @@ export class Rayrun {
114
114
  };
115
115
  this.clients = {
116
116
  list: (query) => this.request('GET', '/clients', { query }),
117
+ setAccessProfile: (uid, profileUid, expectedVersion) =>
118
+ this.request('PATCH', `/clients/${uid}/access-profile`, {
119
+ body: { expectedVersion, profileUid },
120
+ }),
117
121
  setPolicy: (uid, mode) => this.request('PATCH', `/clients/${uid}/policy`, { body: { mode } }),
118
122
  setToolPolicy: (uid, toolUid, body) =>
119
123
  this.request('PATCH', `/clients/${uid}/tools/${toolUid}/policy`, { body }),
120
124
  };
125
+ const archiveAccessProfile = (uid, expectedVersion) =>
126
+ this.request('DELETE', `/access-profiles/${uid}`, { query: { expectedVersion } });
127
+ this.accessProfiles = {
128
+ archive: archiveAccessProfile,
129
+ create: (body) => this.request('POST', '/access-profiles', { body }),
130
+ delete: archiveAccessProfile,
131
+ list: (query) => this.request('GET', '/access-profiles', { query }),
132
+ listTools: (uid, query) => this.request('GET', `/access-profiles/${uid}/tools`, { query }),
133
+ setPolicy: (uid, mode, expectedVersion) =>
134
+ this.request('PATCH', `/access-profiles/${uid}/policy`, {
135
+ body: { expectedVersion, mode },
136
+ }),
137
+ setToolPolicy: (uid, toolUid, body) =>
138
+ this.request('PATCH', `/access-profiles/${uid}/tools/${toolUid}/policy`, { body }),
139
+ update: (uid, body) => this.request('PATCH', `/access-profiles/${uid}`, { body }),
140
+ };
121
141
  this.activity = { list: (query) => this.request('GET', '/activity', { query }) };
122
142
  this.reviews = { list: (query) => this.request('GET', '/reviews', { query }) };
123
143
  this.webhooks = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayrun/sdk",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Type-safe client for the Rayrun public API",
5
5
  "license": "MIT",
6
6
  "repository": {