newo 3.3.3 → 3.4.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/CHANGELOG.md +41 -0
- package/dist/api.d.ts +6 -1
- package/dist/api.js +63 -1
- package/dist/application/migration/MigrationEngine.d.ts +141 -0
- package/dist/application/migration/MigrationEngine.js +322 -0
- package/dist/application/migration/index.d.ts +5 -0
- package/dist/application/migration/index.js +5 -0
- package/dist/application/sync/SyncEngine.d.ts +134 -0
- package/dist/application/sync/SyncEngine.js +335 -0
- package/dist/application/sync/index.d.ts +5 -0
- package/dist/application/sync/index.js +5 -0
- package/dist/cli/commands/add-project.d.ts +3 -0
- package/dist/cli/commands/add-project.js +136 -0
- package/dist/cli/commands/create-customer.d.ts +3 -0
- package/dist/cli/commands/create-customer.js +159 -0
- package/dist/cli/commands/diff.d.ts +6 -0
- package/dist/cli/commands/diff.js +288 -0
- package/dist/cli/commands/help.js +75 -4
- package/dist/cli/commands/list-registries.d.ts +3 -0
- package/dist/cli/commands/list-registries.js +39 -0
- package/dist/cli/commands/list-registry-items.d.ts +3 -0
- package/dist/cli/commands/list-registry-items.js +112 -0
- package/dist/cli/commands/logs.d.ts +18 -0
- package/dist/cli/commands/logs.js +283 -0
- package/dist/cli/commands/pull.js +114 -10
- package/dist/cli/commands/push.js +122 -12
- package/dist/cli/commands/watch.d.ts +6 -0
- package/dist/cli/commands/watch.js +195 -0
- package/dist/cli-new/bootstrap.d.ts +74 -0
- package/dist/cli-new/bootstrap.js +154 -0
- package/dist/cli-new/di/Container.d.ts +64 -0
- package/dist/cli-new/di/Container.js +122 -0
- package/dist/cli-new/di/tokens.d.ts +77 -0
- package/dist/cli-new/di/tokens.js +76 -0
- package/dist/cli.js +28 -0
- package/dist/domain/resources/common/types.d.ts +71 -0
- package/dist/domain/resources/common/types.js +42 -0
- package/dist/domain/strategies/sync/AkbSyncStrategy.d.ts +63 -0
- package/dist/domain/strategies/sync/AkbSyncStrategy.js +274 -0
- package/dist/domain/strategies/sync/AttributeSyncStrategy.d.ts +87 -0
- package/dist/domain/strategies/sync/AttributeSyncStrategy.js +378 -0
- package/dist/domain/strategies/sync/ConversationSyncStrategy.d.ts +61 -0
- package/dist/domain/strategies/sync/ConversationSyncStrategy.js +232 -0
- package/dist/domain/strategies/sync/ISyncStrategy.d.ts +149 -0
- package/dist/domain/strategies/sync/ISyncStrategy.js +24 -0
- package/dist/domain/strategies/sync/IntegrationSyncStrategy.d.ts +68 -0
- package/dist/domain/strategies/sync/IntegrationSyncStrategy.js +413 -0
- package/dist/domain/strategies/sync/ProjectSyncStrategy.d.ts +111 -0
- package/dist/domain/strategies/sync/ProjectSyncStrategy.js +523 -0
- package/dist/domain/strategies/sync/index.d.ts +13 -0
- package/dist/domain/strategies/sync/index.js +19 -0
- package/dist/sync/migrate.js +99 -23
- package/dist/types.d.ts +162 -0
- package/package.json +3 -1
- package/src/api.ts +77 -2
- package/src/application/migration/MigrationEngine.ts +492 -0
- package/src/application/migration/index.ts +5 -0
- package/src/application/sync/SyncEngine.ts +467 -0
- package/src/application/sync/index.ts +5 -0
- package/src/cli/commands/add-project.ts +159 -0
- package/src/cli/commands/create-customer.ts +185 -0
- package/src/cli/commands/diff.ts +360 -0
- package/src/cli/commands/help.ts +75 -4
- package/src/cli/commands/list-registries.ts +53 -0
- package/src/cli/commands/list-registry-items.ts +149 -0
- package/src/cli/commands/logs.ts +329 -0
- package/src/cli/commands/pull.ts +128 -11
- package/src/cli/commands/push.ts +131 -13
- package/src/cli/commands/watch.ts +227 -0
- package/src/cli-new/bootstrap.ts +252 -0
- package/src/cli-new/di/Container.ts +152 -0
- package/src/cli-new/di/tokens.ts +105 -0
- package/src/cli.ts +35 -0
- package/src/domain/resources/common/types.ts +106 -0
- package/src/domain/strategies/sync/AkbSyncStrategy.ts +358 -0
- package/src/domain/strategies/sync/AttributeSyncStrategy.ts +508 -0
- package/src/domain/strategies/sync/ConversationSyncStrategy.ts +299 -0
- package/src/domain/strategies/sync/ISyncStrategy.ts +182 -0
- package/src/domain/strategies/sync/IntegrationSyncStrategy.ts +522 -0
- package/src/domain/strategies/sync/ProjectSyncStrategy.ts +747 -0
- package/src/domain/strategies/sync/index.ts +46 -0
- package/src/sync/migrate.ts +103 -24
- package/src/types.ts +178 -0
package/dist/sync/migrate.js
CHANGED
|
@@ -156,38 +156,94 @@ verbose) {
|
|
|
156
156
|
idn: sourceFlow.idn,
|
|
157
157
|
title: sourceFlow.title
|
|
158
158
|
});
|
|
159
|
-
|
|
159
|
+
// Handle "pending-sync" response - re-fetch to get actual flow ID
|
|
160
|
+
if (flowResponse.id === 'pending-sync' || !flowResponse.id.match(/^[0-9a-f-]{36}$/i)) {
|
|
161
|
+
// Retry with increasing wait times
|
|
162
|
+
let createdFlow = null;
|
|
163
|
+
for (const waitMs of [1500, 3000, 5000]) {
|
|
164
|
+
await new Promise(resolve => setTimeout(resolve, waitMs));
|
|
165
|
+
const refreshedAgents = await listAgents(destClient, projectId);
|
|
166
|
+
const refreshedAgent = refreshedAgents.find(a => a.id === agentId);
|
|
167
|
+
createdFlow = refreshedAgent?.flows?.find(f => f.idn === sourceFlow.idn);
|
|
168
|
+
if (createdFlow)
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
if (createdFlow) {
|
|
172
|
+
flowId = createdFlow.id;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
if (verbose)
|
|
176
|
+
console.error(` ⚠️ Flow ${sourceFlow.idn} created but could not retrieve ID after retries`);
|
|
177
|
+
continue; // Skip this flow
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
flowId = flowResponse.id;
|
|
182
|
+
}
|
|
160
183
|
flowsCreated++;
|
|
161
184
|
}
|
|
162
|
-
//
|
|
163
|
-
const
|
|
164
|
-
if (await fs.pathExists(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const
|
|
185
|
+
// Flow directory path
|
|
186
|
+
const flowDirPath = path.join(customerProjectsDir(sourceCustomer.idn), sourceProj.idn, sourceAgent.idn, sourceFlow.idn);
|
|
187
|
+
if (await fs.pathExists(flowDirPath)) {
|
|
188
|
+
// Read flow metadata for events and states
|
|
189
|
+
const flowMetaPath = path.join(flowDirPath, 'metadata.yaml');
|
|
190
|
+
const flowMeta = await fs.pathExists(flowMetaPath)
|
|
191
|
+
? yaml.load(await fs.readFile(flowMetaPath, 'utf8'))
|
|
192
|
+
: {};
|
|
193
|
+
// Create skills by reading skill subdirectories
|
|
194
|
+
let destSkills;
|
|
195
|
+
try {
|
|
196
|
+
destSkills = await listFlowSkills(destClient, flowId);
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
if (verbose)
|
|
200
|
+
console.error(` ⚠️ Failed to list skills for flow ${sourceFlow.idn} (${flowId}): ${err.message}`);
|
|
201
|
+
continue; // Skip this flow if we can't list skills
|
|
202
|
+
}
|
|
168
203
|
const destSkillMap = new Map(destSkills.map(s => [s.idn, s]));
|
|
169
|
-
|
|
170
|
-
|
|
204
|
+
// Get all subdirectories in flow directory (these are skills)
|
|
205
|
+
const flowDirContents = await fs.readdir(flowDirPath, { withFileTypes: true });
|
|
206
|
+
const skillDirs = flowDirContents.filter(d => d.isDirectory());
|
|
207
|
+
for (const skillDir of skillDirs) {
|
|
208
|
+
const skillIdn = skillDir.name;
|
|
209
|
+
if (destSkillMap.has(skillIdn))
|
|
171
210
|
continue;
|
|
211
|
+
// Read skill metadata
|
|
212
|
+
const skillMetaPath = path.join(flowDirPath, skillIdn, 'metadata.yaml');
|
|
213
|
+
if (!await fs.pathExists(skillMetaPath))
|
|
214
|
+
continue;
|
|
215
|
+
const skillMeta = yaml.load(await fs.readFile(skillMetaPath, 'utf8'));
|
|
172
216
|
try {
|
|
173
217
|
await createSkill(destClient, flowId, {
|
|
174
|
-
idn:
|
|
175
|
-
title:
|
|
176
|
-
runner_type:
|
|
177
|
-
model:
|
|
218
|
+
idn: skillMeta.idn || skillIdn,
|
|
219
|
+
title: skillMeta.title || skillIdn,
|
|
220
|
+
runner_type: skillMeta.runner_type || 'guidance',
|
|
221
|
+
model: skillMeta.model,
|
|
178
222
|
prompt_script: ''
|
|
179
223
|
});
|
|
180
224
|
skillsCreated++;
|
|
225
|
+
if (verbose)
|
|
226
|
+
console.log(` ✅ Created skill: ${skillIdn}`);
|
|
181
227
|
}
|
|
182
228
|
catch (error) {
|
|
183
229
|
if (verbose && error.response?.status !== 409) {
|
|
184
|
-
console.error(` ⚠️ Failed to create skill ${
|
|
230
|
+
console.error(` ⚠️ Failed to create skill ${skillIdn}: ${error.message}`);
|
|
185
231
|
}
|
|
186
232
|
}
|
|
187
233
|
}
|
|
188
|
-
//
|
|
234
|
+
// Get current skills in destination to validate event references
|
|
235
|
+
const currentDestSkills = await listFlowSkills(destClient, flowId);
|
|
236
|
+
const destSkillIdnSet = new Set(currentDestSkills.map(s => s.idn));
|
|
237
|
+
// Create events with full metadata (only if referenced skill exists)
|
|
189
238
|
for (const event of flowMeta.events || []) {
|
|
190
239
|
try {
|
|
240
|
+
// Skip events that reference skills not yet created
|
|
241
|
+
if (event.skill_idn && !destSkillIdnSet.has(event.skill_idn)) {
|
|
242
|
+
if (verbose) {
|
|
243
|
+
console.log(` ⏭️ Skipping event ${event.idn} - skill ${event.skill_idn} not yet created`);
|
|
244
|
+
}
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
191
247
|
const eventRequest = {
|
|
192
248
|
idn: event.idn,
|
|
193
249
|
description: event.description || event.idn,
|
|
@@ -205,8 +261,10 @@ verbose) {
|
|
|
205
261
|
await createFlowEvent(destClient, flowId, eventRequest);
|
|
206
262
|
}
|
|
207
263
|
catch (error) {
|
|
208
|
-
|
|
209
|
-
|
|
264
|
+
// Don't log 409 (already exists) or 422 (validation) errors as they're expected
|
|
265
|
+
if (error.response?.status !== 409 && error.response?.status !== 422) {
|
|
266
|
+
if (verbose)
|
|
267
|
+
console.error(` ⚠️ Failed to create event ${event.idn}: ${error.message}`);
|
|
210
268
|
}
|
|
211
269
|
}
|
|
212
270
|
}
|
|
@@ -350,9 +408,7 @@ verbose) {
|
|
|
350
408
|
}
|
|
351
409
|
return { personas: personasCreated, articles: articlesImported };
|
|
352
410
|
}
|
|
353
|
-
async function migrateIntegrationConnectors(sourceClient, destClient,
|
|
354
|
-
// @ts-ignore - Parameter kept for future use
|
|
355
|
-
verbose) {
|
|
411
|
+
async function migrateIntegrationConnectors(sourceClient, destClient, verbose) {
|
|
356
412
|
const sourceIntegrations = await listIntegrations(sourceClient);
|
|
357
413
|
const destIntegrations = await listIntegrations(destClient);
|
|
358
414
|
const destIntMap = new Map(destIntegrations.map(i => [i.idn, i]));
|
|
@@ -361,24 +417,44 @@ verbose) {
|
|
|
361
417
|
const destInt = destIntMap.get(sourceInt.idn);
|
|
362
418
|
if (!destInt)
|
|
363
419
|
continue;
|
|
420
|
+
// Build set of allowed setting idns from destination integration schema
|
|
421
|
+
const destSettingIdns = new Set((destInt.connector_settings_descriptions || []).map(s => s.idn));
|
|
364
422
|
const sourceConnectors = await listConnectors(sourceClient, sourceInt.id);
|
|
365
423
|
const destConnectors = await listConnectors(destClient, destInt.id);
|
|
366
424
|
const destConnMap = new Map(destConnectors.map(c => [c.connector_idn, c]));
|
|
367
425
|
for (const sourceConn of sourceConnectors) {
|
|
368
426
|
if (destConnMap.has(sourceConn.connector_idn))
|
|
369
427
|
continue;
|
|
428
|
+
// Filter settings to only include those that exist in destination schema
|
|
429
|
+
const filteredSettings = sourceConn.settings.filter(s => {
|
|
430
|
+
const allowed = destSettingIdns.size === 0 || destSettingIdns.has(s.idn);
|
|
431
|
+
if (!allowed && verbose) {
|
|
432
|
+
console.log(` ⏭️ Skipping setting ${s.idn} for ${sourceConn.connector_idn} (not in dest schema)`);
|
|
433
|
+
}
|
|
434
|
+
return allowed;
|
|
435
|
+
});
|
|
436
|
+
// Log if settings were filtered
|
|
437
|
+
if (filteredSettings.length !== sourceConn.settings.length && verbose) {
|
|
438
|
+
const skippedCount = sourceConn.settings.length - filteredSettings.length;
|
|
439
|
+
console.log(` 📋 Filtered ${skippedCount} settings for ${sourceConn.connector_idn}`);
|
|
440
|
+
}
|
|
370
441
|
try {
|
|
371
442
|
await createConnector(destClient, destInt.id, {
|
|
372
443
|
title: sourceConn.title,
|
|
373
444
|
connector_idn: sourceConn.connector_idn,
|
|
374
445
|
integration_idn: sourceInt.idn,
|
|
375
|
-
settings:
|
|
446
|
+
settings: filteredSettings
|
|
376
447
|
});
|
|
377
448
|
connectorsCreated++;
|
|
449
|
+
if (verbose) {
|
|
450
|
+
console.log(` ✅ Created connector: ${sourceConn.connector_idn} (${sourceInt.idn})`);
|
|
451
|
+
}
|
|
378
452
|
}
|
|
379
453
|
catch (error) {
|
|
380
|
-
|
|
381
|
-
|
|
454
|
+
// Always log connector creation failures (not just in verbose mode)
|
|
455
|
+
const errMsg = error.response?.data?.reason || error.message;
|
|
456
|
+
if (error.response?.status !== 409) {
|
|
457
|
+
console.error(` ⚠️ Failed to create connector ${sourceConn.connector_idn} (${sourceInt.idn}): ${errMsg}`);
|
|
382
458
|
}
|
|
383
459
|
}
|
|
384
460
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -494,6 +494,20 @@ export interface PublishFlowRequest {
|
|
|
494
494
|
export interface PublishFlowResponse {
|
|
495
495
|
success: boolean;
|
|
496
496
|
}
|
|
497
|
+
export interface IntegrationSettingDescription {
|
|
498
|
+
readonly title: string;
|
|
499
|
+
readonly idn: string;
|
|
500
|
+
readonly control_type: string;
|
|
501
|
+
readonly value_type: string;
|
|
502
|
+
readonly is_required: boolean;
|
|
503
|
+
readonly is_readonly: boolean;
|
|
504
|
+
readonly default_value?: string | null;
|
|
505
|
+
readonly description?: string | null;
|
|
506
|
+
readonly group?: string | null;
|
|
507
|
+
readonly possible_values?: readonly string[] | null;
|
|
508
|
+
readonly possible_values_only?: boolean;
|
|
509
|
+
readonly possible_values_url?: string | null;
|
|
510
|
+
}
|
|
497
511
|
export interface Integration {
|
|
498
512
|
readonly id: string;
|
|
499
513
|
readonly title: string;
|
|
@@ -501,6 +515,8 @@ export interface Integration {
|
|
|
501
515
|
readonly description: string;
|
|
502
516
|
readonly is_disabled: boolean;
|
|
503
517
|
readonly channel: string;
|
|
518
|
+
readonly integration_settings_descriptions?: readonly IntegrationSettingDescription[];
|
|
519
|
+
readonly connector_settings_descriptions?: readonly IntegrationSettingDescription[];
|
|
504
520
|
}
|
|
505
521
|
export interface IntegrationSetting {
|
|
506
522
|
readonly title: string;
|
|
@@ -703,4 +719,150 @@ export interface AkbYamlTopic {
|
|
|
703
719
|
labels: string[];
|
|
704
720
|
topic_summary: string;
|
|
705
721
|
}
|
|
722
|
+
export interface Registry {
|
|
723
|
+
readonly id: string;
|
|
724
|
+
readonly idn: string;
|
|
725
|
+
readonly account_id: string;
|
|
726
|
+
readonly is_public: boolean;
|
|
727
|
+
}
|
|
728
|
+
export interface RegistryItemProjectImage {
|
|
729
|
+
readonly id: string;
|
|
730
|
+
readonly idn: string;
|
|
731
|
+
readonly image_hash: string;
|
|
732
|
+
readonly storage_id: string;
|
|
733
|
+
readonly customer_idn: string;
|
|
734
|
+
readonly account_id: string;
|
|
735
|
+
readonly created_at: string;
|
|
736
|
+
}
|
|
737
|
+
export interface RegistryItem {
|
|
738
|
+
readonly id: string;
|
|
739
|
+
readonly idn: string;
|
|
740
|
+
readonly version: string;
|
|
741
|
+
readonly project_image: RegistryItemProjectImage;
|
|
742
|
+
readonly account_id: string;
|
|
743
|
+
readonly account_idn: string | null;
|
|
744
|
+
readonly account_email: string | null;
|
|
745
|
+
readonly is_public: boolean;
|
|
746
|
+
readonly active_project_count: number;
|
|
747
|
+
readonly created_at: string;
|
|
748
|
+
readonly published_at: string;
|
|
749
|
+
}
|
|
750
|
+
export interface AddProjectFromRegistryRequest {
|
|
751
|
+
idn: string;
|
|
752
|
+
title: string;
|
|
753
|
+
version?: string;
|
|
754
|
+
description?: string;
|
|
755
|
+
is_auto_update_enabled?: boolean;
|
|
756
|
+
registry_idn: string;
|
|
757
|
+
registry_item_idn: string;
|
|
758
|
+
registry_item_version: string | null;
|
|
759
|
+
}
|
|
760
|
+
export interface CustomerMember {
|
|
761
|
+
email: string;
|
|
762
|
+
role: 'owner' | 'account_manager' | 'technical_owner' | 'referral';
|
|
763
|
+
tenants?: string[];
|
|
764
|
+
first_name?: string;
|
|
765
|
+
external_account_id?: string;
|
|
766
|
+
contact_email?: string;
|
|
767
|
+
}
|
|
768
|
+
export interface CustomerAttributeInput {
|
|
769
|
+
idn: string;
|
|
770
|
+
value: string;
|
|
771
|
+
is_hidden?: boolean;
|
|
772
|
+
group?: string;
|
|
773
|
+
}
|
|
774
|
+
export interface CustomerProjectInput {
|
|
775
|
+
idn: string;
|
|
776
|
+
title?: string;
|
|
777
|
+
registry_idn?: string;
|
|
778
|
+
registry_item_idn?: string;
|
|
779
|
+
registry_item_version?: string;
|
|
780
|
+
is_auto_update_enabled?: boolean;
|
|
781
|
+
}
|
|
782
|
+
export interface CreateNewoCustomerRequest {
|
|
783
|
+
secret: string;
|
|
784
|
+
customer: {
|
|
785
|
+
organization_name: string;
|
|
786
|
+
tenant: string;
|
|
787
|
+
comment?: string;
|
|
788
|
+
query_params?: string;
|
|
789
|
+
members: CustomerMember[];
|
|
790
|
+
contact_email: string;
|
|
791
|
+
contact_phone?: string;
|
|
792
|
+
external_customer_id?: string;
|
|
793
|
+
organization_type?: 'customer' | 'partner';
|
|
794
|
+
organization_status?: 'temporal' | 'permanent';
|
|
795
|
+
billing_method?: string;
|
|
796
|
+
platform_links?: {
|
|
797
|
+
portal?: string;
|
|
798
|
+
builder?: string;
|
|
799
|
+
creator?: string;
|
|
800
|
+
chat_widget?: string;
|
|
801
|
+
};
|
|
802
|
+
organization_logo?: {
|
|
803
|
+
title?: string;
|
|
804
|
+
external_logo_id?: string;
|
|
805
|
+
};
|
|
806
|
+
attributes?: CustomerAttributeInput[];
|
|
807
|
+
a_service?: {
|
|
808
|
+
partner_idn: string;
|
|
809
|
+
member_idn: string;
|
|
810
|
+
};
|
|
811
|
+
};
|
|
812
|
+
projects?: CustomerProjectInput[];
|
|
813
|
+
}
|
|
814
|
+
export interface CreateNewoCustomerResponse {
|
|
815
|
+
id: string;
|
|
816
|
+
idn: string;
|
|
817
|
+
}
|
|
818
|
+
export type LogLevel = 'info' | 'warning' | 'error';
|
|
819
|
+
export type LogType = 'system' | 'operation' | 'call';
|
|
820
|
+
export interface LogEntry {
|
|
821
|
+
readonly log_id: string;
|
|
822
|
+
readonly level: LogLevel;
|
|
823
|
+
readonly log_type: LogType;
|
|
824
|
+
readonly project_idn: string;
|
|
825
|
+
readonly data: {
|
|
826
|
+
readonly external_event_id?: string;
|
|
827
|
+
readonly reference_idn?: string;
|
|
828
|
+
readonly operation_type?: string;
|
|
829
|
+
readonly arguments?: readonly {
|
|
830
|
+
name: string;
|
|
831
|
+
value: string;
|
|
832
|
+
}[];
|
|
833
|
+
readonly user_actor_id?: string;
|
|
834
|
+
readonly integration_idn?: string;
|
|
835
|
+
readonly connector_idn?: string;
|
|
836
|
+
readonly to_integration_idn?: string;
|
|
837
|
+
readonly to_connector_idn?: string;
|
|
838
|
+
readonly flow_idn?: string;
|
|
839
|
+
readonly skill_idn?: string;
|
|
840
|
+
readonly agent_idn?: string;
|
|
841
|
+
readonly line?: number;
|
|
842
|
+
readonly runtime_context_id?: string;
|
|
843
|
+
readonly [key: string]: unknown;
|
|
844
|
+
};
|
|
845
|
+
readonly message: string;
|
|
846
|
+
readonly datetime: string;
|
|
847
|
+
}
|
|
848
|
+
export interface LogsResponse {
|
|
849
|
+
readonly items: readonly LogEntry[];
|
|
850
|
+
}
|
|
851
|
+
export interface LogsQueryParams {
|
|
852
|
+
page?: number;
|
|
853
|
+
per?: number;
|
|
854
|
+
from_datetime?: string;
|
|
855
|
+
to_datetime?: string;
|
|
856
|
+
levels?: LogLevel | LogLevel[];
|
|
857
|
+
log_types?: LogType | LogType[];
|
|
858
|
+
message?: string;
|
|
859
|
+
project_idn?: string;
|
|
860
|
+
flow_idn?: string;
|
|
861
|
+
skill_idn?: string;
|
|
862
|
+
external_event_id?: string;
|
|
863
|
+
runtime_context_id?: string;
|
|
864
|
+
user_persona_ids?: string;
|
|
865
|
+
user_actor_ids?: string;
|
|
866
|
+
agent_persona_ids?: string;
|
|
867
|
+
}
|
|
706
868
|
//# sourceMappingURL=types.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newo",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
4
4
|
"description": "NEWO CLI: Professional command-line tool with modular architecture for NEWO AI Agent development. Features account migration, integration management, webhook automation, AKB knowledge base, project attributes, sandbox testing, IDN-based file management, real-time progress tracking, intelligent sync operations, and comprehensive multi-customer support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"axios": "^1.7.7",
|
|
64
|
+
"chokidar": "^5.0.0",
|
|
64
65
|
"dotenv": "^16.4.5",
|
|
65
66
|
"fs-extra": "^11.2.0",
|
|
66
67
|
"js-yaml": "^4.1.0",
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
72
|
"@types/chai": "^4.3.11",
|
|
73
|
+
"@types/chokidar": "^1.7.5",
|
|
72
74
|
"@types/fs-extra": "^11.0.4",
|
|
73
75
|
"@types/js-yaml": "^4.0.9",
|
|
74
76
|
"@types/minimist": "^1.2.5",
|
package/src/api.ts
CHANGED
|
@@ -52,7 +52,14 @@ import type {
|
|
|
52
52
|
OutgoingWebhook,
|
|
53
53
|
IncomingWebhook,
|
|
54
54
|
PersonaSearchResponse,
|
|
55
|
-
AkbTopicsResponse
|
|
55
|
+
AkbTopicsResponse,
|
|
56
|
+
Registry,
|
|
57
|
+
RegistryItem,
|
|
58
|
+
AddProjectFromRegistryRequest,
|
|
59
|
+
CreateNewoCustomerRequest,
|
|
60
|
+
CreateNewoCustomerResponse,
|
|
61
|
+
LogsQueryParams,
|
|
62
|
+
LogsResponse
|
|
56
63
|
} from './types.js';
|
|
57
64
|
|
|
58
65
|
// Per-request retry tracking to avoid shared state issues
|
|
@@ -103,7 +110,7 @@ export async function makeClient(verbose: boolean = false, token?: string): Prom
|
|
|
103
110
|
// Use per-request retry tracking to avoid shared state issues
|
|
104
111
|
const config = error.config as InternalAxiosRequestConfig & { [RETRY_SYMBOL]?: boolean };
|
|
105
112
|
|
|
106
|
-
if (status === 401 && !config?.[RETRY_SYMBOL]) {
|
|
113
|
+
if ((status === 401 || status === 403) && !config?.[RETRY_SYMBOL]) {
|
|
107
114
|
if (config) {
|
|
108
115
|
config[RETRY_SYMBOL] = true;
|
|
109
116
|
if (verbose) console.log('🔄 Retrying with fresh token...');
|
|
@@ -552,4 +559,72 @@ export async function createIncomingWebhook(
|
|
|
552
559
|
): Promise<{ id: string; url: string }> {
|
|
553
560
|
const response = await client.post('/api/v1/webhooks/incoming', webhookData);
|
|
554
561
|
return response.data;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Registry API Functions
|
|
565
|
+
|
|
566
|
+
export async function listRegistries(client: AxiosInstance): Promise<Registry[]> {
|
|
567
|
+
const response = await client.get<Registry[]>('/api/v1/designer/registries');
|
|
568
|
+
return response.data;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export async function listRegistryItems(client: AxiosInstance, registryId: string): Promise<RegistryItem[]> {
|
|
572
|
+
const response = await client.get<RegistryItem[]>(`/api/v1/designer/registries/${registryId}/items`);
|
|
573
|
+
return response.data;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export async function addProjectFromRegistry(
|
|
577
|
+
client: AxiosInstance,
|
|
578
|
+
projectData: AddProjectFromRegistryRequest
|
|
579
|
+
): Promise<CreateProjectResponse> {
|
|
580
|
+
// Uses the same endpoint as createProject, but with registry fields populated
|
|
581
|
+
const response = await client.post<CreateProjectResponse>('/api/v1/designer/projects', projectData);
|
|
582
|
+
return response.data;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Create NEWO Customer (v3 API - creates a new customer account)
|
|
586
|
+
export async function createNewoCustomer(
|
|
587
|
+
client: AxiosInstance,
|
|
588
|
+
customerData: CreateNewoCustomerRequest
|
|
589
|
+
): Promise<CreateNewoCustomerResponse> {
|
|
590
|
+
const response = await client.post<CreateNewoCustomerResponse>('/api/v3/customer', customerData);
|
|
591
|
+
return response.data;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Analytics Logs API
|
|
595
|
+
export async function getLogs(
|
|
596
|
+
client: AxiosInstance,
|
|
597
|
+
params: LogsQueryParams
|
|
598
|
+
): Promise<LogsResponse> {
|
|
599
|
+
// Build query params, handling arrays for levels and log_types
|
|
600
|
+
const queryParams = new URLSearchParams();
|
|
601
|
+
|
|
602
|
+
if (params.page !== undefined) queryParams.set('page', String(params.page));
|
|
603
|
+
if (params.per !== undefined) queryParams.set('per', String(params.per));
|
|
604
|
+
if (params.from_datetime) queryParams.set('from_datetime', params.from_datetime);
|
|
605
|
+
if (params.to_datetime) queryParams.set('to_datetime', params.to_datetime);
|
|
606
|
+
if (params.message) queryParams.set('message', params.message);
|
|
607
|
+
if (params.project_idn) queryParams.set('project_idn', params.project_idn);
|
|
608
|
+
if (params.flow_idn) queryParams.set('flow_idn', params.flow_idn);
|
|
609
|
+
if (params.skill_idn) queryParams.set('skill_idn', params.skill_idn);
|
|
610
|
+
if (params.external_event_id) queryParams.set('external_event_id', params.external_event_id);
|
|
611
|
+
if (params.runtime_context_id) queryParams.set('runtime_context_id', params.runtime_context_id);
|
|
612
|
+
if (params.user_persona_ids) queryParams.set('user_persona_ids', params.user_persona_ids);
|
|
613
|
+
if (params.user_actor_ids) queryParams.set('user_actor_ids', params.user_actor_ids);
|
|
614
|
+
if (params.agent_persona_ids) queryParams.set('agent_persona_ids', params.agent_persona_ids);
|
|
615
|
+
|
|
616
|
+
// Handle levels (can be single or array)
|
|
617
|
+
if (params.levels) {
|
|
618
|
+
const levelsValue = Array.isArray(params.levels) ? params.levels.join(',') : params.levels;
|
|
619
|
+
queryParams.set('levels', levelsValue);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Handle log_types (can be single or array)
|
|
623
|
+
if (params.log_types) {
|
|
624
|
+
const typesValue = Array.isArray(params.log_types) ? params.log_types.join(',') : params.log_types;
|
|
625
|
+
queryParams.set('log_types', typesValue);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const response = await client.get<LogsResponse>(`/api/v1/analytics/logs?${queryParams.toString()}`);
|
|
629
|
+
return response.data;
|
|
555
630
|
}
|