clarity-ai 4.3.0 → 4.3.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/package.json +1 -1
- package/src/chat.js +61 -32
package/package.json
CHANGED
package/src/chat.js
CHANGED
|
@@ -3,6 +3,8 @@ import { setKey } from './config/keys.js';
|
|
|
3
3
|
import { TOOLS, executeTool } from './tools.js';
|
|
4
4
|
import { extractCommandFromText } from './intentDetect.js';
|
|
5
5
|
|
|
6
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
7
|
+
|
|
6
8
|
export function createChatState() {
|
|
7
9
|
return {
|
|
8
10
|
messages: [],
|
|
@@ -26,10 +28,23 @@ export async function handleSend(state, setState, input, model, provider) {
|
|
|
26
28
|
setState(s => ({ ...s, messages: [...s.messages, userMsg], thinking: true, streamBuffer: '' }));
|
|
27
29
|
|
|
28
30
|
try {
|
|
29
|
-
const history = [...state.messages, userMsg].map(m =>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const history = [...state.messages, userMsg].map(m => {
|
|
32
|
+
const base = {
|
|
33
|
+
role: m.role === 'error' ? 'assistant' : m.role,
|
|
34
|
+
content: m.content,
|
|
35
|
+
};
|
|
36
|
+
if (m.role === 'tool' && m.tool_call_id) {
|
|
37
|
+
base.tool_call_id = m.tool_call_id;
|
|
38
|
+
}
|
|
39
|
+
if (m.role === 'assistant' && m.toolCalls) {
|
|
40
|
+
base.tool_calls = m.toolCalls.map(tc => ({
|
|
41
|
+
id: tc.id,
|
|
42
|
+
type: 'function',
|
|
43
|
+
function: { name: tc.function.name, arguments: tc.function.arguments },
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
return base;
|
|
47
|
+
});
|
|
33
48
|
|
|
34
49
|
await processStream(provider, model, history, state.agentMode, setState);
|
|
35
50
|
} catch (err) {
|
|
@@ -50,48 +65,62 @@ async function processStream(provider, model, history, agentMode, setState, dept
|
|
|
50
65
|
return;
|
|
51
66
|
}
|
|
52
67
|
|
|
53
|
-
|
|
68
|
+
let stream;
|
|
69
|
+
try {
|
|
70
|
+
stream = callAI(provider, model, history, { tools: agentMode ? TOOLS : undefined });
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (err.type === 'rate_limit') {
|
|
73
|
+
await sleep(2000);
|
|
74
|
+
return processStream(provider, model, history, agentMode, setState, depth);
|
|
75
|
+
}
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
|
|
54
79
|
let buffer = '';
|
|
55
80
|
let toolCalls = null;
|
|
56
81
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
try {
|
|
83
|
+
for await (const event of stream) {
|
|
84
|
+
if (event.type === 'token') {
|
|
85
|
+
buffer += event.content;
|
|
86
|
+
setState(s => ({
|
|
87
|
+
...s,
|
|
88
|
+
streamBuffer: buffer,
|
|
89
|
+
messages: updateLastAssistant(s.messages, buffer),
|
|
90
|
+
}));
|
|
91
|
+
} else if (event.type === 'tool_calls') {
|
|
92
|
+
toolCalls = event.calls;
|
|
93
|
+
} else if (event.type === 'error') {
|
|
94
|
+
handleError(setState, event);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
if (err.type === 'rate_limit') {
|
|
100
|
+
await sleep(2000);
|
|
101
|
+
return processStream(provider, model, history, agentMode, setState, depth);
|
|
70
102
|
}
|
|
103
|
+
throw err;
|
|
71
104
|
}
|
|
72
105
|
|
|
73
106
|
if (toolCalls && toolCalls.length > 0 && agentMode) {
|
|
74
|
-
const assistantMsg = { id: nextId(), role: 'assistant', content: buffer || '', toolCalls };
|
|
75
107
|
const toolResults = [];
|
|
76
|
-
|
|
77
108
|
for (const tc of toolCalls) {
|
|
78
109
|
const { name, arguments: argsStr } = tc.function;
|
|
79
110
|
let args;
|
|
80
|
-
try {
|
|
81
|
-
args = JSON.parse(argsStr);
|
|
82
|
-
} catch {
|
|
83
|
-
args = {};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
setState(s => ({
|
|
87
|
-
...s,
|
|
88
|
-
messages: [...s.messages, { id: nextId(), role: 'tool', content: '⚙ ' + name + '(' + JSON.stringify(args).slice(0, 100) + ')...', toolName: name }],
|
|
89
|
-
}));
|
|
90
|
-
|
|
111
|
+
try { args = JSON.parse(argsStr); } catch { args = {}; }
|
|
91
112
|
const result = await executeTool(name, args);
|
|
92
|
-
toolResults.push({ tool_call_id: tc.id, role: 'tool', content: result });
|
|
113
|
+
toolResults.push({ tool_call_id: tc.id, role: 'tool', content: result, name });
|
|
93
114
|
}
|
|
94
115
|
|
|
116
|
+
const newAssistantMsg = { id: nextId(), role: 'assistant', content: buffer || '', toolCalls };
|
|
117
|
+
const toolMsgs = toolResults.map(tr => ({
|
|
118
|
+
id: nextId(), role: 'tool', content: tr.content,
|
|
119
|
+
tool_call_id: tr.tool_call_id, toolName: tr.name,
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
setState(s => ({ ...s, messages: [...s.messages, newAssistantMsg, ...toolMsgs] }));
|
|
123
|
+
|
|
95
124
|
const newHistory = [
|
|
96
125
|
...history,
|
|
97
126
|
{ role: 'assistant', content: buffer || null, tool_calls: toolCalls.map(tc => ({
|