agent.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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.config import config
  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. """
  20. Serialize an object to str format
  21. """
  22. return json.dumps(obj, **kwargs)
  23. def history_to_json(history: ShortTermHistory, max_events=20, **kwargs):
  24. """
  25. Serialize and simplify history to str format
  26. """
  27. # TODO: get agent specific llm config
  28. llm_config = config.get_llm_config()
  29. max_message_chars = llm_config.max_message_chars
  30. processed_history = []
  31. event_count = 0
  32. for event in history.get_events(reverse=True):
  33. if event_count >= max_events:
  34. break
  35. processed_history.append(event_to_memory(event, max_message_chars))
  36. event_count += 1
  37. # history is in reverse order, let's fix it
  38. processed_history.reverse()
  39. return json.dumps(processed_history, **kwargs)
  40. class MicroAgent(Agent):
  41. VERSION = '1.0'
  42. prompt = ''
  43. agent_definition: dict = {}
  44. def __init__(self, llm: LLM):
  45. super().__init__(llm)
  46. if 'name' not in self.agent_definition:
  47. raise ValueError('Agent definition must contain a name')
  48. self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
  49. self.delegates = all_microagents.copy()
  50. del self.delegates[self.agent_definition['name']]
  51. def step(self, state: State) -> Action:
  52. prompt = self.prompt_template.render(
  53. state=state,
  54. instructions=instructions,
  55. to_json=to_json,
  56. history_to_json=history_to_json,
  57. delegates=self.delegates,
  58. latest_user_message=state.get_current_user_intent(),
  59. )
  60. messages = [{'content': prompt, 'role': 'user'}]
  61. resp = self.llm.completion(messages=messages)
  62. action_resp = resp['choices'][0]['message']['content']
  63. action = parse_response(action_resp)
  64. return action