lua-cli 2.3.0 → 2.4.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/dist/api/products.api.service.js +1 -0
- package/dist/cli/command-definitions.d.ts +0 -8
- package/dist/cli/command-definitions.js +51 -18
- package/dist/commands/chat.d.ts +17 -0
- package/dist/commands/chat.js +236 -0
- package/dist/commands/chatClear.d.ts +15 -0
- package/dist/commands/chatClear.js +75 -0
- package/dist/commands/deploy.d.ts +7 -5
- package/dist/commands/deploy.js +34 -15
- package/dist/commands/env.d.ts +19 -0
- package/dist/commands/env.js +434 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.js +6 -0
- package/dist/commands/init.js +6 -6
- package/dist/commands/persona.d.ts +15 -0
- package/dist/commands/persona.js +503 -0
- package/dist/commands/production.d.ts +15 -0
- package/dist/commands/production.js +532 -0
- package/dist/commands/push.d.ts +7 -5
- package/dist/commands/push.js +100 -21
- package/dist/commands/resources.d.ts +17 -0
- package/dist/commands/resources.js +361 -0
- package/dist/common/data.entry.instance.js +6 -2
- package/dist/common/http.client.js +7 -0
- package/dist/config/compile.constants.d.ts +4 -3
- package/dist/config/compile.constants.js +3 -7
- package/dist/config/constants.d.ts +6 -0
- package/dist/config/constants.js +11 -0
- package/dist/errors/auth.error.d.ts +15 -0
- package/dist/errors/auth.error.js +27 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.js +4 -0
- package/dist/index.d.ts +0 -9
- package/dist/index.js +30 -11
- package/dist/interfaces/agent.d.ts +33 -49
- package/dist/services/auth.d.ts +1 -2
- package/dist/services/auth.js +3 -4
- package/dist/utils/bundling.js +61 -0
- package/dist/utils/cli.js +6 -0
- package/dist/utils/deploy-helpers.d.ts +22 -0
- package/dist/utils/deploy-helpers.js +61 -2
- package/dist/utils/deployment.js +33 -1
- package/dist/utils/dev-server.js +255 -0
- package/dist/utils/init-agent.js +3 -3
- package/dist/utils/prompt-handler.d.ts +12 -0
- package/dist/utils/prompt-handler.js +31 -0
- package/dist/utils/push-helpers.d.ts +47 -3
- package/dist/utils/push-helpers.js +167 -10
- package/dist/utils/sandbox.js +18 -5
- package/dist/web/app.css +1302 -465
- package/dist/web/app.js +53 -46
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/template/src/tools/BasketTool.ts +4 -1
- package/template/src/tools/ProductsTool.ts +7 -7
- package/dist/web/tools-page.css +0 -381
package/dist/commands/push.js
CHANGED
|
@@ -5,19 +5,23 @@
|
|
|
5
5
|
import { compileCommand } from './compile.js';
|
|
6
6
|
import { checkApiKey, loadApiKey } from '../services/auth.js';
|
|
7
7
|
import { readSkillConfig } from '../utils/files.js';
|
|
8
|
-
import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
|
|
9
|
-
import {
|
|
8
|
+
import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
|
|
9
|
+
import { safePrompt } from '../utils/prompt-handler.js';
|
|
10
|
+
import { readDeployJson, validatePushConfig, validateDeployData, promptSkillSelection, promptVersionConfirmOrUpdate, getAvailableSkills, updateSkillVersionInYaml, getSkillDeployData, } from '../utils/push-helpers.js';
|
|
10
11
|
import { pushVersion } from '../utils/push-api.js';
|
|
12
|
+
import { fetchVersions, publishVersion, } from '../utils/deploy-api.js';
|
|
11
13
|
/**
|
|
12
14
|
* Main push command - pushes a skill version to the server.
|
|
13
15
|
*
|
|
14
16
|
* This command performs the following steps:
|
|
15
17
|
* 1. Validates configuration has required fields
|
|
16
|
-
* 2. Prompts
|
|
17
|
-
* 3.
|
|
18
|
-
* 4.
|
|
19
|
-
* 5.
|
|
20
|
-
* 6.
|
|
18
|
+
* 2. Prompts user to select a skill (if multiple skills exist)
|
|
19
|
+
* 3. Prompts to confirm or update version
|
|
20
|
+
* 4. Authenticates the user
|
|
21
|
+
* 5. Compiles the skill (always, to ensure deploy.json is current)
|
|
22
|
+
* 6. Validates deploy.json matches configuration for selected skill
|
|
23
|
+
* 7. Extracts the specific skill's deploy data
|
|
24
|
+
* 8. Pushes version to server
|
|
21
25
|
*
|
|
22
26
|
* Use this command to:
|
|
23
27
|
* - Upload a new version of your skill
|
|
@@ -33,14 +37,33 @@ export async function pushCommand() {
|
|
|
33
37
|
// Step 1: Validate configuration
|
|
34
38
|
const config = readSkillConfig();
|
|
35
39
|
validatePushConfig(config);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// Step 2: Get available skills and prompt for selection
|
|
41
|
+
const availableSkills = getAvailableSkills(config);
|
|
42
|
+
if (availableSkills.length === 0) {
|
|
43
|
+
console.error("❌ No skills found in configuration. Please compile your skill first using 'lua compile'.");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
let selectedSkill;
|
|
47
|
+
if (availableSkills.length === 1) {
|
|
48
|
+
// Only one skill, use it automatically
|
|
49
|
+
selectedSkill = availableSkills[0];
|
|
50
|
+
writeInfo(`📦 Pushing skill: ${selectedSkill.name}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Multiple skills, prompt for selection
|
|
54
|
+
selectedSkill = await promptSkillSelection(availableSkills);
|
|
55
|
+
writeInfo(`📦 Selected skill: ${selectedSkill.name}`);
|
|
56
|
+
}
|
|
57
|
+
// Step 3: Confirm or update version
|
|
58
|
+
const confirmedVersion = await promptVersionConfirmOrUpdate(selectedSkill.version);
|
|
59
|
+
let versionUpdated = false;
|
|
60
|
+
if (confirmedVersion !== selectedSkill.version) {
|
|
61
|
+
writeInfo(`📝 Updating version from ${selectedSkill.version} to ${confirmedVersion}`);
|
|
62
|
+
updateSkillVersionInYaml(selectedSkill.name, confirmedVersion);
|
|
63
|
+
selectedSkill.version = confirmedVersion;
|
|
64
|
+
versionUpdated = true;
|
|
42
65
|
}
|
|
43
|
-
// Step
|
|
66
|
+
// Step 4: Authenticate
|
|
44
67
|
const apiKey = await loadApiKey();
|
|
45
68
|
if (!apiKey) {
|
|
46
69
|
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
@@ -48,19 +71,33 @@ export async function pushCommand() {
|
|
|
48
71
|
}
|
|
49
72
|
const userData = await checkApiKey(apiKey);
|
|
50
73
|
writeProgress("✅ Authenticated");
|
|
51
|
-
// Step
|
|
74
|
+
// Step 5: Compile the skill (always compile to ensure up-to-date, or if version was updated)
|
|
52
75
|
writeProgress("🔄 Compiling skill...");
|
|
53
76
|
await compileCommand();
|
|
54
|
-
// Step
|
|
77
|
+
// Step 6: Validate deploy data for the selected skill
|
|
55
78
|
const deployData = readDeployJson();
|
|
56
|
-
validateDeployData(deployData,
|
|
57
|
-
// Step
|
|
79
|
+
validateDeployData(deployData, selectedSkill);
|
|
80
|
+
// Step 7: Extract the specific skill's deploy data
|
|
81
|
+
const skillDeployData = getSkillDeployData(deployData, selectedSkill.name);
|
|
82
|
+
// Step 8: Push version to server
|
|
58
83
|
const agentId = config.agent.agentId;
|
|
59
|
-
const skillId =
|
|
84
|
+
const skillId = selectedSkill.skillId;
|
|
60
85
|
writeProgress("🔄 Pushing version to server...");
|
|
61
|
-
const result = await pushVersion(apiKey, agentId, skillId,
|
|
86
|
+
const result = await pushVersion(apiKey, agentId, skillId, skillDeployData);
|
|
62
87
|
if (result.success && result.data) {
|
|
63
|
-
writeSuccess(`✅ Version ${result.data.version} pushed successfully`);
|
|
88
|
+
writeSuccess(`✅ Version ${result.data.version} of "${selectedSkill.name}" pushed successfully`);
|
|
89
|
+
// Ask if user wants to deploy now
|
|
90
|
+
const deployAnswer = await safePrompt([
|
|
91
|
+
{
|
|
92
|
+
type: 'confirm',
|
|
93
|
+
name: 'deployNow',
|
|
94
|
+
message: 'Would you like to deploy this version to production now?',
|
|
95
|
+
default: false
|
|
96
|
+
}
|
|
97
|
+
]);
|
|
98
|
+
if (deployAnswer && deployAnswer.deployNow) {
|
|
99
|
+
await deployVersionAfterPush(apiKey, config.agent.agentId, selectedSkill, result.data.version);
|
|
100
|
+
}
|
|
64
101
|
}
|
|
65
102
|
else if (result.error) {
|
|
66
103
|
console.error(`❌ ${result.error.message}`);
|
|
@@ -72,3 +109,45 @@ export async function pushCommand() {
|
|
|
72
109
|
}
|
|
73
110
|
}, "push");
|
|
74
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Deploy a version immediately after pushing
|
|
114
|
+
*/
|
|
115
|
+
async function deployVersionAfterPush(apiKey, agentId, selectedSkill, pushedVersion) {
|
|
116
|
+
try {
|
|
117
|
+
writeProgress("\n🔄 Fetching available versions...");
|
|
118
|
+
// Fetch versions to verify the pushed version exists
|
|
119
|
+
const versionsResponse = await fetchVersions(apiKey, agentId, selectedSkill.skillId);
|
|
120
|
+
if (!versionsResponse.versions || versionsResponse.versions.length === 0) {
|
|
121
|
+
console.error("❌ No versions available. The push may have failed.");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Show warning
|
|
125
|
+
console.log("\n⚠️ WARNING: You are about to deploy to PRODUCTION!");
|
|
126
|
+
console.log("⚠️ This will affect ALL users immediately.\n");
|
|
127
|
+
const confirmAnswer = await safePrompt([
|
|
128
|
+
{
|
|
129
|
+
type: 'confirm',
|
|
130
|
+
name: 'confirm',
|
|
131
|
+
message: 'Are you absolutely sure you want to deploy?',
|
|
132
|
+
default: false
|
|
133
|
+
}
|
|
134
|
+
]);
|
|
135
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
136
|
+
console.log("\n❌ Deployment cancelled. Version pushed but not deployed.\n");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// Find the pushed version in the list
|
|
140
|
+
const versionToDeploy = versionsResponse.versions.find((v) => v.version === pushedVersion);
|
|
141
|
+
if (!versionToDeploy) {
|
|
142
|
+
console.error(`\n❌ Version ${pushedVersion} not found in available versions.\n`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
writeProgress("🔄 Publishing version...");
|
|
146
|
+
const publishResponse = await publishVersion(apiKey, agentId, selectedSkill.skillId, pushedVersion);
|
|
147
|
+
writeSuccess(`\n✅ Version ${pushedVersion} of "${selectedSkill.name}" deployed successfully to production\n`);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error('\n❌ Error deploying version:', error);
|
|
151
|
+
console.log('💡 You can deploy later using: lua deploy\n');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resources Command
|
|
3
|
+
* Manages agent resources (knowledge base documents)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Main resources command - manages agent resources
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - List all resources
|
|
10
|
+
* - Create new resources
|
|
11
|
+
* - Update existing resources
|
|
12
|
+
* - Delete resources
|
|
13
|
+
* - View resource content
|
|
14
|
+
*
|
|
15
|
+
* @returns Promise that resolves when command completes
|
|
16
|
+
*/
|
|
17
|
+
export declare function resourcesCommand(): Promise<void>;
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resources Command
|
|
3
|
+
* Manages agent resources (knowledge base documents)
|
|
4
|
+
*/
|
|
5
|
+
import { loadApiKey, checkApiKey } from '../services/auth.js';
|
|
6
|
+
import { readSkillConfig } from '../utils/files.js';
|
|
7
|
+
import { withErrorHandling, writeProgress, writeSuccess } from '../utils/cli.js';
|
|
8
|
+
import { BASE_URLS } from '../config/constants.js';
|
|
9
|
+
import { safePrompt } from '../utils/prompt-handler.js';
|
|
10
|
+
import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
|
|
11
|
+
/**
|
|
12
|
+
* Main resources command - manages agent resources
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - List all resources
|
|
16
|
+
* - Create new resources
|
|
17
|
+
* - Update existing resources
|
|
18
|
+
* - Delete resources
|
|
19
|
+
* - View resource content
|
|
20
|
+
*
|
|
21
|
+
* @returns Promise that resolves when command completes
|
|
22
|
+
*/
|
|
23
|
+
export async function resourcesCommand() {
|
|
24
|
+
return withErrorHandling(async () => {
|
|
25
|
+
// Step 1: Load configuration
|
|
26
|
+
const config = readSkillConfig();
|
|
27
|
+
validateConfig(config);
|
|
28
|
+
validateAgentConfig(config);
|
|
29
|
+
const agentId = config.agent.agentId;
|
|
30
|
+
// Step 2: Authenticate
|
|
31
|
+
const apiKey = await loadApiKey();
|
|
32
|
+
if (!apiKey) {
|
|
33
|
+
console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
await checkApiKey(apiKey);
|
|
37
|
+
writeProgress("✅ Authenticated");
|
|
38
|
+
const context = {
|
|
39
|
+
agentId,
|
|
40
|
+
apiKey,
|
|
41
|
+
};
|
|
42
|
+
// Step 3: Start management loop
|
|
43
|
+
await manageResources(context);
|
|
44
|
+
}, "resources");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Main resources management loop
|
|
48
|
+
*/
|
|
49
|
+
async function manageResources(context) {
|
|
50
|
+
let continueManaging = true;
|
|
51
|
+
while (continueManaging) {
|
|
52
|
+
// Load current resources
|
|
53
|
+
const resources = await loadResources(context);
|
|
54
|
+
console.log("\n" + "=".repeat(60));
|
|
55
|
+
console.log("📚 Agent Resources");
|
|
56
|
+
console.log("=".repeat(60) + "\n");
|
|
57
|
+
if (resources.length === 0) {
|
|
58
|
+
console.log("ℹ️ No resources configured.\n");
|
|
59
|
+
console.log("💡 Resources are knowledge base documents your agent can reference.\n");
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
resources.forEach((resource, index) => {
|
|
63
|
+
const preview = resource.content.length > 60
|
|
64
|
+
? resource.content.substring(0, 60) + '...'
|
|
65
|
+
: resource.content;
|
|
66
|
+
console.log(`${index + 1}. ${resource.name}`);
|
|
67
|
+
console.log(` Preview: ${preview}`);
|
|
68
|
+
console.log();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const actionAnswer = await safePrompt([
|
|
72
|
+
{
|
|
73
|
+
type: 'list',
|
|
74
|
+
name: 'action',
|
|
75
|
+
message: 'What would you like to do?',
|
|
76
|
+
choices: [
|
|
77
|
+
{ name: '➕ Create new resource', value: 'create' },
|
|
78
|
+
{ name: '✏️ Update existing resource', value: 'update' },
|
|
79
|
+
{ name: '🗑️ Delete resource', value: 'delete' },
|
|
80
|
+
{ name: '👁️ View resource content', value: 'view' },
|
|
81
|
+
{ name: '🔄 Refresh list', value: 'refresh' },
|
|
82
|
+
{ name: '❌ Exit', value: 'exit' }
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
]);
|
|
86
|
+
if (!actionAnswer)
|
|
87
|
+
return;
|
|
88
|
+
const { action } = actionAnswer;
|
|
89
|
+
switch (action) {
|
|
90
|
+
case 'create':
|
|
91
|
+
await createResource(context);
|
|
92
|
+
break;
|
|
93
|
+
case 'update':
|
|
94
|
+
await updateResource(context, resources);
|
|
95
|
+
break;
|
|
96
|
+
case 'delete':
|
|
97
|
+
await deleteResource(context, resources);
|
|
98
|
+
break;
|
|
99
|
+
case 'view':
|
|
100
|
+
await viewResource(resources);
|
|
101
|
+
break;
|
|
102
|
+
case 'refresh':
|
|
103
|
+
// Just loop again
|
|
104
|
+
break;
|
|
105
|
+
case 'exit':
|
|
106
|
+
continueManaging = false;
|
|
107
|
+
console.log("\n👋 Goodbye!\n");
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Load resources from API
|
|
114
|
+
*/
|
|
115
|
+
async function loadResources(context) {
|
|
116
|
+
try {
|
|
117
|
+
const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources`, {
|
|
118
|
+
method: 'GET',
|
|
119
|
+
headers: {
|
|
120
|
+
'accept': 'application/json',
|
|
121
|
+
'Authorization': `Bearer ${context.apiKey}`
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
const data = await response.json();
|
|
128
|
+
if (Array.isArray(data)) {
|
|
129
|
+
return data;
|
|
130
|
+
}
|
|
131
|
+
else if (data.data && Array.isArray(data.data)) {
|
|
132
|
+
return data.data;
|
|
133
|
+
}
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error('⚠️ Error loading resources');
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Create a new resource
|
|
143
|
+
*/
|
|
144
|
+
async function createResource(context) {
|
|
145
|
+
const answers = await safePrompt([
|
|
146
|
+
{
|
|
147
|
+
type: 'input',
|
|
148
|
+
name: 'name',
|
|
149
|
+
message: 'Resource name:',
|
|
150
|
+
validate: (input) => {
|
|
151
|
+
if (!input.trim())
|
|
152
|
+
return 'Resource name is required';
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
type: 'editor',
|
|
158
|
+
name: 'content',
|
|
159
|
+
message: 'Resource content (will open in your default editor):',
|
|
160
|
+
validate: (input) => {
|
|
161
|
+
if (!input.trim())
|
|
162
|
+
return 'Resource content cannot be empty';
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
]);
|
|
167
|
+
if (!answers)
|
|
168
|
+
return;
|
|
169
|
+
writeProgress("🔄 Creating resource...");
|
|
170
|
+
try {
|
|
171
|
+
const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources`, {
|
|
172
|
+
method: 'POST',
|
|
173
|
+
headers: {
|
|
174
|
+
'accept': 'application/json',
|
|
175
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
176
|
+
'Content-Type': 'application/json'
|
|
177
|
+
},
|
|
178
|
+
body: JSON.stringify({
|
|
179
|
+
name: answers.name.trim(),
|
|
180
|
+
content: answers.content.trim()
|
|
181
|
+
})
|
|
182
|
+
});
|
|
183
|
+
if (!response.ok) {
|
|
184
|
+
const errorText = await response.text();
|
|
185
|
+
throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
|
|
186
|
+
}
|
|
187
|
+
writeSuccess(`✅ Resource "${answers.name}" created successfully`);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
console.error('❌ Error creating resource:', error);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Update an existing resource
|
|
195
|
+
*/
|
|
196
|
+
async function updateResource(context, resources) {
|
|
197
|
+
if (resources.length === 0) {
|
|
198
|
+
console.log("\nℹ️ No resources to update.\n");
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const selectAnswer = await safePrompt([
|
|
202
|
+
{
|
|
203
|
+
type: 'list',
|
|
204
|
+
name: 'selectedId',
|
|
205
|
+
message: 'Select resource to update:',
|
|
206
|
+
choices: resources.map(r => ({
|
|
207
|
+
name: r.name,
|
|
208
|
+
value: r.id
|
|
209
|
+
}))
|
|
210
|
+
}
|
|
211
|
+
]);
|
|
212
|
+
if (!selectAnswer)
|
|
213
|
+
return;
|
|
214
|
+
const selectedResource = resources.find(r => r.id === selectAnswer.selectedId);
|
|
215
|
+
const updateAnswers = await safePrompt([
|
|
216
|
+
{
|
|
217
|
+
type: 'input',
|
|
218
|
+
name: 'name',
|
|
219
|
+
message: 'Resource name:',
|
|
220
|
+
default: selectedResource.name,
|
|
221
|
+
validate: (input) => {
|
|
222
|
+
if (!input.trim())
|
|
223
|
+
return 'Resource name is required';
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
type: 'editor',
|
|
229
|
+
name: 'content',
|
|
230
|
+
message: 'Resource content (will open in your default editor):',
|
|
231
|
+
default: selectedResource.content,
|
|
232
|
+
validate: (input) => {
|
|
233
|
+
if (!input.trim())
|
|
234
|
+
return 'Resource content cannot be empty';
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
]);
|
|
239
|
+
if (!updateAnswers)
|
|
240
|
+
return;
|
|
241
|
+
writeProgress("🔄 Updating resource...");
|
|
242
|
+
try {
|
|
243
|
+
const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources/${selectAnswer.selectedId}`, {
|
|
244
|
+
method: 'PUT',
|
|
245
|
+
headers: {
|
|
246
|
+
'accept': 'application/json',
|
|
247
|
+
'Authorization': `Bearer ${context.apiKey}`,
|
|
248
|
+
'Content-Type': 'application/json'
|
|
249
|
+
},
|
|
250
|
+
body: JSON.stringify({
|
|
251
|
+
name: updateAnswers.name.trim(),
|
|
252
|
+
content: updateAnswers.content.trim()
|
|
253
|
+
})
|
|
254
|
+
});
|
|
255
|
+
if (!response.ok) {
|
|
256
|
+
const errorText = await response.text();
|
|
257
|
+
throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
|
|
258
|
+
}
|
|
259
|
+
writeSuccess(`✅ Resource "${updateAnswers.name}" updated successfully`);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
console.error('❌ Error updating resource:', error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Delete a resource
|
|
267
|
+
*/
|
|
268
|
+
async function deleteResource(context, resources) {
|
|
269
|
+
if (resources.length === 0) {
|
|
270
|
+
console.log("\nℹ️ No resources to delete.\n");
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const selectAnswer = await safePrompt([
|
|
274
|
+
{
|
|
275
|
+
type: 'list',
|
|
276
|
+
name: 'selectedId',
|
|
277
|
+
message: 'Select resource to delete:',
|
|
278
|
+
choices: resources.map(r => ({
|
|
279
|
+
name: r.name,
|
|
280
|
+
value: r.id
|
|
281
|
+
}))
|
|
282
|
+
}
|
|
283
|
+
]);
|
|
284
|
+
if (!selectAnswer)
|
|
285
|
+
return;
|
|
286
|
+
const selectedResource = resources.find(r => r.id === selectAnswer.selectedId);
|
|
287
|
+
const confirmAnswer = await safePrompt([
|
|
288
|
+
{
|
|
289
|
+
type: 'confirm',
|
|
290
|
+
name: 'confirm',
|
|
291
|
+
message: `Are you sure you want to delete "${selectedResource.name}"?`,
|
|
292
|
+
default: false
|
|
293
|
+
}
|
|
294
|
+
]);
|
|
295
|
+
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
296
|
+
console.log("\nℹ️ Deletion cancelled.\n");
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
writeProgress("🔄 Deleting resource...");
|
|
300
|
+
try {
|
|
301
|
+
const response = await fetch(`${BASE_URLS.API}/admin/agents/${context.agentId}/resources/${selectAnswer.selectedId}`, {
|
|
302
|
+
method: 'DELETE',
|
|
303
|
+
headers: {
|
|
304
|
+
'accept': '*/*',
|
|
305
|
+
'Authorization': `Bearer ${context.apiKey}`
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
if (!response.ok) {
|
|
309
|
+
const errorText = await response.text();
|
|
310
|
+
throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
|
|
311
|
+
}
|
|
312
|
+
writeSuccess(`✅ Resource "${selectedResource.name}" deleted successfully`);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
console.error('❌ Error deleting resource:', error);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* View a resource's full content
|
|
320
|
+
*/
|
|
321
|
+
async function viewResource(resources) {
|
|
322
|
+
if (resources.length === 0) {
|
|
323
|
+
console.log("\nℹ️ No resources to view.\n");
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const selectAnswer = await safePrompt([
|
|
327
|
+
{
|
|
328
|
+
type: 'list',
|
|
329
|
+
name: 'selectedId',
|
|
330
|
+
message: 'Select resource to view:',
|
|
331
|
+
choices: resources.map(r => ({
|
|
332
|
+
name: r.name,
|
|
333
|
+
value: r.id
|
|
334
|
+
}))
|
|
335
|
+
}
|
|
336
|
+
]);
|
|
337
|
+
if (!selectAnswer)
|
|
338
|
+
return;
|
|
339
|
+
const resource = resources.find(r => r.id === selectAnswer.selectedId);
|
|
340
|
+
console.log("\n" + "=".repeat(60));
|
|
341
|
+
console.log(`📄 Resource: ${resource.name}`);
|
|
342
|
+
console.log("=".repeat(60));
|
|
343
|
+
if (resource.createdAt) {
|
|
344
|
+
const date = new Date(resource.createdAt);
|
|
345
|
+
console.log(`Created: ${date.toLocaleString()}`);
|
|
346
|
+
}
|
|
347
|
+
if (resource.updatedAt) {
|
|
348
|
+
const date = new Date(resource.updatedAt);
|
|
349
|
+
console.log(`Updated: ${date.toLocaleString()}`);
|
|
350
|
+
}
|
|
351
|
+
console.log("=".repeat(60) + "\n");
|
|
352
|
+
console.log(resource.content);
|
|
353
|
+
console.log("\n" + "=".repeat(60) + "\n");
|
|
354
|
+
await safePrompt([
|
|
355
|
+
{
|
|
356
|
+
type: 'input',
|
|
357
|
+
name: 'continue',
|
|
358
|
+
message: 'Press Enter to continue...'
|
|
359
|
+
}
|
|
360
|
+
]);
|
|
361
|
+
}
|
|
@@ -29,7 +29,9 @@ export default class DataEntryInstance {
|
|
|
29
29
|
toJSON() {
|
|
30
30
|
return {
|
|
31
31
|
...this.data,
|
|
32
|
-
score: this.score
|
|
32
|
+
score: this.score,
|
|
33
|
+
id: this.id,
|
|
34
|
+
collectionName: this.collectionName
|
|
33
35
|
};
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
@@ -39,7 +41,9 @@ export default class DataEntryInstance {
|
|
|
39
41
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
40
42
|
return {
|
|
41
43
|
...this.data,
|
|
42
|
-
score: this.score
|
|
44
|
+
score: this.score,
|
|
45
|
+
id: this.id,
|
|
46
|
+
collectionName: this.collectionName
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AuthenticationError } from "../errors/auth.error.js";
|
|
1
2
|
/**
|
|
2
3
|
* Generic HTTP client with common error handling
|
|
3
4
|
* Provides a base class for all API service classes with standardized HTTP methods
|
|
@@ -28,6 +29,9 @@ export class HttpClient {
|
|
|
28
29
|
});
|
|
29
30
|
// Check if response is ok (status 200-299)
|
|
30
31
|
if (!response.ok) {
|
|
32
|
+
if (response.status === 401) {
|
|
33
|
+
throw new AuthenticationError("Invalid API key");
|
|
34
|
+
}
|
|
31
35
|
return {
|
|
32
36
|
success: false,
|
|
33
37
|
error: {
|
|
@@ -55,6 +59,9 @@ export class HttpClient {
|
|
|
55
59
|
};
|
|
56
60
|
}
|
|
57
61
|
catch (error) {
|
|
62
|
+
if (AuthenticationError.isAuthenticationError(error)) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
58
65
|
// Handle network errors, timeouts, etc.
|
|
59
66
|
return {
|
|
60
67
|
success: false,
|
|
@@ -33,10 +33,11 @@ export declare const SKILL_DEFAULTS: {
|
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
35
|
* External packages that should not be bundled with tools
|
|
36
|
-
* These are
|
|
37
|
-
*
|
|
36
|
+
* These are native modules, or modules that should be provided by the runtime environment
|
|
37
|
+
* Note: lua-cli is NOT in this list because it's handled by the sandboxGlobalsPlugin
|
|
38
|
+
* which transforms imports to use sandbox globals instead
|
|
38
39
|
*/
|
|
39
|
-
export declare const EXTERNAL_PACKAGES: readonly ["
|
|
40
|
+
export declare const EXTERNAL_PACKAGES: readonly ["zod", "keytar", "esbuild", "commander", "inquirer", "node-fetch", "ws", "socket.io-client", "ts-morph"];
|
|
40
41
|
/**
|
|
41
42
|
* Common esbuild configuration for tool bundling
|
|
42
43
|
*/
|
|
@@ -32,15 +32,11 @@ export const SKILL_DEFAULTS = {
|
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
34
|
* External packages that should not be bundled with tools
|
|
35
|
-
* These are
|
|
36
|
-
*
|
|
35
|
+
* These are native modules, or modules that should be provided by the runtime environment
|
|
36
|
+
* Note: lua-cli is NOT in this list because it's handled by the sandboxGlobalsPlugin
|
|
37
|
+
* which transforms imports to use sandbox globals instead
|
|
37
38
|
*/
|
|
38
39
|
export const EXTERNAL_PACKAGES = [
|
|
39
|
-
'lua-cli/skill',
|
|
40
|
-
'lua-cli',
|
|
41
|
-
'lua-cli/user-data-api',
|
|
42
|
-
'lua-cli/product-api',
|
|
43
|
-
'lua-cli/custom-data-api',
|
|
44
40
|
'zod',
|
|
45
41
|
'keytar',
|
|
46
42
|
'esbuild',
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base URLs for the API, Auth, and Chat - Production
|
|
3
|
+
*/
|
|
1
4
|
export declare const BASE_URLS: {
|
|
2
5
|
readonly API: "https://api.heylua.ai";
|
|
3
6
|
readonly AUTH: "https://auth.heylua.ai";
|
|
4
7
|
readonly CHAT: "https://api.heylua.ai";
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Base URLs for the API, Auth, and Chat - Development
|
|
11
|
+
*/
|
package/dist/config/constants.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base URLs for the API, Auth, and Chat - Production
|
|
3
|
+
*/
|
|
1
4
|
export const BASE_URLS = {
|
|
2
5
|
API: 'https://api.heylua.ai',
|
|
3
6
|
AUTH: 'https://auth.heylua.ai',
|
|
4
7
|
CHAT: 'https://api.heylua.ai',
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Base URLs for the API, Auth, and Chat - Development
|
|
11
|
+
*/
|
|
12
|
+
// export const BASE_URLS = {
|
|
13
|
+
// API: 'http://localhost:3022',
|
|
14
|
+
// AUTH: 'https://auth.heylua.ai',
|
|
15
|
+
// CHAT: 'http://localhost:3001',
|
|
16
|
+
// } as const;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Error
|
|
3
|
+
* Thrown when API requests fail with 401 Unauthorized status
|
|
4
|
+
*/
|
|
5
|
+
export declare class AuthenticationError extends Error {
|
|
6
|
+
readonly statusCode: number;
|
|
7
|
+
readonly isAuthenticationError: boolean;
|
|
8
|
+
constructor(message?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Checks if an error is an AuthenticationError
|
|
11
|
+
* @param error - The error to check
|
|
12
|
+
* @returns True if the error is an AuthenticationError
|
|
13
|
+
*/
|
|
14
|
+
static isAuthenticationError(error: unknown): error is AuthenticationError;
|
|
15
|
+
}
|