@deepagents/context 0.29.0 → 0.30.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.d.ts CHANGED
@@ -8,6 +8,7 @@ export * from './lib/estimate.ts';
8
8
  export * from './lib/fragments.ts';
9
9
  export * from './lib/fragments/domain.ts';
10
10
  export * from './lib/fragments/message/user.ts';
11
+ export * from './lib/fragments/reasoning.ts';
11
12
  export * from './lib/fragments/user.ts';
12
13
  export * from './lib/guardrail.ts';
13
14
  export * from './lib/guardrails/error-recovery.guardrail.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,sCAAsC,CAAC;AACrD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,sCAAsC,CAAC;AACrD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,qCAAqC,CAAC;AACpD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -612,6 +612,12 @@ function or(...predicates) {
612
612
  function not(predicate) {
613
613
  return (turn) => !predicate(turn);
614
614
  }
615
+ function isConditionalReminder(fragment2) {
616
+ return fragment2.name === "reminder" && !!fragment2.metadata?.reminder;
617
+ }
618
+ function getConditionalReminder(fragment2) {
619
+ return fragment2.metadata.reminder;
620
+ }
615
621
  var SYSTEM_REMINDER_OPEN_TAG = "<system-reminder>";
616
622
  var SYSTEM_REMINDER_CLOSE_TAG = "</system-reminder>";
617
623
  function getReminderRanges(metadata) {
@@ -746,54 +752,61 @@ function applyPartReminder(message2, value) {
746
752
  mode: "part"
747
753
  };
748
754
  }
