newo 1.4.0 → 1.5.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 +41 -0
- package/README.md +41 -1
- package/dist/akb.d.ts +10 -0
- package/dist/akb.js +84 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.js +100 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +104 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +111 -0
- package/dist/fsutil.d.ts +12 -0
- package/dist/fsutil.js +28 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +17 -0
- package/dist/sync.d.ts +7 -0
- package/dist/sync.js +337 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.js +5 -0
- package/package.json +26 -12
- package/src/{akb.js → akb.ts} +16 -25
- package/src/api.ts +127 -0
- package/src/auth.ts +142 -0
- package/src/{cli.js → cli.ts} +17 -10
- package/src/{fsutil.js → fsutil.ts} +14 -7
- package/src/hash.ts +20 -0
- package/src/{sync.js → sync.ts} +91 -44
- package/src/types.ts +248 -0
- package/src/api.js +0 -103
- package/src/auth.js +0 -92
- package/src/hash.js +0 -17
package/src/{sync.js → sync.ts}
RENAMED
|
@@ -1,11 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
listProjects,
|
|
3
|
+
listAgents,
|
|
4
|
+
listFlowSkills,
|
|
5
|
+
updateSkill,
|
|
6
|
+
listFlowEvents,
|
|
7
|
+
listFlowStates,
|
|
8
|
+
getProjectMeta
|
|
9
|
+
} from './api.js';
|
|
10
|
+
import {
|
|
11
|
+
ensureState,
|
|
12
|
+
skillPath,
|
|
13
|
+
writeFileAtomic,
|
|
14
|
+
readIfExists,
|
|
15
|
+
MAP_PATH,
|
|
16
|
+
projectDir,
|
|
17
|
+
metadataPath
|
|
18
|
+
} from './fsutil.js';
|
|
3
19
|
import fs from 'fs-extra';
|
|
4
20
|
import { sha256, loadHashes, saveHashes } from './hash.js';
|
|
5
21
|
import yaml from 'js-yaml';
|
|
6
22
|
import path from 'path';
|
|
23
|
+
import type { AxiosInstance } from 'axios';
|
|
24
|
+
import type {
|
|
25
|
+
Agent,
|
|
26
|
+
ProjectData,
|
|
27
|
+
ProjectMap,
|
|
28
|
+
LegacyProjectMap,
|
|
29
|
+
HashStore,
|
|
30
|
+
FlowsYamlData,
|
|
31
|
+
FlowsYamlAgent,
|
|
32
|
+
FlowsYamlFlow,
|
|
33
|
+
FlowsYamlSkill,
|
|
34
|
+
FlowsYamlEvent,
|
|
35
|
+
FlowsYamlState
|
|
36
|
+
} from './types.js';
|
|
7
37
|
|
|
8
|
-
export async function pullSingleProject(
|
|
38
|
+
export async function pullSingleProject(
|
|
39
|
+
client: AxiosInstance,
|
|
40
|
+
projectId: string,
|
|
41
|
+
projectIdn: string,
|
|
42
|
+
verbose: boolean = false
|
|
43
|
+
): Promise<ProjectData> {
|
|
9
44
|
if (verbose) console.log(`🔍 Fetching agents for project ${projectId} (${projectIdn})...`);
|
|
10
45
|
const agents = await listAgents(client, projectId);
|
|
11
46
|
if (verbose) console.log(`📦 Found ${agents.length} agents`);
|
|
@@ -15,28 +50,29 @@ export async function pullSingleProject(client, projectId, projectIdn, verbose =
|
|
|
15
50
|
await writeFileAtomic(metadataPath(projectIdn), JSON.stringify(projectMeta, null, 2));
|
|
16
51
|
if (verbose) console.log(`✓ Saved metadata for ${projectIdn}`);
|
|
17
52
|
|
|
18
|
-
const projectMap = { projectId, projectIdn, agents: {} };
|
|
53
|
+
const projectMap: ProjectData = { projectId, projectIdn, agents: {} };
|
|
19
54
|
|
|
20
55
|
for (const agent of agents) {
|
|
21
56
|
const aKey = agent.idn;
|
|
22
57
|
projectMap.agents[aKey] = { id: agent.id, flows: {} };
|
|
23
58
|
|
|
24
59
|
for (const flow of agent.flows ?? []) {
|
|
25
|
-
projectMap.agents[aKey]
|
|
60
|
+
projectMap.agents[aKey]!.flows[flow.idn] = { id: flow.id, skills: {} };
|
|
26
61
|
|
|
27
62
|
const skills = await listFlowSkills(client, flow.id);
|
|
28
|
-
for (const
|
|
29
|
-
const file = skillPath(projectIdn, agent.idn, flow.idn,
|
|
30
|
-
await writeFileAtomic(file,
|
|
63
|
+
for (const skill of skills) {
|
|
64
|
+
const file = skillPath(projectIdn, agent.idn, flow.idn, skill.idn, skill.runner_type);
|
|
65
|
+
await writeFileAtomic(file, skill.prompt_script || '');
|
|
66
|
+
|
|
31
67
|
// Store complete skill metadata for push operations
|
|
32
|
-
projectMap.agents[aKey]
|
|
33
|
-
id:
|
|
34
|
-
title:
|
|
35
|
-
idn:
|
|
36
|
-
runner_type:
|
|
37
|
-
model:
|
|
38
|
-
parameters:
|
|
39
|
-
path:
|
|
68
|
+
projectMap.agents[aKey]!.flows[flow.idn]!.skills[skill.idn] = {
|
|
69
|
+
id: skill.id,
|
|
70
|
+
title: skill.title,
|
|
71
|
+
idn: skill.idn,
|
|
72
|
+
runner_type: skill.runner_type,
|
|
73
|
+
model: skill.model,
|
|
74
|
+
parameters: skill.parameters,
|
|
75
|
+
path: skill.path || undefined
|
|
40
76
|
};
|
|
41
77
|
console.log(`✓ Pulled ${file}`);
|
|
42
78
|
}
|
|
@@ -50,7 +86,11 @@ export async function pullSingleProject(client, projectId, projectIdn, verbose =
|
|
|
50
86
|
return projectMap;
|
|
51
87
|
}
|
|
52
88
|
|
|
53
|
-
export async function pullAll(
|
|
89
|
+
export async function pullAll(
|
|
90
|
+
client: AxiosInstance,
|
|
91
|
+
projectId: string | null = null,
|
|
92
|
+
verbose: boolean = false
|
|
93
|
+
): Promise<void> {
|
|
54
94
|
await ensureState();
|
|
55
95
|
|
|
56
96
|
if (projectId) {
|
|
@@ -58,11 +98,11 @@ export async function pullAll(client, projectId = null, verbose = false) {
|
|
|
58
98
|
const projectMeta = await getProjectMeta(client, projectId);
|
|
59
99
|
const projectMap = await pullSingleProject(client, projectId, projectMeta.idn, verbose);
|
|
60
100
|
|
|
61
|
-
const idMap = { projects: { [projectMeta.idn]: projectMap } };
|
|
101
|
+
const idMap: ProjectMap = { projects: { [projectMeta.idn]: projectMap } };
|
|
62
102
|
await fs.writeJson(MAP_PATH, idMap, { spaces: 2 });
|
|
63
103
|
|
|
64
104
|
// Generate hash tracking for this project
|
|
65
|
-
const hashes = {};
|
|
105
|
+
const hashes: HashStore = {};
|
|
66
106
|
for (const [agentIdn, agentObj] of Object.entries(projectMap.agents)) {
|
|
67
107
|
for (const [flowIdn, flowObj] of Object.entries(agentObj.flows)) {
|
|
68
108
|
for (const [skillIdn, skillMeta] of Object.entries(flowObj.skills)) {
|
|
@@ -77,12 +117,12 @@ export async function pullAll(client, projectId = null, verbose = false) {
|
|
|
77
117
|
}
|
|
78
118
|
|
|
79
119
|
// Multi-project mode
|
|
80
|
-
if (verbose) console.log(
|
|
120
|
+
if (verbose) console.log('🔍 Fetching all projects...');
|
|
81
121
|
const projects = await listProjects(client);
|
|
82
122
|
if (verbose) console.log(`📦 Found ${projects.length} projects`);
|
|
83
123
|
|
|
84
|
-
const idMap = { projects: {} };
|
|
85
|
-
const allHashes = {};
|
|
124
|
+
const idMap: ProjectMap = { projects: {} };
|
|
125
|
+
const allHashes: HashStore = {};
|
|
86
126
|
|
|
87
127
|
for (const project of projects) {
|
|
88
128
|
if (verbose) console.log(`\n📁 Processing project: ${project.idn} (${project.title})`);
|
|
@@ -105,24 +145,24 @@ export async function pullAll(client, projectId = null, verbose = false) {
|
|
|
105
145
|
await saveHashes(allHashes);
|
|
106
146
|
}
|
|
107
147
|
|
|
108
|
-
export async function pushChanged(client, verbose = false) {
|
|
148
|
+
export async function pushChanged(client: AxiosInstance, verbose: boolean = false): Promise<void> {
|
|
109
149
|
await ensureState();
|
|
110
150
|
if (!(await fs.pathExists(MAP_PATH))) {
|
|
111
151
|
throw new Error('Missing .newo/map.json. Run `newo pull` first.');
|
|
112
152
|
}
|
|
113
153
|
|
|
114
154
|
if (verbose) console.log('📋 Loading project mapping...');
|
|
115
|
-
const idMap = await fs.readJson(MAP_PATH);
|
|
155
|
+
const idMap = await fs.readJson(MAP_PATH) as ProjectMap | LegacyProjectMap;
|
|
116
156
|
if (verbose) console.log('🔍 Loading file hashes...');
|
|
117
157
|
const oldHashes = await loadHashes();
|
|
118
|
-
const newHashes = { ...oldHashes };
|
|
158
|
+
const newHashes: HashStore = { ...oldHashes };
|
|
119
159
|
|
|
120
160
|
if (verbose) console.log('🔄 Scanning for changes...');
|
|
121
161
|
let pushed = 0;
|
|
122
162
|
let scanned = 0;
|
|
123
163
|
|
|
124
164
|
// Handle both old single-project format and new multi-project format
|
|
125
|
-
const projects = idMap.projects
|
|
165
|
+
const projects = 'projects' in idMap && idMap.projects ? idMap.projects : { '': idMap as ProjectData };
|
|
126
166
|
|
|
127
167
|
for (const [projectIdn, projectData] of Object.entries(projects)) {
|
|
128
168
|
if (verbose && projectIdn) console.log(`📁 Scanning project: ${projectIdn}`);
|
|
@@ -164,7 +204,7 @@ export async function pushChanged(client, verbose = false) {
|
|
|
164
204
|
runner_type: skillMeta.runner_type,
|
|
165
205
|
model: skillMeta.model,
|
|
166
206
|
parameters: skillMeta.parameters,
|
|
167
|
-
path: skillMeta.path
|
|
207
|
+
path: skillMeta.path || undefined
|
|
168
208
|
};
|
|
169
209
|
|
|
170
210
|
if (verbose) {
|
|
@@ -193,7 +233,7 @@ export async function pushChanged(client, verbose = false) {
|
|
|
193
233
|
console.log(pushed ? `✅ Push complete. ${pushed} file(s) updated.` : '✅ Nothing to push.');
|
|
194
234
|
}
|
|
195
235
|
|
|
196
|
-
export async function status(verbose = false) {
|
|
236
|
+
export async function status(verbose: boolean = false): Promise<void> {
|
|
197
237
|
await ensureState();
|
|
198
238
|
if (!(await fs.pathExists(MAP_PATH))) {
|
|
199
239
|
console.log('No map. Run `newo pull` first.');
|
|
@@ -201,12 +241,12 @@ export async function status(verbose = false) {
|
|
|
201
241
|
}
|
|
202
242
|
|
|
203
243
|
if (verbose) console.log('📋 Loading project mapping and hashes...');
|
|
204
|
-
const idMap = await fs.readJson(MAP_PATH);
|
|
244
|
+
const idMap = await fs.readJson(MAP_PATH) as ProjectMap | LegacyProjectMap;
|
|
205
245
|
const hashes = await loadHashes();
|
|
206
246
|
let dirty = 0;
|
|
207
247
|
|
|
208
248
|
// Handle both old single-project format and new multi-project format
|
|
209
|
-
const projects = idMap.projects
|
|
249
|
+
const projects = 'projects' in idMap && idMap.projects ? idMap.projects : { '': idMap as ProjectData };
|
|
210
250
|
|
|
211
251
|
for (const [projectIdn, projectData] of Object.entries(projects)) {
|
|
212
252
|
if (verbose && projectIdn) console.log(`📁 Checking project: ${projectIdn}`);
|
|
@@ -248,20 +288,25 @@ export async function status(verbose = false) {
|
|
|
248
288
|
console.log(dirty ? `${dirty} changed file(s).` : 'Clean.');
|
|
249
289
|
}
|
|
250
290
|
|
|
251
|
-
async function generateFlowsYaml(
|
|
252
|
-
|
|
291
|
+
async function generateFlowsYaml(
|
|
292
|
+
client: AxiosInstance,
|
|
293
|
+
agents: Agent[],
|
|
294
|
+
projectIdn: string,
|
|
295
|
+
verbose: boolean = false
|
|
296
|
+
): Promise<void> {
|
|
297
|
+
const flowsData: FlowsYamlData = { flows: [] };
|
|
253
298
|
|
|
254
299
|
for (const agent of agents) {
|
|
255
300
|
if (verbose) console.log(` 📁 Processing agent: ${agent.idn}`);
|
|
256
301
|
|
|
257
|
-
const agentFlows = [];
|
|
302
|
+
const agentFlows: FlowsYamlFlow[] = [];
|
|
258
303
|
|
|
259
304
|
for (const flow of agent.flows ?? []) {
|
|
260
305
|
if (verbose) console.log(` 📄 Processing flow: ${flow.idn}`);
|
|
261
306
|
|
|
262
307
|
// Get skills for this flow
|
|
263
308
|
const skills = await listFlowSkills(client, flow.id);
|
|
264
|
-
const skillsData = skills.map(skill => ({
|
|
309
|
+
const skillsData: FlowsYamlSkill[] = skills.map(skill => ({
|
|
265
310
|
idn: skill.idn,
|
|
266
311
|
title: skill.title || "",
|
|
267
312
|
prompt_script: `flows/${flow.idn}/${skill.idn}.${skill.runner_type === 'nsl' ? 'jinja' : 'nsl'}`,
|
|
@@ -277,17 +322,17 @@ async function generateFlowsYaml(client, agents, projectIdn, verbose = false) {
|
|
|
277
322
|
}));
|
|
278
323
|
|
|
279
324
|
// Get events for this flow
|
|
280
|
-
let eventsData = [];
|
|
325
|
+
let eventsData: FlowsYamlEvent[] = [];
|
|
281
326
|
try {
|
|
282
327
|
const events = await listFlowEvents(client, flow.id);
|
|
283
328
|
eventsData = events.map(event => ({
|
|
284
329
|
title: event.description,
|
|
285
330
|
idn: event.idn,
|
|
286
331
|
skill_selector: `!enum "SkillSelector.${event.skill_selector}"`,
|
|
287
|
-
skill_idn: event.skill_idn,
|
|
288
|
-
state_idn: event.state_idn,
|
|
289
|
-
integration_idn: event.integration_idn,
|
|
290
|
-
connector_idn: event.connector_idn,
|
|
332
|
+
skill_idn: event.skill_idn || undefined,
|
|
333
|
+
state_idn: event.state_idn || undefined,
|
|
334
|
+
integration_idn: event.integration_idn || undefined,
|
|
335
|
+
connector_idn: event.connector_idn || undefined,
|
|
291
336
|
interrupt_mode: `!enum "InterruptMode.${event.interrupt_mode}"`
|
|
292
337
|
}));
|
|
293
338
|
if (verbose) console.log(` 📋 Found ${events.length} events`);
|
|
@@ -296,13 +341,13 @@ async function generateFlowsYaml(client, agents, projectIdn, verbose = false) {
|
|
|
296
341
|
}
|
|
297
342
|
|
|
298
343
|
// Get state fields for this flow
|
|
299
|
-
let stateFieldsData = [];
|
|
344
|
+
let stateFieldsData: FlowsYamlState[] = [];
|
|
300
345
|
try {
|
|
301
346
|
const states = await listFlowStates(client, flow.id);
|
|
302
347
|
stateFieldsData = states.map(state => ({
|
|
303
348
|
title: state.title,
|
|
304
349
|
idn: state.idn,
|
|
305
|
-
default_value: state.default_value,
|
|
350
|
+
default_value: state.default_value || undefined,
|
|
306
351
|
scope: `!enum "StateFieldScope.${state.scope}"`
|
|
307
352
|
}));
|
|
308
353
|
if (verbose) console.log(` 📊 Found ${states.length} state fields`);
|
|
@@ -323,11 +368,13 @@ async function generateFlowsYaml(client, agents, projectIdn, verbose = false) {
|
|
|
323
368
|
});
|
|
324
369
|
}
|
|
325
370
|
|
|
326
|
-
|
|
371
|
+
const agentData: FlowsYamlAgent = {
|
|
327
372
|
agent_idn: agent.idn,
|
|
328
|
-
agent_description: agent.description,
|
|
373
|
+
agent_description: agent.description || undefined,
|
|
329
374
|
agent_flows: agentFlows
|
|
330
|
-
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
flowsData.flows.push(agentData);
|
|
331
378
|
}
|
|
332
379
|
|
|
333
380
|
// Convert to YAML and write to file with custom enum handling
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive type definitions for NEWO CLI
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface NewoEnvironment {
|
|
6
|
+
NEWO_BASE_URL?: string;
|
|
7
|
+
NEWO_PROJECT_ID?: string;
|
|
8
|
+
NEWO_API_KEY?: string;
|
|
9
|
+
NEWO_ACCESS_TOKEN?: string;
|
|
10
|
+
NEWO_REFRESH_TOKEN?: string;
|
|
11
|
+
NEWO_REFRESH_URL?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Authentication Types
|
|
15
|
+
export interface TokenResponse {
|
|
16
|
+
access_token?: string;
|
|
17
|
+
token?: string;
|
|
18
|
+
accessToken?: string;
|
|
19
|
+
refresh_token?: string;
|
|
20
|
+
refreshToken?: string;
|
|
21
|
+
expires_in?: number;
|
|
22
|
+
expiresIn?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StoredTokens {
|
|
26
|
+
access_token: string;
|
|
27
|
+
refresh_token: string;
|
|
28
|
+
expires_at: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// API Response Types
|
|
32
|
+
export interface ProjectMeta {
|
|
33
|
+
id: string;
|
|
34
|
+
idn: string;
|
|
35
|
+
title: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
created_at?: string;
|
|
38
|
+
updated_at?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Agent {
|
|
42
|
+
id: string;
|
|
43
|
+
idn: string;
|
|
44
|
+
title?: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
flows?: Flow[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface Flow {
|
|
50
|
+
id: string;
|
|
51
|
+
idn: string;
|
|
52
|
+
title: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
default_runner_type: RunnerType;
|
|
55
|
+
default_model: ModelConfig;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ModelConfig {
|
|
59
|
+
model_idn: string;
|
|
60
|
+
provider_idn: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface SkillParameter {
|
|
64
|
+
name: string;
|
|
65
|
+
default_value?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface Skill {
|
|
69
|
+
id: string;
|
|
70
|
+
idn: string;
|
|
71
|
+
title: string;
|
|
72
|
+
prompt_script?: string;
|
|
73
|
+
runner_type: RunnerType;
|
|
74
|
+
model: ModelConfig;
|
|
75
|
+
parameters: SkillParameter[];
|
|
76
|
+
path?: string | undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface FlowEvent {
|
|
80
|
+
id: string;
|
|
81
|
+
idn: string;
|
|
82
|
+
description: string;
|
|
83
|
+
skill_selector: SkillSelector;
|
|
84
|
+
skill_idn?: string;
|
|
85
|
+
state_idn?: string;
|
|
86
|
+
integration_idn?: string;
|
|
87
|
+
connector_idn?: string;
|
|
88
|
+
interrupt_mode: InterruptMode;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface FlowState {
|
|
92
|
+
id: string;
|
|
93
|
+
idn: string;
|
|
94
|
+
title: string;
|
|
95
|
+
default_value?: string;
|
|
96
|
+
scope: StateFieldScope;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Enum Types
|
|
100
|
+
export type RunnerType = 'guidance' | 'nsl';
|
|
101
|
+
export type SkillSelector = 'first' | 'last' | 'random' | 'all';
|
|
102
|
+
export type InterruptMode = 'allow' | 'deny' | 'queue';
|
|
103
|
+
export type StateFieldScope = 'flow' | 'agent' | 'project' | 'global';
|
|
104
|
+
|
|
105
|
+
// File System Types
|
|
106
|
+
export interface SkillMetadata {
|
|
107
|
+
id: string;
|
|
108
|
+
title: string;
|
|
109
|
+
idn: string;
|
|
110
|
+
runner_type: RunnerType;
|
|
111
|
+
model: ModelConfig;
|
|
112
|
+
parameters: SkillParameter[];
|
|
113
|
+
path?: string | undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface FlowData {
|
|
117
|
+
id: string;
|
|
118
|
+
skills: Record<string, SkillMetadata>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface AgentData {
|
|
122
|
+
id: string;
|
|
123
|
+
flows: Record<string, FlowData>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ProjectData {
|
|
127
|
+
projectId: string;
|
|
128
|
+
projectIdn: string;
|
|
129
|
+
agents: Record<string, AgentData>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface ProjectMap {
|
|
133
|
+
projects: Record<string, ProjectData>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Legacy single-project format support
|
|
137
|
+
export interface LegacyProjectMap extends ProjectData {
|
|
138
|
+
projects?: Record<string, ProjectData>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface HashStore {
|
|
142
|
+
[filePath: string]: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// AKB Types
|
|
146
|
+
export interface ParsedArticle {
|
|
147
|
+
topic_name: string;
|
|
148
|
+
persona_id: string | null;
|
|
149
|
+
topic_summary: string;
|
|
150
|
+
topic_facts: string[];
|
|
151
|
+
confidence: number;
|
|
152
|
+
source: string;
|
|
153
|
+
labels: string[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface AkbImportArticle extends Omit<ParsedArticle, 'persona_id'> {
|
|
157
|
+
persona_id: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// CLI Types
|
|
161
|
+
export interface CliArgs {
|
|
162
|
+
_: string[];
|
|
163
|
+
verbose?: boolean;
|
|
164
|
+
v?: boolean;
|
|
165
|
+
[key: string]: unknown;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// flows.yaml Generation Types
|
|
169
|
+
export interface FlowsYamlSkill {
|
|
170
|
+
idn: string;
|
|
171
|
+
title: string;
|
|
172
|
+
prompt_script: string;
|
|
173
|
+
runner_type: string;
|
|
174
|
+
model: ModelConfig;
|
|
175
|
+
parameters: Array<{
|
|
176
|
+
name: string;
|
|
177
|
+
default_value: string;
|
|
178
|
+
}>;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface FlowsYamlEvent {
|
|
182
|
+
title: string;
|
|
183
|
+
idn: string;
|
|
184
|
+
skill_selector: string;
|
|
185
|
+
skill_idn?: string | undefined;
|
|
186
|
+
state_idn?: string | undefined;
|
|
187
|
+
integration_idn?: string | undefined;
|
|
188
|
+
connector_idn?: string | undefined;
|
|
189
|
+
interrupt_mode: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface FlowsYamlState {
|
|
193
|
+
title: string;
|
|
194
|
+
idn: string;
|
|
195
|
+
default_value?: string | undefined;
|
|
196
|
+
scope: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface FlowsYamlFlow {
|
|
200
|
+
idn: string;
|
|
201
|
+
title: string;
|
|
202
|
+
description: string | null;
|
|
203
|
+
default_runner_type: string;
|
|
204
|
+
default_provider_idn: string;
|
|
205
|
+
default_model_idn: string;
|
|
206
|
+
skills: FlowsYamlSkill[];
|
|
207
|
+
events: FlowsYamlEvent[];
|
|
208
|
+
state_fields: FlowsYamlState[];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface FlowsYamlAgent {
|
|
212
|
+
agent_idn: string;
|
|
213
|
+
agent_description?: string | undefined;
|
|
214
|
+
agent_flows: FlowsYamlFlow[];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface FlowsYamlData {
|
|
218
|
+
flows: FlowsYamlAgent[];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// HTTP Client Types
|
|
222
|
+
export interface AxiosClientConfig {
|
|
223
|
+
baseURL?: string;
|
|
224
|
+
headers?: Record<string, string>;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Error Types
|
|
228
|
+
export interface NewoApiError extends Error {
|
|
229
|
+
response?: {
|
|
230
|
+
status: number;
|
|
231
|
+
data: unknown;
|
|
232
|
+
};
|
|
233
|
+
config?: {
|
|
234
|
+
method?: string;
|
|
235
|
+
url?: string;
|
|
236
|
+
headers?: Record<string, string>;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Status Types
|
|
241
|
+
export type FileStatus = 'M' | 'D' | 'clean';
|
|
242
|
+
|
|
243
|
+
export interface StatusResult {
|
|
244
|
+
filePath: string;
|
|
245
|
+
status: FileStatus;
|
|
246
|
+
oldHash?: string;
|
|
247
|
+
newHash?: string;
|
|
248
|
+
}
|
package/src/api.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
import { getValidAccessToken, forceReauth } from './auth.js';
|
|
4
|
-
dotenv.config();
|
|
5
|
-
|
|
6
|
-
const { NEWO_BASE_URL } = process.env;
|
|
7
|
-
|
|
8
|
-
export async function makeClient(verbose = false) {
|
|
9
|
-
let accessToken = await getValidAccessToken();
|
|
10
|
-
if (verbose) console.log('✓ Access token obtained');
|
|
11
|
-
|
|
12
|
-
const client = axios.create({
|
|
13
|
-
baseURL: NEWO_BASE_URL,
|
|
14
|
-
headers: { accept: 'application/json' }
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
client.interceptors.request.use(async (config) => {
|
|
18
|
-
config.headers = config.headers || {};
|
|
19
|
-
config.headers.Authorization = `Bearer ${accessToken}`;
|
|
20
|
-
if (verbose) {
|
|
21
|
-
console.log(`→ ${config.method?.toUpperCase()} ${config.url}`);
|
|
22
|
-
if (config.data) console.log(' Data:', JSON.stringify(config.data, null, 2));
|
|
23
|
-
if (config.params) console.log(' Params:', config.params);
|
|
24
|
-
}
|
|
25
|
-
return config;
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
let retried = false;
|
|
29
|
-
client.interceptors.response.use(
|
|
30
|
-
r => {
|
|
31
|
-
if (verbose) {
|
|
32
|
-
console.log(`← ${r.status} ${r.config.method?.toUpperCase()} ${r.config.url}`);
|
|
33
|
-
if (r.data && Object.keys(r.data).length < 20) {
|
|
34
|
-
console.log(' Response:', JSON.stringify(r.data, null, 2));
|
|
35
|
-
} else if (r.data) {
|
|
36
|
-
console.log(` Response: [${typeof r.data}] ${Array.isArray(r.data) ? r.data.length + ' items' : 'large object'}`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return r;
|
|
40
|
-
},
|
|
41
|
-
async (error) => {
|
|
42
|
-
const status = error?.response?.status;
|
|
43
|
-
if (verbose) {
|
|
44
|
-
console.log(`← ${status} ${error.config?.method?.toUpperCase()} ${error.config?.url} - ${error.message}`);
|
|
45
|
-
if (error.response?.data) console.log(' Error data:', error.response.data);
|
|
46
|
-
}
|
|
47
|
-
if (status === 401 && !retried) {
|
|
48
|
-
retried = true;
|
|
49
|
-
if (verbose) console.log('🔄 Retrying with fresh token...');
|
|
50
|
-
accessToken = await forceReauth();
|
|
51
|
-
error.config.headers.Authorization = `Bearer ${accessToken}`;
|
|
52
|
-
return client.request(error.config);
|
|
53
|
-
}
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
return client;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function listProjects(client) {
|
|
62
|
-
const r = await client.get(`/api/v1/designer/projects`);
|
|
63
|
-
return r.data;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export async function listAgents(client, projectId) {
|
|
67
|
-
const r = await client.get(`/api/v1/bff/agents/list`, { params: { project_id: projectId } });
|
|
68
|
-
return r.data;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export async function getProjectMeta(client, projectId) {
|
|
72
|
-
const r = await client.get(`/api/v1/designer/projects/by-id/${projectId}`);
|
|
73
|
-
return r.data;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export async function listFlowSkills(client, flowId) {
|
|
77
|
-
const r = await client.get(`/api/v1/designer/flows/${flowId}/skills`);
|
|
78
|
-
return r.data;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function getSkill(client, skillId) {
|
|
82
|
-
const r = await client.get(`/api/v1/designer/skills/${skillId}`);
|
|
83
|
-
return r.data;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export async function updateSkill(client, skillObject) {
|
|
87
|
-
await client.put(`/api/v1/designer/flows/skills/${skillObject.id}`, skillObject);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export async function listFlowEvents(client, flowId) {
|
|
91
|
-
const r = await client.get(`/api/v1/designer/flows/${flowId}/events`);
|
|
92
|
-
return r.data;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function listFlowStates(client, flowId) {
|
|
96
|
-
const r = await client.get(`/api/v1/designer/flows/${flowId}/states`);
|
|
97
|
-
return r.data;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export async function importAkbArticle(client, articleData) {
|
|
101
|
-
const r = await client.post('/api/v1/akb/append-manual', articleData);
|
|
102
|
-
return r.data;
|
|
103
|
-
}
|