@deepagents/context 7.0.2 → 7.1.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.
Files changed (80) hide show
  1. package/README.md +4 -4
  2. package/dist/browser.js +210 -77
  3. package/dist/browser.js.map +4 -4
  4. package/dist/index.js +1311 -1363
  5. package/dist/index.js.map +4 -4
  6. package/dist/lib/agent.d.ts +21 -45
  7. package/dist/lib/agent.d.ts.map +1 -1
  8. package/dist/lib/chat.d.ts +11 -5
  9. package/dist/lib/chat.d.ts.map +1 -1
  10. package/dist/lib/codec/serialized-fragments.d.ts +7 -5
  11. package/dist/lib/codec/serialized-fragments.d.ts.map +1 -1
  12. package/dist/lib/engine.d.ts.map +1 -1
  13. package/dist/lib/estimate.d.ts +8 -3
  14. package/dist/lib/estimate.d.ts.map +1 -1
  15. package/dist/lib/fragments/plan-shared.d.ts +1 -1
  16. package/dist/lib/fragments/reminders/src/predicates/tool.d.ts.map +1 -1
  17. package/dist/lib/fragments.d.ts +6 -0
  18. package/dist/lib/fragments.d.ts.map +1 -1
  19. package/dist/lib/resolvers/async-resolver.d.ts +2 -2
  20. package/dist/lib/resolvers/async-resolver.d.ts.map +1 -1
  21. package/dist/lib/resolvers/function-resolver.d.ts +2 -2
  22. package/dist/lib/resolvers/function-resolver.d.ts.map +1 -1
  23. package/dist/lib/resolvers/generator-resolver.d.ts +2 -2
  24. package/dist/lib/resolvers/generator-resolver.d.ts.map +1 -1
  25. package/dist/lib/resolvers/iterable-resolver.d.ts +1 -1
  26. package/dist/lib/resolvers/iterable-resolver.d.ts.map +1 -1
  27. package/dist/lib/resolvers/loader-resolver.d.ts.map +1 -1
  28. package/dist/lib/resolvers/promise-resolver.d.ts +1 -1
  29. package/dist/lib/resolvers/promise-resolver.d.ts.map +1 -1
  30. package/dist/lib/resolvers/types.d.ts +3 -2
  31. package/dist/lib/resolvers/types.d.ts.map +1 -1
  32. package/dist/lib/sandbox/apple-container-sandbox.d.ts.map +1 -1
  33. package/dist/lib/sandbox/ast-utils.d.ts +3 -1
  34. package/dist/lib/sandbox/ast-utils.d.ts.map +1 -1
  35. package/dist/lib/sandbox/binary-bridges.d.ts.map +1 -1
  36. package/dist/lib/sandbox/cli-process.d.ts +6 -1
  37. package/dist/lib/sandbox/cli-process.d.ts.map +1 -1
  38. package/dist/lib/sandbox/container-engine.d.ts +4 -1
  39. package/dist/lib/sandbox/container-engine.d.ts.map +1 -1
  40. package/dist/lib/sandbox/container-sandbox.d.ts.map +1 -1
  41. package/dist/lib/sandbox/docker-sandbox.d.ts +3 -3
  42. package/dist/lib/sandbox/docker-sandbox.d.ts.map +1 -1
  43. package/dist/lib/sandbox/index.d.ts +0 -1
  44. package/dist/lib/sandbox/index.d.ts.map +1 -1
  45. package/dist/lib/sandbox/installers/installer.d.ts +6 -1
  46. package/dist/lib/sandbox/installers/installer.d.ts.map +1 -1
  47. package/dist/lib/sandbox/installers/url-binary.d.ts.map +1 -1
  48. package/dist/lib/sandbox/read-file.d.ts +2 -1
  49. package/dist/lib/sandbox/read-file.d.ts.map +1 -1
  50. package/dist/lib/sandbox/strace/index.js +3 -3
  51. package/dist/lib/sandbox/strace/index.js.map +2 -2
  52. package/dist/lib/sandbox/types.d.ts +4 -5
  53. package/dist/lib/sandbox/types.d.ts.map +1 -1
  54. package/dist/lib/skills/frontmatter.d.ts.map +1 -1
  55. package/dist/lib/store/columns.d.ts +13 -0
  56. package/dist/lib/store/columns.d.ts.map +1 -0
  57. package/dist/lib/store/postgres.store.d.ts.map +1 -1
  58. package/dist/lib/store/sqlite.store.d.ts.map +1 -1
  59. package/dist/lib/store/sqlserver.store.d.ts.map +1 -1
  60. package/dist/lib/stream/postgres-notify-change-source.d.ts.map +1 -1
  61. package/dist/lib/stream/postgres.stream-store.d.ts.map +1 -1
  62. package/dist/lib/stream/rows.d.ts +16 -0
  63. package/dist/lib/stream/rows.d.ts.map +1 -0
  64. package/dist/lib/stream/sqlite.stream-store.d.ts.map +1 -1
  65. package/dist/lib/stream-buffer.d.ts +10 -1
  66. package/dist/lib/stream-buffer.d.ts.map +1 -1
  67. package/dist/lib/telemetry/file/index.js +23 -13
  68. package/dist/lib/telemetry/file/index.js.map +2 -2
  69. package/dist/lib/telemetry/index.js +23 -13
  70. package/dist/lib/telemetry/index.js.map +2 -2
  71. package/dist/lib/telemetry/redact-telemetry-event.d.ts +1 -0
  72. package/dist/lib/telemetry/redact-telemetry-event.d.ts.map +1 -1
  73. package/dist/lib/tracing/index.js +27 -24
  74. package/dist/lib/tracing/index.js.map +3 -3
  75. package/dist/lib/tracing/openai-traces-integration.d.ts.map +1 -1
  76. package/dist/lib/tracing/serialization.d.ts +2 -0
  77. package/dist/lib/tracing/serialization.d.ts.map +1 -1
  78. package/package.json +3 -11
  79. package/dist/lib/sandbox/agent-os-sandbox.d.ts +0 -85
  80. package/dist/lib/sandbox/agent-os-sandbox.d.ts.map +0 -1
