@deepagents/context 0.22.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
@@ -412,6 +412,18 @@ import {
412
412
  createUIMessageStream as createUIMessageStream2,
413
413
  generateId as generateId3
414
414
  } from "ai";
415
+ function toMessageFragment(item) {
416
+ if (isFragment(item) && isMessageFragment(item)) {
417
+ return item;
418
+ }
419
+ return message(item);
420
+ }
421
+ function chatMessageToUIMessage(item) {
422
+ if (isFragment(item) && isMessageFragment(item)) {
423
+ return item.codec.decode();
424
+ }
425
+ return item;
426
+ }
415
427
  async function chat(agent2, messages, options) {
416
428
  const context = agent2.context;
417
429
  if (!context) {
@@ -422,17 +434,20 @@ async function chat(agent2, messages, options) {
422
434
  if (messages.length === 0) {
423
435
  throw new Error("messages must not be empty");
424
436
  }
425
- const lastMessage = messages[messages.length - 1];
437
+ const lastItem = messages[messages.length - 1];
438
+ const lastFragment = toMessageFragment(lastItem);
439
+ const lastUIMessage = chatMessageToUIMessage(lastItem);
426
440
  let assistantMsgId;
427
- if (lastMessage.role === "assistant") {
428
- context.set(message(lastMessage));
441
+ if (lastUIMessage.role === "assistant") {
442
+ context.set(lastFragment);
429
443
  await context.save({ branch: false });
430
- assistantMsgId = lastMessage.id;
444
+ assistantMsgId = lastUIMessage.id;
431
445
  } else {
432
- context.set(message(lastMessage));
446
+ context.set(lastFragment);
433
447
  await context.save();
434
448
  assistantMsgId = options?.generateMessageId?.() ?? generateId3();
435
449
  }
450
+ const uiMessages = messages.map(chatMessageToUIMessage);
436
451
  const streamContextVariables = options?.contextVariables === void 0 ? {} : options.contextVariables;
437
452
  const result = await agent2.stream(streamContextVariables, {
438
453
  transform: options?.transform
@@ -443,12 +458,12 @@ async function chat(agent2, messages, options) {
443
458
  sendFinish: true,
444
459
  sendReasoning: true,
445
460
  sendSources: true,
446
- originalMessages: messages,
461
+ originalMessages: uiMessages,
447
462
  generateMessageId: () => assistantMsgId,
448
463
  messageMetadata: options?.messageMetadata
449
464
  });
450
465
  return createUIMessageStream2({
451
- originalMessages: messages,
466
+ originalMessages: uiMessages,
452
467
  generateId: () => assistantMsgId,
453
468
  onStepFinish: async ({ responseMessage }) => {
454
469
  const normalizedMessage = {
@@ -2364,7 +2379,7 @@ function policy(input) {
2364
2379
  }
2365
2380
 
2366
2381
  // packages/context/src/lib/fragments/message/user.ts
2367
- import { generateId as generateId4 } from "ai";
2382
+ import { generateId as generateId4, isTextUIPart } from "ai";
2368
2383
  var SYSTEM_REMINDER_OPEN_TAG = "<system-reminder>";
2369
2384
  var SYSTEM_REMINDER_CLOSE_TAG = "</system-reminder>";
2370
2385
  function getReminderRanges(metadata) {
@@ -2433,6 +2448,9 @@ function stripReminders(message2) {
2433
2448
  }
2434
2449
  return nextMessage;
2435
2450
  }
2451
+ function extractPlainText(message2) {
2452
+ return message2.parts.filter(isTextUIPart).map((part) => part.text).join(" ");
2453
+ }
2436
2454
  function isRecord(value) {
2437
2455
  return typeof value === "object" && value !== null && !Array.isArray(value);
2438
2456
  }
@@ -2497,7 +2515,9 @@ function applyPartReminder(message2, value) {
2497
2515
  };
2498
2516
  }
2499
2517
  function reminder(text, options) {
2500
- assertReminderText(text);
2518
+ if (typeof text === "string") {
2519
+ assertReminderText(text);
2520
+ }
2501
2521
  return {
2502
2522
  text,
2503
2523
  asPart: options?.asPart ?? false
@@ -2511,16 +2531,22 @@ function user(content, ...reminders) {
2511
2531
  } : { ...content, role: "user", parts: [...content.parts] };
2512
2532
  if (reminders.length > 0) {
2513
2533
  const addedReminders = [];
2534
+ const plainText = extractPlainText(message2);
2514
2535
  for (const item of reminders) {
2515
- assertReminderText(item.text);
2536
+ const resolvedText = typeof item.text === "function" ? item.text(plainText) : item.text;
2537
+ if (resolvedText.trim().length === 0) {
2538
+ continue;
2539
+ }
2516
2540
  addedReminders.push(
2517
- item.asPart ? applyPartReminder(message2, item.text) : applyInlineReminder(message2, item.text)
2541
+ item.asPart ? applyPartReminder(message2, resolvedText) : applyInlineReminder(message2, resolvedText)
2518
2542
  );
2519
2543
  }
2520
- const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
2521
- const existingReminders = Array.isArray(metadata.reminders) ? metadata.reminders : [];
2522
- metadata.reminders = [...existingReminders, ...addedReminders];
2523
- 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
+ }
2524
2550
  }
2525
2551
  return {
2526
2552
  id: message2.id,
@@ -3456,6 +3482,46 @@ async function createContainerTool(options = {}) {
3456
3482
  };
3457
3483
  }
3458
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
+
3459
3525
  // packages/context/src/lib/skills/fragments.ts
3460
3526
  import dedent from "dedent";
3461
3527
 
@@ -4106,7 +4172,7 @@ var SqliteContextStore = class extends ContextStore {
4106
4172
  ).all(chatId);
4107
4173
  const nodes = messageRows.map((row) => {
4108
4174
  const data = JSON.parse(row.data);
4109
- const content = typeof data === "string" ? data : JSON.stringify(data);
4175
+ const content = typeof data === "string" ? data : Array.isArray(data.parts) ? data.parts.filter((p) => p.type === "text").map((p) => p.text).join(" ") : JSON.stringify(data);
4110
4176
  return {
4111
4177
  id: row.id,
4112
4178
  parentId: row.parentId,
@@ -6161,6 +6227,12 @@ var StreamManager = class {
6161
6227
  streamId,
6162
6228
  latencyMs
6163
6229
  });
6230
+ if (options?.onCancelDetected) {
6231
+ try {
6232
+ await options.onCancelDetected({ streamId, latencyMs });
6233
+ } catch {
6234
+ }
6235
+ }
6164
6236
  ac.abort();
6165
6237
  break;
6166
6238
  }
@@ -6449,6 +6521,7 @@ function visualizeGraph(data) {
6449
6521
  return lines.join("\n");
6450
6522
  }
6451
6523
  export {
6524
+ BM25SkillClassifier,
6452
6525
  BinaryInstallError,
6453
6526
  ComposeStartError,
6454
6527
  ComposeStrategy,
@@ -6485,6 +6558,7 @@ export {
6485
6558
  assistant,
6486
6559
  assistantText,
6487
6560
  chat,
6561
+ chatMessageToUIMessage,
6488
6562
  clarification,
6489
6563
  correction,
6490
6564
  createAdaptivePollingState,
@@ -6531,6 +6605,7 @@ export {
6531
6605
  role,
6532
6606
  runGuardrailChain,
6533
6607
  skills,
6608
+ skillsReminder,
6534
6609
  soul,
6535
6610
  stop,
6536
6611
  stripReminders,
@@ -6538,6 +6613,7 @@ export {
6538
6613
  structuredOutput,
6539
6614
  styleGuide,
6540
6615
  term,
6616
+ toMessageFragment,
6541
6617
  useSandbox,
6542
6618
  user,
6543
6619
  userContext,