@orchestration-ai/sdk 0.2.0 → 0.3.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.
- package/README.md +280 -208
- package/dist/cjs/app-builder.d.ts +39 -0
- package/dist/cjs/app-builder.d.ts.map +1 -0
- package/dist/cjs/app-builder.js +589 -0
- package/dist/cjs/app-builder.js.map +1 -0
- package/dist/cjs/services.d.ts +33 -0
- package/dist/cjs/services.d.ts.map +1 -0
- package/dist/cjs/services.js +121 -0
- package/dist/cjs/services.js.map +1 -0
- package/dist/cjs/shared-types.d.ts +66 -0
- package/dist/cjs/shared-types.d.ts.map +1 -0
- package/dist/cjs/shared-types.js +30 -0
- package/dist/cjs/shared-types.js.map +1 -0
- package/dist/cjs/types.gen.d.ts +28 -0
- package/dist/cjs/types.gen.d.ts.map +1 -1
- package/dist/esm/app-builder.d.ts +39 -0
- package/dist/esm/app-builder.d.ts.map +1 -0
- package/dist/esm/app-builder.js +547 -0
- package/dist/esm/app-builder.js.map +1 -0
- package/dist/esm/services.d.ts +33 -0
- package/dist/esm/services.d.ts.map +1 -0
- package/dist/esm/services.js +104 -0
- package/dist/esm/services.js.map +1 -0
- package/dist/esm/shared-types.d.ts +66 -0
- package/dist/esm/shared-types.d.ts.map +1 -0
- package/dist/esm/shared-types.js +25 -0
- package/dist/esm/shared-types.js.map +1 -0
- package/dist/esm/types.gen.d.ts +28 -0
- package/dist/esm/types.gen.d.ts.map +1 -1
- package/package.json +35 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @orchestration-ai/sdk
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for [Orchestration AI](https://orchestration-ai.com)
|
|
3
|
+
TypeScript SDK for [Orchestration AI](https://orchestration-ai.com) - The Operating System for AI-Powered Businesses.
|
|
4
4
|
|
|
5
5
|
Works in both **Node.js** and the **browser** using the same package.
|
|
6
6
|
|
|
@@ -10,307 +10,379 @@ Works in both **Node.js** and the **browser** using the same package.
|
|
|
10
10
|
npm install @orchestration-ai/sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Building Applications
|
|
14
14
|
|
|
15
|
-
The SDK
|
|
15
|
+
The SDK provides everything you need to build Orchestration AI applications that expose services and tools to agents.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
import { client } from '@orchestration-ai/sdk/client.gen';
|
|
19
|
-
import { workspaceFind } from '@orchestration-ai/sdk/sdk.gen';
|
|
17
|
+
### Quick Start - Define an Application
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
```typescript
|
|
20
|
+
import { createApp, defineService } from '@orchestration-ai/sdk/app-builder';
|
|
21
|
+
|
|
22
|
+
createApp()
|
|
23
|
+
.permissions([
|
|
24
|
+
{ permission_name: "role_agent_reader", justification: "Read agent context." },
|
|
25
|
+
{ permission_name: "role_agent_writer", justification: "Register endpoints." },
|
|
26
|
+
])
|
|
27
|
+
.service(defineService({
|
|
28
|
+
unique_name: "my-service",
|
|
29
|
+
service_name: "My Service",
|
|
30
|
+
service_description: "Does useful things for agents.",
|
|
31
|
+
defaultSettings: [
|
|
32
|
+
{ setting_name: "API_KEY", setting_description: "External API key", setting_type: "Secret", text_value: "" },
|
|
33
|
+
],
|
|
34
|
+
description: [
|
|
35
|
+
{
|
|
36
|
+
path: "do_thing",
|
|
37
|
+
method: "POST",
|
|
38
|
+
description: "Performs an action.",
|
|
39
|
+
parameters: {
|
|
40
|
+
input: { type: "string", optional: false, description: "The input value." },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
tools: {
|
|
45
|
+
do_thing: async (body, context, engineClient, apiClient) => {
|
|
46
|
+
// body is the request payload
|
|
47
|
+
// context contains the agent identity
|
|
48
|
+
// engineClient is for engine calls (sendMessages, getContext)
|
|
49
|
+
// apiClient is for API calls (settingFindByAgent, endpointCreate, etc.)
|
|
50
|
+
return { result: `Processed: ${body.input}` };
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
}))
|
|
54
|
+
.listen(3001);
|
|
23
55
|
```
|
|
24
56
|
|
|
25
|
-
|
|
57
|
+
Visit `http://localhost:3001/explore` to see your services and test tools interactively.
|
|
26
58
|
|
|
27
|
-
###
|
|
59
|
+
### Application Structure
|
|
60
|
+
|
|
61
|
+
An application consists of:
|
|
62
|
+
|
|
63
|
+
- **Permissions** - Roles the app requires (granted on installation)
|
|
64
|
+
- **Services** - Each service exposes tools that agents can call
|
|
65
|
+
|
|
66
|
+
### Service Definition
|
|
67
|
+
|
|
68
|
+
Each service has:
|
|
28
69
|
|
|
29
|
-
|
|
70
|
+
| Field | Description |
|
|
71
|
+
|-------|-------------|
|
|
72
|
+
| `unique_name` | URL-safe identifier |
|
|
73
|
+
| `service_name` | Human-readable name |
|
|
74
|
+
| `service_description` | What the service does |
|
|
75
|
+
| `defaultSettings` | Settings created when the service is installed |
|
|
76
|
+
| `description` | Static array or dynamic function returning tool descriptions |
|
|
77
|
+
| `touch` | Called when the service's context may have changed |
|
|
78
|
+
| `tools` | Handler functions for each tool |
|
|
79
|
+
|
|
80
|
+
### Handler Signatures
|
|
81
|
+
|
|
82
|
+
All handlers receive the engine client and API client:
|
|
30
83
|
|
|
31
84
|
```typescript
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
import { workspaceFind } from '@orchestration-ai/sdk/sdk.gen';
|
|
85
|
+
// Tool handler
|
|
86
|
+
(body: any, context: Context, engineClient: Client, apiClient: Client) => unknown | Promise<unknown>
|
|
35
87
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
client_id: 'your-client-id',
|
|
39
|
-
client_secret: 'your-client-secret',
|
|
40
|
-
scope: 'role_admin', // any supported role as scope
|
|
41
|
-
});
|
|
88
|
+
// Touch handler
|
|
89
|
+
(context: Context, engineClient: Client, apiClient: Client) => void | Promise<void>
|
|
42
90
|
|
|
43
|
-
//
|
|
44
|
-
|
|
91
|
+
// Description handler (dynamic)
|
|
92
|
+
(context: Context, engineClient: Client, apiClient: Client) => ServiceDescription | Promise<ServiceDescription>
|
|
45
93
|
```
|
|
46
94
|
|
|
47
|
-
|
|
48
|
-
- Automatically obtain an access token via `client_credentials` on the first request
|
|
49
|
-
- Re-fetch the token when it expires (with a 30s buffer)
|
|
50
|
-
- Retry once on 401 responses with a fresh token
|
|
51
|
-
- Deduplicate concurrent token requests
|
|
95
|
+
### Two Clients
|
|
52
96
|
|
|
53
|
-
The
|
|
97
|
+
The app-builder provides two pre-configured clients to every handler:
|
|
54
98
|
|
|
55
|
-
|
|
99
|
+
| Client | Purpose | Auth |
|
|
100
|
+
|--------|---------|------|
|
|
101
|
+
| `engineClient` | Internal engine calls (`sendMessages`, `getContext`) | Bearer access key |
|
|
102
|
+
| `apiClient` | Public API calls (`settingFindByAgent`, `endpointCreate`, `linkCreate`) | OAuth client_credentials |
|
|
103
|
+
|
|
104
|
+
### Static vs Dynamic Descriptions
|
|
56
105
|
|
|
57
|
-
|
|
106
|
+
**Static** - TypeScript enforces that `tools` keys match the `path` values in `description`:
|
|
58
107
|
|
|
59
108
|
```typescript
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
import { defineService } from '@orchestration-ai/sdk/app-builder';
|
|
110
|
+
|
|
111
|
+
export const myService = defineService({
|
|
112
|
+
unique_name: "calculator",
|
|
113
|
+
service_name: "Calculator",
|
|
114
|
+
service_description: "Math operations.",
|
|
115
|
+
description: [
|
|
116
|
+
{ path: "add", method: "POST", description: "Adds two numbers.", parameters: { a: { type: "number", optional: false, description: "First number" }, b: { type: "number", optional: false, description: "Second number" } } },
|
|
117
|
+
],
|
|
118
|
+
tools: {
|
|
119
|
+
add: (body) => ({ result: body.a + body.b }),
|
|
120
|
+
// TypeScript error if you add a tool not in description, or miss one
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Dynamic** - When the description depends on context/settings:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { defineServiceWithDynamicDescription } from '@orchestration-ai/sdk/app-builder';
|
|
129
|
+
|
|
130
|
+
export const myService = defineServiceWithDynamicDescription({
|
|
131
|
+
unique_name: "conditional",
|
|
132
|
+
service_name: "Conditional Service",
|
|
133
|
+
service_description: "Tools depend on settings.",
|
|
134
|
+
description: async (context, engineClient, apiClient) => {
|
|
135
|
+
const { data } = await settingFindByAgent({ client: apiClient, path: { ... } });
|
|
136
|
+
// Return different tools based on settings
|
|
137
|
+
return [...];
|
|
138
|
+
},
|
|
139
|
+
tools: {
|
|
140
|
+
tool_a: (body, context) => { ... },
|
|
141
|
+
tool_b: (body, context) => { ... },
|
|
79
142
|
},
|
|
80
143
|
});
|
|
81
144
|
```
|
|
82
145
|
|
|
83
|
-
|
|
146
|
+
### Touch Handler
|
|
84
147
|
|
|
85
|
-
|
|
148
|
+
Called by the engine when a service's context may have changed. Use it to register endpoints or links:
|
|
86
149
|
|
|
87
150
|
```typescript
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
151
|
+
touch: async (context, engineClient, apiClient) => {
|
|
152
|
+
await endpointCreate({
|
|
153
|
+
client: apiClient,
|
|
154
|
+
path: {
|
|
155
|
+
workspaceId: context.identity.workspaceId,
|
|
156
|
+
orchestrationId: context.identity.orchestrationId,
|
|
157
|
+
agentId: context.identity.agentId,
|
|
158
|
+
},
|
|
159
|
+
body: {
|
|
160
|
+
description: "Webhook for receiving events.",
|
|
161
|
+
endpoint: `https://my-app.com/webhook/${context.identity.layerId}`,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
97
164
|
}
|
|
98
165
|
```
|
|
99
166
|
|
|
100
|
-
|
|
167
|
+
### Settings
|
|
101
168
|
|
|
102
|
-
|
|
169
|
+
Three types of settings:
|
|
170
|
+
|
|
171
|
+
| Type | Use Case |
|
|
172
|
+
|------|----------|
|
|
173
|
+
| `Text` | General configuration values |
|
|
174
|
+
| `Boolean` | Feature flags, toggles |
|
|
175
|
+
| `Secret` | API keys, passwords (treated securely by the engine) |
|
|
103
176
|
|
|
104
|
-
|
|
177
|
+
Utility functions for reading settings:
|
|
105
178
|
|
|
106
179
|
```typescript
|
|
107
|
-
import {
|
|
180
|
+
import { getBooleanSetting, getTextSetting, getSecretSetting } from '@orchestration-ai/sdk/services';
|
|
108
181
|
|
|
109
|
-
const
|
|
182
|
+
const enabled = getBooleanSetting(settings, "FEATURE_ENABLED");
|
|
183
|
+
const host = getTextSetting(settings, "SMTP_HOST");
|
|
184
|
+
const apiKey = getSecretSetting(settings, "API_KEY");
|
|
185
|
+
```
|
|
110
186
|
|
|
111
|
-
|
|
112
|
-
// Send the code to your backend to exchange for tokens securely
|
|
113
|
-
// IMPORTANT: pass the same redirect_uri used in initiateLogin
|
|
114
|
-
const tokens = await fetch('/api/auth/exchange', {
|
|
115
|
-
method: 'POST',
|
|
116
|
-
body: JSON.stringify({
|
|
117
|
-
code: result.code,
|
|
118
|
-
redirect_uri: 'https://your-app.com/callback',
|
|
119
|
-
}),
|
|
120
|
-
}).then(r => r.json());
|
|
187
|
+
### Sending Messages to Agents
|
|
121
188
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
189
|
+
Use the engine client to send messages:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { sendMessages } from '@orchestration-ai/sdk/services';
|
|
193
|
+
|
|
194
|
+
const response = await sendMessages(
|
|
195
|
+
agentId,
|
|
196
|
+
layerIndex,
|
|
197
|
+
[{ message: "Hello from my service" }],
|
|
198
|
+
context.identity.layerId,
|
|
199
|
+
engineClient
|
|
200
|
+
);
|
|
127
201
|
```
|
|
128
202
|
|
|
129
|
-
|
|
203
|
+
### Getting Agent Context
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import { getContext } from '@orchestration-ai/sdk/services';
|
|
207
|
+
|
|
208
|
+
const context = await getContext(layerId, engineClient);
|
|
209
|
+
// context.identity.agentId, .layerId, .orchestrationId, .workspaceId, etc.
|
|
210
|
+
```
|
|
130
211
|
|
|
131
|
-
|
|
212
|
+
### Custom Endpoints
|
|
132
213
|
|
|
133
|
-
|
|
214
|
+
Access the underlying Express app and HTTP server for custom routes or WebSockets:
|
|
134
215
|
|
|
135
216
|
```typescript
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
217
|
+
const app = createApp().service(myService);
|
|
218
|
+
|
|
219
|
+
// Custom route
|
|
220
|
+
app.expressApp.post("/custom/:id", (req, res) => { ... });
|
|
221
|
+
|
|
222
|
+
// WebSocket
|
|
223
|
+
import { Server } from "socket.io";
|
|
224
|
+
const io = new Server(app.httpServer, { path: "/ws" });
|
|
225
|
+
io.on("connection", (socket) => { ... });
|
|
226
|
+
|
|
227
|
+
app.listen(3001);
|
|
146
228
|
```
|
|
147
229
|
|
|
148
|
-
|
|
230
|
+
### Explore Page
|
|
149
231
|
|
|
150
|
-
|
|
151
|
-
import { logout } from '@orchestration-ai/sdk/oauth-utils';
|
|
232
|
+
The `/explore` endpoint renders an interactive page showing all services, tools, and permissions. You can test tools directly from the browser.
|
|
152
233
|
|
|
153
|
-
|
|
234
|
+
Disable in production:
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
createApp({ explore: false }).service(...).listen(3001);
|
|
154
238
|
```
|
|
155
239
|
|
|
156
|
-
##
|
|
240
|
+
## Client Factories
|
|
241
|
+
|
|
242
|
+
### createEngineClient
|
|
157
243
|
|
|
158
|
-
|
|
244
|
+
For calling engine internal endpoints:
|
|
159
245
|
|
|
160
246
|
```typescript
|
|
161
|
-
import {
|
|
247
|
+
import { createEngineClient } from '@orchestration-ai/sdk/services';
|
|
162
248
|
|
|
163
|
-
//
|
|
164
|
-
const
|
|
249
|
+
// Production (default URL)
|
|
250
|
+
const client = createEngineClient(accessKey);
|
|
165
251
|
|
|
166
|
-
//
|
|
167
|
-
const
|
|
168
|
-
body: { workspace_name: 'My Workspace' },
|
|
169
|
-
});
|
|
252
|
+
// Custom URL
|
|
253
|
+
const client = createEngineClient("https://my-engine.com", accessKey);
|
|
170
254
|
|
|
171
|
-
//
|
|
172
|
-
const
|
|
255
|
+
// Nullable URL (falls back to production)
|
|
256
|
+
const client = createEngineClient(process.env.ENGINE_URL ?? null, accessKey);
|
|
173
257
|
```
|
|
174
258
|
|
|
175
|
-
###
|
|
259
|
+
### createApplicationClient
|
|
260
|
+
|
|
261
|
+
For calling another OAI application's services:
|
|
176
262
|
|
|
177
263
|
```typescript
|
|
178
|
-
import {
|
|
179
|
-
orchestrationFindByWorkspace,
|
|
180
|
-
orchestrationCreate,
|
|
181
|
-
} from '@orchestration-ai/sdk/sdk.gen';
|
|
182
|
-
|
|
183
|
-
// List orchestrations in a workspace
|
|
184
|
-
const { data } = await orchestrationFindByWorkspace({
|
|
185
|
-
path: { workspaceId: 'workspace-id' },
|
|
186
|
-
});
|
|
264
|
+
import { createApplicationClient, listServices, callServiceTool } from '@orchestration-ai/sdk/services';
|
|
187
265
|
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
body: {
|
|
192
|
-
orchestration_name: 'My Orchestration',
|
|
193
|
-
orchestration_description: 'Handles customer support',
|
|
194
|
-
},
|
|
195
|
-
});
|
|
266
|
+
const client = createApplicationClient(application, layerId);
|
|
267
|
+
const services = await listServices(client);
|
|
268
|
+
const result = await callServiceTool("service-name", "tool-path", client, { body: { key: "value" } });
|
|
196
269
|
```
|
|
197
270
|
|
|
198
|
-
###
|
|
271
|
+
### createApiClient
|
|
272
|
+
|
|
273
|
+
For making authenticated API calls with OAuth:
|
|
199
274
|
|
|
200
275
|
```typescript
|
|
201
|
-
import {
|
|
276
|
+
import { createApiClient } from '@orchestration-ai/sdk/services';
|
|
277
|
+
import { setupClientCredentials } from '@orchestration-ai/sdk/oauth-utils';
|
|
202
278
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
279
|
+
const apiClient = createApiClient();
|
|
280
|
+
setupClientCredentials(apiClient, {
|
|
281
|
+
client_id: accessKey,
|
|
282
|
+
client_secret: `${accessKey}:${workspaceOwnerId}`,
|
|
206
283
|
});
|
|
207
284
|
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
285
|
+
// Now use with sdk.gen functions
|
|
286
|
+
await settingFindByAgent({ client: apiClient, path: { ... } });
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Authentication
|
|
290
|
+
|
|
291
|
+
### Node.js (Server-Side)
|
|
292
|
+
|
|
293
|
+
For server-to-server authentication, use the **client_credentials** OAuth flow:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { client } from '@orchestration-ai/sdk/client.gen';
|
|
297
|
+
import { setupClientCredentials } from '@orchestration-ai/sdk/oauth-utils';
|
|
298
|
+
|
|
299
|
+
setupClientCredentials(client, {
|
|
300
|
+
client_id: 'your-client-id',
|
|
301
|
+
client_secret: 'your-client-secret',
|
|
302
|
+
scope: 'role_admin',
|
|
215
303
|
});
|
|
216
304
|
```
|
|
217
305
|
|
|
218
|
-
|
|
306
|
+
The SDK automatically obtains and refreshes tokens.
|
|
307
|
+
|
|
308
|
+
### Browser (Client-Side)
|
|
219
309
|
|
|
220
310
|
```typescript
|
|
221
|
-
import {
|
|
311
|
+
import { client } from '@orchestration-ai/sdk/client.gen';
|
|
312
|
+
import { setupBrowserAuth, initiateLogin, parseLoginRedirect, saveLogin, logout } from '@orchestration-ai/sdk/oauth-utils';
|
|
313
|
+
|
|
314
|
+
setupBrowserAuth(client, {
|
|
315
|
+
onRefreshToken: async () => {
|
|
316
|
+
const response = await fetch('/api/auth/refresh');
|
|
317
|
+
return response.ok ? response.json() : null;
|
|
318
|
+
},
|
|
319
|
+
});
|
|
222
320
|
|
|
223
|
-
|
|
321
|
+
// Initiate login
|
|
322
|
+
initiateLogin(client.getConfig().baseURL, {
|
|
323
|
+
client_id: 'your-client-id',
|
|
324
|
+
redirect_uri: 'https://your-app.com/callback',
|
|
325
|
+
});
|
|
224
326
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
327
|
+
// Handle callback
|
|
328
|
+
const result = parseLoginRedirect();
|
|
329
|
+
if (result.granted) {
|
|
330
|
+
const tokens = await fetch('/api/auth/exchange', {
|
|
331
|
+
method: 'POST',
|
|
332
|
+
body: JSON.stringify({ code: result.code, redirect_uri: '...' }),
|
|
333
|
+
}).then(r => r.json());
|
|
334
|
+
saveLogin(tokens);
|
|
229
335
|
}
|
|
230
336
|
```
|
|
231
337
|
|
|
232
|
-
|
|
338
|
+
## API Usage Examples
|
|
233
339
|
|
|
234
340
|
```typescript
|
|
235
|
-
import { workspaceFind } from '@orchestration-ai/sdk/sdk.gen';
|
|
341
|
+
import { workspaceFind, orchestrationCreate, agentCreate } from '@orchestration-ai/sdk/sdk.gen';
|
|
236
342
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
343
|
+
// List workspaces
|
|
344
|
+
const { data } = await workspaceFind();
|
|
345
|
+
|
|
346
|
+
// Create an orchestration
|
|
347
|
+
const { data: orch } = await orchestrationCreate({
|
|
348
|
+
path: { workspaceId: 'ws-id' },
|
|
349
|
+
body: { orchestration_name: 'My Orchestration', orchestration_description: '...' },
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// Create an agent
|
|
353
|
+
const { data: agent } = await agentCreate({
|
|
354
|
+
path: { workspaceId: 'ws-id', orchestrationId: 'orch-id' },
|
|
355
|
+
body: { agent_name: 'Support Agent', agent_description: '...' },
|
|
356
|
+
});
|
|
243
357
|
```
|
|
244
358
|
|
|
245
359
|
## Roles & Permissions
|
|
246
360
|
|
|
247
|
-
|
|
361
|
+
Applications declare permissions using Casbin role names:
|
|
248
362
|
|
|
249
|
-
|
|
363
|
+
| Role | Description |
|
|
364
|
+
|------|-------------|
|
|
365
|
+
| `role_admin` | Full access to everything |
|
|
366
|
+
| `role_workspace_admin` | Full workspace + orchestration + agent access |
|
|
367
|
+
| `role_agent_reader` | Read agent data |
|
|
368
|
+
| `role_agent_writer` | Read + create + update agents |
|
|
369
|
+
| `role_agent_admin` | Full agent CRUD |
|
|
370
|
+
| `role_service_reader` | Read services |
|
|
250
371
|
|
|
251
|
-
|
|
252
|
-
|------|----------|
|
|
253
|
-
| `role_admin` | `role_workspace_admin`, `role_application_admin`, `role_access_admin`, `role_llm_keys_admin`, `role_llm_reader`, `role_llm_lister`, `role_service_reader`, `role_service_lister`, `role_day_pass_transaction_lister` |
|
|
372
|
+
See the full hierarchy in the [Roles & Permissions](#roles-hierarchy) section below.
|
|
254
373
|
|
|
255
|
-
###
|
|
374
|
+
### Roles Hierarchy
|
|
256
375
|
|
|
257
376
|
| Role | Inherits |
|
|
258
377
|
|------|----------|
|
|
378
|
+
| `role_admin` | All admin roles + `role_llm_reader`, `role_llm_lister`, `role_service_reader`, `role_service_lister`, `role_day_pass_transaction_lister` |
|
|
259
379
|
| `role_workspace_admin` | `role_workspace_writer`, `role_workspace_lister`, `role_workspace_deleter`, `role_orchestration_admin` |
|
|
260
380
|
| `role_orchestration_admin` | `role_orchestration_writer`, `role_orchestration_lister`, `role_orchestration_deleter`, `role_agent_admin` |
|
|
261
381
|
| `role_agent_admin` | `role_agent_writer`, `role_agent_lister`, `role_agent_deleter` |
|
|
262
382
|
| `role_application_admin` | `role_application_writer`, `role_application_lister`, `role_application_deleter` |
|
|
263
383
|
| `role_access_admin` | `role_access_writer`, `role_access_lister`, `role_access_deleter` |
|
|
264
|
-
| `role_llm_keys_admin` | `role_llm_keys_writer`, `role_llm_keys_lister` |
|
|
265
|
-
|
|
266
|
-
### Writer Roles
|
|
267
|
-
|
|
268
|
-
| Role | Inherits |
|
|
269
|
-
|------|----------|
|
|
270
|
-
| `role_workspace_writer` | `role_workspace_inserter`, `role_workspace_reader`, `role_workspace_updater` |
|
|
271
|
-
| `role_orchestration_writer` | `role_orchestration_inserter`, `role_orchestration_reader`, `role_orchestration_updater` |
|
|
272
|
-
| `role_agent_writer` | `role_agent_inserter`, `role_agent_reader`, `role_agent_updater` |
|
|
273
|
-
| `role_application_writer` | `role_application_inserter`, `role_application_reader`, `role_application_updater` |
|
|
274
|
-
| `role_access_writer` | `role_access_inserter`, `role_access_reader` |
|
|
275
|
-
| `role_llm_keys_writer` | `role_llm_keys_inserter`, `role_llm_keys_reader`, `role_llm_keys_updater` |
|
|
276
|
-
|
|
277
|
-
### Granular Permissions
|
|
278
|
-
|
|
279
|
-
Each resource has fine-grained permissions:
|
|
280
|
-
|
|
281
|
-
- `*_reader` — Read a single resource by ID
|
|
282
|
-
- `*_lister` — List/query resources
|
|
283
|
-
- `*_inserter` — Create new resources
|
|
284
|
-
- `*_updater` — Update existing resources
|
|
285
|
-
- `*_deleter` — Delete resources
|
|
286
384
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
import { accessCreate } from '@orchestration-ai/sdk/sdk.gen';
|
|
291
|
-
|
|
292
|
-
// Grant a user full admin access to a workspace
|
|
293
|
-
await accessCreate({
|
|
294
|
-
body: {
|
|
295
|
-
resource_id: 'workspace-id',
|
|
296
|
-
principal_id: 'user-uid',
|
|
297
|
-
principal_name: 'Jane Doe',
|
|
298
|
-
principal_email: 'jane@example.com',
|
|
299
|
-
role: 'role_admin',
|
|
300
|
-
},
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// Grant read-only access to orchestrations
|
|
304
|
-
await accessCreate({
|
|
305
|
-
body: {
|
|
306
|
-
resource_id: 'workspace-id',
|
|
307
|
-
principal_id: 'user-uid',
|
|
308
|
-
principal_name: 'Viewer',
|
|
309
|
-
principal_email: 'viewer@example.com',
|
|
310
|
-
role: 'role_orchestration_reader',
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
```
|
|
385
|
+
Writer roles inherit inserter + reader + updater. Each resource has `_reader`, `_lister`, `_inserter`, `_updater`, `_deleter` granular permissions.
|
|
314
386
|
|
|
315
387
|
## License
|
|
316
388
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { type Server as HttpServer } from "node:http";
|
|
3
|
+
import type { Client } from "./client";
|
|
4
|
+
import type { Context, Permission, ServiceDescription, Setting } from "./shared-types";
|
|
5
|
+
export type ToolHandler = (body: any, context: Context, engineClient: Client, apiClient: Client) => unknown | Promise<unknown>;
|
|
6
|
+
export type TouchHandler = (context: Context, engineClient: Client, apiClient: Client) => void | Promise<void>;
|
|
7
|
+
export type DescriptionHandler = (context: Context, engineClient: Client, apiClient: Client) => ServiceDescription | Promise<ServiceDescription>;
|
|
8
|
+
type ExtractPaths<T extends ServiceDescription> = T[number]["path"];
|
|
9
|
+
export type ServiceDefinition<TDesc extends ServiceDescription | DescriptionHandler = ServiceDescription | DescriptionHandler> = {
|
|
10
|
+
unique_name: string;
|
|
11
|
+
service_name: string;
|
|
12
|
+
service_description: string;
|
|
13
|
+
defaultSettings?: Setting[];
|
|
14
|
+
description: TDesc;
|
|
15
|
+
touch?: TouchHandler;
|
|
16
|
+
tools?: TDesc extends ServiceDescription ? Record<ExtractPaths<TDesc>, ToolHandler> : Record<string, ToolHandler>;
|
|
17
|
+
};
|
|
18
|
+
export declare function defineService<const TDesc extends ServiceDescription>(definition: ServiceDefinition<TDesc>): ServiceDefinition<TDesc>;
|
|
19
|
+
export declare function defineServiceWithDynamicDescription(definition: ServiceDefinition<DescriptionHandler>): ServiceDefinition<DescriptionHandler>;
|
|
20
|
+
export type AppConfig = {
|
|
21
|
+
port?: number | string;
|
|
22
|
+
permissions?: Permission[];
|
|
23
|
+
engineUrl?: string;
|
|
24
|
+
accessKey?: string;
|
|
25
|
+
/** Set to false to disable the /explore page. Defaults to true. */
|
|
26
|
+
explore?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type OaiApp = {
|
|
29
|
+
service: (definition: ServiceDefinition<any>) => OaiApp;
|
|
30
|
+
permissions: (permissions: Permission[]) => OaiApp;
|
|
31
|
+
listen: (port?: number | string) => HttpServer;
|
|
32
|
+
expressApp: express.Application;
|
|
33
|
+
httpServer: HttpServer;
|
|
34
|
+
};
|
|
35
|
+
export type { Client } from "./client";
|
|
36
|
+
export type { Context, Permission, ServiceDescription, Setting } from "./shared-types";
|
|
37
|
+
export { getBooleanSetting, getTextSetting, getSecretSetting } from "./shared-types";
|
|
38
|
+
export declare function createApp(config?: AppConfig): OaiApp;
|
|
39
|
+
//# sourceMappingURL=app-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-builder.d.ts","sourceRoot":"","sources":["../../typescript/app-builder.ts"],"names":[],"mappings":"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"}
|