agent.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from jinja2 import BaseLoader, Environment
  2. from opendevin.controller.agent import Agent
  3. from opendevin.controller.state.state import State
  4. from opendevin.core.message import ImageContent, Message, TextContent
  5. from opendevin.core.utils import json
  6. from opendevin.events.action import Action
  7. from opendevin.events.serialization.action import action_from_dict
  8. from opendevin.events.serialization.event import event_to_memory
  9. from opendevin.llm.llm import LLM
  10. from opendevin.memory.history import ShortTermHistory
  11. from .instructions import instructions
  12. from .registry import all_microagents
  13. def parse_response(orig_response: str) -> Action:
  14. # attempt to load the JSON dict from the response
  15. action_dict = json.loads(orig_response)
  16. # load the action from the dict
  17. return action_from_dict(action_dict)
  18. def to_json(obj, **kwargs):
  19. """Serialize an object to str format"""
  20. return json.dumps(obj, **kwargs)
  21. class MicroAgent(Agent):
  22. VERSION = '1.0'
  23. prompt = ''
  24. agent_definition: dict = {}
  25. def history_to_json(
  26. self, history: ShortTermHistory, max_events: int = 20, **kwargs
  27. ):
  28. """
  29. Serialize and simplify history to str format
  30. """
  31. processed_history = []
  32. event_count = 0
  33. for event in history.get_events(reverse=True):
  34. if event_count >= max_events:
  35. break
  36. processed_history.append(
  37. event_to_memory(event, self.llm.config.max_message_chars)
  38. )
  39. event_count += 1
  40. # history is in reverse order, let's fix it
  41. processed_history.reverse()
  42. return json.dumps(processed_history, **kwargs)
  43. def __init__(self, llm: LLM):
  44. super().__init__(llm)
  45. if 'name' not in self.agent_definition:
  46. raise ValueError('Agent definition must contain a name')
  47. self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
  48. self.delegates = all_microagents.copy()
  49. del self.delegates[self.agent_definition['name']]
  50. def step(self, state: State) -> Action:
  51. last_user_message, last_image_urls = state.get_current_user_intent()
  52. prompt = self.prompt_template.render(
  53. state=state,
  54. instructions=instructions,
  55. to_json=to_json,
  56. history_to_json=self.history_to_json,
  57. delegates=self.delegates,
  58. latest_user_message=last_user_message,
  59. )
  60. content = [TextContent(text=prompt)]
  61. if last_image_urls:
  62. content.append(ImageContent(image_urls=last_image_urls))
  63. message = Message(role='user', content=content)
  64. resp = self.llm.completion(messages=[message.model_dump()])
  65. action_resp = resp['choices'][0]['message']['content']
  66. action = parse_response(action_resp)
  67. return action