newo 1.6.0 → 1.7.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/CHANGELOG.md +94 -0
- package/README.md +1 -1
- package/dist/api.d.ts +3 -1
- package/dist/api.js +21 -0
- package/dist/cli.js +6 -1
- package/dist/fsutil.d.ts +8 -0
- package/dist/fsutil.js +29 -0
- package/dist/sync.d.ts +1 -0
- package/dist/sync.js +313 -50
- package/dist/types.d.ts +61 -6
- package/package.json +2 -2
- package/src/api.ts +31 -6
- package/src/cli.ts +5 -1
- package/src/fsutil.ts +60 -4
- package/src/sync.ts +393 -85
- package/src/types.ts +69 -6
package/src/api.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import axios, { type AxiosInstance, type InternalAxiosRequestConfig, type AxiosResponse, type AxiosError } from 'axios';
|
|
2
2
|
import { getValidAccessToken, forceReauth } from './auth.js';
|
|
3
3
|
import { ENV } from './env.js';
|
|
4
|
-
import type {
|
|
5
|
-
ProjectMeta,
|
|
6
|
-
Agent,
|
|
7
|
-
Skill,
|
|
8
|
-
FlowEvent,
|
|
4
|
+
import type {
|
|
5
|
+
ProjectMeta,
|
|
6
|
+
Agent,
|
|
7
|
+
Skill,
|
|
8
|
+
FlowEvent,
|
|
9
9
|
FlowState,
|
|
10
10
|
AkbImportArticle,
|
|
11
|
-
CustomerProfile
|
|
11
|
+
CustomerProfile,
|
|
12
|
+
CustomerAttribute,
|
|
13
|
+
CustomerAttributesResponse
|
|
12
14
|
} from './types.js';
|
|
13
15
|
|
|
14
16
|
// Per-request retry tracking to avoid shared state issues
|
|
@@ -127,4 +129,27 @@ export async function importAkbArticle(client: AxiosInstance, articleData: AkbIm
|
|
|
127
129
|
export async function getCustomerProfile(client: AxiosInstance): Promise<CustomerProfile> {
|
|
128
130
|
const response = await client.get<CustomerProfile>('/api/v1/customer/profile');
|
|
129
131
|
return response.data;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export async function getCustomerAttributes(client: AxiosInstance, includeHidden: boolean = true): Promise<CustomerAttributesResponse> {
|
|
135
|
+
const response = await client.get<CustomerAttributesResponse>('/api/v1/bff/customer/attributes', {
|
|
136
|
+
params: { include_hidden: includeHidden }
|
|
137
|
+
});
|
|
138
|
+
return response.data;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export async function updateCustomerAttribute(client: AxiosInstance, attribute: CustomerAttribute): Promise<void> {
|
|
142
|
+
if (!attribute.id) {
|
|
143
|
+
throw new Error(`Attribute ${attribute.idn} is missing ID - cannot update`);
|
|
144
|
+
}
|
|
145
|
+
await client.put(`/api/v1/customer/attributes/${attribute.id}`, {
|
|
146
|
+
idn: attribute.idn,
|
|
147
|
+
value: attribute.value,
|
|
148
|
+
title: attribute.title,
|
|
149
|
+
description: attribute.description,
|
|
150
|
+
group: attribute.group,
|
|
151
|
+
is_hidden: attribute.is_hidden,
|
|
152
|
+
possible_values: attribute.possible_values,
|
|
153
|
+
value_type: attribute.value_type
|
|
154
|
+
});
|
|
130
155
|
}
|
package/src/cli.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import minimist from 'minimist';
|
|
3
3
|
import dotenv from 'dotenv';
|
|
4
4
|
import { makeClient, getProjectMeta, importAkbArticle } from './api.js';
|
|
5
|
-
import { pullAll, pushChanged, status } from './sync.js';
|
|
5
|
+
import { pullAll, pushChanged, status, saveCustomerAttributes } from './sync.js';
|
|
6
6
|
import { parseAkbFile, prepareArticlesForImport } from './akb.js';
|
|
7
7
|
import { initializeEnvironment, ENV, EnvValidationError } from './env.js';
|
|
8
8
|
import { parseCustomerConfigAsync, listCustomers, getCustomer, getDefaultCustomer, tryGetDefaultCustomer, getAllCustomers, validateCustomerConfig } from './customerAsync.js';
|
|
@@ -281,6 +281,10 @@ File Structure:
|
|
|
281
281
|
}
|
|
282
282
|
const meta = await getProjectMeta(client, selectedCustomer.projectId);
|
|
283
283
|
console.log(JSON.stringify(meta, null, 2));
|
|
284
|
+
} else if (cmd === 'pull-attributes') {
|
|
285
|
+
console.log(`🔍 Fetching customer attributes for ${selectedCustomer.idn}...`);
|
|
286
|
+
await saveCustomerAttributes(client, selectedCustomer, verbose);
|
|
287
|
+
console.log(`✅ Customer attributes saved to newo_customers/${selectedCustomer.idn}/attributes.yaml`);
|
|
284
288
|
} else if (cmd === 'import-akb') {
|
|
285
289
|
const akbFile = args._[1];
|
|
286
290
|
const personaId = args._[2];
|
package/src/fsutil.ts
CHANGED
|
@@ -39,18 +39,74 @@ export function flowsYamlPath(customerIdn: string): string {
|
|
|
39
39
|
return path.posix.join(customerProjectsDir(customerIdn), 'flows.yaml');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
export function customerAttributesPath(customerIdn: string): string {
|
|
43
|
+
return path.posix.join(customerDir(customerIdn), 'attributes.yaml');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function customerAttributesMapPath(customerIdn: string): string {
|
|
47
|
+
return path.join(customerStateDir(customerIdn), 'attributes-map.json');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Legacy skill path - direct file
|
|
42
51
|
export function skillPath(
|
|
43
52
|
customerIdn: string,
|
|
44
|
-
projectIdn: string,
|
|
45
|
-
agentIdn: string,
|
|
46
|
-
flowIdn: string,
|
|
47
|
-
skillIdn: string,
|
|
53
|
+
projectIdn: string,
|
|
54
|
+
agentIdn: string,
|
|
55
|
+
flowIdn: string,
|
|
56
|
+
skillIdn: string,
|
|
48
57
|
runnerType: RunnerType = 'guidance'
|
|
49
58
|
): string {
|
|
50
59
|
const extension = runnerType === 'nsl' ? '.jinja' : '.guidance';
|
|
51
60
|
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, agentIdn, flowIdn, `${skillIdn}${extension}`);
|
|
52
61
|
}
|
|
53
62
|
|
|
63
|
+
// New hierarchical structure paths
|
|
64
|
+
export function skillFolderPath(
|
|
65
|
+
customerIdn: string,
|
|
66
|
+
projectIdn: string,
|
|
67
|
+
agentIdn: string,
|
|
68
|
+
flowIdn: string,
|
|
69
|
+
skillIdn: string
|
|
70
|
+
): string {
|
|
71
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, agentIdn, flowIdn, skillIdn);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function skillScriptPath(
|
|
75
|
+
customerIdn: string,
|
|
76
|
+
projectIdn: string,
|
|
77
|
+
agentIdn: string,
|
|
78
|
+
flowIdn: string,
|
|
79
|
+
skillIdn: string,
|
|
80
|
+
runnerType: RunnerType = 'guidance'
|
|
81
|
+
): string {
|
|
82
|
+
const extension = runnerType === 'nsl' ? '.jinja' : '.guidance';
|
|
83
|
+
return path.posix.join(skillFolderPath(customerIdn, projectIdn, agentIdn, flowIdn, skillIdn), `skill${extension}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Metadata paths for hierarchical structure
|
|
87
|
+
export function projectMetadataPath(customerIdn: string, projectIdn: string): string {
|
|
88
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, 'metadata.yaml');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function agentMetadataPath(customerIdn: string, projectIdn: string, agentIdn: string): string {
|
|
92
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, agentIdn, 'metadata.yaml');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function flowMetadataPath(customerIdn: string, projectIdn: string, agentIdn: string, flowIdn: string): string {
|
|
96
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, agentIdn, flowIdn, 'metadata.yaml');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function skillMetadataPath(
|
|
100
|
+
customerIdn: string,
|
|
101
|
+
projectIdn: string,
|
|
102
|
+
agentIdn: string,
|
|
103
|
+
flowIdn: string,
|
|
104
|
+
skillIdn: string
|
|
105
|
+
): string {
|
|
106
|
+
return path.posix.join(skillFolderPath(customerIdn, projectIdn, agentIdn, flowIdn, skillIdn), 'metadata.yaml');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Legacy metadata path - keep for backwards compatibility
|
|
54
110
|
export function metadataPath(customerIdn: string, projectIdn: string): string {
|
|
55
111
|
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, 'metadata.json');
|
|
56
112
|
}
|