p-api-agent 0.0.5 → 0.0.7
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.cjs +121 -4
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +121 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -261,16 +261,133 @@ ${tool_schemas}`;
|
|
|
261
261
|
return [...input];
|
|
262
262
|
}
|
|
263
263
|
parse_command(raw) {
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
return
|
|
264
|
+
const normalized = this.normalize_llm_output(raw);
|
|
265
|
+
const json = this.safe_extract_json(normalized);
|
|
266
|
+
if (!json) return null;
|
|
267
|
+
if (typeof json.command === "string") {
|
|
268
|
+
return json;
|
|
269
|
+
}
|
|
270
|
+
return this.adapt_common_tool_call(json);
|
|
267
271
|
}
|
|
268
272
|
safe_extract_json(content) {
|
|
269
273
|
try {
|
|
270
274
|
return LLM_Utils.extract_json(content);
|
|
271
275
|
} catch {
|
|
272
|
-
|
|
276
|
+
const json_candidate = this.find_first_json_block(content);
|
|
277
|
+
if (!json_candidate) return null;
|
|
278
|
+
try {
|
|
279
|
+
return LLM_Utils.parse_json(json_candidate);
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* 兼容部分模型返回的函数调用包裹标记,例如:
|
|
287
|
+
* <|FunctionCallBegin|> ... <|FunctionCallEnd|>
|
|
288
|
+
*/
|
|
289
|
+
normalize_llm_output(raw) {
|
|
290
|
+
return raw.replace(/<\|FunctionCallBegin\|>/gi, "").replace(/<\|FunctionCallEnd\|>/gi, "").replace(/<\|tool_call\|>/gi, "").replace(/<tool_call>/gi, "").replace(/<\/tool_call>/gi, "").trim();
|
|
291
|
+
}
|
|
292
|
+
/** 从混杂文本中提取第一个 JSON 对象字符串 */
|
|
293
|
+
find_first_json_block(content) {
|
|
294
|
+
const fenced = content.match(/```json\s*([\s\S]*?)\s*```/i);
|
|
295
|
+
if (fenced?.[1]) return fenced[1];
|
|
296
|
+
const objectStart = content.indexOf("{");
|
|
297
|
+
const arrayStart = content.indexOf("[");
|
|
298
|
+
let start = -1;
|
|
299
|
+
let openChar = "{";
|
|
300
|
+
let closeChar = "}";
|
|
301
|
+
if (objectStart >= 0 && (arrayStart < 0 || objectStart < arrayStart)) {
|
|
302
|
+
start = objectStart;
|
|
303
|
+
openChar = "{";
|
|
304
|
+
closeChar = "}";
|
|
305
|
+
} else if (arrayStart >= 0) {
|
|
306
|
+
start = arrayStart;
|
|
307
|
+
openChar = "[";
|
|
308
|
+
closeChar = "]";
|
|
309
|
+
}
|
|
310
|
+
if (start < 0) return null;
|
|
311
|
+
let depth = 0;
|
|
312
|
+
let inString = false;
|
|
313
|
+
let escaped = false;
|
|
314
|
+
for (let i = start; i < content.length; i++) {
|
|
315
|
+
const ch = content[i];
|
|
316
|
+
if (inString) {
|
|
317
|
+
if (escaped) {
|
|
318
|
+
escaped = false;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (ch === "\\") {
|
|
322
|
+
escaped = true;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (ch === '"') {
|
|
326
|
+
inString = false;
|
|
327
|
+
}
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (ch === '"') {
|
|
331
|
+
inString = true;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (ch === openChar) depth++;
|
|
335
|
+
if (ch === closeChar) {
|
|
336
|
+
depth--;
|
|
337
|
+
if (depth === 0) {
|
|
338
|
+
return content.slice(start, i + 1);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
/** 兼容常见 Function Calling 输出结构并转换为内部指令 */
|
|
345
|
+
adapt_common_tool_call(json) {
|
|
346
|
+
if (Array.isArray(json) && json.length > 0) {
|
|
347
|
+
return this.adapt_common_tool_call(json[0]);
|
|
348
|
+
}
|
|
349
|
+
if (typeof json?.name === "string") {
|
|
350
|
+
const params = this.normalize_params(json.params ?? json.arguments ?? {});
|
|
351
|
+
return {
|
|
352
|
+
command: "use_tool",
|
|
353
|
+
tool_name: json.name,
|
|
354
|
+
params,
|
|
355
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (typeof json?.function?.name === "string") {
|
|
359
|
+
const params = this.normalize_params(json.function.arguments ?? {});
|
|
360
|
+
return {
|
|
361
|
+
command: "use_tool",
|
|
362
|
+
tool_name: json.function.name,
|
|
363
|
+
params,
|
|
364
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
const first_tool_call = Array.isArray(json?.tool_calls) ? json.tool_calls[0] : null;
|
|
368
|
+
if (typeof first_tool_call?.function?.name === "string") {
|
|
369
|
+
const params = this.normalize_params(first_tool_call.function.arguments ?? {});
|
|
370
|
+
return {
|
|
371
|
+
command: "use_tool",
|
|
372
|
+
tool_name: first_tool_call.function.name,
|
|
373
|
+
params,
|
|
374
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
normalize_params(params) {
|
|
380
|
+
if (params == null) return {};
|
|
381
|
+
if (typeof params === "string") {
|
|
382
|
+
try {
|
|
383
|
+
const parsed = LLM_Utils.parse_json(params);
|
|
384
|
+
return typeof parsed === "object" && parsed ? parsed : { value: parsed };
|
|
385
|
+
} catch {
|
|
386
|
+
return { value: params };
|
|
387
|
+
}
|
|
273
388
|
}
|
|
389
|
+
if (typeof params === "object") return params;
|
|
390
|
+
return { value: params };
|
|
274
391
|
}
|
|
275
392
|
async call_llm_with_retry(input) {
|
|
276
393
|
let last_error;
|
package/dist/index.d.cts
CHANGED
|
@@ -121,6 +121,16 @@ declare class Agent {
|
|
|
121
121
|
private normalize_input;
|
|
122
122
|
private parse_command;
|
|
123
123
|
private safe_extract_json;
|
|
124
|
+
/**
|
|
125
|
+
* 兼容部分模型返回的函数调用包裹标记,例如:
|
|
126
|
+
* <|FunctionCallBegin|> ... <|FunctionCallEnd|>
|
|
127
|
+
*/
|
|
128
|
+
private normalize_llm_output;
|
|
129
|
+
/** 从混杂文本中提取第一个 JSON 对象字符串 */
|
|
130
|
+
private find_first_json_block;
|
|
131
|
+
/** 兼容常见 Function Calling 输出结构并转换为内部指令 */
|
|
132
|
+
private adapt_common_tool_call;
|
|
133
|
+
private normalize_params;
|
|
124
134
|
private call_llm_with_retry;
|
|
125
135
|
}
|
|
126
136
|
|
package/dist/index.d.ts
CHANGED
|
@@ -121,6 +121,16 @@ declare class Agent {
|
|
|
121
121
|
private normalize_input;
|
|
122
122
|
private parse_command;
|
|
123
123
|
private safe_extract_json;
|
|
124
|
+
/**
|
|
125
|
+
* 兼容部分模型返回的函数调用包裹标记,例如:
|
|
126
|
+
* <|FunctionCallBegin|> ... <|FunctionCallEnd|>
|
|
127
|
+
*/
|
|
128
|
+
private normalize_llm_output;
|
|
129
|
+
/** 从混杂文本中提取第一个 JSON 对象字符串 */
|
|
130
|
+
private find_first_json_block;
|
|
131
|
+
/** 兼容常见 Function Calling 输出结构并转换为内部指令 */
|
|
132
|
+
private adapt_common_tool_call;
|
|
133
|
+
private normalize_params;
|
|
124
134
|
private call_llm_with_retry;
|
|
125
135
|
}
|
|
126
136
|
|
package/dist/index.js
CHANGED
|
@@ -232,16 +232,133 @@ ${tool_schemas}`;
|
|
|
232
232
|
return [...input];
|
|
233
233
|
}
|
|
234
234
|
parse_command(raw) {
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
return
|
|
235
|
+
const normalized = this.normalize_llm_output(raw);
|
|
236
|
+
const json = this.safe_extract_json(normalized);
|
|
237
|
+
if (!json) return null;
|
|
238
|
+
if (typeof json.command === "string") {
|
|
239
|
+
return json;
|
|
240
|
+
}
|
|
241
|
+
return this.adapt_common_tool_call(json);
|
|
238
242
|
}
|
|
239
243
|
safe_extract_json(content) {
|
|
240
244
|
try {
|
|
241
245
|
return LLM_Utils.extract_json(content);
|
|
242
246
|
} catch {
|
|
243
|
-
|
|
247
|
+
const json_candidate = this.find_first_json_block(content);
|
|
248
|
+
if (!json_candidate) return null;
|
|
249
|
+
try {
|
|
250
|
+
return LLM_Utils.parse_json(json_candidate);
|
|
251
|
+
} catch {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 兼容部分模型返回的函数调用包裹标记,例如:
|
|
258
|
+
* <|FunctionCallBegin|> ... <|FunctionCallEnd|>
|
|
259
|
+
*/
|
|
260
|
+
normalize_llm_output(raw) {
|
|
261
|
+
return raw.replace(/<\|FunctionCallBegin\|>/gi, "").replace(/<\|FunctionCallEnd\|>/gi, "").replace(/<\|tool_call\|>/gi, "").replace(/<tool_call>/gi, "").replace(/<\/tool_call>/gi, "").trim();
|
|
262
|
+
}
|
|
263
|
+
/** 从混杂文本中提取第一个 JSON 对象字符串 */
|
|
264
|
+
find_first_json_block(content) {
|
|
265
|
+
const fenced = content.match(/```json\s*([\s\S]*?)\s*```/i);
|
|
266
|
+
if (fenced?.[1]) return fenced[1];
|
|
267
|
+
const objectStart = content.indexOf("{");
|
|
268
|
+
const arrayStart = content.indexOf("[");
|
|
269
|
+
let start = -1;
|
|
270
|
+
let openChar = "{";
|
|
271
|
+
let closeChar = "}";
|
|
272
|
+
if (objectStart >= 0 && (arrayStart < 0 || objectStart < arrayStart)) {
|
|
273
|
+
start = objectStart;
|
|
274
|
+
openChar = "{";
|
|
275
|
+
closeChar = "}";
|
|
276
|
+
} else if (arrayStart >= 0) {
|
|
277
|
+
start = arrayStart;
|
|
278
|
+
openChar = "[";
|
|
279
|
+
closeChar = "]";
|
|
280
|
+
}
|
|
281
|
+
if (start < 0) return null;
|
|
282
|
+
let depth = 0;
|
|
283
|
+
let inString = false;
|
|
284
|
+
let escaped = false;
|
|
285
|
+
for (let i = start; i < content.length; i++) {
|
|
286
|
+
const ch = content[i];
|
|
287
|
+
if (inString) {
|
|
288
|
+
if (escaped) {
|
|
289
|
+
escaped = false;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
if (ch === "\\") {
|
|
293
|
+
escaped = true;
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if (ch === '"') {
|
|
297
|
+
inString = false;
|
|
298
|
+
}
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if (ch === '"') {
|
|
302
|
+
inString = true;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
if (ch === openChar) depth++;
|
|
306
|
+
if (ch === closeChar) {
|
|
307
|
+
depth--;
|
|
308
|
+
if (depth === 0) {
|
|
309
|
+
return content.slice(start, i + 1);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
/** 兼容常见 Function Calling 输出结构并转换为内部指令 */
|
|
316
|
+
adapt_common_tool_call(json) {
|
|
317
|
+
if (Array.isArray(json) && json.length > 0) {
|
|
318
|
+
return this.adapt_common_tool_call(json[0]);
|
|
319
|
+
}
|
|
320
|
+
if (typeof json?.name === "string") {
|
|
321
|
+
const params = this.normalize_params(json.params ?? json.arguments ?? {});
|
|
322
|
+
return {
|
|
323
|
+
command: "use_tool",
|
|
324
|
+
tool_name: json.name,
|
|
325
|
+
params,
|
|
326
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
if (typeof json?.function?.name === "string") {
|
|
330
|
+
const params = this.normalize_params(json.function.arguments ?? {});
|
|
331
|
+
return {
|
|
332
|
+
command: "use_tool",
|
|
333
|
+
tool_name: json.function.name,
|
|
334
|
+
params,
|
|
335
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const first_tool_call = Array.isArray(json?.tool_calls) ? json.tool_calls[0] : null;
|
|
339
|
+
if (typeof first_tool_call?.function?.name === "string") {
|
|
340
|
+
const params = this.normalize_params(first_tool_call.function.arguments ?? {});
|
|
341
|
+
return {
|
|
342
|
+
command: "use_tool",
|
|
343
|
+
tool_name: first_tool_call.function.name,
|
|
344
|
+
params,
|
|
345
|
+
reasoning: typeof json.reasoning === "string" ? json.reasoning : void 0
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
normalize_params(params) {
|
|
351
|
+
if (params == null) return {};
|
|
352
|
+
if (typeof params === "string") {
|
|
353
|
+
try {
|
|
354
|
+
const parsed = LLM_Utils.parse_json(params);
|
|
355
|
+
return typeof parsed === "object" && parsed ? parsed : { value: parsed };
|
|
356
|
+
} catch {
|
|
357
|
+
return { value: params };
|
|
358
|
+
}
|
|
244
359
|
}
|
|
360
|
+
if (typeof params === "object") return params;
|
|
361
|
+
return { value: params };
|
|
245
362
|
}
|
|
246
363
|
async call_llm_with_retry(input) {
|
|
247
364
|
let last_error;
|