@comchatx/cx-topics 0.1.0 → 0.1.1

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.
@@ -190,7 +190,8 @@ async function routeTopic(input, dependencies) {
190
190
  // src/source-packages/cx-topics/box/core/titling.ts
191
191
  var TITLE_SYSTEM = [
192
192
  "You write the title of one topic in a seller's History: the piece of work the seller's messages ask for.",
193
- 'Write at most eight words, in the language the seller writes in, such as "Competitor price history" or "\u745C\u4F3D\u57AB\u8865\u8D27\u68C0\u67E5".',
193
+ "The title is for the seller, who reads it to find this work again: name the work in the seller's own words, as they would write it.",
194
+ 'Write at most eight words, in the language the seller writes in, such as "Competitor price history" or "\u745C\u4F3D\u57AB listing \u65B0\u6807\u9898".',
194
195
  "Reply with the title alone: no quotes, no punctuation at its end, no explanation."
195
196
  ].join("\n");
196
197
  function titleLanguage(newest) {
@@ -213,7 +214,7 @@ function titlePrompt(request) {
213
214
 
214
215
  // src/source-packages/cx-topics/box/extensions/judge.ts
215
216
  var JEV = Object.freeze({ provider: "typesafe", model: "jev-latest" });
216
- var TITLE_MODEL = Object.freeze({ provider: "openrouter", model: "minimax/minimax-m3" });
217
+ var TITLE_MODEL = Object.freeze({ provider: "balance", model: "minimax/minimax-m3" });
217
218
  var CALL_MS = 2e4;
218
219
  var isSellers = (entry) => entry.type === "message" && entry.message.role === "user";
219
220
  var QUOTE = /<quote\b[^>]*>[\s\S]*?<\/quote>/g;
@@ -418,17 +419,45 @@ var TITLE_CHARS = 80;
418
419
  var QUOTED_CHARS = 8e3;
419
420
  var AROUND_CHARS = 1e3;
420
421
  var AROUND = 2;
422
+ var spaced = (words2) => words2.replace(/([A-Za-z0-9])([\u4e00-\u9fff])/g, "$1 $2").replace(/([\u4e00-\u9fff])([A-Za-z0-9])/g, "$1 $2");
421
423
  function title(raw) {
422
- const words2 = raw.replace(/\s+/g, " ").trim().split(" ").slice(0, TITLE_WORDS).join(" ");
424
+ const words2 = spaced(raw.replace(/\s+/g, " ").trim()).split(" ").slice(0, TITLE_WORDS).join(" ");
423
425
  const cut3 = [...words2].slice(0, TITLE_CHARS).join("").trim();
424
426
  return cut3 === "" ? void 0 : cut3;
425
427
  }
426
428
  var blocksOf = (content) => typeof content === "string" ? [{ type: "text", text: content }] : Array.isArray(content) ? content : [];
427
429
  var cut2 = (text2, chars) => text2.length <= chars ? text2 : `${text2.slice(0, chars)} [${text2.length - chars} more characters]`;
428
- var when = (timestamp) => {
430
+ var when = (timestamp, zone) => {
429
431
  const at = new Date(timestamp);
430
- return Number.isNaN(at.getTime()) ? "" : ` \xB7 ${at.toISOString().slice(0, 16).replace("T", " ")} UTC`;
432
+ if (Number.isNaN(at.getTime())) return "";
433
+ if (zone !== void 0) {
434
+ try {
435
+ const part = Object.fromEntries(new Intl.DateTimeFormat("en-CA", { timeZone: zone, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", hourCycle: "h23" }).formatToParts(at).map((one) => [one.type, one.value]));
436
+ return ` \xB7 ${part["year"]}-${part["month"]}-${part["day"]} ${part["hour"]}:${part["minute"]} ${zone}`;
437
+ } catch {
438
+ }
439
+ }
440
+ return ` \xB7 ${at.toISOString().slice(0, 16).replace("T", " ")} UTC`;
431
441
  };
442
+ function attributesOf(text2) {
443
+ const found = /* @__PURE__ */ new Map();
444
+ const one = /\s+([A-Za-z_][\w.:-]*)="([^"]*)"/y;
445
+ for (let match = one.exec(text2); match !== null; match = one.exec(text2)) if (!found.has(match[1])) found.set(match[1], match[2]);
446
+ return found;
447
+ }
448
+ function zoneOf(entries, id) {
449
+ for (const entry of [...entries].reverse()) {
450
+ if (entry.type !== "message" || entry.message.role !== "user") continue;
451
+ const words2 = blocksOf("content" in entry.message ? entry.message.content : void 0).map((block) => block.text ?? "").join("\n");
452
+ for (const marker of words2.matchAll(/<quote\b([^>]*)>/g)) {
453
+ const attributes = attributesOf(marker[1] ?? "");
454
+ if (attributes.get("entry") !== id) continue;
455
+ const zone = attributes.get("zone");
456
+ if (zone !== void 0 && zone !== "") return zone;
457
+ }
458
+ }
459
+ return void 0;
460
+ }
432
461
  var UNDRAWN = "topic";
433
462
  function parts(entry) {
434
463
  const blocks = blocksOf("content" in entry.message ? entry.message.content : void 0);
@@ -436,10 +465,10 @@ function parts(entry) {
436
465
  const steps = blocks.filter((block) => block.type === "toolCall" && block.name !== UNDRAWN).map((block) => `(step: ${block.name ?? "tool"})`);
437
466
  return { words: words2, steps };
438
467
  }
439
- function line(entry, chars) {
468
+ function line(entry, chars, zone) {
440
469
  const who = entry.message.role === "user" ? "seller" : "cx";
441
470
  const { words: words2, steps } = parts(entry);
442
- return [`[${who}${when(entry.timestamp)}]`, ...words2 === "" ? [] : [cut2(words2, chars)], ...steps].join("\n");
471
+ return [`[${who}${when(entry.timestamp, zone)}]`, ...words2 === "" ? [] : [cut2(words2, chars)], ...steps].join("\n");
443
472
  }
444
473
  var isSaid = (entry) => entry.type === "message" && (entry.message.role === "user" || entry.message.role === "assistant");
445
474
  var isShown = (entry) => {
@@ -447,14 +476,16 @@ var isShown = (entry) => {
447
476
  return words2 !== "" || steps.length > 0;
448
477
  };
449
478
  function quoted(session, id) {
450
- const said = session.entries().filter(isSaid).filter((entry) => entry.id === id || isShown(entry));
479
+ const entries = session.entries();
480
+ const zone = zoneOf(entries, id);
481
+ const said = entries.filter(isSaid).filter((entry) => entry.id === id || isShown(entry));
451
482
  const at = said.findIndex((entry) => entry.id === id);
452
483
  if (at < 0) return "This message is from an earlier conversation and can't be read here.";
453
- const around = (from, to) => said.slice(Math.max(0, from), Math.max(0, to)).map((entry) => line(entry, AROUND_CHARS));
484
+ const around = (from, to) => said.slice(Math.max(0, from), Math.max(0, to)).map((entry) => line(entry, AROUND_CHARS, zone));
454
485
  return [
455
486
  ...around(at - AROUND, at),
456
487
  `>>> The quoted message:
457
- ${line(said[at], QUOTED_CHARS)}
488
+ ${line(said[at], QUOTED_CHARS, zone)}
458
489
  <<<`,
459
490
  ...around(at + 1, at + 1 + AROUND)
460
491
  ].join("\n\n");
@@ -513,5 +544,6 @@ export {
513
544
  topics as default,
514
545
  ownKey,
515
546
  quoted,
547
+ spaced,
516
548
  title
517
549
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comchatx/cx-topics",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",