Skip to content

Commit

Permalink
fix: update for GuiAgentInterpreterChatResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu007 committed May 6, 2024
1 parent ac982e8 commit 0417b36
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 67 deletions.
168 changes: 108 additions & 60 deletions server.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,112 @@
from codeinterpreterapi import CodeInterpreterSession

model = "claude-3-haiku-20240307"
model = "gemini-1.5-pro-latest"
session = CodeInterpreterSession(model=model)

try:
message = """SVG画像を自動生成するプログラムの要件を以下のように定義します。
目的:
電子書籍のヘッダ画像を自動生成すること
別のコンテンツ生成プログラムが出力したSVGファイルを入力として受け取ること
入力SVGファイルを指定の要件に従って加工し、新たなSVGファイルとして出力すること
機能要件:
グリッドレイアウト機能の実装
指定したグリッドサイズ(行数、列数)に基づいて要素を配置できるようにする
グリッドの各セルに対して要素を割り当てられるようにする
グリッドのサイズや間隔を柔軟に設定できるようにする
SVG要素の配置と編集
import traceback

グリッド上の指定した位置にSVG要素(テキスト、図形、画像など)を配置できるようにする
配置する要素の属性(サイズ、色、フォントなど)を柔軟に設定できるようにする
既存のSVG要素を削除、移動、変更できるようにする
外部画像ファイルの読み込みと配置
from gui_agent_loop_core.gui_agent_loop_core import GuiAgentLoopCore
from gui_agent_loop_core.schema.schema import (
GuiAgentInterpreterBase,
GuiAgentInterpreterChatMessage,
GuiAgentInterpreterChatMessages,
GuiAgentInterpreterChatResponse,
GuiAgentInterpreterChatResponseAny,
)

PNGやJPEGなどの外部画像ファイルを読み込んでSVGファイルに埋め込めるようにする
読み込んだ画像をグリッド上の指定した位置に配置できるようにする
画像のサイズを変更できるようにする
SVGファイルの入出力
SVGファイルを入力として読み込み、加工後のSVGファイルを出力できるようにする
出力ファイルのファイル名やパスを指定できるようにする
非機能要件:
Python3とsvgwriteライブラリを使用して実装すること
コードはモジュール化し、再利用性と保守性を高めること
エラーハンドリングを適切に行い、ログ出力を行うこと
コードにはコメントを付けて可読性を高めること
実装の進め方:
svgwriteを使ったSVGファイルの基本的な読み込み、編集、出力の機能を実装する
グリッドレイアウト機能を実装し、要素を配置できるようにする
外部画像ファイルの読み込みと配置機能を実装する
入力SVGファイルを読み込んで、指定の要件に従って加工し、新たなSVGファイルを出力する一連の処理を実装する
細かい仕様について検討し、機能を拡張する
テストを行い、不具合を修正する
ドキュメントを整備し、コードをリファクタリングする
まずはこの要件定義に基づいて、各機能の実装に着手してください。実装方法や詳細な手順は、要件に合わせて適宜ご判断ください。
作業フォルダは/app/workを使ってください。
from codeinterpreterapi import CodeInterpreterSession

全ての処理は自動で実施して結果とプログラムだけ報告してください。

"""
status = session.start_local()
result = session.generate_response(message)
result.show()
except Exception as e:
print(e)
class CodeInterpreter(GuiAgentInterpreterBase):
def __init__(self):
model = "claude-3-haiku-20240307"
model = "gemini-1.5-pro-latest"
self.session = CodeInterpreterSession(model=model)
self.status = self.session.start_local()

