@deepagents/agent 7.0.1 → 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.
package/README.md CHANGED
@@ -83,9 +83,7 @@ const researcher = agent({
83
83
  model: openai('gpt-4o'),
84
84
  prompt: 'You research topics and provide detailed information.',
85
85
  handoffDescription: 'Handles research and fact-finding tasks',
86
- tools: {
87
- /* research tools */
88
- },
86
+ tools: {/* research tools */},
89
87
  });
90
88
 
91
89
  const writer = agent({
@@ -142,25 +140,29 @@ console.log(result.output);
142
140
  Share state between agents and tools:
143
141
 
144
142
  ```typescript
145
- import { tool } from 'ai';
143
+ import { type ToolExecutionOptions, tool } from 'ai';
146
144
  import { z } from 'zod';
147
145
 
148
- import { agent, execute, toState } from '@deepagents/agent';
146
+ import { agent, execute } from '@deepagents/agent';
149
147
 
150
- interface AppContext {
148
+ // A `type`, not an `interface`: the AI SDK requires a tool context to
149
+ // extend Record<string, unknown>, which an interface does not.
150
+ type AppContext = {
151
151
  userId: string;
152
152
  preferences: Record<string, string>;
153
- }
153
+ };
154
154
 
155
155
  const preferenceTool = tool({
156
156
  description: 'Save user preference',
157
- parameters: z.object({
157
+ inputSchema: z.object({
158
158
  key: z.string(),
159
159
  value: z.string(),
160
160
  }),
161
- execute: async ({ key, value }, options) => {
162
- const ctx = toState<AppContext>(options);
163
- ctx.preferences[key] = value;
161
+ execute: async (
162
+ { key, value },
163
+ { context }: ToolExecutionOptions<AppContext>,
164
+ ) => {
165
+ context.preferences[key] = value;
164
166
  return `Saved ${key}=${value}`;
165
167
  },
166
168
  });
@@ -233,9 +235,6 @@ swarm(agent, messages, context, abortSignal?)
233
235
  // Create user message
234
236
  user(message: string): UIMessage
235
237
 
236
- // Access context in tools
237
- toState<T>(options: ToolCallOptions): T
238
-
239
238
  // Extract structured output
240
239
  toOutput<T>(result): Promise<T>
241
240
  ```
package/dist/index.js CHANGED
@@ -441,9 +441,6 @@ async function finished(iterable) {
441
441
  function toOutput(result) {
442
442
  return isPromise(result) ? result.then((res) => res.output) : last(result.partialOutputStream);
443
443
  }
444
- function toState(options) {
445
- return options.context;
446
- }
447
444
  function toToolsContext(tools, context) {
448
445
  return Object.fromEntries(
449
446
  Object.keys(tools).map((toolName) => [toolName, context])
@@ -463,7 +460,6 @@ import {
463
460
  toUIMessageStream
464
461
  } from "ai";
465
462
  import chalk2 from "chalk";
466
- import dedent2 from "dedent";
467
463
  async function generate(agent2, messages, contextVariables, config) {
468
464
  const tools = agent2.toToolset();
469
465
  return generateText2({
@@ -552,7 +548,14 @@ var prepareStep = (agent2, model, contextVariables) => {
552
548
  console.error(`Debug: ${chalk2.red("NotFound")}: Agent ${agentName}`);
553
549
  console.dir(
554
550
  {
555
- steps: steps.map(({ request, response, ...etc }) => etc),
551
+ // Each step without its raw request and response.
552
+ steps: steps.map(
553
+ (step2) => Object.fromEntries(
554
+ Object.entries(step2).filter(
555
+ ([key]) => key !== "request" && key !== "response"
556
+ )
557
+ )
558
+ ),
556
559
  messages
557
560
  },
558
561
  { depth: null }
@@ -588,14 +591,13 @@ function swarm(agent2, messages, contextVariables, abortSignal) {
588
591
  await last(stream2.stream);
589
592
  if (!agent2.prepareEnd) return;
590
593
  while (true) {
591
- const state = contextVariables;
592
- if (state.currentActiveAgent === void 0) {
594
+ if (contextVariables.currentActiveAgent === void 0) {
593
595
  console.warn(
594
596
  `swarm: active agent was never set, so no prepareEnd call will be made`
595
597
  );
596
598
  return;
597
599
  }
598
- if (state.currentActiveAgent === agent2.internalName) {
600
+ if (contextVariables.currentActiveAgent === agent2.internalName) {
599
601
  console.warn(
600
602
  `swarm: active agent is the root agent, so no prepareEnd call will be made`
601
603
  );
@@ -637,7 +639,6 @@ async function prepareAgent(defaultModel, agent2, messages, contextVariables) {
637
639
  activeTools: agent2.toolsNames,
638
640
  model: stepModel,
639
641
  messages,
640
- // messages: removeTransferCalls(messages),
641
642
  toolChoice: agent2.toolChoice
642
643
  };
643
644
  }
@@ -648,25 +649,57 @@ function findAgent(agent2, agentName) {
648
649
  }
649
650
 
650
651
  // packages/agent/src/lib/tool-output.ts
652
+ import { isJSONValue } from "@ai-sdk/provider";
651
653
  function withHostOnlyToolMetadata(tools) {
652
654
  const wrapped = {};
653
655
  for (const [name, tool2] of Object.entries(tools)) {
654
- wrapped[name] = tool2.toModelOutput !== void 0 ? tool2 : Object.defineProperties(
656
+ if (tool2.toModelOutput !== void 0) {
657
+ wrapped[name] = tool2;
658
+ continue;
659
+ }
660
+ const descriptors = Object.getOwnPropertyDescriptors(tool2);
661
+ Reflect.deleteProperty(descriptors, "toModelOutput");
662
+ wrapped[name] = Object.defineProperties(
655
663
  {
656
664
  ...tool2,
657
665
  toModelOutput: ({ output }) => defaultToolModelOutput(output)
658
666
  },
659
- Object.getOwnPropertyDescriptors(tool2)
667
+ descriptors
668
+ );
669
+ }
670
+ if (!projectsEveryTool(tools, wrapped)) {
671
+ throw new Error(
672
+ "withHostOnlyToolMetadata left a tool without a projection"
660
673
  );
661
674
  }
662
675
  return wrapped;
663
676
  }
677
+ function projectsEveryTool(tools, wrapped) {
678
+ return Object.keys(tools).every(
679
+ (name) => Object.hasOwn(wrapped, name) && wrapped[name].toModelOutput !== void 0
680
+ );
681
+ }
664
682
  function defaultToolModelOutput(output) {
665
- if (typeof output === "object" && output !== null && !Array.isArray(output) && Object.hasOwn(output, "meta")) {
666
- const { meta: _meta, ...visible } = output;
667
- return { type: "json", value: visible };
683
+ return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(withoutMeta(output)) };
684
+ }
685
+ function withoutMeta(output) {
686
+ if (typeof output !== "object" || output === null || Array.isArray(output) || !Object.hasOwn(output, "meta")) {
687
+ return output;
668
688
  }
669
- return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: output ?? null };
689
+ const visible = { ...output };
690
+ Reflect.deleteProperty(visible, "meta");
691
+ return visible;
692
+ }
693
+ function toJSONValue(value) {
694
+ if (isJSONValue(value)) {
695
+ return value;
696
+ }
697
+ const serialized = JSON.stringify(value);
698
+ if (serialized === void 0) {
699
+ return null;
700
+ }
701
+ const parsed = JSON.parse(serialized);
702
+ return isJSONValue(parsed) ? parsed : null;
670
703
  }
671
704
 
672
705
  // packages/agent/src/lib/agent.ts
@@ -717,9 +750,8 @@ var Agent = class _Agent {
717
750
  properties: {},
718
751
  additionalProperties: true
719
752
  }),
720
- execute: async (_, options) => {
721
- const state = toState(options);
722
- state.currentActiveAgent = this.internalName;
753
+ execute: async (_, { context }) => {
754
+ context.currentActiveAgent = this.internalName;
723
755
  return `Transfer successful to ${this.internalName}.`;
724
756
  }
725
757
  })
@@ -783,9 +815,12 @@ var Agent = class _Agent {
783
815
  "Optional instructions on how the final output should be formatted. this would be passed to the underlying llm as part of the prompt."
784
816
  )
785
817
  }),
786
- execute: async ({ input: input2, output }, options) => {
818
+ execute: async ({ input: input2, output }, {
819
+ context: contextVariables,
820
+ abortSignal
821
+ }) => {
787
822
  try {
788
- const contextVariables = options.context;
823
+ const tools = this.handoff.tools;
789
824
  const result = await generateText3({
790
825
  model: this.model,
791
826
  instructions: this.#prepareInstructions(),
@@ -798,17 +833,12 @@ ${output}
798
833
  </OutputInstructions>` : ""}
799
834
  `,
800
835
  temperature: 0,
801
- tools: this.handoff.tools,
802
- abortSignal: options.abortSignal,
836
+ tools,
837
+ abortSignal,
803
838
  stopWhen: isStepCount2(25),
804
- repairToolCall: this.repairToolCall(options.abortSignal),
839
+ repairToolCall: this.repairToolCall(abortSignal),
805
840
  runtimeContext: contextVariables,
806
- toolsContext: Object.fromEntries(
807
- Object.keys(this.handoff.tools).map((toolName) => [
808
- toolName,
809
- contextVariables
810
- ])
811
- ),
841
+ toolsContext: toToolsContext(tools, contextVariables),
812
842
  output: this.output ? Output3.object({ schema: this.output }) : void 0,
813
843
  onToolExecutionStart: ({ toolCall }) => {
814
844
  if (this.logging) {
@@ -872,9 +902,7 @@ ${details}
872
902
  }
873
903
  clone(agent2) {
874
904
  return new _Agent({
875
- prepareHandoff: (messages) => {
876
- this.prepareHandoff?.(messages);
877
- },
905
+ prepareHandoff: (messages) => this.prepareHandoff?.(messages),
878
906
  model: agent2?.model ?? this.model,
879
907
  toolChoice: agent2?.toolChoice ?? this.toolChoice,
880
908
  prompt: agent2?.prompt ?? this.handoff.instructions,
@@ -991,34 +1019,6 @@ instructions.supervisor_subagent = ({
991
1019
  }
992
1020
  return lines.join("\n");
993
1021
  };
994
- function isTransferToolResult(call) {
995
- if (!call) {
996
- return false;
997
- }
998
- if (typeof call !== "object") {
999
- return false;
1000
- }
1001
- if (!("output" in call)) {
1002
- return false;
1003
- }
1004
- const lastActiveAgent = call.output.lastActiveAgent;
1005
- if (!lastActiveAgent) {
1006
- return false;
1007
- }
1008
- return true;
1009
- }
1010
- function lastTransferResult(messages) {
1011
- for (let i = messages.length - 1; i >= 0; i--) {
1012
- const message = messages[i];
1013
- for (let i2 = message.parts.length - 1; i2 >= 0; i2--) {
1014
- const part = message.parts[i2];
1015
- if (part.type === "dynamic-tool" && part.toolName.startsWith("transfer_to_") && part.state === "output-available" && isTransferToolResult(part)) {
1016
- return part.output;
1017
- }
1018
- }
1019
- }
1020
- return void 0;
1021
- }
1022
1022
 
1023
1023
  // packages/agent/src/lib/models.ts
1024
1024
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
@@ -1114,10 +1114,7 @@ function pipe(state, ...processes) {
1114
1114
  await result.consumeStream();
1115
1115
  } else {
1116
1116
  const output = await it(state, (newState) => {
1117
- Object.assign(
1118
- state,
1119
- newState
1120
- );
1117
+ Object.assign(state, newState);
1121
1118
  });
1122
1119
  if (typeof output === "string") {
1123
1120
  writer.write({
@@ -1161,9 +1158,7 @@ export {
1161
1158
  glm,
1162
1159
  input,
1163
1160
  instructions,
1164
- isTransferToolResult,
1165
1161
  last,
1166
- lastTransferResult,
1167
1162
  lmstudio,
1168
1163
  messageToUiMessage,
1169
1164
  minimax,
@@ -1179,7 +1174,6 @@ export {
1179
1174
  swarm,
1180
1175
  thirdPersonPrompt,
1181
1176
  toOutput,
1182
- toState,
1183
1177
  toToolsContext,
1184
1178
  user,
1185
1179
  withHostOnlyToolMetadata