orquesta-cli 0.2.42 → 0.2.43
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.
|
@@ -138,11 +138,17 @@ export class LLMClient {
|
|
|
138
138
|
}
|
|
139
139
|
preprocessMessages(messages, modelId) {
|
|
140
140
|
return messages.map((msg) => {
|
|
141
|
+
let processedMsg = { ...msg };
|
|
142
|
+
const multimodal = processedMsg.multimodal;
|
|
143
|
+
if (multimodal && Array.isArray(multimodal)) {
|
|
144
|
+
processedMsg.content = multimodal;
|
|
145
|
+
delete processedMsg.multimodal;
|
|
146
|
+
return processedMsg;
|
|
147
|
+
}
|
|
141
148
|
if (msg.role !== 'assistant') {
|
|
142
|
-
return
|
|
149
|
+
return processedMsg;
|
|
143
150
|
}
|
|
144
|
-
const msgAny =
|
|
145
|
-
let processedMsg = { ...msg };
|
|
151
|
+
const msgAny = processedMsg;
|
|
146
152
|
if (msgAny.reasoning_content && (!msg.content || msg.content.trim() === '')) {
|
|
147
153
|
processedMsg.content = msgAny.reasoning_content;
|
|
148
154
|
delete processedMsg.reasoning_content;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,13 +21,25 @@ export interface ModelInfo {
|
|
|
21
21
|
lastHealthCheck?: Date;
|
|
22
22
|
healthStatus?: 'healthy' | 'degraded' | 'unhealthy';
|
|
23
23
|
}
|
|
24
|
+
export type ContentPart = {
|
|
25
|
+
type: 'text';
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'image_url';
|
|
29
|
+
image_url: {
|
|
30
|
+
url: string;
|
|
31
|
+
detail?: 'auto' | 'low' | 'high';
|
|
32
|
+
};
|
|
33
|
+
};
|
|
24
34
|
export interface Message {
|
|
25
35
|
role: 'system' | 'user' | 'assistant' | 'tool' | 'error';
|
|
26
36
|
content: string;
|
|
37
|
+
multimodal?: ContentPart[];
|
|
27
38
|
name?: string;
|
|
28
39
|
tool_calls?: ToolCall[];
|
|
29
40
|
tool_call_id?: string;
|
|
30
41
|
}
|
|
42
|
+
export declare function messageText(content: string | ContentPart[] | undefined | null): string;
|
|
31
43
|
export interface ToolCall {
|
|
32
44
|
id: string;
|
|
33
45
|
type: 'function';
|
package/dist/types/index.js
CHANGED
|
@@ -923,14 +923,19 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
|
|
|
923
923
|
content: userMessage,
|
|
924
924
|
});
|
|
925
925
|
const processedResult = await processFileReferences(userMessage);
|
|
926
|
-
const processedMessage = processedResult.content;
|
|
926
|
+
const processedMessage = typeof processedResult.content === 'string' ? processedResult.content : userMessage;
|
|
927
|
+
const multimodal = Array.isArray(processedResult.content) ? processedResult.content : undefined;
|
|
927
928
|
if (processedResult.includedFiles.length > 0) {
|
|
928
929
|
logger.debug('Files included in message', {
|
|
929
930
|
files: processedResult.includedFiles,
|
|
930
931
|
failedFiles: processedResult.failedFiles,
|
|
932
|
+
hasImages: !!multimodal,
|
|
931
933
|
});
|
|
932
934
|
}
|
|
933
|
-
|
|
935
|
+
const userMsg = { role: 'user', content: processedMessage };
|
|
936
|
+
if (multimodal)
|
|
937
|
+
userMsg.multimodal = multimodal;
|
|
938
|
+
let updatedMessages = [...messages, userMsg];
|
|
934
939
|
setMessages(updatedMessages);
|
|
935
940
|
setIsProcessing(true);
|
|
936
941
|
setActivityStartTime(Date.now());
|
|
@@ -1052,7 +1057,8 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
|
|
|
1052
1057
|
});
|
|
1053
1058
|
const processAndExecute = async () => {
|
|
1054
1059
|
const processedResult = await processFileReferences(queuedMessage);
|
|
1055
|
-
const processedMessage = processedResult.content;
|
|
1060
|
+
const processedMessage = typeof processedResult.content === 'string' ? processedResult.content : queuedMessage;
|
|
1061
|
+
const queuedMultimodal = Array.isArray(processedResult.content) ? processedResult.content : undefined;
|
|
1056
1062
|
setIsProcessing(true);
|
|
1057
1063
|
setActivityStartTime(Date.now());
|
|
1058
1064
|
try {
|
|
@@ -1062,7 +1068,10 @@ export const PlanExecuteApp = ({ llmClient: initialLlmClient, modelInfo }) => {
|
|
|
1062
1068
|
}
|
|
1063
1069
|
else {
|
|
1064
1070
|
logger.flow('No pending TODOs - starting fresh execution');
|
|
1065
|
-
const
|
|
1071
|
+
const queuedMsg = { role: 'user', content: processedMessage };
|
|
1072
|
+
if (queuedMultimodal)
|
|
1073
|
+
queuedMsg.multimodal = queuedMultimodal;
|
|
1074
|
+
const updatedMessages = [...messages, queuedMsg];
|
|
1066
1075
|
setMessages(updatedMessages);
|
|
1067
1076
|
await planExecutionState.executeAutoMode(processedMessage, llmClient, updatedMessages, setMessages);
|
|
1068
1077
|
}
|
|
@@ -6,7 +6,14 @@ export interface AtTriggerInfo {
|
|
|
6
6
|
export declare function detectAtTrigger(input: string): AtTriggerInfo;
|
|
7
7
|
export declare function insertFilePaths(input: string, atPosition: number, filterLength: number, filePaths: string[]): string;
|
|
8
8
|
export interface ProcessedMessage {
|
|
9
|
-
content: string
|
|
9
|
+
content: string | Array<{
|
|
10
|
+
type: string;
|
|
11
|
+
text?: string;
|
|
12
|
+
image_url?: {
|
|
13
|
+
url: string;
|
|
14
|
+
detail?: string;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
10
17
|
includedFiles: string[];
|
|
11
18
|
failedFiles: string[];
|
|
12
19
|
}
|
|
@@ -48,6 +48,12 @@ export async function processFileReferences(input) {
|
|
|
48
48
|
const includedFiles = [];
|
|
49
49
|
const failedFiles = [];
|
|
50
50
|
const fileContents = [];
|
|
51
|
+
const imageBlocks = [];
|
|
52
|
+
const IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp']);
|
|
53
|
+
const MIME_MAP = {
|
|
54
|
+
'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
|
|
55
|
+
'.gif': 'image/gif', '.webp': 'image/webp', '.bmp': 'image/bmp',
|
|
56
|
+
};
|
|
51
57
|
for (const filePath of fileRefs) {
|
|
52
58
|
try {
|
|
53
59
|
const resolvedPath = path.resolve(process.cwd(), filePath);
|
|
@@ -60,15 +66,41 @@ export async function processFileReferences(input) {
|
|
|
60
66
|
const entries = await fs.readdir(resolvedPath);
|
|
61
67
|
fileContents.push(`\n--- Directory: ${filePath} ---\n${entries.join('\n')}\n---`);
|
|
62
68
|
includedFiles.push(filePath);
|
|
69
|
+
continue;
|
|
63
70
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
71
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
72
|
+
if (IMAGE_EXTS.has(ext)) {
|
|
73
|
+
const buffer = await fs.readFile(resolvedPath);
|
|
74
|
+
const base64 = buffer.toString('base64');
|
|
75
|
+
const mime = MIME_MAP[ext] || 'image/png';
|
|
76
|
+
imageBlocks.push({
|
|
77
|
+
type: 'image_url',
|
|
78
|
+
image_url: { url: `data:${mime};base64,${base64}`, detail: 'auto' },
|
|
79
|
+
});
|
|
68
80
|
includedFiles.push(filePath);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (ext === '.pdf') {
|
|
84
|
+
try {
|
|
85
|
+
const buffer = await fs.readFile(resolvedPath);
|
|
86
|
+
const pdfParse = (await import('pdf-parse')).default;
|
|
87
|
+
const data = await pdfParse(buffer);
|
|
88
|
+
const text = data.text.slice(0, 50000);
|
|
89
|
+
fileContents.push(`\n--- PDF: ${filePath} (${data.numpages} pages) ---\n${text}\n---`);
|
|
90
|
+
includedFiles.push(filePath);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
fileContents.push(`\n--- PDF: ${filePath} (text extraction unavailable — install pdf-parse) ---`);
|
|
94
|
+
failedFiles.push(filePath);
|
|
95
|
+
}
|
|
96
|
+
continue;
|
|
69
97
|
}
|
|
98
|
+
const content = await fs.readFile(resolvedPath, 'utf-8');
|
|
99
|
+
const langExt = ext.slice(1) || 'txt';
|
|
100
|
+
fileContents.push(`\n--- File: ${filePath} ---\n\`\`\`${langExt}\n${content}\n\`\`\`\n---`);
|
|
101
|
+
includedFiles.push(filePath);
|
|
70
102
|
}
|
|
71
|
-
catch
|
|
103
|
+
catch {
|
|
72
104
|
failedFiles.push(filePath);
|
|
73
105
|
}
|
|
74
106
|
}
|
|
@@ -76,6 +108,19 @@ export async function processFileReferences(input) {
|
|
|
76
108
|
for (const filePath of new Set(fileRefs)) {
|
|
77
109
|
cleanedInput = cleanedInput.replaceAll(`@${filePath}`, `[${filePath}]`);
|
|
78
110
|
}
|
|
111
|
+
if (imageBlocks.length > 0) {
|
|
112
|
+
const textContent = fileContents.length > 0
|
|
113
|
+
? `${cleanedInput}\n\n<attached_files>${fileContents.join('\n')}</attached_files>`
|
|
114
|
+
: cleanedInput;
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{ type: 'text', text: textContent },
|
|
118
|
+
...imageBlocks,
|
|
119
|
+
],
|
|
120
|
+
includedFiles,
|
|
121
|
+
failedFiles,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
79
124
|
const finalContent = fileContents.length > 0
|
|
80
125
|
? `${cleanedInput}\n\n<attached_files>${fileContents.join('\n')}</attached_files>`
|
|
81
126
|
: cleanedInput;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orquesta-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.43",
|
|
4
4
|
"description": "Orquesta CLI - AI-powered coding assistant with team collaboration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
"ink-text-input": "^5.0.1",
|
|
100
100
|
"inquirer": "^8.2.6",
|
|
101
101
|
"ora": "^5.4.1",
|
|
102
|
+
"pdf-parse": "^1.1.1",
|
|
102
103
|
"semver": "^7.7.3",
|
|
103
104
|
"socket.io-client": "^4.8.3",
|
|
104
105
|
"ws": "^8.18.3"
|
|
@@ -106,6 +107,7 @@
|
|
|
106
107
|
"devDependencies": {
|
|
107
108
|
"@types/inquirer": "^9.0.7",
|
|
108
109
|
"@types/node": "^20.10.5",
|
|
110
|
+
"@types/pdf-parse": "^1.1.5",
|
|
109
111
|
"@types/react": "^19.2.2",
|
|
110
112
|
"@types/semver": "^7.7.1",
|
|
111
113
|
"@types/ws": "^8.18.1",
|