mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-04 00:15:28 +08:00
108 lines
2.5 KiB
JavaScript
108 lines
2.5 KiB
JavaScript
'use strict';
|
|
|
|
const crypto = require('crypto');
|
|
|
|
const {
|
|
extractToolNames,
|
|
} = require('../helpers/stream-tool-sieve');
|
|
|
|
function resolveToolcallPolicy(prepBody, payloadTools) {
|
|
const preparedToolNames = normalizePreparedToolNames(prepBody && prepBody.tool_names);
|
|
const toolNames = preparedToolNames.length > 0 ? preparedToolNames : extractToolNames(payloadTools);
|
|
const featureMatchEnabled = boolDefaultTrue(prepBody && prepBody.toolcall_feature_match);
|
|
const emitEarlyToolDeltas = boolDefaultTrue(prepBody && prepBody.toolcall_early_emit_high);
|
|
return {
|
|
toolNames,
|
|
toolSieveEnabled: toolNames.length > 0 && featureMatchEnabled,
|
|
emitEarlyToolDeltas,
|
|
};
|
|
}
|
|
|
|
function normalizePreparedToolNames(v) {
|
|
if (!Array.isArray(v) || v.length === 0) {
|
|
return [];
|
|
}
|
|
const out = [];
|
|
for (const item of v) {
|
|
const name = asString(item);
|
|
if (!name) {
|
|
continue;
|
|
}
|
|
out.push(name);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function boolDefaultTrue(v) {
|
|
return v !== false;
|
|
}
|
|
|
|
function formatIncrementalToolCallDeltas(deltas, idStore) {
|
|
if (!Array.isArray(deltas) || deltas.length === 0) {
|
|
return [];
|
|
}
|
|
const out = [];
|
|
for (const d of deltas) {
|
|
if (!d || typeof d !== 'object') {
|
|
continue;
|
|
}
|
|
const index = Number.isInteger(d.index) ? d.index : 0;
|
|
const id = ensureStreamToolCallID(idStore, index);
|
|
const item = {
|
|
index,
|
|
id,
|
|
type: 'function',
|
|
};
|
|
const fn = {};
|
|
if (asString(d.name)) {
|
|
fn.name = asString(d.name);
|
|
}
|
|
if (typeof d.arguments === 'string' && d.arguments !== '') {
|
|
fn.arguments = d.arguments;
|
|
}
|
|
if (Object.keys(fn).length > 0) {
|
|
item.function = fn;
|
|
}
|
|
out.push(item);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function ensureStreamToolCallID(idStore, index) {
|
|
const key = Number.isInteger(index) ? index : 0;
|
|
const existing = idStore.get(key);
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
const next = `call_${newCallID()}`;
|
|
idStore.set(key, next);
|
|
return next;
|
|
}
|
|
|
|
function newCallID() {
|
|
if (typeof crypto.randomUUID === 'function') {
|
|
return crypto.randomUUID().replace(/-/g, '');
|
|
}
|
|
return `${Date.now()}${Math.floor(Math.random() * 1e9)}`;
|
|
}
|
|
|
|
function asString(v) {
|
|
if (typeof v === 'string') {
|
|
return v.trim();
|
|
}
|
|
if (Array.isArray(v)) {
|
|
return asString(v[0]);
|
|
}
|
|
if (v == null) {
|
|
return '';
|
|
}
|
|
return String(v).trim();
|
|
}
|
|
|
|
module.exports = {
|
|
resolveToolcallPolicy,
|
|
normalizePreparedToolNames,
|
|
boolDefaultTrue,
|
|
formatIncrementalToolCallDeltas,
|
|
};
|