def chat(
self,
message: GuiAgentInterpreterChatMessages,
display: bool = False,
stream: bool = False,
blocking: bool = False,
) -> GuiAgentInterpreterChatResponseAny:
try:
message = """SVG画像を自動生成するプログラムの要件を以下のように定義します。
目的:
電子書籍のヘッダ画像を自動生成すること
別のコンテンツ生成プログラムが出力したSVGファイルを入力として受け取ること
入力SVGファイルを指定の要件に従って加工し、新たなSVGファイルとして出力すること
機能要件:
グリッドレイアウト機能の実装
指定したグリッドサイズ(行数、列数)に基づいて要素を配置できるようにする
グリッドの各セルに対して要素を割り当てられるようにする
グリッドのサイズや間隔を柔軟に設定できるようにする
SVG要素の配置と編集
グリッド上の指定した位置にSVG要素(テキスト、図形、画像など)を配置できるようにする
配置する要素の属性(サイズ、色、フォントなど)を柔軟に設定できるようにする
既存のSVG要素を削除、移動、変更できるようにする
外部画像ファイルの読み込みと配置
PNGやJPEGなどの外部画像ファイルを読み込んでSVGファイルに埋め込めるようにする
読み込んだ画像をグリッド上の指定した位置に配置できるようにする
画像のサイズを変更できるようにする
SVGファイルの入出力
SVGファイルを入力として読み込み、加工後のSVGファイルを出力できるようにする
出力ファイルのファイル名やパスを指定できるようにする
非機能要件:
Python3とsvgwriteライブラリを使用して実装すること
コードはモジュール化し、再利用性と保守性を高めること
エラーハンドリングを適切に行い、ログ出力を行うこと
コードにはコメントを付けて可読性を高めること
実装の進め方:
svgwriteを使ったSVGファイルの基本的な読み込み、編集、出力の機能を実装する
グリッドレイアウト機能を実装し、要素を配置できるようにする
外部画像ファイルの読み込みと配置機能を実装する
入力SVGファイルを読み込んで、指定の要件に従って加工し、新たなSVGファイルを出力する一連の処理を実装する
細かい仕様について検討し、機能を拡張する
テストを行い、不具合を修正する
ドキュメントを整備し、コードをリファクタリングする
まずはこの要件定義に基づいて、各機能の実装に着手してください。実装方法や詳細な手順は、要件に合わせて適宜ご判断ください。
作業フォルダは/app/workを使ってください。
全ての処理は自動で実施して結果とプログラムだけ報告してください。
"""

is_stream = False
if is_stream:
# ChainExecutorのエラーが出て動かない
"""
process_messages_gradio response_chunks= <async_generator object process_and_format_message at 0x7f9f2652bec0>
llm stream start
server chat chunk_response= type=<Type.MESSAGE: 'message'> role=<Role.USER: 'user'> content="Error in CodeInterpreterSession: AttributeError - 'ChainExecutor' object has no attribute 'stream'" format='' code='' start=False end=False
process_messages_gradio response= type=<Type.MESSAGE: 'message'> role=<Role.USER: 'user'> content="Error in CodeInterpreterSession: AttributeError - 'ChainExecutor' object has no attribute 'stream'" format='' code='' start=False end=False
memory.save_context full_response= Error in CodeInterpr
"""
for chunk_str in self.session.generate_response_stream(message):
chunk_response = GuiAgentInterpreterChatResponse()
chunk_response.content = chunk_str
print("server chat chunk_response=", chunk_response)
yield chunk_response
else:
response = self.session.generate_response(message)
print("server chat response(no stream)=", response)
yield response

except Exception as e:
print(e)
traceback.print_exc()
error_response = {"role": GuiAgentInterpreterChatMessage.Role.ASSISTANT, "content": str(e)}
yield error_response


interpreter = CodeInterpreter()
core = GuiAgentLoopCore()
core.launch_server(interpreter)
109 changes: 102 additions & 7 deletions src/codeinterpreterapi/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@