package/README.md CHANGED
@@ -28,10 +28,10 @@ like store implementations, sandbox tooling, and filesystem-based skill loading.
28
28
  The server-side package also ships the sandbox primitives used by
29
29
  `@deepagents/text2sql` and other tool-driven agents. Use `createBashTool()`
30
30
  with `createVirtualSandbox()`, `createDockerSandbox()`,
31
- `createAppleContainerSandbox()`, `createMicrosandboxSandbox()`,
32
- `createDaytonaSandbox(client, options)`, or `createAgentOsSandbox()` depending
33
- on whether commands should run in memory, Docker, Apple Container lightweight
34
- VMs, Microsandbox microVMs, managed Daytona sandboxes, or Agent OS.
31
+ `createAppleContainerSandbox()`, `createMicrosandboxSandbox()`, or
32
+ `createDaytonaSandbox(client, options)` depending on whether commands should
33
+ run in memory, Docker, Apple Container lightweight VMs, Microsandbox microVMs,
34
+ or managed Daytona sandboxes.
35
35
  Virtual sandboxes can opt into in-process JavaScript execution with
36
36
  `createVirtualSandbox({ javascript: true, ... })`.
37
37
 
package/dist/browser.js CHANGED
@@ -1,8 +1,28 @@
1
+ // packages/context/src/lib/codec/serialized-fragments.ts
2
+ import { z } from "zod";
3
+
1
4
  // packages/context/src/lib/fragments.ts
2
5
  import { generateId } from "ai";
3
6
  function isFragment(data) {
4
7
  return typeof data === "object" && data !== null && "name" in data && ("data" in data || "codec" in data) && typeof data.name === "string";
5
8
  }
