@rei-standard/amsg-shared 0.4.0-next.3 → 0.4.0-next.5

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 CHANGED
@@ -264,7 +264,10 @@ async function callLlm(payload, options = {}) {
264
264
  }
265
265
  function buildLlmRequestBody(payload, options = {}) {
266
266
  const llmMessages = Array.isArray(payload.messages) && payload.messages.length > 0 ? payload.messages : [{ role: "user", content: payload.completePrompt }];
267
+ const extraBody = payload.llmExtraBody && typeof payload.llmExtraBody === "object" && !Array.isArray(payload.llmExtraBody) ? payload.llmExtraBody : null;
267
268
  const requestBody = {
269
+ // 先展开 extra body,核心字段随后写入(撞键时核心字段赢)。
270
+ ...extraBody || {},
268
271
  model: payload.primaryModel,
269
272
  messages: llmMessages
270
273
  };
@@ -511,7 +514,7 @@ async function verifyVapidJwt(jwt, publicKey) {
511
514
  utf8(`${h}.${p}`)
512
515
  );
513
516
  if (!ok) throw new Error("VAPID JWT: signature mismatch");
514
- const payload = JSON.parse(new TextDecoder().decode(base64UrlToBytes(p)));
517
+ const payload = JSON.parse(utf8Decode(base64UrlToBytes(p)));
515
518
  if (!payload.exp || payload.exp <= Math.floor(Date.now() / 1e3)) {
516
519
  throw new Error("VAPID JWT: expired");
517
520
  }
@@ -836,12 +839,20 @@ function buildSessionContext({
836
839
  scratch
837
840
  }) {
838
841
  const llmOutputText = readLlmOutputText(llmResponse);
842
+ const usage = llmResponse && typeof llmResponse === "object" && /** @type {any} */
843
+ llmResponse.usage && typeof /** @type {any} */
844
+ llmResponse.usage === "object" ? (
845
+ /** @type {Record<string, unknown>} */
846
+ /** @type {any} */
847
+ llmResponse.usage
848
+ ) : null;
839
849
  const ctx = {
840
850
  sessionId,
841
851
  charId,
842
852
  messages,
843
853
  llmResponse,
844
854
  llmOutputText,
855
+ usage,
845
856
  iteration,
846
857
  metadata: metadata && typeof metadata === "object" ? metadata : {},
847
858
  contactName,
package/dist/index.d.cts CHANGED
@@ -296,6 +296,7 @@ export function stripReasoningTags(content: string): string;
296
296
  * @property {ChatMessage[]} messages - Including the just-appended assistant turn.
297
297
  * @property {unknown} llmResponse - Full LLM response (choices, usage, …).
298
298
  * @property {string} llmOutputText - May be '' for pure tool-call responses.
299
+ * @property {Record<string, unknown>|null} usage - `llmResponse.usage` 的直接引用(prompt/completion/total tokens)。响应没带 usage → null。llmResponse 里本来就有,单独提出来是让「记本轮用量」不必依赖响应对象的具体形状。
299
300
  * @property {number} iteration - 0-indexed: the round that just finished.
300
301
  * @property {Record<string, unknown>} metadata
301
302
  * @property {string} contactName
@@ -690,6 +691,10 @@ export type SessionContext = {
690
691
  * - May be '' for pure tool-call responses.
691
692
  */
692
693
  llmOutputText: string;
694
+ /**
695
+ * - `llmResponse.usage` 的直接引用(prompt/completion/total tokens)。响应没带 usage → null。llmResponse 里本来就有,单独提出来是让「记本轮用量」不必依赖响应对象的具体形状。
696
+ */
697
+ usage: Record<string, unknown> | null;
693
698
  /**
694
699
  * - 0-indexed: the round that just finished.
695
700
  */
package/dist/index.d.ts CHANGED
@@ -296,6 +296,7 @@ export function stripReasoningTags(content: string): string;
296
296
  * @property {ChatMessage[]} messages - Including the just-appended assistant turn.
297
297
  * @property {unknown} llmResponse - Full LLM response (choices, usage, …).
298
298
  * @property {string} llmOutputText - May be '' for pure tool-call responses.
299
+ * @property {Record<string, unknown>|null} usage - `llmResponse.usage` 的直接引用(prompt/completion/total tokens)。响应没带 usage → null。llmResponse 里本来就有,单独提出来是让「记本轮用量」不必依赖响应对象的具体形状。
299
300
  * @property {number} iteration - 0-indexed: the round that just finished.
300
301
  * @property {Record<string, unknown>} metadata
301
302
  * @property {string} contactName
@@ -690,6 +691,10 @@ export type SessionContext = {
690
691
  * - May be '' for pure tool-call responses.
691
692
  */
692
693
  llmOutputText: string;
694
+ /**
695
+ * - `llmResponse.usage` 的直接引用(prompt/completion/total tokens)。响应没带 usage → null。llmResponse 里本来就有,单独提出来是让「记本轮用量」不必依赖响应对象的具体形状。
696
+ */
697
+ usage: Record<string, unknown> | null;
693
698
  /**
694
699
  * - 0-indexed: the round that just finished.
695
700
  */
package/dist/index.mjs CHANGED
@@ -186,7 +186,10 @@ async function callLlm(payload, options = {}) {
186
186
  }
187
187
  function buildLlmRequestBody(payload, options = {}) {
188
188
  const llmMessages = Array.isArray(payload.messages) && payload.messages.length > 0 ? payload.messages : [{ role: "user", content: payload.completePrompt }];
189
+ const extraBody = payload.llmExtraBody && typeof payload.llmExtraBody === "object" && !Array.isArray(payload.llmExtraBody) ? payload.llmExtraBody : null;
189
190
  const requestBody = {
191
+ // 先展开 extra body,核心字段随后写入(撞键时核心字段赢)。
192
+ ...extraBody || {},
190
193
  model: payload.primaryModel,
191
194
  messages: llmMessages
192
195
  };
@@ -433,7 +436,7 @@ async function verifyVapidJwt(jwt, publicKey) {
433
436
  utf8(`${h}.${p}`)
434
437
  );
435
438
  if (!ok) throw new Error("VAPID JWT: signature mismatch");
436
- const payload = JSON.parse(new TextDecoder().decode(base64UrlToBytes(p)));
439
+ const payload = JSON.parse(utf8Decode(base64UrlToBytes(p)));
437
440
  if (!payload.exp || payload.exp <= Math.floor(Date.now() / 1e3)) {
438
441
  throw new Error("VAPID JWT: expired");
439
442
  }
@@ -758,12 +761,20 @@ function buildSessionContext({
758
761
  scratch
759
762
  }) {
760
763
  const llmOutputText = readLlmOutputText(llmResponse);
764
+ const usage = llmResponse && typeof llmResponse === "object" && /** @type {any} */
765
+ llmResponse.usage && typeof /** @type {any} */
766
+ llmResponse.usage === "object" ? (
767
+ /** @type {Record<string, unknown>} */
768
+ /** @type {any} */
769
+ llmResponse.usage
770
+ ) : null;
761
771
  const ctx = {
762
772
  sessionId,
763
773
  charId,
764
774
  messages,
765
775
  llmResponse,
766
776
  llmOutputText,
777
+ usage,
767
778
  iteration,
768
779
  metadata: metadata && typeof metadata === "object" ? metadata : {},
769
780
  contactName,
@@ -79,6 +79,11 @@ export function callLlm(payload: any, options?: {
79
79
  * non-empty payload.tools. An empty array is treated as "no tools"
80
80
  * because some OpenAI-compatible relays reject `tools: []`.
81
81
  *
82
+ * `payload.llmExtraBody`(可选,普通对象):原样展开进请求体,给上游中转的
83
+ * 非标准参数用(thinking / reasoning_effort 之类库不认识也不该认识的字段)。
84
+ * 先展开它、再写核心字段——model / messages / temperature / max_tokens /
85
+ * tools 永远以库的口径为准,extra body 撞了这些键也盖不掉。
86
+ *
82
87
  * @param {Object} payload
83
88
  * @param {{ stream?: boolean, forwardTools?: boolean }} [options]
84
89
  * stream — set to include an explicit `stream` field in the body
@@ -79,6 +79,11 @@ export function callLlm(payload: any, options?: {
79
79
  * non-empty payload.tools. An empty array is treated as "no tools"
80
80
  * because some OpenAI-compatible relays reject `tools: []`.
81
81
  *
82
+ * `payload.llmExtraBody`(可选,普通对象):原样展开进请求体,给上游中转的
83
+ * 非标准参数用(thinking / reasoning_effort 之类库不认识也不该认识的字段)。
84
+ * 先展开它、再写核心字段——model / messages / temperature / max_tokens /
85
+ * tools 永远以库的口径为准,extra body 撞了这些键也盖不掉。
86
+ *
82
87
  * @param {Object} payload
83
88
  * @param {{ stream?: boolean, forwardTools?: boolean }} [options]
84
89
  * stream — set to include an explicit `stream` field in the body
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-shared",
3
- "version": "0.4.0-next.3",
3
+ "version": "0.4.0-next.5",
4
4
  "description": "ReiStandard Active Messaging shared types and push builders — the lowest layer (no deps on other amsg packages)",
5
5
  "repository": {
6
6
  "type": "git",