agent.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from json import JSONDecodeError
  2. from jinja2 import BaseLoader, Environment
  3. from opendevin.controller.agent import Agent
  4. from opendevin.controller.state.state import State
  5. from opendevin.core.exceptions import LLMOutputError
  6. from opendevin.core.utils import json
  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 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 to_json(obj, **kwargs):
  33. """
  34. Serialize an object to str format
  35. """
  36. return json.dumps(obj, **kwargs)
  37. class MicroAgent(Agent):
  38. prompt = ''
  39. agent_definition: dict = {}
  40. def __init__(self, llm: LLM):
  41. super().__init__(llm)
  42. if 'name' not in self.agent_definition:
  43. raise ValueError('Agent definition must contain a name')
  44. self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
  45. self.delegates = all_microagents.copy()
  46. del self.delegates[self.agent_definition['name']]
  47. def step(self, state: State) -> Action:
  48. prompt = self.prompt_template.render(
  49. state=state,
  50. instructions=instructions,
  51. to_json=to_json,
  52. delegates=self.delegates,
  53. )
  54. messages = [{'content': prompt, 'role': 'user'}]
  55. resp = self.llm.completion(messages=messages)
  56. action_resp = resp['choices'][0]['message']['content']
  57. state.num_of_chars += len(prompt) + len(action_resp)
  58. action = parse_response(action_resp)
  59. return action
  60. def search_memory(self, query: str) -> list[str]:
  61. return []