9
+ function isFragmentData(value) {
10
+ return fitsFragmentData(value, /* @__PURE__ */ new WeakSet());
11
+ }
12
+ function fitsFragmentData(value, visited) {
13
+ if (typeof value !== "object") {
14
+ return typeof value !== "bigint" && typeof value !== "symbol";
15
+ }
16
+ if (value === null || visited.has(value)) return true;
17
+ visited.add(value);
18
+ if (Array.isArray(value)) {
19
+ return value.every((item) => fitsFragmentData(item, visited));
20
+ }
21
+ if (value instanceof Promise) return true;
22
+ if (Symbol.asyncIterator in value || Symbol.iterator in value) return true;
23
+ if (isFragment(value)) return fitsFragmentData(value.data, visited);
24
+ return Object.values(value).every((item) => fitsFragmentData(item, visited));
25
+ }
6
26
  function isFragmentObject(data) {
7
27
  if (typeof data !== "object" || data === null) return false;
8
28
  if (Array.isArray(data)) return false;
@@ -16,7 +36,13 @@ function isMessageFragment(fragment2) {
16
36
  }
17
37
  function getFragmentData(fragment2) {
18
38
  if (fragment2.codec) {
19
- return fragment2.codec.decode();
39
+ const decoded = fragment2.codec.decode();
40
+ if (!isFragmentData(decoded)) {
41
+ throw new Error(
42
+ `Fragment "${fragment2.name}" codec decoded a value that is not fragment data`
43
+ );
44
+ }
45
+ return decoded;
20
46
  }
21
47
  if ("data" in fragment2) {
22
48
  return fragment2.data;
@@ -589,118 +615,198 @@ function toFragmentData(value, options) {
589
615
  ])
590
616
  );
591
617
  }
618
+ if (!isFragmentData(value)) {
619
+ throw new Error(`Unsupported serialized value of type ${typeof value}`);
620
+ }
592
621
  return value;
593
622
  }
