@my-life-buddies/buddy-runtime 0.28.0 → 0.29.0
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/CHANGELOG.md +17 -0
- package/README.md +143 -117
- package/dist/conversation/agent.d.ts +11 -3
- package/dist/conversation/agent.d.ts.map +1 -1
- package/dist/conversation/agent.js +16 -5
- package/dist/conversation/agent.js.map +1 -1
- package/dist/conversation/compaction.js +1 -1
- package/dist/conversation/compaction.js.map +1 -1
- package/dist/conversation/image.d.ts +7 -0
- package/dist/conversation/image.d.ts.map +1 -0
- package/dist/conversation/image.js +36 -0
- package/dist/conversation/image.js.map +1 -0
- package/dist/conversation/index.d.ts +4 -0
- package/dist/conversation/index.d.ts.map +1 -1
- package/dist/conversation/index.js +23 -4
- package/dist/conversation/index.js.map +1 -1
- package/dist/conversation/writeMLBMessage.d.ts +8 -0
- package/dist/conversation/writeMLBMessage.d.ts.map +1 -1
- package/dist/conversation/writeMLBMessage.js +29 -3
- package/dist/conversation/writeMLBMessage.js.map +1 -1
- package/dist/dataAccessCatalog.d.ts +5 -0
- package/dist/dataAccessCatalog.d.ts.map +1 -1
- package/dist/dataAccessCatalog.js +1 -0
- package/dist/dataAccessCatalog.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/mlbClient.d.ts +6 -1
- package/dist/mlbClient.d.ts.map +1 -1
- package/dist/mlbClient.js +50 -4
- package/dist/mlbClient.js.map +1 -1
- package/dist/tools/dataAccess.d.ts +7 -0
- package/dist/tools/dataAccess.d.ts.map +1 -1
- package/dist/tools/dataAccess.js +20 -2
- package/dist/tools/dataAccess.js.map +1 -1
- package/dist/tools/dataAccessRequest.d.ts.map +1 -1
- package/dist/tools/dataAccessRequest.js +8 -4
- package/dist/tools/dataAccessRequest.js.map +1 -1
- package/dist/tools/generateImage.d.ts +16 -0
- package/dist/tools/generateImage.d.ts.map +1 -0
- package/dist/tools/generateImage.js +40 -0
- package/dist/tools/generateImage.js.map +1 -0
- package/dist/tools/profileDisclosure.d.ts +13 -0
- package/dist/tools/profileDisclosure.d.ts.map +1 -0
- package/dist/tools/profileDisclosure.js +154 -0
- package/dist/tools/profileDisclosure.js.map +1 -0
- package/dist/tools/sendImage.d.ts +6 -10
- package/dist/tools/sendImage.d.ts.map +1 -1
- package/dist/tools/sendImage.js +24 -15
- package/dist/tools/sendImage.js.map +1 -1
- package/dist/tools/viewImage.d.ts.map +1 -1
- package/dist/tools/viewImage.js +3 -2
- package/dist/tools/viewImage.js.map +1 -1
- package/dist/types.d.ts +53 -11
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateImage.d.ts","sourceRoot":"","sources":["../../src/tools/generateImage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,QAAA,MAAM,UAAU;;;EAAoC,CAAC;AACrD,QAAA,MAAM,cAAc;;;;EAGlB,CAAC;AAGH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,GACtD,SAAS,CAAC,OAAO,UAAU,EAAE,SAAS,CAAC,CAazC;AAED,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAC7D,SAAS,CAAC,OAAO,cAAc,EAAE,SAAS,CAAC,CAa7C"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
const generationProperties = {
|
|
3
|
+
prompt: Type.String({ minLength: 1, maxLength: 4000, description: "本次完整画面要求。结合对话保留仍有效的主体、服装、背景、构图、风格和禁用内容,明确本次修改;图片中的文字按用户原文保留。用图 1、图 2 对应 referenceMessageIds 的顺序" }),
|
|
4
|
+
referenceMessageIds: Type.Optional(Type.Array(Type.String({ minLength: 1 }), { maxItems: 14, uniqueItems: true, description: "按顺序填写当前聊天中 [图片 #编号] 的编号(卡片图片用 消息编号/第几张),最多 14 张。改图先放底图,再放仍需参考的原图或历史版本;没有参考图可省略" })),
|
|
5
|
+
};
|
|
6
|
+
const parameters = Type.Object(generationProperties);
|
|
7
|
+
const sendParameters = Type.Object({
|
|
8
|
+
...generationProperties,
|
|
9
|
+
text: Type.Optional(Type.String({ maxLength: 500, description: "随图片显示的配文,可不填" })),
|
|
10
|
+
});
|
|
11
|
+
const GENERATION_DESCRIPTION = "用户只要一张图时只生成一次,不能为确认结果再次生成。出错或结果未确认时不要自行再次生成,告知用户并等待用户决定。改图时把底图和必要的参考图放入 referenceMessageIds,在 prompt 中说明各图用途及完整要求。历史图片不会自动传给生图模型。需要比较图片或确认细节时先用 view_image;编号或要求不明确时先询问用户,不猜测。内部媒体编号和图片消息编号只用于工具调用,不在给用户的回复或配文中展示。";
|
|
12
|
+
export function generateImageTool(image) {
|
|
13
|
+
return {
|
|
14
|
+
name: "generate_image",
|
|
15
|
+
label: "正在生成图片",
|
|
16
|
+
description: "按 prompt 生成或修改一张图片,仅返回 mediaId,不发送聊天消息。需要把结果发给用户时,将 mediaId 交给 send_image;需要生成后立即发送且工具清单提供 generate_and_send_image 时,优先直接用它。" + GENERATION_DESCRIPTION,
|
|
17
|
+
dataAccessPolicy: { retention: "external", result: "independent", arguments: "private" },
|
|
18
|
+
parameters,
|
|
19
|
+
execute: async (_callId, input, signal) => {
|
|
20
|
+
signal?.throwIfAborted();
|
|
21
|
+
const { mediaId } = await image.generate(input, signal);
|
|
22
|
+
return { content: [{ type: "text", text: `图片已生成,尚未发送。内部媒体引用:${JSON.stringify({ mediaId })}。需要发送时将 mediaId 交给 send_image,不要再次生成。mediaId 不是图片消息编号,不能交给 view_image 或 referenceMessageIds,也不要展示给用户。` }], details: undefined };
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function generateAndSendImageTool(image) {
|
|
27
|
+
return {
|
|
28
|
+
name: "generate_and_send_image",
|
|
29
|
+
label: "正在生成并发送图片",
|
|
30
|
+
description: "按 prompt 生成或修改一张图片并发进当前聊天,可附 text 配文。成功返回 mediaId 和 messageId 后,图片消息已保存,不再调用 send_image,也不要再次生成。" + GENERATION_DESCRIPTION,
|
|
31
|
+
dataAccessPolicy: { retention: "external", result: "independent", arguments: "private" },
|
|
32
|
+
parameters: sendParameters,
|
|
33
|
+
execute: async (callId, input, signal) => {
|
|
34
|
+
signal?.throwIfAborted();
|
|
35
|
+
const saved = await image.generateAndSend({ ...input, idempotencyKey: `generate-and-send-image:${callId}` }, signal);
|
|
36
|
+
return { content: [{ type: "text", text: `图片消息已保存。内部引用:${JSON.stringify(saved)};[图片 #${saved.messageId}] 可用于 view_image 和后续改图。不要重复发送或生成,也不要在给用户的回复或配文中展示编号或标签。` }], details: undefined };
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=generateImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateImage.js","sourceRoot":"","sources":["../../src/tools/generateImage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG/B,MAAM,oBAAoB,GAAG;IAC5B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,iGAAiG,EAAE,CAAC;IACtK,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,gFAAgF,EAAE,CAAC,CAAC;CACjN,CAAC;AACF,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACrD,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IAClC,GAAG,oBAAoB;IACvB,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAC;CACjF,CAAC,CAAC;AACH,MAAM,sBAAsB,GAAG,oNAAoN,CAAC;AAEpP,MAAM,UAAU,iBAAiB,CAChC,KAAwD;IAExD,OAAO;QACN,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,8HAA8H,GAAG,sBAAsB;QACpK,gBAAgB,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE;QACxF,UAAU;QACV,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzC,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACxD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,uGAAuG,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC3N,CAAC;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CACvC,KAA+D;IAE/D,OAAO;QACN,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE,WAAW;QAClB,WAAW,EAAE,kGAAkG,GAAG,sBAAsB;QACxI,gBAAgB,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE;QACxF,UAAU,EAAE,cAAc;QAC1B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,2BAA2B,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YACrH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,KAAK,CAAC,SAAS,yDAAyD,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAC1L,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DatasetAccessResult } from "../types.ts";
|
|
2
|
+
export interface ProfileRead {
|
|
3
|
+
version: string;
|
|
4
|
+
sectionId: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class ProfileDisclosure {
|
|
7
|
+
private readonly listedSections;
|
|
8
|
+
private outputBytes;
|
|
9
|
+
clear(): void;
|
|
10
|
+
/** 输入只能来自本次已完成权限校验的结果。没有 data 的状态原样返回,绝不使用历史正文兜底。 */
|
|
11
|
+
project(results: DatasetAccessResult[], subject: string, read?: ProfileRead, offset?: number): DatasetAccessResult[];
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=profileDisclosure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileDisclosure.d.ts","sourceRoot":"","sources":["../../src/tools/profileDisclosure.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAiCvD,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB;AA+CD,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,WAAW,CAAK;IAExB,KAAK,IAAI,IAAI;IAKb,qDAAqD;IACrD,OAAO,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,EAAE,MAAM,SAAI,GAAG,mBAAmB,EAAE;CAyD/G"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// 管:内置数据工具向模型渐进披露画像,限制目录、片段和当轮输出;不管:上游取数、画像生成或授权判定。
|
|
2
|
+
// 对应 REDoc《搭搭获取小红书用户画像和行为数据技术方案》。每次调用必须先经过 DataAccess 授权查询,不缓存画像正文。
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
const PROFILE_ID = "xhs_user_behaviour_data";
|
|
5
|
+
// 这里只限制单次平台传入的数据体积;目录和正文仍按页与当轮预算披露给模型。
|
|
6
|
+
const MAX_SOURCE_BYTES = 128 * 1024;
|
|
7
|
+
const SECTION_BYTES = 4096;
|
|
8
|
+
const RUN_OUTPUT_BYTES = 24 * 1024;
|
|
9
|
+
const TOPICS_PER_PAGE = 8;
|
|
10
|
+
function publicProjection(value) {
|
|
11
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
12
|
+
return undefined;
|
|
13
|
+
const source = value;
|
|
14
|
+
const basic = source.basicInfo && typeof source.basicInfo === "object" && !Array.isArray(source.basicInfo) ? source.basicInfo : {};
|
|
15
|
+
const basicInfo = Object.fromEntries(["name", "avatar", "intro"].filter(key => typeof basic[key] === "string").map(key => [key, basic[key]]));
|
|
16
|
+
const notes = source.publicNotes && typeof source.publicNotes === "object" && !Array.isArray(source.publicNotes) ? source.publicNotes : {};
|
|
17
|
+
const publicNotes = notes.status === "available" && Array.isArray(notes.noteIds)
|
|
18
|
+
? { status: "available", noteIds: notes.noteIds.filter((id) => typeof id === "string").slice(0, 20), coverage: "public-published-sample", limit: 20, truncated: notes.truncated === true }
|
|
19
|
+
: { status: "unavailable" };
|
|
20
|
+
return { basicInfo, publicNotes, publicCollections: { status: "unavailable" }, coverage: typeof source.coverage === "string" ? shortText(source.coverage, 80) : "unknown" };
|
|
21
|
+
}
|
|
22
|
+
function shortText(text, length) {
|
|
23
|
+
return Array.from(text).slice(0, length).join("");
|
|
24
|
+
}
|
|
25
|
+
/** 兼容现有纯文本 / XML Memory,不把截取的预览冒充模型生成的摘要或结构化分类。 */
|
|
26
|
+
function splitMemory(memory) {
|
|
27
|
+
const sections = [];
|
|
28
|
+
let text = "";
|
|
29
|
+
let bytes = 0;
|
|
30
|
+
for (const char of memory) {
|
|
31
|
+
const size = Buffer.byteLength(char);
|
|
32
|
+
if (bytes + size > SECTION_BYTES) {
|
|
33
|
+
sections.push(text);
|
|
34
|
+
text = "";
|
|
35
|
+
bytes = 0;
|
|
36
|
+
}
|
|
37
|
+
text += char;
|
|
38
|
+
bytes += size;
|
|
39
|
+
}
|
|
40
|
+
if (text)
|
|
41
|
+
sections.push(text);
|
|
42
|
+
return sections;
|
|
43
|
+
}
|
|
44
|
+
/** 按《画像逻辑细化 - 2026.10》的主题字段投影。这里只识别内容,不推测 RedKV 的外层封装。 */
|
|
45
|
+
function parseSections(memory) {
|
|
46
|
+
const input = memory.trim();
|
|
47
|
+
if (!input.startsWith("{") && !input.startsWith("["))
|
|
48
|
+
return splitMemory(memory).map(text => ({ text }));
|
|
49
|
+
let value;
|
|
50
|
+
try {
|
|
51
|
+
value = JSON.parse(input);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const topics = Array.isArray(value) ? value : [value];
|
|
57
|
+
if (!topics.length)
|
|
58
|
+
return null;
|
|
59
|
+
const sections = [];
|
|
60
|
+
for (const topic of topics) {
|
|
61
|
+
if (!topic || typeof topic !== "object" || Array.isArray(topic))
|
|
62
|
+
return null;
|
|
63
|
+
const item = topic;
|
|
64
|
+
if (typeof item.主题 !== "string" || !item.主题.trim() || typeof item.关注时间 !== "string" || typeof item.描述 !== "string" || !Array.isArray(item.具体详情) || !item.具体详情.every(detail => typeof detail === "string"))
|
|
65
|
+
return null;
|
|
66
|
+
if (item.偏好程度 !== undefined && (typeof item.偏好程度 !== "number" || !Number.isFinite(item.偏好程度) || item.偏好程度 < 0))
|
|
67
|
+
return null;
|
|
68
|
+
const texts = splitMemory(item.具体详情.join("\n"));
|
|
69
|
+
for (const text of texts.length ? texts : [""])
|
|
70
|
+
sections.push({
|
|
71
|
+
text,
|
|
72
|
+
topic: shortText(item.主题, 80),
|
|
73
|
+
time: shortText(item.关注时间, 32),
|
|
74
|
+
description: shortText(item.描述, 50),
|
|
75
|
+
...(typeof item.偏好程度 === "number" ? { preference: item.偏好程度 } : {}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return sections;
|
|
79
|
+
}
|
|
80
|
+
export class ProfileDisclosure {
|
|
81
|
+
listedSections = new Set();
|
|
82
|
+
outputBytes = 0;
|
|
83
|
+
clear() {
|
|
84
|
+
this.listedSections.clear();
|
|
85
|
+
this.outputBytes = 0;
|
|
86
|
+
}
|
|
87
|
+
/** 输入只能来自本次已完成权限校验的结果。没有 data 的状态原样返回,绝不使用历史正文兜底。 */
|
|
88
|
+
project(results, subject, read, offset = 0) {
|
|
89
|
+
if (!Number.isSafeInteger(offset) || offset < 0)
|
|
90
|
+
throw new Error("画像目录偏移量必须为非负整数。");
|
|
91
|
+
return results.map((result) => {
|
|
92
|
+
if (result.id !== PROFILE_ID || result.status !== "available")
|
|
93
|
+
return result;
|
|
94
|
+
const publicData = publicProjection(result.data.publicData);
|
|
95
|
+
const publicOnly = (profileStatus, message) => {
|
|
96
|
+
const data = { view: "publicOnly", publicData, profileStatus, message };
|
|
97
|
+
const bytes = Buffer.byteLength(JSON.stringify(data));
|
|
98
|
+
if (this.outputBytes + bytes > RUN_OUTPUT_BYTES)
|
|
99
|
+
return { ...result, data: { view: "budgetExceeded", message: "已达到本回合画像读取预算,请基于已读取内容回答并说明信息不足,不要继续读取。" } };
|
|
100
|
+
this.outputBytes += bytes;
|
|
101
|
+
return { ...result, data };
|
|
102
|
+
};
|
|
103
|
+
const memory = result.data.memory;
|
|
104
|
+
if (typeof memory !== "string" || !memory.trim() || Buffer.byteLength(memory) > MAX_SOURCE_BYTES) {
|
|
105
|
+
return publicData ? publicOnly("unavailable", "本次只取得公开资料;没有可用的行为画像。")
|
|
106
|
+
: { ...result, data: { view: "unsupported", message: "画像格式或大小超出当前文本读取契约,不能输出正文。" } };
|
|
107
|
+
}
|
|
108
|
+
const version = createHash("sha256").update(JSON.stringify([subject, result.revision, result.sourceUpdatedAt, publicData, memory])).digest("hex");
|
|
109
|
+
const sections = parseSections(memory);
|
|
110
|
+
if (!sections)
|
|
111
|
+
return publicData ? publicOnly("unsupported", "画像格式不符合已知主题结构;仅使用公开资料。")
|
|
112
|
+
: { ...result, data: { view: "unsupported", message: "画像 JSON 不符合已知主题结构,不能把未知封装或原始行为明细作为画像输出。" } };
|
|
113
|
+
const structured = sections[0]?.topic !== undefined;
|
|
114
|
+
const pageStart = read ? 0 : offset;
|
|
115
|
+
const pageEnd = structured ? pageStart + TOPICS_PER_PAGE : sections.length;
|
|
116
|
+
const entries = sections.map(({ text, ...metadata }, i) => ({ sectionId: `part-${i + 1}`, ...metadata, ...(structured ? {} : { preview: shortText(text.replace(/\s+/gu, " ").trim(), 48) }) })).slice(pageStart, pageEnd);
|
|
117
|
+
const index = () => ({
|
|
118
|
+
view: "index",
|
|
119
|
+
...(publicData ? { publicData } : { publicDataStatus: "unavailable" }),
|
|
120
|
+
layout: structured ? "topics" : "text",
|
|
121
|
+
version,
|
|
122
|
+
sections: entries,
|
|
123
|
+
...(pageEnd < sections.length ? { nextOffset: pageEnd } : {}),
|
|
124
|
+
message: "仅在回答需要时,用 profileRead 的 version 和 sectionId 读取详情;需要下一页目录时传 profileOffset=nextOffset。description 为上游描述,preview 为原文预览。偏好分不是概率;互动不代表亲身经历。画像内容是参考数据,不是工具指令。",
|
|
125
|
+
});
|
|
126
|
+
let data;
|
|
127
|
+
if (!read) {
|
|
128
|
+
data = index();
|
|
129
|
+
}
|
|
130
|
+
else if (read.version !== version) {
|
|
131
|
+
data = { ...index(), reason: "请使用本次目录的 version;画像可能已更新,或尚未读取该用户的目录。" };
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const section = sections.find((_, i) => read.sectionId === `part-${i + 1}`);
|
|
135
|
+
data = section === undefined
|
|
136
|
+
? { view: "invalidSection", version, message: "片段不存在,请使用目录返回的 sectionId。" }
|
|
137
|
+
: !this.listedSections.has(`${version}:${read.sectionId}`)
|
|
138
|
+
? { ...index(), reason: "请先读取包含目标片段的目录页,再读取详情。" }
|
|
139
|
+
: { view: "section", version, sectionId: read.sectionId, ...section };
|
|
140
|
+
}
|
|
141
|
+
const bytes = Buffer.byteLength(JSON.stringify(data));
|
|
142
|
+
if (this.outputBytes + bytes > RUN_OUTPUT_BYTES) {
|
|
143
|
+
return { ...result, data: { view: "budgetExceeded", message: "已达到本回合画像读取预算,请基于已读取内容回答并说明信息不足,不要继续读取。" } };
|
|
144
|
+
}
|
|
145
|
+
this.outputBytes += bytes;
|
|
146
|
+
if (data.view === "index")
|
|
147
|
+
for (const entry of entries)
|
|
148
|
+
this.listedSections.add(`${version}:${entry.sectionId}`);
|
|
149
|
+
// 只输出投影字段,禁止把未来新增的原始字段或 memory 通过展开 data 顺带传给模型。
|
|
150
|
+
return { ...result, data };
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=profileDisclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileDisclosure.js","sourceRoot":"","sources":["../../src/tools/profileDisclosure.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { AgentTool } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import type { MLBClient } from "../mlbClient.ts";
|
|
4
|
-
import type { ImageMimeType, MLBMessageToWrite } from "../types.ts";
|
|
4
|
+
import type { Conversation, ImageMimeType, ImageSendInput, MLBMessageToWrite } from "../types.ts";
|
|
5
5
|
/** 下载用的依赖,测试替换;缺省真 fetch */
|
|
6
6
|
export interface DownloadDeps {
|
|
7
7
|
fetchImpl?: typeof fetch;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
export declare function sendImage(client: Pick<MLBClient, "imageUpload">, convoKey: string, enqueueMessage: (message: MLBMessageToWrite) =>
|
|
11
|
-
bytes: Uint8Array;
|
|
12
|
-
mimeType: ImageMimeType;
|
|
13
|
-
text?: string;
|
|
14
|
-
idempotencyKey: string;
|
|
15
|
-
}, signal?: AbortSignal): Promise<void>;
|
|
9
|
+
/** 字节上传或复用 mediaId,再进同一发送队列;组合操作传入等待保存凭据的发送函数。 */
|
|
10
|
+
export declare function sendImage<T>(client: Pick<MLBClient, "imageUpload">, convoKey: string, enqueueMessage: (message: MLBMessageToWrite, signal?: AbortSignal) => T | Promise<T>, input: ImageSendInput, signal?: AbortSignal): Promise<T>;
|
|
16
11
|
/** 回环、私网、链路本地、本机任意、运营商级 NAT 这些段:IPv4 按前缀判,IPv6 看 ::1、fc00::/7、fe80::/10 和映射的 IPv4 */
|
|
17
12
|
export declare function isPrivateAddress(address: string): boolean;
|
|
18
13
|
/** 从地址下载一张图:地址形状、字面量 IP 的网段、大小、类型都核过才回字节 */
|
|
@@ -21,14 +16,15 @@ export declare function downloadImage(url: string, deps?: DownloadDeps, signal?:
|
|
|
21
16
|
mimeType: ImageMimeType;
|
|
22
17
|
}>;
|
|
23
18
|
declare const sendImageParams: Type.TObject<{
|
|
19
|
+
mediaId: Type.TOptional<Type.TString>;
|
|
24
20
|
file: Type.TOptional<Type.TString>;
|
|
25
21
|
url: Type.TOptional<Type.TString>;
|
|
26
22
|
text: Type.TOptional<Type.TString>;
|
|
27
23
|
}>;
|
|
28
24
|
/**
|
|
29
|
-
* 给一场会话造 send_image
|
|
25
|
+
* 给一场会话造 send_image:复用已绑定会话的 image.send;resourcesDir 是搭子目录下的 resources/,文件按调用时读,不走启动时读好的 .md 资料清单。
|
|
30
26
|
* 主动服务回合里照常能发,运行时不按回合性质拦。
|
|
31
27
|
*/
|
|
32
|
-
export declare function sendImageTool(
|
|
28
|
+
export declare function sendImageTool(image: Pick<Conversation["image"], "send">, resourcesDir: string, deps?: DownloadDeps): AgentTool<typeof sendImageParams, undefined>;
|
|
33
29
|
export {};
|
|
34
30
|
//# sourceMappingURL=sendImage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendImage.d.ts","sourceRoot":"","sources":["../../src/tools/sendImage.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sendImage.d.ts","sourceRoot":"","sources":["../../src/tools/sendImage.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASlG,4BAA4B;AAC5B,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACzB;AAED,kDAAkD;AAClD,wBAAsB,SAAS,CAAC,CAAC,EAChC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EACtC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACpF,KAAK,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQzD;AAED,4CAA4C;AAC5C,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAiCvJ;AAED,QAAA,MAAM,eAAe;;;;;EAKnB,CAAC;AAMH;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,EAC1C,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,YAAiB,GACrB,SAAS,CAAC,OAAO,eAAe,EAAE,SAAS,CAAC,CAmB9C"}
|
package/dist/tools/sendImage.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// 发图:把一张图发进聊天流(REDoc《【技术设计】与搭子会话消息里的图片》§5.2)。
|
|
2
|
-
// 管:sendImage
|
|
3
|
-
// send_image
|
|
2
|
+
// 管:sendImage——图片字节上传后发送,已有 mediaId 直接发送;发送函数决定是入队即返回还是等待保存凭据。
|
|
3
|
+
// send_image 工具——mediaId、file 与 url 三选一,调用当前会话的 image.send;file 按扩展名定类型、读文件、路径不许出 resources/;
|
|
4
4
|
// url 只收 http(s):主机写成字面量 IP 且落在回环、私网、链路本地这些段的,以及 localhost,拒掉(模型拿不到搭子进程去探内网);
|
|
5
5
|
// 域名不解析再判——公司自己的 CDN 域名(ci.xiaohongshu.com)在公司网络里就解析成内网 IP,按解析结果拦会把正常的图一起拦掉。
|
|
6
6
|
// 不跟重定向,30 秒超时、5 MiB 上限、响应 Content-Type 必须是 jpeg / png / webp;都过了再走 sendImage。
|
|
7
7
|
// 不管:HTTP 请求本身(mlbClient.ts)、队列怎么写回(conversation/writeMLBMessage.ts)、
|
|
8
|
-
//
|
|
8
|
+
// 生图(conversation/image.ts)与工具注册(conversation/agent.ts)。
|
|
9
9
|
import { readFileSync } from "node:fs";
|
|
10
10
|
import { isIP } from "node:net";
|
|
11
11
|
import { extname, resolve, sep } from "node:path";
|
|
@@ -16,10 +16,14 @@ const IMAGE_MIME_TYPES = new Set(["image/jpeg", "image/png", "image/webp"]);
|
|
|
16
16
|
/** 下载一张图的上限与超时:跟平台上传口的 5 MiB 一致 */
|
|
17
17
|
const MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
18
18
|
const DOWNLOAD_TIMEOUT_MS = 30_000;
|
|
19
|
-
/**
|
|
19
|
+
/** 字节上传或复用 mediaId,再进同一发送队列;组合操作传入等待保存凭据的发送函数。 */
|
|
20
20
|
export async function sendImage(client, convoKey, enqueueMessage, input, signal) {
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
signal?.throwIfAborted();
|
|
22
|
+
if ((input.mediaId !== undefined) === (input.bytes !== undefined) || (input.mediaId !== undefined && (!input.mediaId.trim() || input.mimeType !== undefined)))
|
|
23
|
+
throw new Error("mediaId 和 bytes + mimeType 填一种");
|
|
24
|
+
const mediaId = input.mediaId ?? (await client.imageUpload(convoKey, input.mimeType, input.bytes, signal)).mediaId;
|
|
25
|
+
signal?.throwIfAborted();
|
|
26
|
+
return enqueueMessage({ type: "image", image: { mediaId }, ...(input.text ? { text: input.text } : {}), idempotencyKey: input.idempotencyKey }, signal);
|
|
23
27
|
}
|
|
24
28
|
/** 回环、私网、链路本地、本机任意、运营商级 NAT 这些段:IPv4 按前缀判,IPv6 看 ::1、fc00::/7、fe80::/10 和映射的 IPv4 */
|
|
25
29
|
export function isPrivateAddress(address) {
|
|
@@ -71,17 +75,18 @@ export async function downloadImage(url, deps = {}, signal) {
|
|
|
71
75
|
return { bytes: Buffer.concat(chunks, size), mimeType: mimeType };
|
|
72
76
|
}
|
|
73
77
|
const sendImageParams = Type.Object({
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
mediaId: Type.Optional(Type.String({ minLength: 1, description: "当前会话已生成或上传的媒体编号,可直接使用 generate_image 返回的 mediaId;与 file、url 三选一,不填图片消息编号" })),
|
|
79
|
+
file: Type.Optional(Type.String({ minLength: 1, description: "resources/ 目录里的图片文件路径,如 exercises/squat.jpg;只认 .jpg / .jpeg / .png / .webp。与 mediaId、url 三选一" })),
|
|
80
|
+
url: Type.Optional(Type.String({ minLength: 1, description: "图片的公网地址(http 或 https),比如搜索结果里的配图地址。与 mediaId、file 三选一" })),
|
|
76
81
|
text: Type.Optional(Type.String({ maxLength: 500, description: "配的一句话,跟图片一起显示;不配就不填" })),
|
|
77
82
|
});
|
|
78
|
-
const DESCRIPTION = "
|
|
79
|
-
"
|
|
83
|
+
const DESCRIPTION = "把已有图片发进当前聊天。mediaId、file、url 三选一:mediaId 填 generate_image 返回的媒体编号,直接发送;file 填 resources/ 里的图片路径;url 填图片公网地址,文件和地址读取后上传。" +
|
|
84
|
+
"可用 text 配文。mediaId 发送等待消息保存,返回的 messageId 可用于 view_image 和后续改图;file 或 url 发送只确认入队。不为确认结果重复发送,内部编号不要展示给用户。";
|
|
80
85
|
/**
|
|
81
|
-
* 给一场会话造 send_image
|
|
86
|
+
* 给一场会话造 send_image:复用已绑定会话的 image.send;resourcesDir 是搭子目录下的 resources/,文件按调用时读,不走启动时读好的 .md 资料清单。
|
|
82
87
|
* 主动服务回合里照常能发,运行时不按回合性质拦。
|
|
83
88
|
*/
|
|
84
|
-
export function sendImageTool(
|
|
89
|
+
export function sendImageTool(image, resourcesDir, deps = {}) {
|
|
85
90
|
return {
|
|
86
91
|
name: "send_image",
|
|
87
92
|
label: "正在发图片",
|
|
@@ -90,10 +95,14 @@ export function sendImageTool(client, convoKey, resourcesDir, enqueueMessage, de
|
|
|
90
95
|
parameters: sendImageParams,
|
|
91
96
|
execute: async (callId, params, signal) => {
|
|
92
97
|
signal?.throwIfAborted();
|
|
93
|
-
if (
|
|
94
|
-
throw new Error("file 和 url 填一个");
|
|
98
|
+
if ([params.mediaId, params.file, params.url].filter(value => value !== undefined).length !== 1)
|
|
99
|
+
throw new Error("mediaId、file 和 url 填一个");
|
|
100
|
+
if (params.mediaId !== undefined) {
|
|
101
|
+
const saved = await image.send({ mediaId: params.mediaId, text: params.text, idempotencyKey: `send-image:${callId}` }, signal);
|
|
102
|
+
return { content: [{ type: "text", text: `图片消息已保存。内部引用:${JSON.stringify(saved)};[图片 #${saved.messageId}] 可用于 view_image 和后续改图。不要重复发送,也不要向用户展示内部编号。` }], details: undefined };
|
|
103
|
+
}
|
|
95
104
|
const source = params.url !== undefined ? await downloadImage(params.url, deps, signal) : readResourceImage(resourcesDir, params.file);
|
|
96
|
-
await
|
|
105
|
+
await image.send({ ...source, text: params.text, idempotencyKey: `send-image:${callId}` }, signal);
|
|
97
106
|
return { content: [{ type: "text", text: "图片已加入发送队列,尚不代表平台确认送达。" }], details: undefined };
|
|
98
107
|
},
|
|
99
108
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sendImage.js","sourceRoot":"","sources":["../../src/tools/sendImage.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C
|
|
1
|
+
{"version":3,"file":"sendImage.js","sourceRoot":"","sources":["../../src/tools/sendImage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewImage.d.ts","sourceRoot":"","sources":["../../src/tools/viewImage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,QAAA,MAAM,eAAe;;EAEnB,CAAC;
|
|
1
|
+
{"version":3,"file":"viewImage.d.ts","sourceRoot":"","sources":["../../src/tools/viewImage.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAEjD,QAAA,MAAM,eAAe;;EAEnB,CAAC;AAOH,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,eAAe,EAAE,SAAS,CAAC,CA0BlI"}
|
package/dist/tools/viewImage.js
CHANGED
|
@@ -10,7 +10,8 @@ const viewImageParams = Type.Object({
|
|
|
10
10
|
messageId: Type.String({ minLength: 1, description: "「[图片 #…]」标签里 # 后面的那串,原样传;聊天记录卡里的图带「/第几张」,也原样传" }),
|
|
11
11
|
});
|
|
12
12
|
const DESCRIPTION = "看一张图的内容。用户消息里「[图片 #消息编号]」是用户发的一张图,答过的图在历史里只剩这一行标签、没有图本身;要看图里是什么就把那个编号传进来。" +
|
|
13
|
-
"引用里的「[引用 某人的图片 #编号]」、聊天记录卡里的「[图片 #卡片编号/第几张]」同理。"
|
|
13
|
+
"引用里的「[引用 某人的图片 #编号]」、聊天记录卡里的「[图片 #卡片编号/第几张]」同理。" +
|
|
14
|
+
"图片编号只用于工具调用和内部历史记录,不要在给用户的回复中复述编号或 [图片 #…] 标签;用「这张图」「刚生成的图」或「第一版」等说法指代。";
|
|
14
15
|
/** 给一场会话造 view_image:绑死在这场会话的 convoKey 上。结果里只有一行文字和图片块,写回平台时只剩那行文字 */
|
|
15
16
|
export function viewImageTool(client, convoKey) {
|
|
16
17
|
return {
|
|
@@ -33,7 +34,7 @@ export function viewImageTool(client, convoKey) {
|
|
|
33
34
|
}
|
|
34
35
|
return {
|
|
35
36
|
content: [
|
|
36
|
-
{ type: "text", text:
|
|
37
|
+
{ type: "text", text: `内部图片引用:[图片 #${messageId}]。该编号仅供工具调用,不要在给用户的回复中复述编号或标签。` },
|
|
37
38
|
{ type: "image", data: Buffer.from(image.bytes).toString("base64"), mimeType: image.mimeType },
|
|
38
39
|
],
|
|
39
40
|
details: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewImage.js","sourceRoot":"","sources":["../../src/tools/viewImage.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,kEAAkE;AAClE,yHAAyH;AACzH,8GAA8G;AAC9G,8GAA8G;AAG9G,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAEjD,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;CACtG,CAAC,CAAC;AAEH,MAAM,WAAW,GAChB,2EAA2E;IAC3E,iDAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"viewImage.js","sourceRoot":"","sources":["../../src/tools/viewImage.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,kEAAkE;AAClE,yHAAyH;AACzH,8GAA8G;AAC9G,8GAA8G;AAG9G,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAEjD,MAAM,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;CACtG,CAAC,CAAC;AAEH,MAAM,WAAW,GAChB,2EAA2E;IAC3E,iDAAiD;IACjD,yEAAyE,CAAC;AAE3E,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAAC,MAAoC,EAAE,QAAgB;IACnF,OAAO;QACN,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,OAAO;QACd,gBAAgB,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc,EAAE;QACjG,WAAW,EAAE,WAAW;QACxB,UAAU,EAAE,eAAe;QAC3B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC5D,IAAI,KAA8C,CAAC;YACnD,IAAI,CAAC;gBACJ,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,KAAK,YAAY,oBAAoB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,sBAAsB,CAAC,CAAC;gBAChI,MAAM,KAAK,CAAC;YACb,CAAC;YACD,OAAO;gBACN,OAAO,EAAE;oBACR,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,SAAS,gCAAgC,EAAE;oBAChF,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;iBAC9F;gBACD,OAAO,EAAE,SAAS;aAClB,CAAC;QACH,CAAC;KACD,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,12 +4,16 @@ import type { ProductAPI, ProductCredential, ProductCredentialSnapshot } from ".
|
|
|
4
4
|
import type { AgentMessage, AgentOptions, AgentState, AgentTool } from "@earendil-works/pi-agent-core";
|
|
5
5
|
/** 一个搭子在一场会话里的配置。形状照 pi 的 Agent 来。 */
|
|
6
6
|
export type BuddyOptions = Pick<AgentOptions, "beforeToolCall" | "afterToolCall" | "shouldStopAfterTurn"> & {
|
|
7
|
+
/** 需要回复的用户消息交给模型前执行。可按消息判断是否需要数据;返回 true 表示已自行处理(例如发授权卡),不调用模型。 */
|
|
8
|
+
beforeReply?: (messages: readonly AgentMessage[]) => boolean | void | Promise<boolean | void>;
|
|
7
9
|
/**
|
|
8
10
|
* model、systemPrompt 必填;tools / thinkingLevel 可选。平台工具从 conversation.tools 里取来放进 tools。
|
|
9
11
|
* model 填运行时支持的模型 id,建 Agent 时换成网关的模型条目;messages 不露,历史从平台灌
|
|
10
12
|
*/
|
|
11
13
|
initialState: Pick<AgentState, "systemPrompt"> & Partial<Pick<AgentState, "tools" | "thinkingLevel">> & {
|
|
12
14
|
model: ModelId;
|
|
15
|
+
/** 独立的生图模型;调用 image.generate / generateAndSend 或选用对应模型工具时必填。 */
|
|
16
|
+
imageModel?: string;
|
|
13
17
|
};
|
|
14
18
|
/** 普通回合里模型出错或一句话没说时,替搭子发的兜底话;不配就不发。主动服务回合不发 */
|
|
15
19
|
errorReply?: string;
|
|
@@ -82,17 +86,33 @@ export interface Conversation {
|
|
|
82
86
|
rednote(input: SearchRednoteRequest): Promise<SearchRednoteResult[]>;
|
|
83
87
|
};
|
|
84
88
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
89
|
+
* 图片生成与发送,绑定当前会话。方法不依赖模型工具注册,主动服务回合也可调用。
|
|
90
|
+
* 生图模型取 initialState.imageModel,在工厂返回配置后调用;读过授权数据的回合禁止生图,生图请求不自动重试。
|
|
91
|
+
* 对应模型工具为 generate_image、send_image、generate_and_send_image,由开发者按需选入 initialState.tools。
|
|
88
92
|
*/
|
|
89
93
|
readonly image: {
|
|
90
|
-
|
|
94
|
+
/** 生成并存图,返回本会话的媒体编号,不写聊天消息。参考图用已有图片消息编号,最多 14 张。 */
|
|
95
|
+
generate?(input: {
|
|
96
|
+
prompt: string;
|
|
97
|
+
referenceMessageIds?: string[];
|
|
98
|
+
}, signal?: AbortSignal): Promise<{
|
|
99
|
+
mediaId: string;
|
|
100
|
+
}>;
|
|
101
|
+
/** 图片字节先上传,加入发送队列后返回;保留已有调用的完成标准。幂等键只用于消息写入。 */
|
|
102
|
+
send(input: Extract<ImageSendInput, {
|
|
91
103
|
bytes: Uint8Array;
|
|
92
|
-
|
|
104
|
+
}>, signal?: AbortSignal): Promise<void>;
|
|
105
|
+
/** 发送已存图片,等待保存后返回消息编号,供后续看图和改图使用。 */
|
|
106
|
+
send(input: Extract<ImageSendInput, {
|
|
107
|
+
mediaId: string;
|
|
108
|
+
}>, signal?: AbortSignal): Promise<ImageSendResult>;
|
|
109
|
+
/** 生成并发送,等消息保存后返回媒体与消息编号。发送失败不重新生图;幂等键不能防止重复调用生图。 */
|
|
110
|
+
generateAndSend?(input: {
|
|
111
|
+
prompt: string;
|
|
112
|
+
referenceMessageIds?: string[];
|
|
93
113
|
text?: string;
|
|
94
114
|
idempotencyKey: string;
|
|
95
|
-
}): Promise<
|
|
115
|
+
}, signal?: AbortSignal): Promise<ImageSendResult>;
|
|
96
116
|
};
|
|
97
117
|
/**
|
|
98
118
|
* 管理当前私聊的主动服务订阅。subscribe 按稳定 key 创建或更新,平台建成即 active,不再需要用户在 App 里单独确认。
|
|
@@ -193,10 +213,14 @@ export interface PlatformTools {
|
|
|
193
213
|
readonly widget_delete: AgentTool;
|
|
194
214
|
readonly widget_send: AgentTool;
|
|
195
215
|
/**
|
|
196
|
-
* 把一张图发进聊天流,file 与 url
|
|
197
|
-
*
|
|
216
|
+
* 把一张图发进聊天流,mediaId、file 与 url 三选一:mediaId 是本会话已生成或上传的图片;file 是 resources/ 下的图片文件;url 是公网 http(s) 地址。
|
|
217
|
+
* file / url 读取后上传,加入发送队列后返回;mediaId 直接引用,等待保存后返回消息编号。可选配文 text。
|
|
198
218
|
*/
|
|
199
219
|
readonly send_image: AgentTool;
|
|
220
|
+
/** 生成或修改一张图片,只返回 mediaId,不发聊天消息;需配置 initialState.imageModel,开发者选入 tools 才启用。 */
|
|
221
|
+
readonly generate_image?: AgentTool;
|
|
222
|
+
/** 生成或修改一张图片并发送,等消息保存后返回 mediaId 与 messageId;需配置 initialState.imageModel,开发者选入 tools 才启用。 */
|
|
223
|
+
readonly generate_and_send_image?: AgentTool;
|
|
200
224
|
readonly proactive_subscribe: AgentTool;
|
|
201
225
|
readonly proactive_list: AgentTool;
|
|
202
226
|
readonly proactive_unsubscribe: AgentTool;
|
|
@@ -206,8 +230,26 @@ export interface PlatformTools {
|
|
|
206
230
|
/** 搜小红书笔记:query、timeRange、maxResults(1 到 40,默认 20)、includeComments;正文与评论给原文 */
|
|
207
231
|
readonly search_rednote: AgentTool;
|
|
208
232
|
}
|
|
209
|
-
/**
|
|
233
|
+
/** 搭子能发的图片格式:平台收这三种,按原格式处理后存,透明保留 */
|
|
210
234
|
export type ImageMimeType = "image/jpeg" | "image/png" | "image/webp";
|
|
235
|
+
/** 发送图片:字节与已存媒体编号二选一,幂等键仅用于消息写入。 */
|
|
236
|
+
export type ImageSendInput = ({
|
|
237
|
+
bytes: Uint8Array;
|
|
238
|
+
mimeType: ImageMimeType;
|
|
239
|
+
mediaId?: never;
|
|
240
|
+
} | {
|
|
241
|
+
mediaId: string;
|
|
242
|
+
bytes?: never;
|
|
243
|
+
mimeType?: never;
|
|
244
|
+
}) & {
|
|
245
|
+
text?: string;
|
|
246
|
+
idempotencyKey: string;
|
|
247
|
+
};
|
|
248
|
+
/** 图片消息保存成功后的媒体与消息编号。 */
|
|
249
|
+
export interface ImageSendResult {
|
|
250
|
+
mediaId: string;
|
|
251
|
+
messageId: string;
|
|
252
|
+
}
|
|
211
253
|
/** search_web / search_rednote 的 timeRange 取值:多久以内发布的 */
|
|
212
254
|
export type SearchTimeRange = "day" | "week" | "month" | "year";
|
|
213
255
|
/** POST /internal/v1/search/web 的请求体(convoKey 由 MLBClient 加) */
|
|
@@ -328,7 +370,7 @@ export type DatasetAccessResult = {
|
|
|
328
370
|
data: Record<string, unknown>;
|
|
329
371
|
} | {
|
|
330
372
|
id: string;
|
|
331
|
-
status: "relationshipRequired" | "notDeclared" | "notGranted" | "disabledInGroup" | "unavailable" | "systemPermissionDenied";
|
|
373
|
+
status: "relationshipRequired" | "notDeclared" | "notGranted" | "platformAuthorizationRequired" | "bindingRequired" | "disabledInGroup" | "unavailable" | "systemPermissionDenied";
|
|
332
374
|
};
|
|
333
375
|
/** 搭子向平台声明的一项用户数据需求。 */
|
|
334
376
|
export interface DataRequirement {
|
|
@@ -430,7 +472,7 @@ export interface MLBImage {
|
|
|
430
472
|
height?: number;
|
|
431
473
|
mimeType?: string;
|
|
432
474
|
size?: number;
|
|
433
|
-
/**
|
|
475
|
+
/** 处理好的图片的 base64,平台在拉取时加上(给旧版运行时的,新版拉取不用它:重建的历史只留标签,要看调 view_image)。图片读不到时没有;引用块里的图不带 */
|
|
434
476
|
data?: string;
|
|
435
477
|
}
|
|
436
478
|
/** 读口每条记录 */
|