ai.matey.cli 0.2.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 +21 -0
- package/dist/cjs/convert-request.js +365 -0
- package/dist/cjs/convert-request.js.map +1 -0
- package/dist/cjs/convert-response.js +211 -0
- package/dist/cjs/convert-response.js.map +1 -0
- package/dist/cjs/converters/request-converters.js +183 -0
- package/dist/cjs/converters/request-converters.js.map +1 -0
- package/dist/cjs/converters/response-converters.js +203 -0
- package/dist/cjs/converters/response-converters.js.map +1 -0
- package/dist/cjs/create-backend.js +569 -0
- package/dist/cjs/create-backend.js.map +1 -0
- package/dist/cjs/index.js +31 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/main.js +181 -0
- package/dist/cjs/main.js.map +1 -0
- package/dist/cjs/ollama/commands/list.js +70 -0
- package/dist/cjs/ollama/commands/list.js.map +1 -0
- package/dist/cjs/ollama/commands/ps.js +80 -0
- package/dist/cjs/ollama/commands/ps.js.map +1 -0
- package/dist/cjs/ollama/commands/pull.js +198 -0
- package/dist/cjs/ollama/commands/pull.js.map +1 -0
- package/dist/cjs/ollama/commands/run.js +279 -0
- package/dist/cjs/ollama/commands/run.js.map +1 -0
- package/dist/cjs/ollama/commands/show.js +138 -0
- package/dist/cjs/ollama/commands/show.js.map +1 -0
- package/dist/cjs/ollama/index.js +238 -0
- package/dist/cjs/ollama/index.js.map +1 -0
- package/dist/cjs/ollama/types.js +10 -0
- package/dist/cjs/ollama/types.js.map +1 -0
- package/dist/cjs/proxy.js +406 -0
- package/dist/cjs/proxy.js.map +1 -0
- package/dist/cjs/utils/backend-loader.js +112 -0
- package/dist/cjs/utils/backend-loader.js.map +1 -0
- package/dist/cjs/utils/index.js +29 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/model-translation.js +138 -0
- package/dist/cjs/utils/model-translation.js.map +1 -0
- package/dist/cjs/utils/output-formatter.js +241 -0
- package/dist/cjs/utils/output-formatter.js.map +1 -0
- package/dist/cjs/utils/pipeline-inspector.js +90 -0
- package/dist/cjs/utils/pipeline-inspector.js.map +1 -0
- package/dist/cjs/utils/state-manager.js +114 -0
- package/dist/cjs/utils/state-manager.js.map +1 -0
- package/dist/esm/convert-request.js +331 -0
- package/dist/esm/convert-request.js.map +1 -0
- package/dist/esm/convert-response.js +177 -0
- package/dist/esm/convert-response.js.map +1 -0
- package/dist/esm/converters/request-converters.js +175 -0
- package/dist/esm/converters/request-converters.js.map +1 -0
- package/dist/esm/converters/response-converters.js +191 -0
- package/dist/esm/converters/response-converters.js.map +1 -0
- package/dist/esm/create-backend.js +533 -0
- package/dist/esm/create-backend.js.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/main.js +149 -0
- package/dist/esm/main.js.map +1 -0
- package/dist/esm/ollama/commands/list.js +67 -0
- package/dist/esm/ollama/commands/list.js.map +1 -0
- package/dist/esm/ollama/commands/ps.js +77 -0
- package/dist/esm/ollama/commands/ps.js.map +1 -0
- package/dist/esm/ollama/commands/pull.js +195 -0
- package/dist/esm/ollama/commands/pull.js.map +1 -0
- package/dist/esm/ollama/commands/run.js +243 -0
- package/dist/esm/ollama/commands/run.js.map +1 -0
- package/dist/esm/ollama/commands/show.js +135 -0
- package/dist/esm/ollama/commands/show.js.map +1 -0
- package/dist/esm/ollama/index.js +235 -0
- package/dist/esm/ollama/index.js.map +1 -0
- package/dist/esm/ollama/types.js +9 -0
- package/dist/esm/ollama/types.js.map +1 -0
- package/dist/esm/proxy.js +403 -0
- package/dist/esm/proxy.js.map +1 -0
- package/dist/esm/utils/backend-loader.js +74 -0
- package/dist/esm/utils/backend-loader.js.map +1 -0
- package/dist/esm/utils/index.js +13 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/model-translation.js +99 -0
- package/dist/esm/utils/model-translation.js.map +1 -0
- package/dist/esm/utils/output-formatter.js +224 -0
- package/dist/esm/utils/output-formatter.js.map +1 -0
- package/dist/esm/utils/pipeline-inspector.js +84 -0
- package/dist/esm/utils/pipeline-inspector.js.map +1 -0
- package/dist/esm/utils/state-manager.js +111 -0
- package/dist/esm/utils/state-manager.js.map +1 -0
- package/dist/types/convert-request.d.ts +15 -0
- package/dist/types/convert-request.d.ts.map +1 -0
- package/dist/types/convert-response.d.ts +16 -0
- package/dist/types/convert-response.d.ts.map +1 -0
- package/dist/types/converters/request-converters.d.ts +139 -0
- package/dist/types/converters/request-converters.d.ts.map +1 -0
- package/dist/types/converters/response-converters.d.ts +134 -0
- package/dist/types/converters/response-converters.d.ts.map +1 -0
- package/dist/types/create-backend.d.ts +20 -0
- package/dist/types/create-backend.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/main.d.ts +19 -0
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/ollama/commands/list.d.ts +32 -0
- package/dist/types/ollama/commands/list.d.ts.map +1 -0
- package/dist/types/ollama/commands/ps.d.ts +27 -0
- package/dist/types/ollama/commands/ps.d.ts.map +1 -0
- package/dist/types/ollama/commands/pull.d.ts +21 -0
- package/dist/types/ollama/commands/pull.d.ts.map +1 -0
- package/dist/types/ollama/commands/run.d.ts +48 -0
- package/dist/types/ollama/commands/run.d.ts.map +1 -0
- package/dist/types/ollama/commands/show.d.ts +36 -0
- package/dist/types/ollama/commands/show.d.ts.map +1 -0
- package/dist/types/ollama/index.d.ts +12 -0
- package/dist/types/ollama/index.d.ts.map +1 -0
- package/dist/types/ollama/types.d.ts +58 -0
- package/dist/types/ollama/types.d.ts.map +1 -0
- package/dist/types/proxy.d.ts +16 -0
- package/dist/types/proxy.d.ts.map +1 -0
- package/dist/types/utils/backend-loader.d.ts +55 -0
- package/dist/types/utils/backend-loader.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +13 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/model-translation.d.ts +64 -0
- package/dist/types/utils/model-translation.d.ts.map +1 -0
- package/dist/types/utils/output-formatter.d.ts +113 -0
- package/dist/types/utils/output-formatter.d.ts.map +1 -0
- package/dist/types/utils/pipeline-inspector.d.ts +50 -0
- package/dist/types/utils/pipeline-inspector.d.ts.map +1 -0
- package/dist/types/utils/state-manager.d.ts +91 -0
- package/dist/types/utils/state-manager.d.ts.map +1 -0
- package/package.json +75 -0
- package/readme.md +32 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Formatter Utility
|
|
3
|
+
*
|
|
4
|
+
* Formats output for terminal display.
|
|
5
|
+
* Handles colors, tables, and streaming output.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/utils/output-formatter
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* ANSI color codes.
|
|
11
|
+
*/
|
|
12
|
+
export const colors = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bold: '\x1b[1m',
|
|
15
|
+
dim: '\x1b[2m',
|
|
16
|
+
// Foreground colors
|
|
17
|
+
black: '\x1b[30m',
|
|
18
|
+
red: '\x1b[31m',
|
|
19
|
+
green: '\x1b[32m',
|
|
20
|
+
yellow: '\x1b[33m',
|
|
21
|
+
blue: '\x1b[34m',
|
|
22
|
+
magenta: '\x1b[35m',
|
|
23
|
+
cyan: '\x1b[36m',
|
|
24
|
+
white: '\x1b[37m',
|
|
25
|
+
gray: '\x1b[90m',
|
|
26
|
+
// Background colors
|
|
27
|
+
bgBlack: '\x1b[40m',
|
|
28
|
+
bgRed: '\x1b[41m',
|
|
29
|
+
bgGreen: '\x1b[42m',
|
|
30
|
+
bgYellow: '\x1b[43m',
|
|
31
|
+
bgBlue: '\x1b[44m',
|
|
32
|
+
bgMagenta: '\x1b[45m',
|
|
33
|
+
bgCyan: '\x1b[46m',
|
|
34
|
+
bgWhite: '\x1b[47m',
|
|
35
|
+
};
|
|
36
|
+
let colorsEnabled = true;
|
|
37
|
+
/**
|
|
38
|
+
* Enable or disable colored output.
|
|
39
|
+
*/
|
|
40
|
+
export function setColorsEnabled(enabled) {
|
|
41
|
+
colorsEnabled = enabled;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if colors are enabled.
|
|
45
|
+
*/
|
|
46
|
+
export function areColorsEnabled() {
|
|
47
|
+
return colorsEnabled;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Apply color to text.
|
|
51
|
+
*/
|
|
52
|
+
export function colorize(text, color) {
|
|
53
|
+
if (!colorsEnabled) {
|
|
54
|
+
return text;
|
|
55
|
+
}
|
|
56
|
+
return `${colors[color]}${text}${colors.reset}`;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Format text with multiple styles.
|
|
60
|
+
*/
|
|
61
|
+
export function style(text, ...styles) {
|
|
62
|
+
if (!colorsEnabled) {
|
|
63
|
+
return text;
|
|
64
|
+
}
|
|
65
|
+
const prefix = styles.map((s) => colors[s]).join('');
|
|
66
|
+
return `${prefix}${text}${colors.reset}`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Print success message.
|
|
70
|
+
*/
|
|
71
|
+
export function success(message) {
|
|
72
|
+
console.log(colorize('✓ ' + message, 'green'));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Print error message.
|
|
76
|
+
*/
|
|
77
|
+
export function error(message) {
|
|
78
|
+
console.error(colorize('✗ ' + message, 'red'));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Print warning message.
|
|
82
|
+
*/
|
|
83
|
+
export function warn(message) {
|
|
84
|
+
console.warn(colorize('⚠ ' + message, 'yellow'));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Print info message.
|
|
88
|
+
*/
|
|
89
|
+
export function info(message) {
|
|
90
|
+
console.log(colorize('ℹ ' + message, 'blue'));
|
|
91
|
+
}
|
|
92
|
+
export function formatTable(options) {
|
|
93
|
+
const { columns, rows } = options;
|
|
94
|
+
if (rows.length === 0) {
|
|
95
|
+
return '';
|
|
96
|
+
}
|
|
97
|
+
// Calculate column widths
|
|
98
|
+
const widths = columns.map((col) => {
|
|
99
|
+
const headerWidth = col.header.length;
|
|
100
|
+
const maxContentWidth = Math.max(...rows.map((row) => String(row[col.key] || '').length));
|
|
101
|
+
return col.width || Math.max(headerWidth, maxContentWidth);
|
|
102
|
+
});
|
|
103
|
+
// Format header
|
|
104
|
+
const header = columns.map((col, i) => col.header.padEnd(widths[i] || 0)).join(' ');
|
|
105
|
+
// Format rows
|
|
106
|
+
const formattedRows = rows.map((row) => columns
|
|
107
|
+
.map((col, i) => {
|
|
108
|
+
const value = String(row[col.key] || '');
|
|
109
|
+
const width = widths[i] || 0;
|
|
110
|
+
return col.align === 'right' ? value.padStart(width) : value.padEnd(width);
|
|
111
|
+
})
|
|
112
|
+
.join(' '));
|
|
113
|
+
return [style(header, 'bold'), ...formattedRows].join('\n');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Format file size in human-readable format.
|
|
117
|
+
*/
|
|
118
|
+
export function formatSize(bytes) {
|
|
119
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
120
|
+
let size = bytes;
|
|
121
|
+
let unitIndex = 0;
|
|
122
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
123
|
+
size /= 1024;
|
|
124
|
+
unitIndex++;
|
|
125
|
+
}
|
|
126
|
+
return `${size.toFixed(1)} ${units[unitIndex]}`;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Format duration in human-readable format.
|
|
130
|
+
*/
|
|
131
|
+
export function formatDuration(ms) {
|
|
132
|
+
if (ms < 1000) {
|
|
133
|
+
return `${ms}ms`;
|
|
134
|
+
}
|
|
135
|
+
if (ms < 60000) {
|
|
136
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
137
|
+
}
|
|
138
|
+
if (ms < 3600000) {
|
|
139
|
+
return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;
|
|
140
|
+
}
|
|
141
|
+
const hours = Math.floor(ms / 3600000);
|
|
142
|
+
const minutes = Math.floor((ms % 3600000) / 60000);
|
|
143
|
+
return `${hours}h ${minutes}m`;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Format relative time (e.g., "2 minutes ago").
|
|
147
|
+
*/
|
|
148
|
+
export function formatRelativeTime(timestamp) {
|
|
149
|
+
const now = Date.now();
|
|
150
|
+
const diff = now - timestamp;
|
|
151
|
+
if (diff < 60000) {
|
|
152
|
+
return 'just now';
|
|
153
|
+
}
|
|
154
|
+
if (diff < 3600000) {
|
|
155
|
+
const minutes = Math.floor(diff / 60000);
|
|
156
|
+
return `${minutes} minute${minutes !== 1 ? 's' : ''} ago`;
|
|
157
|
+
}
|
|
158
|
+
if (diff < 86400000) {
|
|
159
|
+
const hours = Math.floor(diff / 3600000);
|
|
160
|
+
return `${hours} hour${hours !== 1 ? 's' : ''} ago`;
|
|
161
|
+
}
|
|
162
|
+
const days = Math.floor(diff / 86400000);
|
|
163
|
+
return `${days} day${days !== 1 ? 's' : ''} ago`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Create a spinner for long-running operations.
|
|
167
|
+
*/
|
|
168
|
+
export class Spinner {
|
|
169
|
+
frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
170
|
+
currentFrame = 0;
|
|
171
|
+
interval;
|
|
172
|
+
text;
|
|
173
|
+
constructor(text) {
|
|
174
|
+
this.text = text;
|
|
175
|
+
}
|
|
176
|
+
start() {
|
|
177
|
+
if (this.interval || !colorsEnabled) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.interval = setInterval(() => {
|
|
181
|
+
const frame = this.frames[this.currentFrame] || '⠋';
|
|
182
|
+
process.stdout.write(`\r${colorize(frame, 'cyan')} ${this.text}`);
|
|
183
|
+
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
|
|
184
|
+
}, 80);
|
|
185
|
+
}
|
|
186
|
+
stop(finalMessage) {
|
|
187
|
+
if (this.interval) {
|
|
188
|
+
clearInterval(this.interval);
|
|
189
|
+
this.interval = undefined;
|
|
190
|
+
}
|
|
191
|
+
// Clear spinner line
|
|
192
|
+
process.stdout.write('\r\x1b[K');
|
|
193
|
+
if (finalMessage) {
|
|
194
|
+
console.log(finalMessage);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
succeed(message) {
|
|
198
|
+
this.stop(success.bind(null, message || this.text));
|
|
199
|
+
}
|
|
200
|
+
fail(message) {
|
|
201
|
+
this.stop(error.bind(null, message || this.text));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Print a box around text.
|
|
206
|
+
*/
|
|
207
|
+
export function printBox(text, options = {}) {
|
|
208
|
+
const { title, padding = 1 } = options;
|
|
209
|
+
const lines = text.split('\n');
|
|
210
|
+
const maxLength = Math.max(...lines.map((l) => l.length));
|
|
211
|
+
const width = maxLength + padding * 2;
|
|
212
|
+
const top = title
|
|
213
|
+
? `╭─ ${title} ${'─'.repeat(Math.max(0, width - title.length - 3))}╮`
|
|
214
|
+
: `╭${'─'.repeat(width + 2)}╮`;
|
|
215
|
+
const bottom = `╰${'─'.repeat(width + 2)}╯`;
|
|
216
|
+
const paddingStr = ' '.repeat(padding);
|
|
217
|
+
console.log(style(top, 'cyan'));
|
|
218
|
+
for (const line of lines) {
|
|
219
|
+
const padded = line.padEnd(maxLength);
|
|
220
|
+
console.log(style('│', 'cyan') + paddingStr + padded + paddingStr + style('│', 'cyan'));
|
|
221
|
+
}
|
|
222
|
+
console.log(style(bottom, 'cyan'));
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=output-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-formatter.js","sourceRoot":"","sources":["../../../src/utils/output-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Pipeline Inspector - visualize pipeline execution
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format a trace for CLI display
|
|
6
|
+
*/
|
|
7
|
+
export function formatTrace(trace) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
lines.push(`\n┌─ Pipeline Trace: ${trace.requestId}`);
|
|
10
|
+
lines.push(`├─ Duration: ${trace.duration ? `${trace.duration}ms` : 'in progress'}`);
|
|
11
|
+
lines.push(`├─ Status: ${trace.error ? '✗ Error' : '✓ Success'}`);
|
|
12
|
+
if (trace.steps.length > 0) {
|
|
13
|
+
lines.push(`└─ Steps:`);
|
|
14
|
+
for (let i = 0; i < trace.steps.length; i++) {
|
|
15
|
+
const step = trace.steps[i];
|
|
16
|
+
const isLast = i === trace.steps.length - 1;
|
|
17
|
+
const prefix = isLast ? ' └─' : ' ├─';
|
|
18
|
+
lines.push(`${prefix} ${step.name} (${step.type}) - ${step.duration ? `${step.duration}ms` : 'running'}`);
|
|
19
|
+
if (step.error) {
|
|
20
|
+
lines.push(`${isLast ? ' ' : ' │ '}✗ ${step.error.message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (trace.error) {
|
|
25
|
+
lines.push(`\nError: ${trace.error.message}`);
|
|
26
|
+
}
|
|
27
|
+
return lines.join('\n');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Format multiple traces
|
|
31
|
+
*/
|
|
32
|
+
export function formatTraces(traces) {
|
|
33
|
+
if (traces.length === 0) {
|
|
34
|
+
return 'No traces available';
|
|
35
|
+
}
|
|
36
|
+
return traces.map(formatTrace).join('\n\n');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Format debug statistics
|
|
40
|
+
*/
|
|
41
|
+
export function formatStats(stats) {
|
|
42
|
+
const lines = [];
|
|
43
|
+
lines.push('\n┌─ Debug Statistics');
|
|
44
|
+
lines.push(`├─ Total Requests: ${stats.totalRequests}`);
|
|
45
|
+
lines.push(`├─ Total Events: ${stats.totalEvents}`);
|
|
46
|
+
lines.push(`├─ Average Duration: ${stats.averageDuration.toFixed(2)}ms`);
|
|
47
|
+
lines.push(`├─ Errors: ${stats.errorCount}`);
|
|
48
|
+
lines.push(`├─ Warnings: ${stats.warningCount}`);
|
|
49
|
+
const eventTypes = Object.entries(stats.eventsByType);
|
|
50
|
+
if (eventTypes.length > 0) {
|
|
51
|
+
lines.push(`└─ Events by Type:`);
|
|
52
|
+
for (let i = 0; i < eventTypes.length; i++) {
|
|
53
|
+
const [type, count] = eventTypes[i];
|
|
54
|
+
const isLast = i === eventTypes.length - 1;
|
|
55
|
+
const prefix = isLast ? ' └─' : ' ├─';
|
|
56
|
+
lines.push(`${prefix} ${type}: ${count}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return lines.join('\n');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create a simple visualization of pipeline flow
|
|
63
|
+
*/
|
|
64
|
+
export function visualizePipeline(trace) {
|
|
65
|
+
const lines = [];
|
|
66
|
+
lines.push('\nPipeline Flow:');
|
|
67
|
+
lines.push('─'.repeat(60));
|
|
68
|
+
let offset = 0;
|
|
69
|
+
const totalDuration = trace.duration || Date.now() - trace.startTime;
|
|
70
|
+
const scale = 50 / totalDuration;
|
|
71
|
+
for (const step of trace.steps) {
|
|
72
|
+
if (!step.duration)
|
|
73
|
+
continue;
|
|
74
|
+
const barLength = Math.max(1, Math.floor(step.duration * scale));
|
|
75
|
+
const bar = '█'.repeat(barLength);
|
|
76
|
+
const status = step.error ? '✗' : '✓';
|
|
77
|
+
lines.push(`${status} ${step.name.padEnd(20)} ${bar} ${step.duration}ms`);
|
|
78
|
+
offset += step.duration;
|
|
79
|
+
}
|
|
80
|
+
lines.push('─'.repeat(60));
|
|
81
|
+
lines.push(`Total: ${totalDuration}ms`);
|
|
82
|
+
return lines.join('\n');
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=pipeline-inspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-inspector.js","sourceRoot":"","sources":["../../../src/utils/pipeline-inspector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Manager Utility
|
|
3
|
+
*
|
|
4
|
+
* Tracks running models and backend state for CLI.
|
|
5
|
+
* Used by `ps` command to show active models.
|
|
6
|
+
*
|
|
7
|
+
* @module cli/utils/state-manager
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Global state manager for running models.
|
|
11
|
+
*/
|
|
12
|
+
class StateManager {
|
|
13
|
+
models = new Map();
|
|
14
|
+
cleanupTimers = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Add a running model.
|
|
17
|
+
*/
|
|
18
|
+
add(model) {
|
|
19
|
+
const key = `${model.backend}:${model.name}`;
|
|
20
|
+
this.models.set(key, model);
|
|
21
|
+
// Set up cleanup timer if TTL specified
|
|
22
|
+
if (model.ttl) {
|
|
23
|
+
this.scheduleCleanup(key, model.ttl);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Update last activity time.
|
|
28
|
+
*/
|
|
29
|
+
touch(backend, modelName) {
|
|
30
|
+
const key = `${backend}:${modelName}`;
|
|
31
|
+
const model = this.models.get(key);
|
|
32
|
+
if (model) {
|
|
33
|
+
model.lastActivity = Date.now();
|
|
34
|
+
// Reschedule cleanup if TTL set
|
|
35
|
+
if (model.ttl) {
|
|
36
|
+
this.scheduleCleanup(key, model.ttl);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Remove a running model.
|
|
42
|
+
*/
|
|
43
|
+
remove(backend, modelName) {
|
|
44
|
+
const key = `${backend}:${modelName}`;
|
|
45
|
+
this.models.delete(key);
|
|
46
|
+
// Clear cleanup timer
|
|
47
|
+
const timer = this.cleanupTimers.get(key);
|
|
48
|
+
if (timer) {
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
this.cleanupTimers.delete(key);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get a running model.
|
|
55
|
+
*/
|
|
56
|
+
get(backend, modelName) {
|
|
57
|
+
const key = `${backend}:${modelName}`;
|
|
58
|
+
return this.models.get(key);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get all running models.
|
|
62
|
+
*/
|
|
63
|
+
getAll() {
|
|
64
|
+
return Array.from(this.models.values());
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get models by backend.
|
|
68
|
+
*/
|
|
69
|
+
getByBackend(backend) {
|
|
70
|
+
return Array.from(this.models.values()).filter((m) => m.backend === backend);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if model is running.
|
|
74
|
+
*/
|
|
75
|
+
isRunning(backend, modelName) {
|
|
76
|
+
const key = `${backend}:${modelName}`;
|
|
77
|
+
return this.models.has(key);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clear all models.
|
|
81
|
+
*/
|
|
82
|
+
clear() {
|
|
83
|
+
// Clear all timers
|
|
84
|
+
for (const timer of this.cleanupTimers.values()) {
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
}
|
|
87
|
+
this.cleanupTimers.clear();
|
|
88
|
+
this.models.clear();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Schedule cleanup after TTL.
|
|
92
|
+
*/
|
|
93
|
+
scheduleCleanup(key, ttl) {
|
|
94
|
+
// Clear existing timer
|
|
95
|
+
const existingTimer = this.cleanupTimers.get(key);
|
|
96
|
+
if (existingTimer) {
|
|
97
|
+
clearTimeout(existingTimer);
|
|
98
|
+
}
|
|
99
|
+
// Schedule new timer
|
|
100
|
+
const timer = setTimeout(() => {
|
|
101
|
+
this.models.delete(key);
|
|
102
|
+
this.cleanupTimers.delete(key);
|
|
103
|
+
}, ttl);
|
|
104
|
+
this.cleanupTimers.set(key, timer);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Global state manager instance.
|
|
109
|
+
*/
|
|
110
|
+
export const stateManager = new StateManager();
|
|
111
|
+
//# sourceMappingURL=state-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-manager.js","sourceRoot":"","sources":["../../../src/utils/state-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI Tool for Converting Requests
|
|
4
|
+
*
|
|
5
|
+
* Convert between Universal IR requests and various provider formats.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ai-matey convert-request --from openai --to ir --input request.json
|
|
9
|
+
* ai-matey convert-request --from ir --to anthropic --input request.json
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
declare function main(): Promise<void>;
|
|
14
|
+
export { main };
|
|
15
|
+
//# sourceMappingURL=convert-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert-request.d.ts","sourceRoot":"","sources":["../../src/convert-request.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAwQH,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsGnC;AAGD,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI Tool for Converting IR Responses
|
|
4
|
+
*
|
|
5
|
+
* Convert Universal IR responses to various frontend formats for debugging.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx ai-matey convert-response --format openai --input response.json
|
|
9
|
+
* npx ai-matey convert-response --format all --input response.json
|
|
10
|
+
* cat response.json | npx ai-matey convert-response --format anthropic
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
declare function main(): Promise<void>;
|
|
15
|
+
export { main };
|
|
16
|
+
//# sourceMappingURL=convert-response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert-response.d.ts","sourceRoot":"","sources":["../../src/convert-response.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AA2IH,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA8DnC;AAGD,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Conversion Utilities
|
|
3
|
+
*
|
|
4
|
+
* Convert Universal IR requests to provider-specific formats for debugging.
|
|
5
|
+
* Complements the response converters - provides full request/response symmetry.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { toOpenAIRequest, toAnthropicRequest } from 'ai.matey';
|
|
10
|
+
*
|
|
11
|
+
* // Convert IR request to see what will be sent to OpenAI
|
|
12
|
+
* const openaiReq = toOpenAIRequest(irRequest);
|
|
13
|
+
* console.log('Will send to OpenAI:', openaiReq);
|
|
14
|
+
*
|
|
15
|
+
* // Convert IR request to Anthropic format
|
|
16
|
+
* const anthropicReq = toAnthropicRequest(irRequest);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import type { IRChatRequest } from 'ai.matey.types';
|
|
22
|
+
import { type OpenAIRequest } from 'ai.matey.backend';
|
|
23
|
+
import { type AnthropicRequest } from 'ai.matey.backend';
|
|
24
|
+
import { type GeminiRequest } from 'ai.matey.backend';
|
|
25
|
+
import { type OllamaRequest } from 'ai.matey.backend';
|
|
26
|
+
import { type MistralRequest } from 'ai.matey.backend';
|
|
27
|
+
/**
|
|
28
|
+
* Convert IR request to OpenAI format.
|
|
29
|
+
*
|
|
30
|
+
* Useful for:
|
|
31
|
+
* - Debugging: See what will be sent to OpenAI
|
|
32
|
+
* - Testing: Create OpenAI requests without a backend
|
|
33
|
+
* - Inspection: Understand format transformations
|
|
34
|
+
*
|
|
35
|
+
* @param request - Universal IR request
|
|
36
|
+
* @returns OpenAI-formatted request
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const openaiReq = toOpenAIRequest({
|
|
41
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
42
|
+
* parameters: { model: 'gpt-4', temperature: 0.7 }
|
|
43
|
+
* });
|
|
44
|
+
* console.log(openaiReq.messages); // OpenAI format
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function toOpenAIRequest(request: IRChatRequest): OpenAIRequest;
|
|
48
|
+
/**
|
|
49
|
+
* Convert IR request to Anthropic format.
|
|
50
|
+
*
|
|
51
|
+
* @param request - Universal IR request
|
|
52
|
+
* @returns Anthropic-formatted request
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const anthropicReq = toAnthropicRequest({
|
|
57
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
58
|
+
* parameters: { model: 'claude-3', maxTokens: 100 }
|
|
59
|
+
* });
|
|
60
|
+
* console.log(anthropicReq.system); // Anthropic uses separate system parameter
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function toAnthropicRequest(request: IRChatRequest): AnthropicRequest;
|
|
64
|
+
/**
|
|
65
|
+
* Convert IR request to Gemini format.
|
|
66
|
+
*
|
|
67
|
+
* @param request - Universal IR request
|
|
68
|
+
* @returns Gemini-formatted request
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const geminiReq = toGeminiRequest({
|
|
73
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
74
|
+
* parameters: { model: 'gemini-pro', temperature: 0.7 }
|
|
75
|
+
* });
|
|
76
|
+
* console.log(geminiReq.contents); // Gemini uses 'contents' array
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function toGeminiRequest(request: IRChatRequest): GeminiRequest;
|
|
80
|
+
/**
|
|
81
|
+
* Convert IR request to Ollama format.
|
|
82
|
+
*
|
|
83
|
+
* @param request - Universal IR request
|
|
84
|
+
* @returns Ollama-formatted request
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const ollamaReq = toOllamaRequest({
|
|
89
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
90
|
+
* parameters: { model: 'llama2', temperature: 0.7 }
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function toOllamaRequest(request: IRChatRequest): OllamaRequest;
|
|
95
|
+
/**
|
|
96
|
+
* Convert IR request to Mistral format.
|
|
97
|
+
*
|
|
98
|
+
* @param request - Universal IR request
|
|
99
|
+
* @returns Mistral-formatted request
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* const mistralReq = toMistralRequest({
|
|
104
|
+
* messages: [{ role: 'user', content: 'Hello!' }],
|
|
105
|
+
* parameters: { model: 'mistral-small', temperature: 0.7 }
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare function toMistralRequest(request: IRChatRequest): MistralRequest;
|
|
110
|
+
/**
|
|
111
|
+
* Convert IR request to multiple provider formats at once.
|
|
112
|
+
*
|
|
113
|
+
* Useful for comparing how the same request looks across different providers.
|
|
114
|
+
*
|
|
115
|
+
* @param request - Universal IR request
|
|
116
|
+
* @param formats - Array of target formats
|
|
117
|
+
* @returns Object with format names as keys and converted requests as values
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const allFormats = toMultipleRequestFormats(irRequest, [
|
|
122
|
+
* 'openai',
|
|
123
|
+
* 'anthropic',
|
|
124
|
+
* 'gemini'
|
|
125
|
+
* ]);
|
|
126
|
+
*
|
|
127
|
+
* console.log('OpenAI:', allFormats.openai);
|
|
128
|
+
* console.log('Anthropic:', allFormats.anthropic);
|
|
129
|
+
* console.log('Gemini:', allFormats.gemini);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export declare function toMultipleRequestFormats(request: IRChatRequest, formats: Array<'openai' | 'anthropic' | 'gemini' | 'ollama' | 'mistral'>): {
|
|
133
|
+
openai?: OpenAIRequest;
|
|
134
|
+
anthropic?: AnthropicRequest;
|
|
135
|
+
gemini?: GeminiRequest;
|
|
136
|
+
ollama?: OllamaRequest;
|
|
137
|
+
mistral?: MistralRequest;
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=request-converters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-converters.d.ts","sourceRoot":"","sources":["../../../src/converters/request-converters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAM9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAGrE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAG3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAGrE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAGrE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,CAGvE;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,KAAK,CAAC,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC,GACvE;IACD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAwBA"}
|