Skip to content

Commit 187a044

Browse files
committed
chore: fix context too long issues
1 parent 5473067 commit 187a044

File tree

13 files changed

+1149
-1016
lines changed

13 files changed

+1149
-1016
lines changed

kube_copilot/chains.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# -*- coding: utf-8 -*-
22
import os
3-
from langchain.chat_models import ChatOpenAI
3+
from langchain.chat_models import ChatOpenAI, AzureChatOpenAI
44
from langchain.agents import AgentType, Tool, initialize_agent
55
from langchain.agents.agent import AgentExecutor
66
from langchain.callbacks import HumanApprovalCallbackHandler
77
from langchain.agents.structured_chat.base import StructuredChatAgent
88
from langchain.utilities import GoogleSearchAPIWrapper
99
from langchain_experimental.plan_and_execute import PlanAndExecute, load_chat_planner
1010
from langchain_experimental.plan_and_execute.executors.base import ChainExecutor
11-
from langchain_experimental.tools import PythonREPLTool
1211
from langchain.agents.structured_chat.base import StructuredChatAgent
1312
from langchain.callbacks import StdOutCallbackHandler
1413
from langchain.memory import ConversationBufferMemory
1514
from langchain.agents import OpenAIMultiFunctionsAgent
1615
from langchain.schema.messages import SystemMessage
1716
from langchain.prompts import MessagesPlaceholder
1817
from langchain.agents import AgentExecutor
18+
from kube_copilot.python import PythonTool
1919
from kube_copilot.shell import KubeProcess
2020
from kube_copilot.prompts import get_planner_prompt, _base_prompt
2121
from kube_copilot.output import ChatOutputParser
@@ -143,15 +143,21 @@ def get_chain(self, verbose=True, model="gpt-4", additional_tools=None, enable_p
143143
def get_llm_tools(model, additional_tools, enable_python=False, auto_approve=False):
144144
'''Initialize the LLM chain with useful tools.'''
145145
if os.getenv("OPENAI_API_TYPE") == "azure" or (os.getenv("OPENAI_API_BASE") is not None and "azure" in os.getenv("OPENAI_API_BASE")):
146-
engine = model.replace(".", "")
147-
llm = ChatOpenAI(model_name=model,
148-
temperature=0,
149-
request_timeout=120,
150-
model_kwargs={"engine": engine})
146+
deployment_name = model.replace(".", "")
147+
llm = AzureChatOpenAI(temperature=0,
148+
request_timeout=120,
149+
openai_api_key=os.getenv("OPENAI_API_KEY"),
150+
openai_api_base=os.getenv("OPENAI_API_BASE"),
151+
openai_api_version="2023-05-15",
152+
deployment_name=deployment_name)
151153
else:
152154
llm = ChatOpenAI(model_name=model,
153155
temperature=0,
154-
request_timeout=120)
156+
request_timeout=120,
157+
openai_api_key=os.getenv("OPENAI_API_KEY"),
158+
openai_api_base=os.getenv(
159+
"OPENAI_API_BASE", "https://api.openai.com/v1"),
160+
openai_organization=os.getenv("OPENAI_ORGANIZATION", None))
155161