from codeboxapi import CodeBox # type: ignore
from codeboxapi.schema import CodeBoxOutput # type: ignore
from gui_agent_loop_core.schema.schema import (
GuiAgentInterpreterChatMessage,
GuiAgentInterpreterChatMessageList,
GuiAgentInterpreterChatResponse,
GuiAgentInterpreterChatResponseGenerator,
GuiAgentInterpreterChatResponseStr,
GuiAgentInterpreterManagerBase,
InterpreterState,
)
from langchain.agents import AgentExecutor
from langchain.callbacks.base import Callbacks
from langchain_community.chat_message_histories.in_memory import ChatMessageHistory
Expand Down Expand Up @@ -391,22 +400,33 @@ def generate_response(
# response = self.agent_executor.invoke(input=user_request.content)
response = self.supervisor.invoke(input=user_request.content)
# ======= ↑↑↑↑ LLM invoke ↑↑↑↑ #=======
print("response(type)=", type(response))
print("response=", response)

output = response["output"]
print("agent_executor.invoke output=", output)
return self._output_handler(output)
print("generate_response agent_executor.invoke output=", output)
inner_response = self._output_handler(output)
final_response = GuiAgentInterpreterChatResponse()
final_response.content = str(inner_response)
return final_response
except Exception as e:
if self.verbose:
traceback.print_exc()
if settings.DETAILED_ERROR:
return CodeInterpreterResponse(
content="Error in CodeInterpreterSession: " f"{e.__class__.__name__} - {e}"
inner_response = CodeInterpreterResponse(
content="Error in CodeInterpreterSession(generate_response): " f"{e.__class__.__name__} - {e}"
)
final_response = GuiAgentInterpreterChatResponse()
final_response.content = str(inner_response)
return final_response
else:
return CodeInterpreterResponse(
inner_response = CodeInterpreterResponse(
content="Sorry, something went while generating your response."
"Please try again or restart the session."
)
final_response = GuiAgentInterpreterChatResponse()
final_response.content = str(inner_response)
return final_response

async def agenerate_response(
self,
Expand All @@ -424,21 +444,96 @@ async def agenerate_response(
# ======= ↑↑↑↑ LLM invoke ↑↑↑↑ #=======

output = response["output"]
print("agent_executor.invoke output=", output)
print("agenerate_response agent_executor.ainvoke output=", output)
return await self._aoutput_handler(output)
except Exception as e:
if self.verbose:
traceback.print_exc()
if settings.DETAILED_ERROR:
return CodeInterpreterResponse(
content="Error in CodeInterpreterSession: " f"{e.__class__.__name__} - {e}"
content="Error in CodeInterpreterSession(agenerate_response): " f"{e.__class__.__name__} - {e}"
)
else:
return CodeInterpreterResponse(
content="Sorry, something went while generating your response."
"Please try again or restart the session."
)

def generate_response_stream(
self,
user_msg: str,
files: list[File] = None,
) -> GuiAgentInterpreterChatResponseStr:
"""Generate a Code Interpreter response based on the user's input."""
if files is None:
files = []
user_request = UserRequest(content=user_msg, files=files)
try:
self._input_handler(user_request)
assert self.agent_executor, "Session not initialized."
print("llm stream start")
# ======= ↓↓↓↓ LLM invoke ↓↓↓↓ #=======
response = self.agent_executor.stream(input=user_request.content)
# ======= ↑↑↑↑ LLM invoke ↑↑↑↑ #=======
print("llm stream response(type)=", type(response))
print("llm stream response=", response)

full_output = ""
for chunk in response:
yield chunk
full_output += chunk["output"]

print("generate_response_stream agent_executor.stream full_output=", full_output)
self._aoutput_handler(full_output)
except Exception as e:
if self.verbose:
traceback.print_exc()
if settings.DETAILED_ERROR:
yield "Error in CodeInterpreterSession(generate_response_stream): " f"{e.__class__.__name__} - {e}"
else:
yield "Sorry, something went while generating your response." + "Please try again or restart the session."

async def agenerate_response_stream(
self,
user_msg: str,
files: list[File] = None,
) -> CodeInterpreterResponse:
"""Generate a Code Interpreter response based on the user's input."""
if files is None:
files = []
user_request = UserRequest(content=user_msg, files=files)
try:
await self._ainput_handler(user_request)
assert self.agent_executor, "Session not initialized."

print("llm astream start")
# ======= ↓↓↓↓ LLM invoke ↓↓↓↓ #=======
response = self.agent_executor.astream(input=user_request.content)
# ======= ↑↑↑↑ LLM invoke ↑↑↑↑ #=======
print("llm astream response(type)=", type(response))
print("llm astream response=", response)

full_output = ""
async for chunk in response:
yield chunk
full_output += chunk["output"]

print("agent_executor.astream full_output=", full_output)
await self._aoutput_handler(full_output)
except Exception as e:
if self.verbose:
traceback.print_exc()
if settings.DETAILED_ERROR:
yield CodeInterpreterResponse(
content="Error in CodeInterpreterSession(agenerate_response_stream): "
f"{e.__class__.__name__} - {e}"
)
else:
yield CodeInterpreterResponse(
content="Sorry, something went while generating your response."
"Please try again or restart the session."
)

def is_running(self) -> bool:
return self.codebox.status() == "running"

Expand Down

0 comments on commit 0417b36

Please sign in to comment.