aui-agent-builder 0.1.8 → 0.1.11
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 +27 -1
- package/dist/commands/add-integration.d.ts +8 -14
- package/dist/commands/add-integration.d.ts.map +1 -1
- package/dist/commands/add-integration.js +133 -363
- package/dist/commands/add-integration.js.map +1 -1
- package/dist/commands/chat.js +2 -2
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +3 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +73 -1
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/rag.d.ts +14 -0
- package/dist/commands/rag.d.ts.map +1 -0
- package/dist/commands/rag.js +268 -0
- package/dist/commands/rag.js.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -1
- package/dist/types/integration.d.ts +38 -0
- package/dist/types/integration.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,9 +71,10 @@ Session is invalidated server-side and cleared locally.
|
|
|
71
71
|
|---------|-------------|
|
|
72
72
|
| `aui login` | Sign in (email OTP or access token) |
|
|
73
73
|
| `aui list-agents` | List all agents in your account |
|
|
74
|
-
| `aui create-agent` | Create a new agent on the backend |
|
|
75
74
|
| `aui import [agent-id]` | Download an agent as local `.aui.json` files |
|
|
76
75
|
| `aui init [directory]` | Scaffold a new agent project with examples |
|
|
76
|
+
| `aui add-integration` | Add an integration (API, RAG, or MCP) |
|
|
77
|
+
| `aui rag` | List and manage RAG knowledge bases and files |
|
|
77
78
|
| `aui validate [path]` | Validate `.aui.json` files for errors |
|
|
78
79
|
| `aui push` | Upload local changes to the backend |
|
|
79
80
|
| `aui status` | Show session, linked agent, and file summary |
|
|
@@ -160,6 +161,31 @@ my-agent/
|
|
|
160
161
|
|
|
161
162
|
**`rules.aui.json`** — Global rules that apply across tools. Define conditions (when) and actions (then) to control agent behavior like blocking certain actions, requiring confirmation, or activating other tools.
|
|
162
163
|
|
|
164
|
+
## Adding Integrations
|
|
165
|
+
|
|
166
|
+
Add API, RAG, or MCP integrations to your project:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
aui add-integration
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Select the integration type, provide a code name, and the command scaffolds the JSON config with the correct structure and placeholder values. Edit the generated `integrations.aui.json` in your editor to fill in the details.
|
|
173
|
+
|
|
174
|
+
- **API** — generates endpoint URL, method, authentication, request schema, and test curl
|
|
175
|
+
- **RAG** — prompts for knowledge hub (new or existing) and scope (organization, account, or network)
|
|
176
|
+
- **MCP** — generates a minimal config to fill in
|
|
177
|
+
|
|
178
|
+
## RAG Knowledge Bases
|
|
179
|
+
|
|
180
|
+
Manage RAG knowledge bases and their files:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
aui rag # List knowledge bases and files by scope
|
|
184
|
+
aui rag --add-file # Add a file or URL to a knowledge hub
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
After adding a RAG integration, use `aui rag --add-file` to attach local files (PDF, TXT, etc.) or URLs for scraping. Files are tracked locally and will be uploaded when push endpoints are ready. On push, only changed files are re-embedded (diff-based).
|
|
188
|
+
|
|
163
189
|
## Validating Changes
|
|
164
190
|
|
|
165
191
|
Check your configuration files for errors before pushing:
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* add-integration command -
|
|
2
|
+
* add-integration command - Scaffold integration config files
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 5. Save to integrations.aui.json
|
|
4
|
+
* Asks only the essentials (type, code, scope for RAG), then generates
|
|
5
|
+
* the .aui.json file with the correct structure and placeholder values
|
|
6
|
+
* for the user to edit in their editor.
|
|
7
|
+
*
|
|
8
|
+
* For RAG, also supports adding files/URLs to the knowledge hub.
|
|
10
9
|
*
|
|
11
10
|
* Usage: aui add-integration
|
|
12
|
-
* Options:
|
|
13
|
-
* --url <url> URL to OpenAPI spec
|
|
14
|
-
* --file <path> Path to OpenAPI JSON file
|
|
15
|
-
* --manual Manual integration entry
|
|
16
11
|
*/
|
|
17
12
|
export interface AddIntegrationOptions {
|
|
18
13
|
url?: string;
|
|
19
14
|
file?: string;
|
|
20
|
-
manual?: boolean;
|
|
21
15
|
}
|
|
22
16
|
/**
|
|
23
|
-
*
|
|
17
|
+
* Scaffold an integration config file
|
|
24
18
|
*/
|
|
25
|
-
export declare function addIntegration(
|
|
19
|
+
export declare function addIntegration(_options?: AddIntegrationOptions): Promise<void>;
|
|
26
20
|
//# sourceMappingURL=add-integration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-integration.d.ts","sourceRoot":"","sources":["../../src/commands/add-integration.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"add-integration.d.ts","sourceRoot":"","sources":["../../src/commands/add-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,QAAQ,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDxF"}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* add-integration command -
|
|
3
|
+
* add-integration command - Scaffold integration config files
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 5. Save to integrations.aui.json
|
|
5
|
+
* Asks only the essentials (type, code, scope for RAG), then generates
|
|
6
|
+
* the .aui.json file with the correct structure and placeholder values
|
|
7
|
+
* for the user to edit in their editor.
|
|
8
|
+
*
|
|
9
|
+
* For RAG, also supports adding files/URLs to the knowledge hub.
|
|
11
10
|
*
|
|
12
11
|
* Usage: aui add-integration
|
|
13
|
-
* Options:
|
|
14
|
-
* --url <url> URL to OpenAPI spec
|
|
15
|
-
* --file <path> Path to OpenAPI JSON file
|
|
16
|
-
* --manual Manual integration entry
|
|
17
12
|
*/
|
|
18
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
14
|
if (k2 === undefined) k2 = k;
|
|
@@ -56,381 +51,173 @@ exports.addIntegration = addIntegration;
|
|
|
56
51
|
const fs = __importStar(require("fs"));
|
|
57
52
|
const path = __importStar(require("path"));
|
|
58
53
|
const chalk_1 = __importDefault(require("chalk"));
|
|
59
|
-
const ora_1 = __importDefault(require("ora"));
|
|
60
54
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
61
55
|
const config_1 = require("../config");
|
|
62
56
|
/**
|
|
63
|
-
*
|
|
57
|
+
* Scaffold an integration config file
|
|
64
58
|
*/
|
|
65
|
-
async function addIntegration(
|
|
66
|
-
console.log(chalk_1.default.
|
|
67
|
-
console.log(chalk_1.default.
|
|
68
|
-
console.log(chalk_1.default.
|
|
69
|
-
const projectRoot = (0, config_1.findProjectRoot)();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
// Choose source type
|
|
75
|
-
const { sourceType } = await inquirer_1.default.prompt([{
|
|
76
|
-
type: 'list',
|
|
77
|
-
name: 'sourceType',
|
|
78
|
-
message: 'How would you like to add the integration?',
|
|
79
|
-
choices: [
|
|
80
|
-
{ name: 'Manual entry - Define integration fields step by step', value: 'manual' },
|
|
81
|
-
{ name: 'OpenAPI URL - Import from OpenAPI spec URL', value: 'url' },
|
|
82
|
-
{ name: 'OpenAPI File - Import from local OpenAPI JSON file', value: 'file' }
|
|
83
|
-
]
|
|
84
|
-
}]);
|
|
85
|
-
let integration;
|
|
86
|
-
if (sourceType === 'manual') {
|
|
87
|
-
integration = await createManualIntegration();
|
|
88
|
-
}
|
|
89
|
-
else if (sourceType === 'url') {
|
|
90
|
-
integration = await createFromOpenAPIUrl(options.url);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
integration = await createFromOpenAPIFile(options.file);
|
|
94
|
-
}
|
|
95
|
-
// Preview
|
|
96
|
-
console.log(chalk_1.default.blue('\n ─── Integration Preview ───\n'));
|
|
97
|
-
console.log(chalk_1.default.white(` Type: ${integration.type}`));
|
|
98
|
-
console.log(chalk_1.default.white(` Code: ${integration.code}`));
|
|
99
|
-
if (integration.settings && 'endpoint' in integration.settings && integration.settings.endpoint) {
|
|
100
|
-
console.log(chalk_1.default.white(` Endpoint: ${integration.settings.endpoint.method} ${integration.settings.endpoint.url}`));
|
|
101
|
-
}
|
|
102
|
-
// Confirm and save
|
|
103
|
-
const { confirm } = await inquirer_1.default.prompt([{
|
|
104
|
-
type: 'confirm',
|
|
105
|
-
name: 'confirm',
|
|
106
|
-
message: 'Add this integration to your project?',
|
|
107
|
-
default: true
|
|
108
|
-
}]);
|
|
109
|
-
if (!confirm) {
|
|
110
|
-
console.log(chalk_1.default.gray('\n Cancelled.\n'));
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
await saveIntegration(integration, projectRoot);
|
|
114
|
-
console.log(chalk_1.default.green(`\n ✓ Integration "${integration.code}" added successfully!\n`));
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
console.error(chalk_1.default.red(`\n Error: ${error instanceof Error ? error.message : error}`));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Create integration manually step by step
|
|
122
|
-
*/
|
|
123
|
-
async function createManualIntegration() {
|
|
124
|
-
const answers = await inquirer_1.default.prompt([
|
|
125
|
-
{
|
|
59
|
+
async function addIntegration(_options = {}) {
|
|
60
|
+
console.log(chalk_1.default.dim('\n ╭──────────────────────────────────────────────╮'));
|
|
61
|
+
console.log(chalk_1.default.dim(' │') + chalk_1.default.white.bold(' Add Integration') + chalk_1.default.dim(' │'));
|
|
62
|
+
console.log(chalk_1.default.dim(' ╰──────────────────────────────────────────────╯\n'));
|
|
63
|
+
const projectRoot = (0, config_1.findProjectRoot)() || process.cwd();
|
|
64
|
+
// Step 1: Integration type
|
|
65
|
+
const { integrationType } = await inquirer_1.default.prompt([{
|
|
126
66
|
type: 'list',
|
|
127
|
-
name: '
|
|
67
|
+
name: 'integrationType',
|
|
128
68
|
message: 'Integration type:',
|
|
129
69
|
choices: [
|
|
130
|
-
{ name: 'API
|
|
131
|
-
{ name: 'RAG
|
|
132
|
-
{ name: 'MCP
|
|
70
|
+
{ name: 'API — REST API endpoint', value: 'API' },
|
|
71
|
+
{ name: 'RAG — Knowledge base (files / URLs)', value: 'RAG' },
|
|
72
|
+
{ name: 'MCP — Model Context Protocol', value: 'MCP' }
|
|
133
73
|
]
|
|
134
|
-
}
|
|
135
|
-
|
|
74
|
+
}]);
|
|
75
|
+
// Step 2: Code
|
|
76
|
+
const { code } = await inquirer_1.default.prompt([{
|
|
136
77
|
type: 'input',
|
|
137
78
|
name: 'code',
|
|
138
79
|
message: 'Integration code (kebab-case):',
|
|
139
80
|
validate: (input) => /^[a-z][a-z0-9-]*$/.test(input) || 'Use lowercase letters, numbers, and hyphens'
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
81
|
+
}]);
|
|
82
|
+
// Step 3: Build the integration based on type
|
|
83
|
+
let integration;
|
|
84
|
+
if (integrationType === 'API') {
|
|
85
|
+
integration = scaffoldAPI(code);
|
|
86
|
+
}
|
|
87
|
+
else if (integrationType === 'RAG') {
|
|
88
|
+
integration = await scaffoldRAG(code);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
integration = scaffoldMCP(code);
|
|
149
92
|
}
|
|
150
|
-
|
|
151
|
-
|
|
93
|
+
// Step 4: Save to integrations.aui.json
|
|
94
|
+
await saveIntegration(integration, projectRoot);
|
|
95
|
+
const filePath = path.join(projectRoot, 'integrations.aui.json');
|
|
96
|
+
console.log(chalk_1.default.green(`\n ✓ ${integrationType} integration "${code}" created`));
|
|
97
|
+
console.log(chalk_1.default.dim(`\n Edit the configuration:`));
|
|
98
|
+
console.log(chalk_1.default.cyan(` ${filePath}`));
|
|
99
|
+
if (integrationType === 'RAG') {
|
|
100
|
+
console.log(chalk_1.default.dim(`\n Add files to the knowledge hub:`));
|
|
101
|
+
console.log(chalk_1.default.cyan(` aui rag --add-file`));
|
|
152
102
|
}
|
|
153
|
-
|
|
103
|
+
console.log(chalk_1.default.dim(`\n Then validate and push:`));
|
|
104
|
+
console.log(chalk_1.default.cyan(` aui validate`));
|
|
105
|
+
console.log(chalk_1.default.cyan(` aui push\n`));
|
|
106
|
+
}
|
|
107
|
+
// ─── Scaffolders ───
|
|
108
|
+
function scaffoldAPI(code) {
|
|
154
109
|
return {
|
|
155
|
-
type:
|
|
156
|
-
code
|
|
157
|
-
description:
|
|
158
|
-
settings:
|
|
110
|
+
type: 'API',
|
|
111
|
+
code,
|
|
112
|
+
description: '',
|
|
113
|
+
settings: {
|
|
114
|
+
endpoint: {
|
|
115
|
+
url: 'https://api.example.com/endpoint',
|
|
116
|
+
method: 'GET',
|
|
117
|
+
authentication: {
|
|
118
|
+
type: 'API_KEY',
|
|
119
|
+
apiKey: `$${code.toUpperCase().replace(/-/g, '_')}_API_KEY`
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
request_schema: [
|
|
123
|
+
{
|
|
124
|
+
key: 'query',
|
|
125
|
+
required: true,
|
|
126
|
+
description: 'Search query or input parameter',
|
|
127
|
+
type: 'STRING',
|
|
128
|
+
value_source: 'dynamic',
|
|
129
|
+
params: [],
|
|
130
|
+
entities: [],
|
|
131
|
+
values: [],
|
|
132
|
+
default_value: ''
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
response_mapping: {},
|
|
136
|
+
test_curl: `curl "https://api.example.com/endpoint?query=test" -H "X-API-Key: YOUR_KEY"`
|
|
137
|
+
}
|
|
159
138
|
};
|
|
160
139
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
async function createAPIIntegration(code, description) {
|
|
165
|
-
const endpointAnswers = await inquirer_1.default.prompt([
|
|
166
|
-
{
|
|
167
|
-
type: 'input',
|
|
168
|
-
name: 'url',
|
|
169
|
-
message: 'Endpoint URL (supports {{param}} placeholders):',
|
|
170
|
-
validate: (input) => input.length > 0 || 'URL is required'
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
type: 'list',
|
|
174
|
-
name: 'method',
|
|
175
|
-
message: 'HTTP Method:',
|
|
176
|
-
choices: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
|
|
177
|
-
},
|
|
178
|
-
{
|
|
140
|
+
async function scaffoldRAG(code) {
|
|
141
|
+
// RAG needs a few extra questions for the knowledge hub
|
|
142
|
+
const { khSource } = await inquirer_1.default.prompt([{
|
|
179
143
|
type: 'list',
|
|
180
|
-
name: '
|
|
181
|
-
message: '
|
|
144
|
+
name: 'khSource',
|
|
145
|
+
message: 'Knowledge hub:',
|
|
182
146
|
choices: [
|
|
183
|
-
{ name: '
|
|
184
|
-
{ name: '
|
|
185
|
-
{ name: 'Bearer Token', value: 'BEARER_TOKEN' },
|
|
186
|
-
{ name: 'Basic Auth', value: 'BASIC' }
|
|
147
|
+
{ name: 'Create a new knowledge hub', value: 'new' },
|
|
148
|
+
{ name: 'Use an existing knowledge hub (enter ID)', value: 'existing' }
|
|
187
149
|
]
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
};
|
|
194
|
-
if (endpointAnswers.authType !== 'NONE') {
|
|
195
|
-
if (endpointAnswers.authType === 'API_KEY') {
|
|
196
|
-
const { envVar } = await inquirer_1.default.prompt([{
|
|
197
|
-
type: 'input',
|
|
198
|
-
name: 'envVar',
|
|
199
|
-
message: 'Environment variable name for API key:',
|
|
200
|
-
default: `${code.toUpperCase().replace(/-/g, '_')}_API_KEY`
|
|
201
|
-
}]);
|
|
202
|
-
endpoint.authentication = { type: 'API_KEY', apiKey: `$${envVar}` };
|
|
203
|
-
}
|
|
204
|
-
else if (endpointAnswers.authType === 'BEARER_TOKEN') {
|
|
205
|
-
const { envVar } = await inquirer_1.default.prompt([{
|
|
206
|
-
type: 'input',
|
|
207
|
-
name: 'envVar',
|
|
208
|
-
message: 'Environment variable name for token:',
|
|
209
|
-
default: `${code.toUpperCase().replace(/-/g, '_')}_TOKEN`
|
|
210
|
-
}]);
|
|
211
|
-
endpoint.authentication = { type: 'BEARER_TOKEN', token: `$${envVar}` };
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
// Request schema fields
|
|
215
|
-
const requestSchema = [];
|
|
216
|
-
let addMore = true;
|
|
217
|
-
console.log(chalk_1.default.gray('\n Define request schema fields (the data this API needs):\n'));
|
|
218
|
-
while (addMore) {
|
|
219
|
-
const { wantField } = await inquirer_1.default.prompt([{
|
|
220
|
-
type: 'confirm',
|
|
221
|
-
name: 'wantField',
|
|
222
|
-
message: requestSchema.length === 0 ? 'Add a request field?' : 'Add another request field?',
|
|
223
|
-
default: requestSchema.length === 0
|
|
224
|
-
}]);
|
|
225
|
-
if (!wantField) {
|
|
226
|
-
addMore = false;
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
const fieldAnswers = await inquirer_1.default.prompt([
|
|
230
|
-
{
|
|
150
|
+
}]);
|
|
151
|
+
let knowledgeHub;
|
|
152
|
+
let knowledgeBaseId = '';
|
|
153
|
+
if (khSource === 'existing') {
|
|
154
|
+
const { id } = await inquirer_1.default.prompt([{
|
|
231
155
|
type: 'input',
|
|
232
|
-
name: '
|
|
233
|
-
message: '
|
|
234
|
-
validate: (input) => input.length > 0 || '
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
},
|
|
156
|
+
name: 'id',
|
|
157
|
+
message: 'Knowledge hub ID:',
|
|
158
|
+
validate: (input) => input.trim().length > 0 || 'ID is required'
|
|
159
|
+
}]);
|
|
160
|
+
knowledgeBaseId = id.trim();
|
|
161
|
+
knowledgeHub = { id: knowledgeBaseId, name: '', scope: 'organization' };
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
const khAnswers = await inquirer_1.default.prompt([
|
|
242
165
|
{
|
|
243
166
|
type: 'input',
|
|
244
|
-
name: '
|
|
245
|
-
message: '
|
|
167
|
+
name: 'name',
|
|
168
|
+
message: 'Knowledge hub name:',
|
|
169
|
+
validate: (input) => input.trim().length > 0 || 'Name is required'
|
|
246
170
|
},
|
|
247
171
|
{
|
|
248
172
|
type: 'list',
|
|
249
|
-
name: '
|
|
250
|
-
message: '
|
|
251
|
-
choices: ['STRING', 'NUMBER', 'BOOLEAN', 'ENUM', 'OBJECT', 'ARRAY']
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
type: 'list',
|
|
255
|
-
name: 'valueSource',
|
|
256
|
-
message: 'Value source:',
|
|
173
|
+
name: 'scope',
|
|
174
|
+
message: 'Scope:',
|
|
257
175
|
choices: [
|
|
258
|
-
{ name: '
|
|
259
|
-
{ name: '
|
|
260
|
-
{ name: '
|
|
261
|
-
{ name: 'Context - From conversation context', value: 'context' },
|
|
262
|
-
{ name: 'Entities - From entity data', value: 'entities' }
|
|
176
|
+
{ name: 'Organization — shared across all accounts and agents', value: 'organization' },
|
|
177
|
+
{ name: 'Account — shared within this account', value: 'account' },
|
|
178
|
+
{ name: 'Network — specific to this agent only', value: 'network' }
|
|
263
179
|
]
|
|
264
180
|
}
|
|
265
181
|
]);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
default_value: ''
|
|
276
|
-
});
|
|
182
|
+
knowledgeHub = {
|
|
183
|
+
name: khAnswers.name.trim(),
|
|
184
|
+
scope: khAnswers.scope,
|
|
185
|
+
files: []
|
|
186
|
+
};
|
|
187
|
+
// TODO: When knowledge hub creation endpoint is ready:
|
|
188
|
+
// POST /knowledge-hub with { name, scope }
|
|
189
|
+
// Response includes the knowledge_base_id
|
|
190
|
+
knowledgeBaseId = `kh-${code}-pending`;
|
|
277
191
|
}
|
|
278
|
-
// Test curl
|
|
279
|
-
const { testCurl } = await inquirer_1.default.prompt([{
|
|
280
|
-
type: 'input',
|
|
281
|
-
name: 'testCurl',
|
|
282
|
-
message: 'Test curl command (optional - used to generate response mapping):'
|
|
283
|
-
}]);
|
|
284
|
-
return {
|
|
285
|
-
type: 'API',
|
|
286
|
-
code,
|
|
287
|
-
description: description || undefined,
|
|
288
|
-
settings: {
|
|
289
|
-
endpoint,
|
|
290
|
-
request_schema: requestSchema,
|
|
291
|
-
response_mapping: {},
|
|
292
|
-
test_curl: testCurl || undefined
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Create a RAG integration
|
|
298
|
-
*/
|
|
299
|
-
async function createRAGIntegration(code, description) {
|
|
300
|
-
const answers = await inquirer_1.default.prompt([
|
|
301
|
-
{
|
|
302
|
-
type: 'input',
|
|
303
|
-
name: 'knowledgeBaseId',
|
|
304
|
-
message: 'Knowledge base ID:',
|
|
305
|
-
validate: (input) => input.length > 0 || 'Knowledge base ID is required'
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
type: 'number',
|
|
309
|
-
name: 'searchTopK',
|
|
310
|
-
message: 'Search top-k results:',
|
|
311
|
-
default: 7
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
type: 'number',
|
|
315
|
-
name: 'rankerTopK',
|
|
316
|
-
message: 'Ranker top-k results:',
|
|
317
|
-
default: 3
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
type: 'number',
|
|
321
|
-
name: 'confidenceThreshold',
|
|
322
|
-
message: 'Confidence threshold (0-1):',
|
|
323
|
-
default: 0.3
|
|
324
|
-
}
|
|
325
|
-
]);
|
|
326
192
|
return {
|
|
327
193
|
type: 'RAG',
|
|
328
194
|
code,
|
|
329
|
-
description:
|
|
195
|
+
description: '',
|
|
330
196
|
settings: {
|
|
331
|
-
search_top_k:
|
|
332
|
-
ranker_top_k:
|
|
197
|
+
search_top_k: 7,
|
|
198
|
+
ranker_top_k: 3,
|
|
333
199
|
ranker_model: null,
|
|
334
|
-
confidence_threshold:
|
|
335
|
-
knowledge_base_id:
|
|
200
|
+
confidence_threshold: 0.3,
|
|
201
|
+
knowledge_base_id: knowledgeBaseId,
|
|
336
202
|
parent_knowledge_base_ids: [],
|
|
337
203
|
allow_multiple_calls: false,
|
|
338
|
-
placeholders: []
|
|
204
|
+
placeholders: [],
|
|
205
|
+
knowledge_hub: knowledgeHub
|
|
339
206
|
}
|
|
340
207
|
};
|
|
341
208
|
}
|
|
342
|
-
|
|
343
|
-
* Create integration from OpenAPI URL
|
|
344
|
-
*/
|
|
345
|
-
async function createFromOpenAPIUrl(url) {
|
|
346
|
-
if (!url) {
|
|
347
|
-
const answers = await inquirer_1.default.prompt([{
|
|
348
|
-
type: 'input',
|
|
349
|
-
name: 'url',
|
|
350
|
-
message: 'OpenAPI spec URL:',
|
|
351
|
-
validate: (input) => {
|
|
352
|
-
if (!input.startsWith('http://') && !input.startsWith('https://')) {
|
|
353
|
-
return 'URL must start with http:// or https://';
|
|
354
|
-
}
|
|
355
|
-
return true;
|
|
356
|
-
}
|
|
357
|
-
}]);
|
|
358
|
-
url = answers.url;
|
|
359
|
-
}
|
|
360
|
-
const spinner = (0, ora_1.default)('Fetching OpenAPI spec...').start();
|
|
361
|
-
try {
|
|
362
|
-
// Note: In production, this would fetch and parse the OpenAPI spec
|
|
363
|
-
// For now, we create a placeholder integration
|
|
364
|
-
spinner.succeed('OpenAPI spec loaded');
|
|
365
|
-
console.log(chalk_1.default.yellow('\n OpenAPI import is a work in progress.'));
|
|
366
|
-
console.log(chalk_1.default.yellow(' Creating a placeholder integration from the URL.\n'));
|
|
367
|
-
const { code } = await inquirer_1.default.prompt([{
|
|
368
|
-
type: 'input',
|
|
369
|
-
name: 'code',
|
|
370
|
-
message: 'Integration code:',
|
|
371
|
-
validate: (input) => /^[a-z][a-z0-9-]*$/.test(input) || 'Use kebab-case'
|
|
372
|
-
}]);
|
|
373
|
-
return {
|
|
374
|
-
type: 'API',
|
|
375
|
-
code,
|
|
376
|
-
settings: {
|
|
377
|
-
endpoint: {
|
|
378
|
-
url: url,
|
|
379
|
-
method: 'GET'
|
|
380
|
-
},
|
|
381
|
-
request_schema: [],
|
|
382
|
-
response_mapping: {}
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
catch (error) {
|
|
387
|
-
spinner.fail('Failed to fetch OpenAPI spec');
|
|
388
|
-
throw error;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Create integration from OpenAPI file
|
|
393
|
-
*/
|
|
394
|
-
async function createFromOpenAPIFile(filePath) {
|
|
395
|
-
if (!filePath) {
|
|
396
|
-
const answers = await inquirer_1.default.prompt([{
|
|
397
|
-
type: 'input',
|
|
398
|
-
name: 'filePath',
|
|
399
|
-
message: 'Path to OpenAPI JSON file:',
|
|
400
|
-
validate: (input) => {
|
|
401
|
-
if (!fs.existsSync(input))
|
|
402
|
-
return `File not found: ${input}`;
|
|
403
|
-
return true;
|
|
404
|
-
}
|
|
405
|
-
}]);
|
|
406
|
-
filePath = answers.filePath;
|
|
407
|
-
}
|
|
408
|
-
console.log(chalk_1.default.yellow('\n OpenAPI file import is a work in progress.'));
|
|
409
|
-
console.log(chalk_1.default.yellow(' Creating a placeholder integration.\n'));
|
|
410
|
-
const { code } = await inquirer_1.default.prompt([{
|
|
411
|
-
type: 'input',
|
|
412
|
-
name: 'code',
|
|
413
|
-
message: 'Integration code:',
|
|
414
|
-
validate: (input) => /^[a-z][a-z0-9-]*$/.test(input) || 'Use kebab-case'
|
|
415
|
-
}]);
|
|
209
|
+
function scaffoldMCP(code) {
|
|
416
210
|
return {
|
|
417
|
-
type: '
|
|
211
|
+
type: 'MCP',
|
|
418
212
|
code,
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
request_schema: [],
|
|
422
|
-
response_mapping: {}
|
|
423
|
-
}
|
|
213
|
+
description: '',
|
|
214
|
+
settings: undefined
|
|
424
215
|
};
|
|
425
216
|
}
|
|
426
|
-
|
|
427
|
-
* Save integration to integrations.aui.json
|
|
428
|
-
*/
|
|
217
|
+
// ─── Save ───
|
|
429
218
|
async function saveIntegration(integration, projectRoot) {
|
|
430
|
-
const
|
|
431
|
-
const integrationsPath = path.join(targetDir, 'integrations.aui.json');
|
|
219
|
+
const integrationsPath = path.join(projectRoot, 'integrations.aui.json');
|
|
432
220
|
let existingIntegrations = [];
|
|
433
|
-
// Load existing file
|
|
434
221
|
if (fs.existsSync(integrationsPath)) {
|
|
435
222
|
try {
|
|
436
223
|
const content = fs.readFileSync(integrationsPath, 'utf-8');
|
|
@@ -438,7 +225,7 @@ async function saveIntegration(integration, projectRoot) {
|
|
|
438
225
|
existingIntegrations = parsed.integrations || [];
|
|
439
226
|
}
|
|
440
227
|
catch {
|
|
441
|
-
//
|
|
228
|
+
// Start fresh if file is invalid
|
|
442
229
|
}
|
|
443
230
|
}
|
|
444
231
|
// Check for duplicate
|
|
@@ -447,38 +234,21 @@ async function saveIntegration(integration, projectRoot) {
|
|
|
447
234
|
const { action } = await inquirer_1.default.prompt([{
|
|
448
235
|
type: 'list',
|
|
449
236
|
name: 'action',
|
|
450
|
-
message: `Integration "${integration.code}" already exists
|
|
237
|
+
message: `Integration "${integration.code}" already exists.`,
|
|
451
238
|
choices: [
|
|
452
|
-
{ name: 'Replace
|
|
453
|
-
{ name: 'Rename new integration', value: 'rename' },
|
|
239
|
+
{ name: 'Replace it', value: 'replace' },
|
|
454
240
|
{ name: 'Cancel', value: 'cancel' }
|
|
455
241
|
]
|
|
456
242
|
}]);
|
|
457
243
|
if (action === 'cancel') {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
if (action === 'replace') {
|
|
461
|
-
existingIntegrations[existingIdx] = integration;
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
const { newCode } = await inquirer_1.default.prompt([{
|
|
465
|
-
type: 'input',
|
|
466
|
-
name: 'newCode',
|
|
467
|
-
message: 'New integration code:',
|
|
468
|
-
validate: (input) => /^[a-z][a-z0-9-]*$/.test(input) || 'Use kebab-case'
|
|
469
|
-
}]);
|
|
470
|
-
integration.code = newCode;
|
|
471
|
-
existingIntegrations.push(integration);
|
|
244
|
+
console.log(chalk_1.default.gray('\n Cancelled.\n'));
|
|
245
|
+
return;
|
|
472
246
|
}
|
|
247
|
+
existingIntegrations[existingIdx] = integration;
|
|
473
248
|
}
|
|
474
249
|
else {
|
|
475
250
|
existingIntegrations.push(integration);
|
|
476
251
|
}
|
|
477
|
-
|
|
478
|
-
const fileContent = {
|
|
479
|
-
integrations: existingIntegrations
|
|
480
|
-
};
|
|
481
|
-
fs.writeFileSync(integrationsPath, JSON.stringify(fileContent, null, 2) + '\n');
|
|
482
|
-
console.log(chalk_1.default.gray(` Saved to: ${integrationsPath}`));
|
|
252
|
+
fs.writeFileSync(integrationsPath, JSON.stringify({ integrations: existingIntegrations }, null, 2) + '\n');
|
|
483
253
|
}
|
|
484
254
|
//# sourceMappingURL=add-integration.js.map
|