156162
tools = [
157163
Tool(
@@ -167,17 +173,17 @@ def get_llm_tools(model, additional_tools, enable_python=False, auto_approve=Fal
167173
]
168174

169175
if enable_python:
170-
python_tool = PythonREPLTool(
176+
python_tool = PythonTool(
171177
callbacks=[HumanApprovalCallbackHandler(
172178
approve=python_approval)]
173179
)
174180
if auto_approve:
175-
python_tool = PythonREPLTool()
181+
python_tool = PythonTool()
176182
tools = [
177183
Tool(
178184
name="python",
179185
func=python_tool.run,
180-
description="Useful for executing Python code with Kubernetes Python SDK client. Results should be print out by calling `print(...)`. Input: Python code. Output: the result from the Python code's print()."
186+
description="Useful for executing Python code with Kubernetes Python SDK client. Results should be print out by calling `print(...)`. Input: Python codes (kubectl commands must be converted to kubernetes python library first). Output: the result from the Python code's print()."
181187
),
182188
Tool(
183189
name="trivy",

kube_copilot/cli.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import logging
44
import sys
55
import click
6-
from kube_copilot.llm import init_openai
76
from kube_copilot.chains import ReActLLM
87
from kube_copilot.shell import KubeProcess
98
from kube_copilot.prompts import (
@@ -106,7 +105,6 @@ def generate(instructions, verbose, model):
106105

107106
def main():
108107
'''Main function'''
109-
init_openai()
110108
cli()
111109

112110

kube_copilot/kubeconfig.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44

55
def get_kubeconfig():
6-
token = open("/run/secrets/kubernetes.io/serviceaccount/token").read().strip() # Strip newline characters
7-
cert = open("/run/secrets/kubernetes.io/serviceaccount/ca.crt").read().strip() # Strip newline characters
6+
'''Get kubeconfig for the current Pod.'''
7+
token = open("/run/secrets/kubernetes.io/serviceaccount/token", "r", encoding="utf-8").read().strip() # Strip newline characters
8+
cert = open("/run/secrets/kubernetes.io/serviceaccount/ca.crt", "r", encoding="utf-8").read().strip() # Strip newline characters
89
cert = base64.b64encode(cert.encode()).decode()
910
host = os.environ.get("KUBERNETES_SERVICE_HOST")
1011
port = os.environ.get("KUBERNETES_SERVICE_PORT")
@@ -30,6 +31,7 @@ def get_kubeconfig():
3031

3132

3233
def setup_kubeconfig():
34+
'''Set up kubeconfig if running inside a Pod.'''
3335
if not os.getenv("KUBERNETES_SERVICE_HOST"):
3436
# Not running inside a Pod, so no need to set up kubeconfig
3537
return
@@ -40,12 +42,12 @@ def setup_kubeconfig():
4042

4143
# If kubeconfig already exists, no need to recreate it
4244
if os.path.exists(kubeconfig_file):
43-
return
45+
return
4446

4547
os.makedirs(kubeconfig_path, exist_ok=True)
4648
kubeconfig = get_kubeconfig()
47-
with open(kubeconfig_file, "w") as f:
48-
f.write(kubeconfig)
49+
with open(kubeconfig_file, "w", encoding="utf-8") as f:
50+
f.write(kubeconfig)
4951

5052

5153
# Call the setup_kubeconfig function to set up kubeconfig if needed

kube_copilot/llm.py

Lines changed: 0 additions & 21 deletions
This file was deleted.

kube_copilot/output.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
4040
)
4141
return AgentAction(response["action"], response["action_input"], text)
4242

43-
except Exception:
43+
except Exception as exc:
4444
if not includes_answer:
45-
raise OutputParserException(
46-
f"Could not parse LLM output: {text}")
45+
raise OutputParserException(f"Could not parse LLM output: {text}") from exc
4746
return AgentFinish(
4847
{"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
4948
)

kube_copilot/python.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- coding: utf-8 -*-
2+
from typing import Any, Dict, Optional, Type
3+
import tiktoken
4+
from langchain_experimental.tools import PythonREPLTool
5+
from langchain.callbacks.manager import (
6+
AsyncCallbackManagerForToolRun,
7+
CallbackManagerForToolRun,
8+
)
9+
10+
class PythonTool(PythonREPLTool):
11+
12+
max_tokens = 2000
13+
model = "gpt-4"
14+
15+
def trunk_tokens(self, msg):
16+
# TODO: workarounds for the following context length error with ChatGPT
17+
# https://github.com/hwchase17/langchain/issues/2140
18+
# https://github.com/hwchase17/langchain/issues/1767
19+
tokens = tiktoken.encoding_for_model(self.model).encode(msg)
20+
while len(tokens) > self.max_tokens:
21+
msg = msg[:len(msg) // 2]
22+
tokens = tiktoken.encoding_for_model(self.model).encode(msg)
23+
return msg
24+
25+
def _run(
26+
self,
27+
query: str,
28+
run_manager: Optional[CallbackManagerForToolRun] = None,
29+
) -> Any:
30+
result = super()._run(query, run_manager)
31+
return self.trunk_tokens(result)
32+
33+
async def _arun(
34+
self,
35+
query: str,
36+
run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
37+
) -> Any:
38+
result = await super()._arun(query, run_manager)
39+
return self.trunk_tokens(result)

0 commit comments

Comments
 (0)