mycomesh-consumer 0.1.46 → 0.1.48

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mycomesh-consumer",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "description": "Native Node.js MycoMesh Consumer and OpenAI-compatible request CLI.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -356,6 +356,38 @@ export function inferenceRequestHash({
356
356
  return `0x${createHash("sha256").update(stableStringify(envelope), "utf8").digest("hex")}`;
357
357
  }
358
358
 
359
+ export function derivePromptCacheKey({ endpoint, model, input, messages, options }) {
360
+ const explicit = options && typeof options === "object" ? options.prompt_cache_key : undefined;
361
+ if (typeof explicit === "string" && explicit.trim()) return explicit.trim();
362
+ const normalizedEndpoint = String(endpoint || "").trim().toLowerCase();
363
+ if (!["responses", "chat"].includes(normalizedEndpoint)) return null;
364
+ const seed = { model: String(model || "") };
365
+ for (const field of ["reasoning", "tool_choice", "tools", "functions", "instructions"]) {
366
+ const value = options && typeof options === "object" ? options[field] : undefined;
367
+ if (value !== undefined && value !== null && value !== "" && !(Array.isArray(value) && value.length === 0)) {
368
+ seed[field] = value;
369
+ }
370
+ }
371
+ const source = normalizedEndpoint === "chat" ? (messages ?? [{ role: "user", content: String(input || "") }]) : (input ?? "");
372
+ let firstUser;
373
+ const system = [];
374
+ if (Array.isArray(source)) {
375
+ for (const item of source) {
376
+ if (!item || typeof item !== "object") continue;
377
+ const role = String(item.role || "").trim().toLowerCase();
378
+ if (role === "system" || role === "developer") system.push(item.content);
379
+ if (firstUser === undefined && role === "user") firstUser = item.content;
380
+ if (firstUser === undefined && item.type === "input_text") firstUser = item.text;
381
+ }
382
+ } else if (typeof source === "string" && source.trim()) {
383
+ firstUser = source;
384
+ }
385
+ if (system.length) seed.system = system;
386
+ if (firstUser === undefined || firstUser === null || firstUser === "" || (Array.isArray(firstUser) && !firstUser.length)) return null;
387
+ seed.first_user = firstUser;
388
+ return `myco_csp_${createHash("sha256").update(stableStringify(seed), "utf8").digest("hex")}`;
389
+ }
390
+
359
391
  function normalizeInferenceOptions(endpoint, options) {
360
392
  if (options === undefined || options === null) return null;
361
393
  if (typeof options !== "object" || Array.isArray(options)) {
@@ -981,8 +1013,22 @@ export class NativeConsumerState {
981
1013
  try { selected = await this.chooseRelay(used); } catch (error) { lastError = error.message; break; }
982
1014
  used.add(selected.relayUrl);
983
1015
  try {
984
- const payment = this.buildRelayPayment(path, body, selected.health, requestId);
985
- const requestBody = { ...body, model: payment.model };
1016
+ const requestBody = {
1017
+ ...body,
1018
+ model: selected.health.v8.model || body.model,
1019
+ };
1020
+ if (!String(requestBody.prompt_cache_key || "").trim()) {
1021
+ const cacheKey = derivePromptCacheKey({
1022
+ endpoint: path.endsWith("/chat/completions") ? "chat" : "responses",
1023
+ model: requestBody.model,
1024
+ input: requestBody.input,
1025
+ messages: requestBody.messages,
1026
+ options: requestBody,
1027
+ });
1028
+ if (cacheKey) requestBody.prompt_cache_key = cacheKey;
1029
+ }
1030
+ const payment = this.buildRelayPayment(path, requestBody, selected.health, requestId);
1031
+ requestBody.model = payment.model;
986
1032
  const encodedPayment = base64Url(Buffer.from(stableStringify(payment.payment), "utf8"));
987
1033
  const response = await fetchWithTimeout(`${selected.relayUrl}${path}`, {
988
1034
  method: "POST",
@@ -1403,7 +1449,16 @@ export function responseSse(payload, compact = false) {
1403
1449
  export function chatCompletionSse(payload, includeUsage = false) {
1404
1450
  const id = String(payload?.id || `chatcmpl_${bytesToHex(randomBytes(16))}`); const model = String(payload?.model || ""); const created = Number(payload?.created || Math.floor(Date.now() / 1000)); const chunks = [];
1405
1451
  const chunk = (index, delta, finishReason = null) => chunks.push(`data: ${JSON.stringify({ id, object: "chat.completion.chunk", created, model, choices: [{ index, delta, finish_reason: finishReason }] })}\n\n`);
1406
- (Array.isArray(payload?.choices) ? payload.choices : []).forEach((choice, fallbackIndex) => { const index = Number.isInteger(choice.index) ? choice.index : fallbackIndex; const message = choice.message || {}; chunk(index, { role: String(message.role || "assistant") }); if (message.content) chunk(index, { content: String(message.content) }); chunk(index, {}, choice.finish_reason || "stop"); });
1452
+ (Array.isArray(payload?.choices) ? payload.choices : []).forEach((choice, fallbackIndex) => {
1453
+ const index = Number.isInteger(choice.index) ? choice.index : fallbackIndex;
1454
+ const message = choice.message || {};
1455
+ chunk(index, { role: String(message.role || "assistant") });
1456
+ if (message.content) chunk(index, { content: String(message.content) });
1457
+ (Array.isArray(message.tool_calls) ? message.tool_calls : []).forEach((call, toolIndex) => {
1458
+ chunk(index, { tool_calls: [{ index: toolIndex, id: call.id, type: call.type || "function", function: { name: call.function?.name, arguments: String(call.function?.arguments || "") } }] });
1459
+ });
1460
+ chunk(index, {}, choice.finish_reason || "stop");
1461
+ });
1407
1462
  if (includeUsage && payload?.usage) chunks.push(`data: ${JSON.stringify({ id, object: "chat.completion.chunk", created, model, choices: [], usage: payload.usage })}\n\n`);
1408
1463
  chunks.push("data: [DONE]\n\n"); return chunks;
1409
1464
  }
package/src/consumer.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  createConsumerServer,
12
12
  } from "./consumer-runtime.mjs";
13
13
 
14
- export const CONSUMER_RELEASE_VERSION = "0.1.46";
14
+ export const CONSUMER_RELEASE_VERSION = "0.1.48";
15
15
  export const API_COMMANDS = new Set(["health", "models", "responses", "chat"]);
16
16
  const API_VALUE_OPTIONS = new Set([
17
17
  "--base-url",