agent.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import json
  2. from typing import Dict, List
  3. from jinja2 import BaseLoader, Environment
  4. from opendevin.controller.agent import Agent
  5. from opendevin.controller.state.state import State
  6. from opendevin.core.exceptions import LLMOutputError
  7. from opendevin.events.action import Action, action_from_dict
  8. from opendevin.llm.llm import LLM
  9. from .instructions import instructions
  10. from .registry import all_microagents
  11. def parse_response(orig_response: str) -> Action:
  12. depth = 0
  13. start = -1
  14. for i, char in enumerate(orig_response):
  15. if char == '{':
  16. if depth == 0:
  17. start = i
  18. depth += 1
  19. elif char == '}':
  20. depth -= 1
  21. if depth == 0 and start != -1:
  22. response = orig_response[start : i + 1]
  23. try:
  24. action_dict = json.loads(response)
  25. action = action_from_dict(action_dict)
  26. return action
  27. except json.JSONDecodeError as e:
  28. raise LLMOutputError(
  29. 'Invalid JSON in response. Please make sure the response is a valid JSON object.'
  30. ) from e
  31. raise LLMOutputError('No valid JSON object found in response.')
  32. def my_encoder(obj):
  33. """
  34. Encodes objects as dictionaries
  35. Parameters:
  36. - obj (Object): An object that will be converted
  37. Returns:
  38. - dict: If the object can be converted it is returned in dict format
  39. """
  40. if hasattr(obj, 'to_dict'):
  41. return obj.to_dict()
  42. def to_json(obj, **kwargs):
  43. """
  44. Serialize an object to str format
  45. """
  46. return json.dumps(obj, default=my_encoder, **kwargs)
  47. class MicroAgent(Agent):
  48. prompt = ''
  49. agent_definition: Dict = {}
  50. def __init__(self, llm: LLM):
  51. super().__init__(llm)
  52. if 'name' not in self.agent_definition:
  53. raise ValueError('Agent definition must contain a name')
  54. self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
  55. self.delegates = all_microagents.copy()
  56. del self.delegates[self.agent_definition['name']]
  57. def step(self, state: State) -> Action:
  58. prompt = self.prompt_template.render(
  59. state=state,
  60. instructions=instructions,
  61. to_json=to_json,
  62. delegates=self.delegates,
  63. )
  64. messages = [{'content': prompt, 'role': 'user'}]
  65. resp = self.llm.completion(messages=messages)
  66. action_resp = resp['choices'][0]['message']['content']
  67. state.num_of_chars += len(prompt) + len(action_resp)
  68. action = parse_response(action_resp)
  69. return action
  70. def search_memory(self, query: str) -> List[str]:
  71. return []