luxlabs 1.0.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/LICENSE +37 -0
- package/README.md +161 -0
- package/commands/ab-tests.js +437 -0
- package/commands/agents.js +226 -0
- package/commands/data.js +966 -0
- package/commands/deploy.js +166 -0
- package/commands/dev.js +569 -0
- package/commands/init.js +126 -0
- package/commands/interface/boilerplate.js +52 -0
- package/commands/interface/git-utils.js +85 -0
- package/commands/interface/index.js +7 -0
- package/commands/interface/init.js +375 -0
- package/commands/interface/path.js +74 -0
- package/commands/interface.js +125 -0
- package/commands/knowledge.js +339 -0
- package/commands/link.js +127 -0
- package/commands/list.js +97 -0
- package/commands/login.js +247 -0
- package/commands/logout.js +19 -0
- package/commands/logs.js +182 -0
- package/commands/pricing.js +328 -0
- package/commands/project.js +704 -0
- package/commands/secrets.js +129 -0
- package/commands/servers.js +411 -0
- package/commands/storage.js +177 -0
- package/commands/up.js +211 -0
- package/commands/validate-data-lux.js +502 -0
- package/commands/voice-agents.js +1055 -0
- package/commands/webview.js +393 -0
- package/commands/workflows.js +836 -0
- package/lib/config.js +403 -0
- package/lib/helpers.js +189 -0
- package/lib/node-helper.js +120 -0
- package/lux.js +268 -0
- package/package.json +56 -0
- package/templates/next-env.d.ts +6 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lux CLI - Pricing Commands
|
|
3
|
+
*
|
|
4
|
+
* Manage AWS AppConfig pricing configuration for Lux credits.
|
|
5
|
+
*
|
|
6
|
+
* Commands:
|
|
7
|
+
* lux pricing show - Show current pricing config
|
|
8
|
+
* lux pricing export [file] - Export pricing config to JSON file
|
|
9
|
+
* lux pricing deploy [file] - Deploy pricing config to AWS AppConfig
|
|
10
|
+
* lux pricing set-secrets - Set AWS credentials in Cloudflare Workers
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const chalk = require('chalk');
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
// AppConfig details (from user's setup)
|
|
18
|
+
const APPCONFIG = {
|
|
19
|
+
region: 'us-east-2',
|
|
20
|
+
applicationId: 'wgicy0c',
|
|
21
|
+
environmentId: 'wz6k5o6',
|
|
22
|
+
environmentName: 'development',
|
|
23
|
+
configProfileId: 'gagerlg',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Default pricing configuration (matches lux-studio-api/src/lib/appconfig-pricing.ts)
|
|
27
|
+
const DEFAULT_PRICING_CONFIG = {
|
|
28
|
+
usdToCredits: 100, // $1 = 100 credits
|
|
29
|
+
luxMarkup: 1.2, // 20% markup
|
|
30
|
+
|
|
31
|
+
sessionExpiryMinutes: 15,
|
|
32
|
+
defaultCreditReservation: 20,
|
|
33
|
+
lowBalanceThreshold: 100,
|
|
34
|
+
|
|
35
|
+
models: {
|
|
36
|
+
'claude-opus-4-5-20250514': {
|
|
37
|
+
input: 15.0,
|
|
38
|
+
output: 75.0,
|
|
39
|
+
cacheRead: 1.50,
|
|
40
|
+
cacheWrite: 18.75,
|
|
41
|
+
},
|
|
42
|
+
'claude-sonnet-4-5-20250514': {
|
|
43
|
+
input: 3.0,
|
|
44
|
+
output: 15.0,
|
|
45
|
+
cacheRead: 0.30,
|
|
46
|
+
cacheWrite: 3.75,
|
|
47
|
+
},
|
|
48
|
+
'claude-opus-4-20250514': {
|
|
49
|
+
input: 15.0,
|
|
50
|
+
output: 75.0,
|
|
51
|
+
cacheRead: 1.50,
|
|
52
|
+
cacheWrite: 18.75,
|
|
53
|
+
},
|
|
54
|
+
'claude-sonnet-4-20250514': {
|
|
55
|
+
input: 3.0,
|
|
56
|
+
output: 15.0,
|
|
57
|
+
cacheRead: 0.30,
|
|
58
|
+
cacheWrite: 3.75,
|
|
59
|
+
},
|
|
60
|
+
'claude-3-5-sonnet-20241022': {
|
|
61
|
+
input: 3.0,
|
|
62
|
+
output: 15.0,
|
|
63
|
+
cacheRead: 0.30,
|
|
64
|
+
cacheWrite: 3.75,
|
|
65
|
+
},
|
|
66
|
+
'claude-3-5-sonnet-20240620': {
|
|
67
|
+
input: 3.0,
|
|
68
|
+
output: 15.0,
|
|
69
|
+
cacheRead: 0.30,
|
|
70
|
+
cacheWrite: 3.75,
|
|
71
|
+
},
|
|
72
|
+
'default': {
|
|
73
|
+
input: 3.0,
|
|
74
|
+
output: 15.0,
|
|
75
|
+
cacheRead: 0.30,
|
|
76
|
+
cacheWrite: 3.75,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
features: {
|
|
81
|
+
enableCaching: true,
|
|
82
|
+
enableDetailedUsageTracking: true,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
version: '1.0.0',
|
|
86
|
+
updatedAt: new Date().toISOString(),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
async function showHelp() {
|
|
90
|
+
console.log(`
|
|
91
|
+
${chalk.bold('Lux Pricing Commands')}
|
|
92
|
+
|
|
93
|
+
Manage AWS AppConfig pricing configuration for Lux credits.
|
|
94
|
+
|
|
95
|
+
${chalk.yellow('Usage:')}
|
|
96
|
+
lux pricing <command> [options]
|
|
97
|
+
|
|
98
|
+
${chalk.yellow('Commands:')}
|
|
99
|
+
show Show current/default pricing configuration
|
|
100
|
+
export [file] Export pricing config to JSON file (default: pricing-config.json)
|
|
101
|
+
deploy <file> Deploy pricing config to AWS AppConfig
|
|
102
|
+
set-secrets Show commands to set AWS credentials in Cloudflare Workers
|
|
103
|
+
|
|
104
|
+
${chalk.yellow('AppConfig Details:')}
|
|
105
|
+
Region: ${APPCONFIG.region}
|
|
106
|
+
Application: ${APPCONFIG.applicationId}
|
|
107
|
+
Environment: ${APPCONFIG.environmentName} (${APPCONFIG.environmentId})
|
|
108
|
+
Profile: ${APPCONFIG.configProfileId}
|
|
109
|
+
|
|
110
|
+
${chalk.yellow('Examples:')}
|
|
111
|
+
${chalk.gray('# View current pricing')}
|
|
112
|
+
lux pricing show
|
|
113
|
+
|
|
114
|
+
${chalk.gray('# Export default config to edit')}
|
|
115
|
+
lux pricing export ./my-pricing.json
|
|
116
|
+
|
|
117
|
+
${chalk.gray('# Deploy updated pricing')}
|
|
118
|
+
lux pricing deploy ./my-pricing.json
|
|
119
|
+
`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function showPricing() {
|
|
123
|
+
console.log(chalk.bold('\nCurrent Pricing Configuration:\n'));
|
|
124
|
+
|
|
125
|
+
console.log(chalk.yellow('Credit Conversion:'));
|
|
126
|
+
console.log(` USD to Credits: ${DEFAULT_PRICING_CONFIG.usdToCredits} credits per $1`);
|
|
127
|
+
console.log(` Markup: ${((DEFAULT_PRICING_CONFIG.luxMarkup - 1) * 100).toFixed(0)}%`);
|
|
128
|
+
|
|
129
|
+
console.log(chalk.yellow('\nSession Settings:'));
|
|
130
|
+
console.log(` Expiry: ${DEFAULT_PRICING_CONFIG.sessionExpiryMinutes} minutes`);
|
|
131
|
+
console.log(` Default Reservation: ${DEFAULT_PRICING_CONFIG.defaultCreditReservation} credits`);
|
|
132
|
+
console.log(` Low Balance Warning: ${DEFAULT_PRICING_CONFIG.lowBalanceThreshold} credits`);
|
|
133
|
+
|
|
134
|
+
console.log(chalk.yellow('\nModel Pricing (per 1M tokens):'));
|
|
135
|
+
for (const [model, pricing] of Object.entries(DEFAULT_PRICING_CONFIG.models)) {
|
|
136
|
+
if (model === 'default') continue;
|
|
137
|
+
console.log(` ${chalk.cyan(model)}:`);
|
|
138
|
+
console.log(` Input: $${pricing.input.toFixed(2)}`);
|
|
139
|
+
console.log(` Output: $${pricing.output.toFixed(2)}`);
|
|
140
|
+
if (pricing.cacheRead) {
|
|
141
|
+
console.log(` Cache Read: $${pricing.cacheRead.toFixed(2)}`);
|
|
142
|
+
console.log(` Cache Write: $${pricing.cacheWrite.toFixed(2)}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(chalk.yellow('\nDefault Fallback Pricing:'));
|
|
147
|
+
const defaultPricing = DEFAULT_PRICING_CONFIG.models.default;
|
|
148
|
+
console.log(` Input: $${defaultPricing.input.toFixed(2)}`);
|
|
149
|
+
console.log(` Output: $${defaultPricing.output.toFixed(2)}`);
|
|
150
|
+
|
|
151
|
+
console.log(chalk.gray('\n(Deploy via AppConfig to customize these values)'));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function exportConfig(args) {
|
|
155
|
+
const outputFile = args[0] || 'pricing-config.json';
|
|
156
|
+
const outputPath = path.resolve(process.cwd(), outputFile);
|
|
157
|
+
|
|
158
|
+
const config = {
|
|
159
|
+
...DEFAULT_PRICING_CONFIG,
|
|
160
|
+
version: '1.0.0',
|
|
161
|
+
updatedAt: new Date().toISOString(),
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));
|
|
165
|
+
console.log(chalk.green(`\nPricing configuration exported to: ${outputPath}`));
|
|
166
|
+
console.log(chalk.gray('\nEdit this file and use "lux pricing deploy <file>" to update pricing.'));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function deployConfig(args) {
|
|
170
|
+
if (!args[0]) {
|
|
171
|
+
console.log(chalk.red('Error: Please provide a configuration file path'));
|
|
172
|
+
console.log(chalk.gray('Usage: lux pricing deploy <file>'));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const configPath = path.resolve(process.cwd(), args[0]);
|
|
177
|
+
|
|
178
|
+
if (!fs.existsSync(configPath)) {
|
|
179
|
+
console.log(chalk.red(`Error: File not found: ${configPath}`));
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let config;
|
|
184
|
+
try {
|
|
185
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
186
|
+
} catch (err) {
|
|
187
|
+
console.log(chalk.red('Error: Invalid JSON in configuration file'));
|
|
188
|
+
console.log(chalk.gray(err.message));
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Validate configuration
|
|
193
|
+
const requiredFields = ['usdToCredits', 'luxMarkup', 'models'];
|
|
194
|
+
for (const field of requiredFields) {
|
|
195
|
+
if (!(field in config)) {
|
|
196
|
+
console.log(chalk.red(`Error: Missing required field: ${field}`));
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Update version and timestamp
|
|
202
|
+
config.version = config.version || '1.0.0';
|
|
203
|
+
config.updatedAt = new Date().toISOString();
|
|
204
|
+
|
|
205
|
+
console.log(chalk.yellow('\nDeploying pricing configuration to AWS AppConfig...\n'));
|
|
206
|
+
|
|
207
|
+
// Check for AWS credentials
|
|
208
|
+
const awsAccessKey = process.env.AWS_ACCESS_KEY_ID;
|
|
209
|
+
const awsSecretKey = process.env.AWS_SECRET_ACCESS_KEY;
|
|
210
|
+
|
|
211
|
+
if (!awsAccessKey || !awsSecretKey) {
|
|
212
|
+
console.log(chalk.red('Error: AWS credentials not found in environment'));
|
|
213
|
+
console.log(chalk.gray('\nSet the following environment variables:'));
|
|
214
|
+
console.log(chalk.gray(' export AWS_ACCESS_KEY_ID="your-access-key"'));
|
|
215
|
+
console.log(chalk.gray(' export AWS_SECRET_ACCESS_KEY="your-secret-key"'));
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
// Use AWS SDK to deploy
|
|
221
|
+
const { AppConfigClient, CreateHostedConfigurationVersionCommand } = require('@aws-sdk/client-appconfig');
|
|
222
|
+
|
|
223
|
+
const client = new AppConfigClient({
|
|
224
|
+
region: APPCONFIG.region,
|
|
225
|
+
credentials: {
|
|
226
|
+
accessKeyId: awsAccessKey,
|
|
227
|
+
secretAccessKey: awsSecretKey,
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const command = new CreateHostedConfigurationVersionCommand({
|
|
232
|
+
ApplicationId: APPCONFIG.applicationId,
|
|
233
|
+
ConfigurationProfileId: APPCONFIG.configProfileId,
|
|
234
|
+
Content: Buffer.from(JSON.stringify(config)),
|
|
235
|
+
ContentType: 'application/json',
|
|
236
|
+
Description: `Pricing update - ${config.version}`,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const response = await client.send(command);
|
|
240
|
+
|
|
241
|
+
console.log(chalk.green('Pricing configuration deployed successfully!'));
|
|
242
|
+
console.log(chalk.gray(` Version: ${response.VersionNumber}`));
|
|
243
|
+
console.log(chalk.gray(` Application: ${APPCONFIG.applicationId}`));
|
|
244
|
+
console.log(chalk.gray(` Environment: ${APPCONFIG.environmentName}`));
|
|
245
|
+
console.log(chalk.gray(` Profile: ${APPCONFIG.configProfileId}`));
|
|
246
|
+
|
|
247
|
+
console.log(chalk.yellow('\nNext step: Start a deployment in AWS AppConfig console'));
|
|
248
|
+
console.log(chalk.gray('Or use AWS CLI:'));
|
|
249
|
+
console.log(chalk.cyan(` aws appconfig start-deployment \\
|
|
250
|
+
--application-id ${APPCONFIG.applicationId} \\
|
|
251
|
+
--environment-id ${APPCONFIG.environmentId} \\
|
|
252
|
+
--deployment-strategy-id AppConfig.AllAtOnce \\
|
|
253
|
+
--configuration-profile-id ${APPCONFIG.configProfileId} \\
|
|
254
|
+
--configuration-version ${response.VersionNumber} \\
|
|
255
|
+
--region ${APPCONFIG.region}`));
|
|
256
|
+
|
|
257
|
+
} catch (err) {
|
|
258
|
+
if (err.code === 'MODULE_NOT_FOUND') {
|
|
259
|
+
console.log(chalk.red('Error: AWS SDK not installed'));
|
|
260
|
+
console.log(chalk.gray('\nInstall the AWS SDK:'));
|
|
261
|
+
console.log(chalk.gray(' npm install @aws-sdk/client-appconfig'));
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log(chalk.red('Error deploying configuration:'));
|
|
266
|
+
console.log(chalk.gray(err.message));
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function setSecrets() {
|
|
272
|
+
console.log(chalk.bold('\nSet AWS credentials in Cloudflare Workers\n'));
|
|
273
|
+
|
|
274
|
+
console.log(chalk.yellow('Run these commands in the lux-studio-api directory:\n'));
|
|
275
|
+
|
|
276
|
+
const secrets = [
|
|
277
|
+
{ name: 'AWS_ACCESS_KEY_ID', desc: 'IAM user access key' },
|
|
278
|
+
{ name: 'AWS_SECRET_ACCESS_KEY', desc: 'IAM user secret key' },
|
|
279
|
+
];
|
|
280
|
+
|
|
281
|
+
for (const secret of secrets) {
|
|
282
|
+
console.log(chalk.gray(`# ${secret.desc}`));
|
|
283
|
+
console.log(chalk.cyan(`npx wrangler secret put ${secret.name}`));
|
|
284
|
+
console.log();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
console.log(chalk.yellow('Optional (defaults are already set in code):'));
|
|
288
|
+
console.log(chalk.gray(`# Region: ${APPCONFIG.region}`));
|
|
289
|
+
console.log(chalk.cyan(`echo "${APPCONFIG.region}" | npx wrangler secret put AWS_REGION`));
|
|
290
|
+
console.log();
|
|
291
|
+
console.log(chalk.gray(`# Application ID: ${APPCONFIG.applicationId}`));
|
|
292
|
+
console.log(chalk.cyan(`echo "${APPCONFIG.applicationId}" | npx wrangler secret put AWS_APPCONFIG_APPLICATION_ID`));
|
|
293
|
+
console.log();
|
|
294
|
+
console.log(chalk.gray(`# Environment ID: ${APPCONFIG.environmentId}`));
|
|
295
|
+
console.log(chalk.cyan(`echo "${APPCONFIG.environmentId}" | npx wrangler secret put AWS_APPCONFIG_ENVIRONMENT_ID`));
|
|
296
|
+
console.log();
|
|
297
|
+
console.log(chalk.gray(`# Profile ID: ${APPCONFIG.configProfileId}`));
|
|
298
|
+
console.log(chalk.cyan(`echo "${APPCONFIG.configProfileId}" | npx wrangler secret put AWS_APPCONFIG_CONFIG_PROFILE_ID`));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async function handlePricing(args) {
|
|
302
|
+
const [subcommand, ...rest] = args;
|
|
303
|
+
|
|
304
|
+
switch (subcommand) {
|
|
305
|
+
case 'show':
|
|
306
|
+
await showPricing();
|
|
307
|
+
break;
|
|
308
|
+
case 'export':
|
|
309
|
+
await exportConfig(rest);
|
|
310
|
+
break;
|
|
311
|
+
case 'deploy':
|
|
312
|
+
await deployConfig(rest);
|
|
313
|
+
break;
|
|
314
|
+
case 'set-secrets':
|
|
315
|
+
await setSecrets();
|
|
316
|
+
break;
|
|
317
|
+
case 'help':
|
|
318
|
+
case undefined:
|
|
319
|
+
await showHelp();
|
|
320
|
+
break;
|
|
321
|
+
default:
|
|
322
|
+
console.log(chalk.red(`Unknown command: ${subcommand}`));
|
|
323
|
+
await showHelp();
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
module.exports = { handlePricing };
|