623
+ function builtInEntry(schema, build) {
624
+ return {
625
+ toFragment: (input, options) => {
626
+ const parsed = schema.safeParse(input);
627
+ if (!parsed.success) {
628
+ throw new Error(
629
+ `Invalid serialized ${input.type} fragment: ${z.prettifyError(parsed.error)}`
630
+ );
631
+ }
632
+ return build(parsed.data, options);
633
+ }
634
+ };
635
+ }
636
+ var nestedPolicies = z.array(z.unknown()).optional();
594
637
  var builtInSerializedRegistry = {
595
- term: {
596
- toFragment: (input) => term(input.name, input.definition)
597
- },
598
- hint: {
599
- toFragment: (input) => hint(input.text)
600
- },
601
- guardrail: {
602
- toFragment: (input) => guardrail({
638
+ term: builtInEntry(
639
+ z.object({ name: z.string(), definition: z.string() }),
640
+ (input) => term(input.name, input.definition)
641
+ ),
642
+ hint: builtInEntry(
643
+ z.object({ text: z.string() }),
644
+ (input) => hint(input.text)
645
+ ),
646
+ guardrail: builtInEntry(
647
+ z.object({
648
+ rule: z.string(),
649
+ reason: z.string().optional(),
650
+ action: z.string().optional()
651
+ }),
652
+ (input) => guardrail({
603
653
  rule: input.rule,
604
654
  reason: input.reason,
605
655
  action: input.action
606
656
  })
607
- },
608
- explain: {
609
- toFragment: (input) => explain({
657
+ ),
658
+ explain: builtInEntry(
659
+ z.object({
660
+ concept: z.string(),
661
+ explanation: z.string(),
662
+ therefore: z.string().optional()
663
+ }),
664
+ (input) => explain({
610
665
  concept: input.concept,
611
666
  explanation: input.explanation,
612
667
  therefore: input.therefore
613
668
  })
614
- },
615
- example: {
616
- toFragment: (input) => example({
669
+ ),
670
+ example: builtInEntry(
671
+ z.object({
672
+ question: z.string(),
673
+ answer: z.string(),
674
+ note: z.string().optional()
675
+ }),
676
+ (input) => example({
617
677
  question: input.question,
618
678
  answer: input.answer,
619
679
  note: input.note
620
680
  })
621
- },
622
- clarification: {
623
- toFragment: (input) => clarification({
681
+ ),
682
+ clarification: builtInEntry(
683
+ z.object({ when: z.string(), ask: z.string(), reason: z.string() }),
684
+ (input) => clarification({
624
685
  when: input.when,
625
686
  ask: input.ask,
626
687
  reason: input.reason
627
688
  })
628
- },
629
- workflow: {
630
- toFragment: (input) => workflow({
689
+ ),
690
+ workflow: builtInEntry(
691
+ z.object({
692
+ task: z.string(),
693
+ steps: z.array(z.string()),
694
+ triggers: z.array(z.string()).optional(),
695
+ notes: z.string().optional()
696
+ }),
697
+ (input) => workflow({
631
698
  task: input.task,
632
699
  steps: input.steps,
633
700
  triggers: input.triggers,
634
701
  notes: input.notes
635
702
  })
636
- },
637
- quirk: {
638
- toFragment: (input) => quirk({
703
+ ),
704
+ quirk: builtInEntry(
705
+ z.object({ issue: z.string(), workaround: z.string() }),
706
+ (input) => quirk({
639
707
  issue: input.issue,
640
708
  workaround: input.workaround
641
709
  })
642
- },
643
- styleGuide: {
644
- toFragment: (input) => styleGuide({
710
+ ),
711
+ styleGuide: builtInEntry(
712
+ z.object({
713
+ prefer: z.string(),
714
+ never: z.string().optional(),
715
+ always: z.string().optional()
716
+ }),
717
+ (input) => styleGuide({
645
718
  prefer: input.prefer,
646
719
  never: input.never,
647
720
  always: input.always
648
721
  })
649
- },
650
- analogy: {
651
- toFragment: (input) => analogy({
722
+ ),
723
+ analogy: builtInEntry(
724
+ z.object({
725
+ concepts: z.array(z.string()),
726
+ relationship: z.string(),
727
+ insight: z.string().optional(),
728
+ therefore: z.string().optional(),
729
+ pitfall: z.string().optional()
730
+ }),
731
+ (input) => analogy({
652
732
  concepts: input.concepts,
653
733
  relationship: input.relationship,
654
734
  insight: input.insight,
655
735
  therefore: input.therefore,
656
736
  pitfall: input.pitfall
657
737
  })
658
- },
659
- glossary: {
660
- toFragment: (input) => glossary(input.entries)
661
- },
662
- role: {
663
- toFragment: (input) => role(input.content)
664
- },
665
- principle: {
666
- toFragment: (input, options) => principle({
738
+ ),
739
+ glossary: builtInEntry(
740
+ z.object({ entries: z.record(z.string(), z.string()) }),
741
+ (input) => glossary(input.entries)
742
+ ),
743
+ role: builtInEntry(
744
+ z.object({ content: z.string() }),
745
+ (input) => role(input.content)
746
+ ),
747
+ principle: builtInEntry(
748
+ z.object({
749
+ title: z.string(),
750
+ description: z.string(),
751
+ policies: nestedPolicies
752
+ }),
753
+ (input, options) => principle({
667
754
  title: input.title,
668
755
  description: input.description,
669
756
  policies: input.policies?.map((item) => toFragmentData(item, options))
670
757
  })
671
- },
672
- policy: {
673
- toFragment: (input, options) => policy({
758
+ ),
759
+ policy: builtInEntry(
760
+ z.object({
761
+ rule: z.string(),
762
+ before: z.string().optional(),
763
+ reason: z.string().optional(),
764
+ policies: nestedPolicies
765
+ }),
766
+ (input, options) => policy({
674
767
  rule: input.rule,
675
768
  before: input.before,
676
769
  reason: input.reason,
677
770
  policies: input.policies?.map((item) => toFragmentData(item, options))
678
771
  })
679
- },
680
- identity: {
681
- toFragment: (input) => identity({
772
+ ),
773
+ identity: builtInEntry(
774
+ z.object({ name: z.string().optional(), role: z.string().optional() }),
775
+ (input) => identity({
682
776
  name: input.name,
683
777
  role: input.role
684
778
  })
685
- },
686
- persona: {
687
- toFragment: (input) => persona({
779
+ ),
780
+ persona: builtInEntry(
781
+ z.object({
782
+ name: z.string(),
783
+ role: z.string().optional(),
784
+ objective: z.string().optional(),
785
+ tone: z.string().optional()
786
+ }),
787
+ (input) => persona({
688
788
  name: input.name,
689
789
  role: input.role,
690
790
  objective: input.objective,
691
791
  tone: input.tone
692
792
  })
693
- },
694
- alias: {
695
- toFragment: (input) => alias(input.term, input.meaning)
696
- },
697
- preference: {
698
- toFragment: (input) => preference(input.aspect, input.value)
699
- },
700
- correction: {
701
- toFragment: (input) => correction(input.subject, input.clarification)
702
- }
793
+ ),
794
+ alias: builtInEntry(
795
+ z.object({ term: z.string(), meaning: z.string() }),
796
+ (input) => alias(input.term, input.meaning)
797
+ ),
798
+ preference: builtInEntry(
799
+ z.object({ aspect: z.string(), value: z.string() }),
800
+ (input) => preference(input.aspect, input.value)
801
+ ),
802
+ correction: builtInEntry(
803
+ z.object({ subject: z.string(), clarification: z.string() }),
804
+ (input) => correction(input.subject, input.clarification)
805
+ )
703
806
  };
807
+ function isBuiltInSerializedType(type) {
808
+ return Object.hasOwn(builtInSerializedRegistry, type);
809
+ }
704
810
  var messageLikeTypes = /* @__PURE__ */ new Set(["user", "assistant", "message"]);
705
811
  function findCustomSerializedFragment(fragment2, options) {
706
812
  if (!options?.registry) {
@@ -720,7 +826,7 @@ function toFragment(input, options) {
720
826
  "Message fragments are not supported by serialized fragment conversion"
721
827
  );
722
828
  }
723
- const entry = options?.registry?.[input.type] ?? builtInSerializedRegistry[input.type];
829
+ const entry = options?.registry?.[input.type] ?? (isBuiltInSerializedType(input.type) ? builtInSerializedRegistry[input.type] : void 0);
724
830
  if (!entry) {
725
831
  throw new Error(`Unsupported serialized fragment type: ${input.type}`);
726
832
  }
@@ -745,7 +851,7 @@ function fromFragment(fragment2, options) {
745
851
  }
746
852
  return encoded;
747
853
  }
748
- if (!builtInSerializedRegistry[fragment2.name]) {
854
+ if (!isBuiltInSerializedType(fragment2.name)) {
749
855
  throw new Error(`Unsupported fragment name: ${fragment2.name}`);
750
856
  }
751
857
  throw new Error(`Fragment "${fragment2.name}" is missing codec`);
@@ -753,6 +859,7 @@ function fromFragment(fragment2, options) {
753
859
 
754
860
  // packages/context/src/lib/estimate.ts
755
861
  import { encode } from "gpt-tokenizer";
862
+ import { z as z2 } from "zod";
756
863
  var defaultTokenizer = {
757
864
  encode(text) {
758
865
  return encode(text);
@@ -761,6 +868,36 @@ var defaultTokenizer = {
761
868
  return encode(text).length;
762
869
  }
763
870
  };
871
+ var modelCostSchema = z2.object({
872
+ input: z2.number(),
873
+ output: z2.number(),
874
+ cache_read: z2.number().optional(),
875
+ cache_write: z2.number().optional(),
876
+ reasoning: z2.number().optional()
877
+ });
878
+ var modelsDevResponseSchema = z2.record(
879
+ z2.string(),
880
+ z2.object({
881
+ models: z2.record(
882
+ z2.string(),
883
+ z2.object({
884
+ id: z2.string(),
885
+ name: z2.string(),
886
+ family: z2.string().optional(),
887
+ cost: modelCostSchema.optional(),
888
+ limit: z2.object({ context: z2.number(), output: z2.number() })
889
+ })
890
+ )
891
+ })
892
+ );
893
+ function inputPricePerMillion(model) {
894
+ if (!model.cost) {
895
+ throw new Error(
896
+ `Model "${model.provider}:${model.id}" has no pricing data on models.dev`
897
+ );
898
+ }
899
+ return model.cost.input;
900
+ }
764
901
  var ModelsRegistry = class {
765
902
  #cache = /* @__PURE__ */ new Map();
766
903
  #loaded = false;
@@ -775,7 +912,7 @@ var ModelsRegistry = class {
775
912
  if (!response.ok) {
776
913
  throw new Error(`Failed to fetch models: ${response.statusText}`);
777
914
  }
778
- const data = await response.json();
915
+ const data = modelsDevResponseSchema.parse(await response.json());
779
916
  for (const [providerId, provider] of Object.entries(data)) {
780
917
  for (const [modelId, model] of Object.entries(provider.models)) {
781
918
  const info = {
@@ -828,14 +965,9 @@ var ModelsRegistry = class {
828
965
  * Get the appropriate tokenizer for a model
829
966
  */
830
967
  getTokenizer(modelId) {
831
- const model = this.get(modelId);
832
- if (model) {
833
- const familyTokenizer = this.#tokenizers.get(model.family);
834
- if (familyTokenizer) {
835
- return familyTokenizer;
836
- }
837
- }
838
- return this.#defaultTokenizer;
968
+ const family = this.get(modelId)?.family;
969
+ const familyTokenizer = family === void 0 ? void 0 : this.#tokenizers.get(family);
970
+ return familyTokenizer ?? this.#defaultTokenizer;
839
971
  }
840
972
  /**
841
973
  * Estimate token count and cost for given text and model
@@ -849,9 +981,10 @@ var ModelsRegistry = class {
849
981
  `Model "${modelId}" not found. Call load() first or check model ID.`
850
982
  );
851
983
  }
984
+ const inputPrice = inputPricePerMillion(model);
852
985
  const tokenizer = this.getTokenizer(modelId);
853
986
  const tokens = tokenizer.count(input);
854
- const cost = tokens / 1e6 * model.cost.input;
987
+ const cost = tokens / 1e6 * inputPrice;
855
988
  return {
856
989
  model: model.id,
857
990
  provider: model.provider,
@@ -866,12 +999,9 @@ var ModelsRegistry = class {
866
999
  };
867
1000
  }
868
1001
  };
869
- var _registry = null;
1002
+ var sharedRegistry = new ModelsRegistry();
870
1003
  function getModelsRegistry() {
871
- if (!_registry) {
872
- _registry = new ModelsRegistry();
873
- }
874
- return _registry;
1004
+ return sharedRegistry;
875
1005
  }
876
1006
  async function estimate(modelId, renderer, ...fragments) {
877
1007
  const registry = getModelsRegistry();
@@ -883,13 +1013,14 @@ async function estimate(modelId, renderer, ...fragments) {
883
1013
  `Model "${modelId}" not found. Call load() first or check model ID.`
884
1014
  );
885
1015
  }
1016
+ const inputPrice = inputPricePerMillion(model);
886
1017
  const tokenizer = registry.getTokenizer(modelId);
887
1018
  const totalTokens = tokenizer.count(input);
888
- const totalCost = totalTokens / 1e6 * model.cost.input;
1019
+ const totalCost = totalTokens / 1e6 * inputPrice;
889
1020
  const fragmentEstimates = fragments.map((fragment2) => {
890
1021
  const rendered = renderer.render([fragment2]);
891
1022
  const tokens = tokenizer.count(rendered);
892
- const cost = tokens / 1e6 * model.cost.input;
1023
+ const cost = tokens / 1e6 * inputPrice;
893
1024
  return {
894
1025
  id: fragment2.id,
895
1026
  name: fragment2.name,
@@ -2427,8 +2558,10 @@ export {
2427
2558
  guardrail,
2428
2559
  hint,
2429
2560
  identity,
2561
+ inputPricePerMillion,
2430
2562
  isConditionalReminder,
2431
2563
  isFragment,
2564
+ isFragmentData,
2432
2565
  isFragmentObject,
2433
2566
  isMessageFragment,
2434
2567
  isRecord,