This repository was archived by the owner on Apr 26, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompletions.py
More file actions
87 lines (68 loc) · 2.82 KB
/
completions.py
File metadata and controls
87 lines (68 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""Chat completions API bot implementation"""
from collections.abc import Sequence
from pathlib import PurePosixPath
from typing import Any, cast
import openai
from ...instructions import SYSTEM_PROMPT
from ..common import ActionSummary, Bot, Goal, UserFeedback, Worktree
from .common import ToolHandler, ToolsFactory, new_client
def new_completions_bot(
api_key: str | None = None,
base_url: str | None = None,
model: str = "gpt-4o",
) -> Bot:
"""Compatibility-mode bot, uses completions with function calling"""
return _CompletionsBot(new_client(api_key, base_url), model)
class _CompletionsBot(Bot):
def __init__(self, client: openai.OpenAI, model: str) -> None:
self._client = client
self._model = model
async def act(
self, goal: Goal, tree: Worktree, feedback: UserFeedback
) -> ActionSummary:
tools = ToolsFactory(strict=False).params()
tool_handler = _CompletionsToolHandler(tree, feedback)
messages: list[openai.types.chat.ChatCompletionMessageParam] = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": goal.prompt},
]
request_count = 0
while True:
response = self._client.chat.completions.create(
model=self._model,
messages=messages,
tools=tools,
tool_choice="required",
)
assert len(response.choices) == 1
choice = response.choices[0]
request_count += 1
done = True
messages.append(cast(Any, choice.message.to_dict(mode="json")))
calls = choice.message.tool_calls
for call in calls or []:
output = tool_handler.handle_function(call.function)
if output is not None:
done = False
messages.append({"role": "user", "content": output})
if done:
break
return ActionSummary(request_count=request_count)
class _CompletionsToolHandler(ToolHandler[str | None]):
def _on_ask_user(self, response: str) -> str:
return response
def _on_read_file(self, path: PurePosixPath, contents: str | None) -> str:
if contents is None:
return f"`{path}` does not exist."
return f"The contents of `{path}` are:\n\n```\n{contents}\n```\n"
def _on_write_file(self, _path: PurePosixPath) -> None:
return None
def _on_delete_file(self, _path: PurePosixPath) -> None:
return None
def _on_rename_file(
self, _src_path: PurePosixPath, _dst_path: PurePosixPath
) -> None:
return None
def _on_list_files(self, paths: Sequence[PurePosixPath]) -> str:
joined = "\n".join(f"* {p}" for p in paths)
return f"Here are the available files: {joined}"