@orchestration-ai/sdk 0.1.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 -207
- 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/oauth-utils.d.ts +41 -0
- package/dist/cjs/oauth-utils.d.ts.map +1 -0
- package/dist/cjs/oauth-utils.js +194 -0
- package/dist/cjs/oauth-utils.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/oauth-utils.d.ts +41 -0
- package/dist/esm/oauth-utils.d.ts.map +1 -0
- package/dist/esm/oauth-utils.js +184 -0
- package/dist/esm/oauth-utils.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 +73 -10
- package/dist/cjs/index.d.ts +0 -3
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/index.js +0 -72
- package/dist/cjs/index.js.map +0 -1
- package/dist/esm/index.d.ts +0 -3
- package/dist/esm/index.d.ts.map +0 -1
- package/dist/esm/index.js +0 -3
- package/dist/esm/index.js.map +0 -1
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,306 +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';
|
|
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
|
|
28
67
|
|
|
29
|
-
|
|
68
|
+
Each service has:
|
|
69
|
+
|
|
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
|
-
|
|
85
|
+
// Tool handler
|
|
86
|
+
(body: any, context: Context, engineClient: Client, apiClient: Client) => unknown | Promise<unknown>
|
|
34
87
|
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
client_id: 'your-client-id',
|
|
38
|
-
client_secret: 'your-client-secret',
|
|
39
|
-
scope: 'role_admin', // any supported role as scope
|
|
40
|
-
});
|
|
88
|
+
// Touch handler
|
|
89
|
+
(context: Context, engineClient: Client, apiClient: Client) => void | Promise<void>
|
|
41
90
|
|
|
42
|
-
//
|
|
43
|
-
|
|
91
|
+
// Description handler (dynamic)
|
|
92
|
+
(context: Context, engineClient: Client, apiClient: Client) => ServiceDescription | Promise<ServiceDescription>
|
|
44
93
|
```
|
|
45
94
|
|
|
46
|
-
|
|
47
|
-
- Automatically obtain an access token via `client_credentials` on the first request
|
|
48
|
-
- Re-fetch the token when it expires (with a 30s buffer)
|
|
49
|
-
- Retry once on 401 responses with a fresh token
|
|
50
|
-
- Deduplicate concurrent token requests
|
|
95
|
+
### Two Clients
|
|
51
96
|
|
|
52
|
-
The
|
|
97
|
+
The app-builder provides two pre-configured clients to every handler:
|
|
53
98
|
|
|
54
|
-
|
|
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
|
|
55
105
|
|
|
56
|
-
|
|
106
|
+
**Static** - TypeScript enforces that `tools` keys match the `path` values in `description`:
|
|
57
107
|
|
|
58
108
|
```typescript
|
|
59
|
-
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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) => { ... },
|
|
78
142
|
},
|
|
79
143
|
});
|
|
80
144
|
```
|
|
81
145
|
|
|
82
|
-
|
|
146
|
+
### Touch Handler
|
|
83
147
|
|
|
84
|
-
|
|
148
|
+
Called by the engine when a service's context may have changed. Use it to register endpoints or links:
|
|
85
149
|
|
|
86
150
|
```typescript
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
+
});
|
|
96
164
|
}
|
|
97
165
|
```
|
|
98
166
|
|
|
99
|
-
|
|
167
|
+
### Settings
|
|
100
168
|
|
|
101
|
-
|
|
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) |
|
|
102
176
|
|
|
103
|
-
|
|
177
|
+
Utility functions for reading settings:
|
|
104
178
|
|
|
105
179
|
```typescript
|
|
106
|
-
import {
|
|
180
|
+
import { getBooleanSetting, getTextSetting, getSecretSetting } from '@orchestration-ai/sdk/services';
|
|
107
181
|
|
|
108
|
-
const
|
|
182
|
+
const enabled = getBooleanSetting(settings, "FEATURE_ENABLED");
|
|
183
|
+
const host = getTextSetting(settings, "SMTP_HOST");
|
|
184
|
+
const apiKey = getSecretSetting(settings, "API_KEY");
|
|
185
|
+
```
|
|
109
186
|
|
|
110
|
-
|
|
111
|
-
// Send the code to your backend to exchange for tokens securely
|
|
112
|
-
// IMPORTANT: pass the same redirect_uri used in initiateLogin
|
|
113
|
-
const tokens = await fetch('/api/auth/exchange', {
|
|
114
|
-
method: 'POST',
|
|
115
|
-
body: JSON.stringify({
|
|
116
|
-
code: result.code,
|
|
117
|
-
redirect_uri: 'https://your-app.com/callback',
|
|
118
|
-
}),
|
|
119
|
-
}).then(r => r.json());
|
|
187
|
+
### Sending Messages to Agents
|
|
120
188
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
);
|
|
126
201
|
```
|
|
127
202
|
|
|
128
|
-
|
|
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
|
+
```
|
|
129
211
|
|
|
130
|
-
|
|
212
|
+
### Custom Endpoints
|
|
131
213
|
|
|
132
|
-
|
|
214
|
+
Access the underlying Express app and HTTP server for custom routes or WebSockets:
|
|
133
215
|
|
|
134
216
|
```typescript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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);
|
|
145
228
|
```
|
|
146
229
|
|
|
147
|
-
|
|
230
|
+
### Explore Page
|
|
148
231
|
|
|
149
|
-
|
|
150
|
-
|
|
232
|
+
The `/explore` endpoint renders an interactive page showing all services, tools, and permissions. You can test tools directly from the browser.
|
|
233
|
+
|
|
234
|
+
Disable in production:
|
|
151
235
|
|
|
152
|
-
|
|
236
|
+
```typescript
|
|
237
|
+
createApp({ explore: false }).service(...).listen(3001);
|
|
153
238
|
```
|
|
154
239
|
|
|
155
|
-
##
|
|
240
|
+
## Client Factories
|
|
156
241
|
|
|
157
|
-
###
|
|
242
|
+
### createEngineClient
|
|
243
|
+
|
|
244
|
+
For calling engine internal endpoints:
|
|
158
245
|
|
|
159
246
|
```typescript
|
|
160
|
-
import {
|
|
247
|
+
import { createEngineClient } from '@orchestration-ai/sdk/services';
|
|
161
248
|
|
|
162
|
-
//
|
|
163
|
-
const
|
|
249
|
+
// Production (default URL)
|
|
250
|
+
const client = createEngineClient(accessKey);
|
|
164
251
|
|
|
165
|
-
//
|
|
166
|
-
const
|
|
167
|
-
body: { workspace_name: 'My Workspace' },
|
|
168
|
-
});
|
|
252
|
+
// Custom URL
|
|
253
|
+
const client = createEngineClient("https://my-engine.com", accessKey);
|
|
169
254
|
|
|
170
|
-
//
|
|
171
|
-
const
|
|
255
|
+
// Nullable URL (falls back to production)
|
|
256
|
+
const client = createEngineClient(process.env.ENGINE_URL ?? null, accessKey);
|
|
172
257
|
```
|
|
173
258
|
|
|
174
|
-
###
|
|
259
|
+
### createApplicationClient
|
|
260
|
+
|
|
261
|
+
For calling another OAI application's services:
|
|
175
262
|
|
|
176
263
|
```typescript
|
|
177
|
-
import {
|
|
178
|
-
orchestrationFindByWorkspace,
|
|
179
|
-
orchestrationCreate,
|
|
180
|
-
} from '@orchestration-ai/sdk';
|
|
181
|
-
|
|
182
|
-
// List orchestrations in a workspace
|
|
183
|
-
const { data } = await orchestrationFindByWorkspace({
|
|
184
|
-
path: { workspaceId: 'workspace-id' },
|
|
185
|
-
});
|
|
264
|
+
import { createApplicationClient, listServices, callServiceTool } from '@orchestration-ai/sdk/services';
|
|
186
265
|
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
body: {
|
|
191
|
-
orchestration_name: 'My Orchestration',
|
|
192
|
-
orchestration_description: 'Handles customer support',
|
|
193
|
-
},
|
|
194
|
-
});
|
|
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" } });
|
|
195
269
|
```
|
|
196
270
|
|
|
197
|
-
###
|
|
271
|
+
### createApiClient
|
|
272
|
+
|
|
273
|
+
For making authenticated API calls with OAuth:
|
|
198
274
|
|
|
199
275
|
```typescript
|
|
200
|
-
import {
|
|
276
|
+
import { createApiClient } from '@orchestration-ai/sdk/services';
|
|
277
|
+
import { setupClientCredentials } from '@orchestration-ai/sdk/oauth-utils';
|
|
201
278
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
279
|
+
const apiClient = createApiClient();
|
|
280
|
+
setupClientCredentials(apiClient, {
|
|
281
|
+
client_id: accessKey,
|
|
282
|
+
client_secret: `${accessKey}:${workspaceOwnerId}`,
|
|
205
283
|
});
|
|
206
284
|
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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',
|
|
214
303
|
});
|
|
215
304
|
```
|
|
216
305
|
|
|
217
|
-
|
|
306
|
+
The SDK automatically obtains and refreshes tokens.
|
|
307
|
+
|
|
308
|
+
### Browser (Client-Side)
|
|
218
309
|
|
|
219
310
|
```typescript
|
|
220
|
-
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
|
+
});
|
|
221
320
|
|
|
222
|
-
|
|
321
|
+
// Initiate login
|
|
322
|
+
initiateLogin(client.getConfig().baseURL, {
|
|
323
|
+
client_id: 'your-client-id',
|
|
324
|
+
redirect_uri: 'https://your-app.com/callback',
|
|
325
|
+
});
|
|
223
326
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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);
|
|
228
335
|
}
|
|
229
336
|
```
|
|
230
337
|
|
|
231
|
-
|
|
338
|
+
## API Usage Examples
|
|
232
339
|
|
|
233
340
|
```typescript
|
|
234
|
-
import { workspaceFind } from '@orchestration-ai/sdk';
|
|
341
|
+
import { workspaceFind, orchestrationCreate, agentCreate } from '@orchestration-ai/sdk/sdk.gen';
|
|
235
342
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
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
|
+
});
|
|
242
357
|
```
|
|
243
358
|
|
|
244
359
|
## Roles & Permissions
|
|
245
360
|
|
|
246
|
-
|
|
361
|
+
Applications declare permissions using Casbin role names:
|
|
247
362
|
|
|
248
|
-
|
|
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 |
|
|
249
371
|
|
|
250
|
-
|
|
251
|
-
|------|----------|
|
|
252
|
-
| `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.
|
|
253
373
|
|
|
254
|
-
###
|
|
374
|
+
### Roles Hierarchy
|
|
255
375
|
|
|
256
376
|
| Role | Inherits |
|
|
257
377
|
|------|----------|
|
|
378
|
+
| `role_admin` | All admin roles + `role_llm_reader`, `role_llm_lister`, `role_service_reader`, `role_service_lister`, `role_day_pass_transaction_lister` |
|
|
258
379
|
| `role_workspace_admin` | `role_workspace_writer`, `role_workspace_lister`, `role_workspace_deleter`, `role_orchestration_admin` |
|
|
259
380
|
| `role_orchestration_admin` | `role_orchestration_writer`, `role_orchestration_lister`, `role_orchestration_deleter`, `role_agent_admin` |
|
|
260
381
|
| `role_agent_admin` | `role_agent_writer`, `role_agent_lister`, `role_agent_deleter` |
|
|
261
382
|
| `role_application_admin` | `role_application_writer`, `role_application_lister`, `role_application_deleter` |
|
|
262
383
|
| `role_access_admin` | `role_access_writer`, `role_access_lister`, `role_access_deleter` |
|
|
263
|
-
| `role_llm_keys_admin` | `role_llm_keys_writer`, `role_llm_keys_lister` |
|
|
264
|
-
|
|
265
|
-
### Writer Roles
|
|
266
|
-
|
|
267
|
-
| Role | Inherits |
|
|
268
|
-
|------|----------|
|
|
269
|
-
| `role_workspace_writer` | `role_workspace_inserter`, `role_workspace_reader`, `role_workspace_updater` |
|
|
270
|
-
| `role_orchestration_writer` | `role_orchestration_inserter`, `role_orchestration_reader`, `role_orchestration_updater` |
|
|
271
|
-
| `role_agent_writer` | `role_agent_inserter`, `role_agent_reader`, `role_agent_updater` |
|
|
272
|
-
| `role_application_writer` | `role_application_inserter`, `role_application_reader`, `role_application_updater` |
|
|
273
|
-
| `role_access_writer` | `role_access_inserter`, `role_access_reader` |
|
|
274
|
-
| `role_llm_keys_writer` | `role_llm_keys_inserter`, `role_llm_keys_reader`, `role_llm_keys_updater` |
|
|
275
|
-
|
|
276
|
-
### Granular Permissions
|
|
277
|
-
|
|
278
|
-
Each resource has fine-grained permissions:
|
|
279
|
-
|
|
280
|
-
- `*_reader` — Read a single resource by ID
|
|
281
|
-
- `*_lister` — List/query resources
|
|
282
|
-
- `*_inserter` — Create new resources
|
|
283
|
-
- `*_updater` — Update existing resources
|
|
284
|
-
- `*_deleter` — Delete resources
|
|
285
384
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
```typescript
|
|
289
|
-
import { accessCreate } from '@orchestration-ai/sdk';
|
|
290
|
-
|
|
291
|
-
// Grant a user full admin access to a workspace
|
|
292
|
-
await accessCreate({
|
|
293
|
-
body: {
|
|
294
|
-
resource_id: 'workspace-id',
|
|
295
|
-
principal_id: 'user-uid',
|
|
296
|
-
principal_name: 'Jane Doe',
|
|
297
|
-
principal_email: 'jane@example.com',
|
|
298
|
-
role: 'role_admin',
|
|
299
|
-
},
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
// Grant read-only access to orchestrations
|
|
303
|
-
await accessCreate({
|
|
304
|
-
body: {
|
|
305
|
-
resource_id: 'workspace-id',
|
|
306
|
-
principal_id: 'user-uid',
|
|
307
|
-
principal_name: 'Viewer',
|
|
308
|
-
principal_email: 'viewer@example.com',
|
|
309
|
-
role: 'role_orchestration_reader',
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
```
|
|
385
|
+
Writer roles inherit inserter + reader + updater. Each resource has `_reader`, `_lister`, `_inserter`, `_updater`, `_deleter` granular permissions.
|
|
313
386
|
|
|
314
387
|
## License
|
|
315
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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"}
|