749
- function hasSchedule(reminder2) {
750
- return reminder2.when !== void 0;
755
+ function resolveReminderText(item, ctx) {
756
+ return typeof item.text === "function" ? item.text(ctx) : item.text;
757
+ }
758
+ function applyReminderToMessage(message2, item, ctx) {
759
+ const resolvedText = resolveReminderText(item, ctx);
760
+ if (resolvedText.trim().length === 0) {
761
+ return null;
762
+ }
763
+ return item.asPart ? applyPartReminder(message2, resolvedText) : applyInlineReminder(message2, resolvedText);
751
764
  }
752
- function shouldIncludeReminder(reminder2, turn) {
753
- if (reminder2.when && !reminder2.when(turn)) return false;
754
- return true;
765
+ function mergeReminderMetadata(message2, addedReminders) {
766
+ if (addedReminders.length === 0) return;
767
+ const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
768
+ const existing = Array.isArray(metadata.reminders) ? metadata.reminders : [];
769
+ metadata.reminders = [...existing, ...addedReminders];
770
+ message2.metadata = metadata;
755
771
  }
756
772
  function reminder(text, options) {
757
773
  if (typeof text === "string") {
758
774
  assertReminderText(text);
759
775
  }
776
+ if (options && "when" in options && options.when) {
777
+ return {
778
+ name: "reminder",
779
+ metadata: {
780
+ reminder: {
781
+ text,
782
+ when: options.when,
783
+ asPart: options.asPart ?? false
784
+ }
785
+ }
786
+ };
787
+ }
760
788
  return {
761
789
  text,
762
- asPart: options?.asPart ?? false,
763
- ...options?.when !== void 0 && { when: options.when }
790
+ asPart: options?.asPart ?? false
764
791
  };
765
792
  }
766
- function resolveReminderText(item, ctx) {
767
- return typeof item.text === "function" ? item.text(ctx) : item.text;
768
- }
769
793
  function user(content, ...reminders) {
770
794
  const message2 = typeof content === "string" ? {
771
795
  id: generateId3(),
772
796
  role: "user",
773
797
  parts: [{ type: "text", text: content }]
774
798
  } : { ...content, role: "user", parts: [...content.parts] };
775
- const immediateReminders = reminders.filter((r) => !hasSchedule(r));
776
- const scheduledReminders = reminders.filter((r) => hasSchedule(r));
777
- if (immediateReminders.length > 0) {
778
- const addedReminders = [];
799
+ if (reminders.length > 0) {
779
800
  const plainText = extractPlainText(message2);
780
- for (const item of immediateReminders) {
781
- const resolvedText = resolveReminderText(item, { content: plainText });
782
- if (resolvedText.trim().length === 0) {
783
- continue;
784
- }
785
- addedReminders.push(
786
- item.asPart ? applyPartReminder(message2, resolvedText) : applyInlineReminder(message2, resolvedText)
787
- );
788
- }
789
- if (addedReminders.length > 0) {
790
- const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
791
- const existingReminders = Array.isArray(metadata.reminders) ? metadata.reminders : [];
792
- metadata.reminders = [...existingReminders, ...addedReminders];
793
- message2.metadata = metadata;
801
+ const addedReminders = [];
802
+ for (const item of reminders) {
803
+ const meta = applyReminderToMessage(message2, item, {
804
+ content: plainText
805
+ });
806
+ if (meta) addedReminders.push(meta);
794
807
  }
808
+ mergeReminderMetadata(message2, addedReminders);
795
809
  }
796
- const fragmentMetadata = scheduledReminders.length > 0 ? { scheduledReminders } : void 0;
797
810
  return {
798
811
  id: message2.id,
799
812
  name: "user",
@@ -806,8 +819,7 @@ function user(content, ...reminders) {
806
819
  encode() {
807
820
  return message2;
808
821
  }
809
- },
810
- metadata: fragmentMetadata
822
+ }
811
823
  };
812
824
  }
813
825
 
@@ -1709,6 +1721,9 @@ var ContextEngine = class {
1709
1721
  #initialized = false;
1710
1722
  /** Initial metadata to merge on first initialization */
1711
1723
  #initialMetadata;
1724
+ get #renderableFragments() {
1725
+ return this.#fragments.filter((f) => !isConditionalReminder(f));
1726
+ }
1712
1727
  constructor(options) {
1713
1728
  if (!options.chatId) {
1714
1729
  throw new Error("chatId is required");
@@ -1875,7 +1890,7 @@ var ContextEngine = class {
1875
1890
  * @internal Use resolve() instead for public API.
1876
1891
  */
1877
1892
  render(renderer) {
1878
- return renderer.render(this.#fragments);
1893
+ return renderer.render(this.#renderableFragments);
1879
1894
  }
1880
1895
  /**
1881
1896
  * Resolve context into AI SDK-ready format.
@@ -1896,7 +1911,7 @@ var ContextEngine = class {
1896
1911
  */
1897
1912
  async resolve(options) {
1898
1913
  await this.#ensureInitialized();
1899
- const systemPrompt = options.renderer.render(this.#fragments);
1914
+ const systemPrompt = options.renderer.render(this.#renderableFragments);
1900
1915
  const messages = [];
1901
1916
  if (this.#branch?.headMessageId) {
1902
1917
  const chain = await this.#store.getMessageChain(
@@ -1912,46 +1927,43 @@ var ContextEngine = class {
1912
1927
  this.#pendingMessages[i] = await this.#resolveLazyFragment(fragment2);
1913
1928
  }
1914
1929
  }
1915
- const turn = await this.getTurnCount();
1916
1930
  for (const fragment2 of this.#pendingMessages) {
1917
1931
  if (!fragment2.codec) {
1918
1932
  throw new Error(
1919
1933
  `Fragment "${fragment2.name}" is missing codec. Lazy fragments must be resolved before encode.`
1920
1934
  );
1921
1935
  }
1922
- const scheduled = fragment2.metadata?.scheduledReminders;
1923
- if (fragment2.name === "user" && scheduled && scheduled.length > 0) {
1924
- const original = fragment2.codec.encode();
1936
+ messages.push(fragment2.codec.encode());
1937
+ }
1938
+ const conditionalReminders = this.#fragments.filter(isConditionalReminder);
1939
+ if (conditionalReminders.length > 0) {
1940
+ const turn = await this.getTurnCount();
1941
+ let lastUserIndex = -1;
1942
+ for (let i = messages.length - 1; i >= 0; i--) {
1943
+ if (messages[i].role === "user") {
1944
+ lastUserIndex = i;
1945
+ break;
1946
+ }
1947
+ }
1948
+ if (lastUserIndex >= 0) {
1949
+ const original = messages[lastUserIndex];
1925
1950
  const message2 = {
1926
1951
  ...original,
1927
1952
  parts: [...original.parts]
1928
1953
  };
1929
1954
  const plainText = message2.parts.filter(isTextUIPart2).map((p) => p.text).join(" ");
1930
1955
  const addedReminders = [];
1931
- for (const item of scheduled) {
1932
- if (!shouldIncludeReminder(item, turn)) {
1933
- continue;
1934
- }
1935
- const resolvedText = resolveReminderText(item, {
1956
+ for (const fragment2 of conditionalReminders) {
1957
+ const config = getConditionalReminder(fragment2);
1958
+ if (!config.when(turn)) continue;
1959
+ const meta = applyReminderToMessage(message2, config, {
1936
1960
  content: plainText,
1937
1961
  turn
1938
1962
  });
1939
- if (resolvedText.trim().length === 0) {
1940
- continue;
1941
- }
1942
- addedReminders.push(
1943
- item.asPart ? applyPartReminder(message2, resolvedText) : applyInlineReminder(message2, resolvedText)
1944
- );
1945
- }
1946
- if (addedReminders.length > 0) {
1947
- const metadata = typeof message2.metadata === "object" && message2.metadata !== null && !Array.isArray(message2.metadata) ? { ...message2.metadata } : {};
1948
- const existingReminders = Array.isArray(metadata.reminders) ? metadata.reminders : [];
1949
- metadata.reminders = [...existingReminders, ...addedReminders];
1950
- message2.metadata = metadata;
1963
+ if (meta) addedReminders.push(meta);
1951
1964
  }
1952
- messages.push(message2);
1953
- } else {
1954
- messages.push(fragment2.codec.encode());
1965
+ mergeReminderMetadata(message2, addedReminders);
1966
+ messages[lastUserIndex] = message2;
1955
1967
  }
1956
1968
  }
1957
1969
  return {
@@ -2088,7 +2100,7 @@ var ContextEngine = class {
2088
2100
  }
2089
2101
  const tokenizer = registry.getTokenizer(modelId);
2090
2102
  const fragmentEstimates = [];
2091
- for (const fragment2 of this.#fragments) {
2103
+ for (const fragment2 of this.#renderableFragments) {
2092
2104
  const rendered = renderer.render([fragment2]);
2093
2105
  const tokens = tokenizer.count(rendered);
2094
2106
  const cost = tokens / 1e6 * model.cost.input;
@@ -2421,7 +2433,7 @@ var ContextEngine = class {
2421
2433
  await this.#ensureInitialized();
2422
2434
  const { renderer } = options;
2423
2435
  const estimateResult = await this.estimate(options.modelId, { renderer });
2424
- const rendered = renderer.render(this.#fragments);
2436
+ const rendered = renderer.render(this.#renderableFragments);
2425
2437
  const persistedMessages = [];
2426
2438
  if (this.#branch?.headMessageId) {
2427
2439
  const chain = await this.#store.getMessageChain(
@@ -3802,6 +3814,130 @@ function fromFragment(fragment2, options) {
3802
3814
  throw new Error(`Fragment "${fragment2.name}" is missing codec`);
3803
3815
  }
3804
3816
 
3817
+ // packages/context/src/lib/fragments/reasoning.ts
3818
+ function reasoningFramework() {
3819
+ return [
3820
+ role(
3821
+ "You are a very strong reasoner and planner. Use these critical instructions to structure your plans, thoughts, and responses."
3822
+ ),
3823
+ fragment(
3824
+ "meta_cognitive_reasoning_framework",
3825
+ hint(
3826
+ "Before taking any action (either tool calls *or* responses to the user), you must proactively, methodically, and independently plan and reason about:"
3827
+ ),
3828
+ principle({
3829
+ title: "Logical dependencies and constraints",
3830
+ description: "Analyze the intended action against the following factors. Resolve conflicts in order of importance:",
3831
+ policies: [
3832
+ policy({
3833
+ rule: "Policy-based rules, mandatory prerequisites, and constraints."
3834
+ }),
3835
+ policy({
3836
+ rule: "Order of operations: Ensure taking an action does not prevent a subsequent necessary action.",
3837
+ policies: [
3838
+ "The user may request actions in a random order, but you may need to reorder operations to maximize successful completion of the task."
3839
+ ]
3840
+ }),
3841
+ policy({
3842
+ rule: "Other prerequisites (information and/or actions needed)."
3843
+ }),
3844
+ policy({ rule: "Explicit user constraints or preferences." })
3845
+ ]
3846
+ }),
3847
+ principle({
3848
+ title: "Risk assessment",
3849
+ description: "What are the consequences of taking the action? Will the new state cause any future issues?",
3850
+ policies: [
3851
+ "For exploratory tasks (like searches), missing *optional* parameters is a LOW risk. **Prefer calling the tool with the available information over asking the user, unless** your Rule 1 (Logical Dependencies) reasoning determines that optional information is required for a later step in your plan."
3852
+ ]
3853
+ }),
3854
+ principle({
3855
+ title: "Abductive reasoning and hypothesis exploration",
3856
+ description: "At each step, identify the most logical and likely reason for any problem encountered.",
3857
+ policies: [
3858
+ "Look beyond immediate or obvious causes. The most likely reason may not be the simplest and may require deeper inference.",
3859
+ "Hypotheses may require additional research. Each hypothesis may take multiple steps to test.",
3860
+ "Prioritize hypotheses based on likelihood, but do not discard less likely ones prematurely. A low-probability event may still be the root cause."
3861
+ ]
3862
+ }),
3863
+ principle({
3864
+ title: "Outcome evaluation and adaptability",
3865
+ description: "Does the previous observation require any changes to your plan?",
3866
+ policies: [
3867
+ "If your initial hypotheses are disproven, actively generate new ones based on the gathered information."
3868
+ ]
3869
+ }),
3870
+ principle({
3871
+ title: "Information availability",
3872
+ description: "Incorporate all applicable and alternative sources of information, including:",
3873
+ policies: [
3874
+ "Using available tools and their capabilities",
3875
+ "All policies, rules, checklists, and constraints",
3876
+ "Previous observations and conversation history",
3877
+ "Information only available by asking the user"
3878
+ ]
3879
+ }),
3880
+ principle({
3881
+ title: "Precision and Grounding",
3882
+ description: "Ensure your reasoning is extremely precise and relevant to each exact ongoing situation.",
3883
+ policies: [
3884
+ "Verify your claims by quoting the exact applicable information (including policies) when referring to them."
3885
+ ]
3886
+ }),
3887
+ principle({
3888
+ title: "Completeness",
3889
+ description: "Ensure that all requirements, constraints, options, and preferences are exhaustively incorporated into your plan.",
3890
+ policies: [
3891
+ policy({
3892
+ rule: "Resolve conflicts using the order of importance in #1."
3893
+ }),
3894
+ policy({
3895
+ rule: "Avoid premature conclusions: There may be multiple relevant options for a given situation.",
3896
+ policies: [
3897
+ "To check for whether an option is relevant, reason about all information sources from #5.",
3898
+ "You may need to consult the user to even know whether something is applicable. Do not assume it is not applicable without checking."
3899
+ ]
3900
+ }),
3901
+ policy({
3902
+ rule: "Review applicable sources of information from #5 to confirm which are relevant to the current state."
3903
+ })
3904
+ ]
3905
+ }),
3906
+ principle({
3907
+ title: "Persistence and patience",
3908
+ description: "Do not give up unless all the reasoning above is exhausted.",
3909
+ policies: [
3910
+ "Don't be dissuaded by time taken or user frustration.",
3911
+ "This persistence must be intelligent: On *transient* errors (e.g. please try again), you *must* retry **unless an explicit retry limit (e.g., max x tries) has been reached**. If such a limit is hit, you *must* stop. On *other* errors, you must change your strategy or arguments, not repeat the same failed call."
3912
+ ]
3913
+ }),
3914
+ principle({
3915
+ title: "Inhibit your response",
3916
+ description: "Only take an action after all the above reasoning is completed. Once you've taken an action, you cannot take it back."
3917
+ }),
3918
+ principle({
3919
+ title: "Continuous self-monitoring",
3920
+ description: "Constantly evaluate your own reasoning process for any gaps, biases, or errors. Apply the above principles iteratively as needed."
3921
+ })
3922
+ )
3923
+ ];
3924
+ }
3925
+ var DEFAULT_SELF_CRITIQUE_CHECKS = [
3926
+ "Did I answer the user's intent, not just their literal words?",
3927
+ "Is every claim grounded in the provided context, schema, or data?",
3928
+ "Did I follow the requested output format and constraints?"
3929
+ ];
3930
+ function selfCritique(checks = DEFAULT_SELF_CRITIQUE_CHECKS) {
3931
+ return workflow({
3932
+ task: "Self-critique before returning final response",
3933
+ steps: [
3934
+ "Before returning your final response, review your generated output against the user's original constraints:",
3935
+ ...checks.map((check, i) => `${i + 1}. ${check}`),
3936
+ "If any check fails, revise your response before returning it."
3937
+ ]
3938
+ });
3939
+ }
3940
+
3805
3941
  // packages/context/src/lib/guardrails/error-recovery.guardrail.ts
3806
3942
  import chalk2 from "chalk";
3807
3943
  var errorRecoveryGuardrail = {
@@ -7237,6 +7373,7 @@ export {
7237
7373
  and,
7238
7374
  applyInlineReminder,
7239
7375
  applyPartReminder,
7376
+ applyReminderToMessage,
7240
7377
  assistant,
7241
7378
  assistantText,
7242
7379
  chat,
@@ -7260,15 +7397,16 @@ export {
7260
7397
  fragment,
7261
7398
  fromFragment,
7262
7399
  generateChatTitle,
7400
+ getConditionalReminder,
7263
7401
  getFragmentData,
7264
7402
  getModelsRegistry,
7265
7403
  getReminderRanges,
7266
7404
  glossary,
7267
7405
  guardrail,
7268
- hasSchedule,
7269
7406
  hint,
7270
7407
  identity,
7271
7408
  isComposeOptions,
7409
+ isConditionalReminder,
7272
7410
  isDockerfileOptions,
7273
7411
  isFragment,
7274
7412
  isFragmentObject,
@@ -7276,6 +7414,7 @@ export {
7276
7414
  isMessageFragment,
7277
7415
  lastAssistantMessage,
7278
7416
  loadSkillMetadata,
7417
+ mergeReminderMetadata,
7279
7418
  message,
7280
7419
  nextAdaptivePollingDelay,
7281
7420
  normalizeCancelPolling,
@@ -7291,13 +7430,14 @@ export {
7291
7430
  preference,
7292
7431
  principle,
7293
7432
  quirk,
7433
+ reasoningFramework,
7294
7434
  reminder,
7295
7435
  render,
7296
7436
  resetAdaptivePolling,
7297
7437
  resolveReminderText,
7298
7438
  role,
7299
7439
  runGuardrailChain,
7300
- shouldIncludeReminder,
7440
+ selfCritique,
7301
7441
  skills,
7302
7442
  skillsReminder,
7303
7443
  soul,