@deepagents/context 0.23.0 → 0.24.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/dist/index.js CHANGED
@@ -2379,7 +2379,7 @@ function policy(input) {
2379
2379
  }
2380
2380
 
2381
2381
  // packages/context/src/lib/fragments/message/user.ts
2382
- import { generateId as generateId4 } from "ai";
2382
+ import { generateId as generateId4, isTextUIPart } from "ai";
2383
2383
  var SYSTEM_REMINDER_OPEN_TAG = "<system-reminder>";
2384
2384
  var SYSTEM_REMINDER_CLOSE_TAG = "</system-reminder>";
2385
2385
  function getReminderRanges(metadata) {
@@ -2448,6 +2448,9 @@ function stripReminders(message2) {
2448
2448
  }
2449
2449
  return nextMessage;
2450
2450
  }
2451
+ function extractPlainText(message2) {
2452
+ return message2.parts.filter(isTextUIPart).map((part) => part.text).join(" ");
2453
+ }
2451
2454
  function isRecord(value) {
2452
2455
  return typeof value === "object" && value !== null && !Array.isArray(value);
2453
2456
  }
@@ -2512,7 +2515,9 @@ function applyPartReminder(message2, value) {
2512
2515
  };
2513
2516
  }
2514
2517
  function reminder(text, options) {
2515
- assertReminderText(text);
2518
+ if (typeof text === "string") {
2519
+ assertReminderText(text);
2520
+ }
2516
2521
  return {
2517
2522
  text,
2518
2523
  asPart: options?.asPart ?? false
@@ -2526,16 +2531,22 @@ function user(content, ...reminders) {
2526
2531
  } : { ...content, role: "user", parts: [...content.parts] };
2527
2532
  if (reminders.length > 0) {
2528
2533
  const addedReminders = [];
2534
+ const plainText = extractPlainText(message2);
2529
2535
  for (const item of reminders) {
2530
- assertReminderText(item.text);
2536
+ const resolvedText = typeof item.text === "function" ? item.text(plainText) : item.text;
2537
+ if (resolvedText.trim().length === 0) {
2538
+ continue;
2539
+ }
2531
2540
  addedReminders.push(
2532
- item.asPart ? applyPartReminder(message2, item.text) : applyInlineReminder(message2, item.text)
2541
+ item.asPart ? applyPartReminder(message2, resolvedText) : applyInlineReminder(message2, resolvedText)
2533
2542
  );
2534
2543
  }
2535
- const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
2536
- const existingReminders = Array.isArray(metadata.reminders) ? metadata.reminders : [];
2537
- metadata.reminders = [...existingReminders, ...addedReminders];
2538
- message2.metadata = metadata;
2544
+ if (addedReminders.length > 0) {
2545
+ const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
2546
+ const existingReminders = Array.isArray(metadata.reminders) ? metadata.reminders : [];
2547
+ metadata.reminders = [...existingReminders, ...addedReminders];
2548
+ message2.metadata = metadata;
2549
+ }
2539
2550
  }
2540
2551
  return {
2541
2552
  id: message2.id,
@@ -3471,6 +3482,46 @@ async function createContainerTool(options = {}) {
3471
3482
  };
3472
3483
  }
3473
3484
 
3485
+ // packages/context/src/lib/skills/classifier.ts
3486
+ import { Corpus } from "tiny-tfidf";
3487
+ var BM25SkillClassifier = class {
3488
+ #corpus;
3489
+ #skillsByName;
3490
+ constructor(skills2) {
3491
+ const names = skills2.map((s) => s.name);
3492
+ const texts = skills2.map((s) => `${s.name} ${s.description}`);
3493
+ this.#corpus = new Corpus(names, texts);
3494
+ this.#skillsByName = new Map(skills2.map((s) => [s.name, s]));
3495
+ }
3496
+ match(query, options) {
3497
+ const topN = options?.topN ?? 5;
3498
+ const threshold = options?.threshold ?? 0;
3499
+ const results = this.#corpus.getResultsForQuery(query);
3500
+ return results.filter(([, score]) => score > threshold).slice(0, topN).map(([name, score]) => ({
3501
+ skill: this.#skillsByName.get(name),
3502
+ score
3503
+ }));
3504
+ }
3505
+ };
3506
+ function isSkillClassifier(value) {
3507
+ return typeof value === "object" && value !== null && "match" in value && typeof value.match === "function";
3508
+ }
3509
+ function formatSkillReminder(matches) {
3510
+ const lines = matches.map(
3511
+ (m) => `- ${m.skill.name} (${m.score.toFixed(2)}): ${m.skill.description} [${m.skill.skillMdPath}]`
3512
+ );
3513
+ return `Relevant skills:
3514
+ ${lines.join("\n")}`;
3515
+ }
3516
+ function skillsReminder(skillsOrClassifier, options) {
3517
+ const classifier = isSkillClassifier(skillsOrClassifier) ? skillsOrClassifier : new BM25SkillClassifier(skillsOrClassifier);
3518
+ return reminder((content) => {
3519
+ const matches = classifier.match(content, options);
3520
+ if (matches.length === 0) return "";
3521
+ return formatSkillReminder(matches);
3522
+ });
3523
+ }
3524
+
3474
3525
  // packages/context/src/lib/skills/fragments.ts
3475
3526
  import dedent from "dedent";
3476
3527
 
@@ -6176,6 +6227,12 @@ var StreamManager = class {
6176
6227
  streamId,
6177
6228
  latencyMs
6178
6229
  });
6230
+ if (options?.onCancelDetected) {
6231
+ try {
6232
+ await options.onCancelDetected({ streamId, latencyMs });
6233
+ } catch {
6234
+ }
6235
+ }
6179
6236
  ac.abort();
6180
6237
  break;
6181
6238
  }
@@ -6464,6 +6521,7 @@ function visualizeGraph(data) {
6464
6521
  return lines.join("\n");
6465
6522
  }
6466
6523
  export {
6524
+ BM25SkillClassifier,
6467
6525
  BinaryInstallError,
6468
6526
  ComposeStartError,
6469
6527
  ComposeStrategy,
@@ -6547,6 +6605,7 @@ export {
6547
6605
  role,
6548
6606
  runGuardrailChain,
6549
6607
  skills,
6608
+ skillsReminder,
6550
6609
  soul,
6551
6610
  stop,
6552
6611
  stripReminders,