@gaberrb/polypus 0.4.12 → 0.4.13
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/dist/index.js +68 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -910,15 +910,33 @@ var OpenAICompatibleProvider = class {
|
|
|
910
910
|
parameters: t2.parameters
|
|
911
911
|
}
|
|
912
912
|
}));
|
|
913
|
+
const base = {
|
|
914
|
+
model: this.model,
|
|
915
|
+
messages,
|
|
916
|
+
...tools && tools.length > 0 ? { tools } : {},
|
|
917
|
+
temperature: req.params?.temperature,
|
|
918
|
+
// Generous default so large files aren't truncated mid tool-call.
|
|
919
|
+
max_tokens: req.params?.maxTokens ?? 8192
|
|
920
|
+
};
|
|
921
|
+
if (req.onDelta) {
|
|
922
|
+
const stream = await this.client.chat.completions.create(
|
|
923
|
+
{ ...base, stream: true, stream_options: { include_usage: true } },
|
|
924
|
+
{ signal: req.signal }
|
|
925
|
+
);
|
|
926
|
+
const agg = await aggregateStream(stream, req.onDelta);
|
|
927
|
+
return {
|
|
928
|
+
content: agg.content,
|
|
929
|
+
toolCalls: agg.toolCalls.map((tc, i) => ({
|
|
930
|
+
id: tc.id || `call_${i}`,
|
|
931
|
+
name: tc.name,
|
|
932
|
+
arguments: safeParseArgs(tc.arguments)
|
|
933
|
+
})),
|
|
934
|
+
finishReason: agg.finishReason || "stop",
|
|
935
|
+
usage: agg.usage
|
|
936
|
+
};
|
|
937
|
+
}
|
|
913
938
|
const completion = await this.client.chat.completions.create(
|
|
914
|
-
{
|
|
915
|
-
model: this.model,
|
|
916
|
-
messages,
|
|
917
|
-
...tools && tools.length > 0 ? { tools } : {},
|
|
918
|
-
temperature: req.params?.temperature,
|
|
919
|
-
// Generous default so large files aren't truncated mid tool-call.
|
|
920
|
-
max_tokens: req.params?.maxTokens ?? 8192
|
|
921
|
-
},
|
|
939
|
+
{ ...base },
|
|
922
940
|
{ signal: req.signal }
|
|
923
941
|
);
|
|
924
942
|
const choice = completion.choices[0];
|
|
@@ -939,6 +957,34 @@ var OpenAICompatibleProvider = class {
|
|
|
939
957
|
};
|
|
940
958
|
}
|
|
941
959
|
};
|
|
960
|
+
async function aggregateStream(stream, onDelta) {
|
|
961
|
+
let content = "";
|
|
962
|
+
let finishReason = "";
|
|
963
|
+
let usage2;
|
|
964
|
+
const toolAcc = [];
|
|
965
|
+
for await (const chunk of stream) {
|
|
966
|
+
const choice = chunk.choices?.[0];
|
|
967
|
+
const delta = choice?.delta;
|
|
968
|
+
if (delta?.content) {
|
|
969
|
+
content += delta.content;
|
|
970
|
+
onDelta?.(delta.content);
|
|
971
|
+
}
|
|
972
|
+
for (const tc of delta?.tool_calls ?? []) {
|
|
973
|
+
const slot = toolAcc[tc.index] ??= { id: "", name: "", arguments: "" };
|
|
974
|
+
if (tc.id) slot.id = tc.id;
|
|
975
|
+
if (tc.function?.name) slot.name = tc.function.name;
|
|
976
|
+
if (tc.function?.arguments) slot.arguments += tc.function.arguments;
|
|
977
|
+
}
|
|
978
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
979
|
+
if (chunk.usage) {
|
|
980
|
+
usage2 = {
|
|
981
|
+
promptTokens: chunk.usage.prompt_tokens,
|
|
982
|
+
completionTokens: chunk.usage.completion_tokens
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return { content, finishReason, usage: usage2, toolCalls: toolAcc.filter(Boolean) };
|
|
987
|
+
}
|
|
942
988
|
function toOpenAIMessage(m) {
|
|
943
989
|
switch (m.role) {
|
|
944
990
|
case "tool":
|
|
@@ -2284,13 +2330,15 @@ async function runAgent(opts) {
|
|
|
2284
2330
|
}
|
|
2285
2331
|
}
|
|
2286
2332
|
}
|
|
2333
|
+
const wantDelta = driver.kind === "native" && typeof events?.onAssistantDelta === "function";
|
|
2287
2334
|
let response;
|
|
2288
2335
|
try {
|
|
2289
2336
|
response = await agent.provider.chat({
|
|
2290
2337
|
messages,
|
|
2291
2338
|
tools: driver.providerTools(),
|
|
2292
2339
|
params: opts.params,
|
|
2293
|
-
signal: opts.signal
|
|
2340
|
+
signal: opts.signal,
|
|
2341
|
+
onDelta: wantDelta ? (chunk) => events.onAssistantDelta(chunk) : void 0
|
|
2294
2342
|
});
|
|
2295
2343
|
} catch (err) {
|
|
2296
2344
|
if (opts.signal?.aborted) return { finished: false, reason: "cancelled", steps: step, messages, usage: usage2 };
|
|
@@ -4406,16 +4454,27 @@ function renderDiff(hunks) {
|
|
|
4406
4454
|
}
|
|
4407
4455
|
}
|
|
4408
4456
|
function renderEvents(spinner3) {
|
|
4457
|
+
let streamed = false;
|
|
4409
4458
|
return {
|
|
4410
4459
|
onStep() {
|
|
4460
|
+
streamed = false;
|
|
4411
4461
|
spinner3.start(t("ui.thinking"));
|
|
4412
4462
|
},
|
|
4413
4463
|
onUsage(usage2) {
|
|
4414
4464
|
const total = usage2.promptTokens + usage2.completionTokens;
|
|
4415
4465
|
if (total > 0) spinner3.setSuffix(t("ui.tokensShort", { total: fmtTokens(total) }));
|
|
4416
4466
|
},
|
|
4467
|
+
onAssistantDelta(chunk) {
|
|
4468
|
+
spinner3.stop();
|
|
4469
|
+
process.stdout.write(pc8.cyan(chunk));
|
|
4470
|
+
streamed = true;
|
|
4471
|
+
},
|
|
4417
4472
|
onAssistantText(text2) {
|
|
4418
4473
|
spinner3.stop();
|
|
4474
|
+
if (streamed) {
|
|
4475
|
+
process.stdout.write("\n");
|
|
4476
|
+
return;
|
|
4477
|
+
}
|
|
4419
4478
|
if (text2.trim()) console.log(pc8.cyan(text2.trim()));
|
|
4420
4479
|
},
|
|
4421
4480
|
onToolCall(call) {
|