langroid 0.6.7__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. langroid/agent/base.py +499 -55
  2. langroid/agent/callbacks/chainlit.py +1 -1
  3. langroid/agent/chat_agent.py +191 -37
  4. langroid/agent/chat_document.py +142 -29
  5. langroid/agent/openai_assistant.py +20 -4
  6. langroid/agent/special/lance_doc_chat_agent.py +25 -18
  7. langroid/agent/special/lance_rag/critic_agent.py +37 -5
  8. langroid/agent/special/lance_rag/query_planner_agent.py +102 -63
  9. langroid/agent/special/lance_tools.py +10 -2
  10. langroid/agent/special/sql/sql_chat_agent.py +69 -13
  11. langroid/agent/task.py +179 -43
  12. langroid/agent/tool_message.py +19 -7
  13. langroid/agent/tools/__init__.py +5 -0
  14. langroid/agent/tools/orchestration.py +216 -0
  15. langroid/agent/tools/recipient_tool.py +6 -11
  16. langroid/agent/tools/rewind_tool.py +1 -1
  17. langroid/agent/typed_task.py +19 -0
  18. langroid/language_models/.chainlit/config.toml +121 -0
  19. langroid/language_models/.chainlit/translations/en-US.json +231 -0
  20. langroid/language_models/base.py +114 -12
  21. langroid/language_models/mock_lm.py +10 -1
  22. langroid/language_models/openai_gpt.py +260 -36
  23. langroid/mytypes.py +0 -1
  24. langroid/parsing/parse_json.py +19 -2
  25. langroid/utils/pydantic_utils.py +19 -0
  26. langroid/vector_store/base.py +3 -1
  27. langroid/vector_store/lancedb.py +2 -0
  28. {langroid-0.6.7.dist-info → langroid-0.9.0.dist-info}/METADATA +4 -1
  29. {langroid-0.6.7.dist-info → langroid-0.9.0.dist-info}/RECORD +32 -33
  30. pyproject.toml +2 -1
  31. langroid/agent/special/lance_rag_new/__init__.py +0 -9
  32. langroid/agent/special/lance_rag_new/critic_agent.py +0 -171
  33. langroid/agent/special/lance_rag_new/lance_rag_task.py +0 -144
  34. langroid/agent/special/lance_rag_new/query_planner_agent.py +0 -222
  35. langroid/agent/team.py +0 -1758
  36. {langroid-0.6.7.dist-info → langroid-0.9.0.dist-info}/LICENSE +0 -0
  37. {langroid-0.6.7.dist-info → langroid-0.9.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,216 @@
1
+ """
2
+ Various tools to for agents to be able to control flow of Task, e.g.
3
+ termination, routing to another agent, etc.
4
+ """
5
+
6
+ from typing import List, Tuple
7
+
8
+ from langroid.agent.chat_agent import ChatAgent
9
+ from langroid.agent.chat_document import ChatDocument
10
+ from langroid.agent.tool_message import ToolMessage
11
+ from langroid.mytypes import Entity
12
+
13
+
14
+ class AgentDoneTool(ToolMessage):
15
+ """Tool for AGENT entity (i.e. agent_response or downstream tool handling fns) to
16
+ signal the current task is done."""
17
+
18
+ purpose: str = """
19
+ To signal the current task is done, along with an optional message <content>
20
+ (default empty string) and an optional list of <tools> (default empty list).
21
+ """
22
+ request: str = "agent_done_tool"
23
+ content: str = ""
24
+ tools: List[ToolMessage] = []
25
+ _handle_only: bool = True
26
+
27
+ def response(self, agent: ChatAgent) -> ChatDocument:
28
+ return agent.create_agent_response(
29
+ self.content,
30
+ tool_messages=[self] + self.tools,
31
+ )
32
+
33
+
34
+ class DoneTool(ToolMessage):
35
+ """Tool for Agent Entity (i.e. agent_response) or LLM entity (i.e. llm_response) to
36
+ signal the current task is done, with some content as the result."""
37
+
38
+ purpose = """
39
+ To signal the current task is done, along with an optional message <content>
40
+ (default empty string).
41
+ """
42
+ request = "done_tool"
43
+ content: str = ""
44
+
45
+ def response(self, agent: ChatAgent) -> ChatDocument:
46
+ return agent.create_agent_response(
47
+ self.content,
48
+ tool_messages=[self],
49
+ )
50
+
51
+ @classmethod
52
+ def instructions(cls) -> str:
53
+ tool_name = cls.default_value("request")
54
+ return f"""
55
+ When you determine your task is finished,
56
+ use the tool `{tool_name}` to signal this,
57
+ along with any message or result, in the `content` field.
58
+ """
59
+
60
+
61
+ class PassTool(ToolMessage):
62
+ """Tool for "passing" on the received msg (ChatDocument),
63
+ so that an as-yet-unspecified agent can handle it.
64
+ Similar to ForwardTool, but without specifying the recipient agent.
65
+ """
66
+
67
+ purpose = """
68
+ To pass the current message so that other agents can handle it.
69
+ """
70
+ request = "pass_tool"
71
+
72
+ def response(self, agent: ChatAgent, chat_doc: ChatDocument) -> ChatDocument:
73
+ """When this tool is enabled for an Agent, this will result in a method
74
+ added to the Agent with signature:
75
+ `forward_tool(self, tool: PassTool, chat_doc: ChatDocument) -> ChatDocument:`
76
+ """
77
+ # if PassTool is in chat_doc, pass its parent, else pass chat_doc itself
78
+ tools = agent.get_tool_messages(chat_doc)
79
+ doc = (
80
+ chat_doc.parent
81
+ if any(isinstance(t, type(self)) for t in tools)
82
+ else chat_doc
83
+ )
84
+ assert doc is not None, "PassTool: parent of chat_doc must not be None"
85
+ new_doc = ChatDocument.deepcopy(doc)
86
+ new_doc.metadata.sender = Entity.AGENT
87
+ return new_doc
88
+
89
+ @classmethod
90
+ def instructions(cls) -> str:
91
+ return """
92
+ Use the `pass_tool` to PASS the current message
93
+ so that another agent can handle it.
94
+ """
95
+
96
+
97
+ class DonePassTool(PassTool):
98
+ """Tool to signal DONE, AND Pass incoming/current msg as result.
99
+ Similar to PassTool, except we append a DoneTool to the result tool_messages.
100
+ """
101
+
102
+ purpose = """
103
+ To signal the current task is done, with results set to the current/incoming msg.
104
+ """
105
+ request = "done_pass_tool"
106
+
107
+ def response(self, agent: ChatAgent, chat_doc: ChatDocument) -> ChatDocument:
108
+ # use PassTool to get the right ChatDocument to pass...
109
+ new_doc = PassTool.response(self, agent, chat_doc)
110
+ tools = agent.get_tool_messages(new_doc)
111
+ # ...then return an AgentDoneTool with content, tools from this ChatDocument
112
+ return AgentDoneTool(content=new_doc.content, tools=tools) # type: ignore
113
+
114
+ @classmethod
115
+ def instructions(cls) -> str:
116
+ return """
117
+ When you determine your task is finished,
118
+ and want to pass the current message as the result of the task,
119
+ use the `done_pass_tool` to signal this.
120
+ """
121
+
122
+
123
+ class ForwardTool(PassTool):
124
+ """Tool for forwarding the received msg (ChatDocument) to another agent.
125
+ Similar to PassTool, but with a specified recipient agent.
126
+ """
127
+
128
+ purpose: str = """
129
+ To forward the current message to an <agent>.
130
+ """
131
+ request: str = "forward_tool"
132
+ agent: str
133
+
134
+ def response(self, agent: ChatAgent, chat_doc: ChatDocument) -> ChatDocument:
135
+ """When this tool is enabled for an Agent, this will result in a method
136
+ added to the Agent with signature:
137
+ `forward_tool(self, tool: ForwardTool, chat_doc: ChatDocument) -> ChatDocument:`
138
+ """
139
+ # if chat_doc contains ForwardTool, then we forward its parent ChatDocument;
140
+ # else forward chat_doc itself
141
+ new_doc = PassTool.response(self, agent, chat_doc)
142
+ new_doc.metadata.recipient = self.agent
143
+ return new_doc
144
+
145
+ @classmethod
146
+ def instructions(cls) -> str:
147
+ return """
148
+ If you need to forward the current message to another agent,
149
+ use the `forward_tool` to do so,
150
+ setting the `recipient` field to the name of the recipient agent.
151
+ """
152
+
153
+
154
+ class SendTool(ToolMessage):
155
+ """Tool for agent or LLM to send content to a specified agent.
156
+ Similar to RecipientTool.
157
+ """
158
+
159
+ purpose: str = """
160
+ To send message <content> to agent specified in <to> field.
161
+ """
162
+ request: str = "send_tool"
163
+ to: str
164
+ content: str = ""
165
+
166
+ def response(self, agent: ChatAgent) -> ChatDocument:
167
+ return agent.create_agent_response(
168
+ self.content,
169
+ recipient=self.to,
170
+ )
171
+
172
+ @classmethod
173
+ def instructions(cls) -> str:
174
+ return """
175
+ If you need to send a message to another agent,
176
+ use the `send_tool` to do so, with these field values:
177
+ - `to` field = name of the recipient agent,
178
+ - `content` field = the message to send.
179
+ """
180
+
181
+ @classmethod
182
+ def examples(cls) -> List["ToolMessage" | Tuple[str, "ToolMessage"]]:
183
+ return [
184
+ cls(to="agent1", content="Hello, agent1!"),
185
+ (
186
+ """
187
+ I need to send the content 'Who built the Gemini model?',
188
+ to the 'Searcher' agent.
189
+ """,
190
+ cls(to="Searcher", content="Who built the Gemini model?"),
191
+ ),
192
+ ]
193
+
194
+
195
+ class AgentSendTool(ToolMessage):
196
+ """Tool for Agent (i.e. agent_response) to send content or tool_messages
197
+ to a specified agent. Similar to SendTool except that AgentSendTool is only
198
+ usable by agent_response (or handler of another tool), to send content or
199
+ tools to another agent. SendTool does not allow sending tools.
200
+ """
201
+
202
+ purpose: str = """
203
+ To send message <content> and <tools> to agent specified in <to> field.
204
+ """
205
+ request: str = "agent_send_tool"
206
+ to: str
207
+ content: str = ""
208
+ tools: List[ToolMessage] = []
209
+ _handle_only: bool = True
210
+
211
+ def response(self, agent: ChatAgent) -> ChatDocument:
212
+ return agent.create_agent_response(
213
+ self.content,
214
+ tool_messages=self.tools,
215
+ recipient=self.to,
216
+ )
@@ -32,12 +32,7 @@ class AddRecipientTool(ToolMessage):
32
32
  "to clarify who the message is intended for."
33
33
  )
34
34
  intended_recipient: str
35
- saved_content: str = ""
36
-
37
- class Config:
38
- # do not include these fields in the generated schema
39
- # since we don't require the LLM to specify them
40
- schema_extra = {"exclude": {"saved_content", "purpose"}}
35
+ _saved_content: str = ""
41
36
 
42
37
  def response(self, agent: ChatAgent) -> ChatDocument:
43
38
  """
@@ -49,7 +44,7 @@ class AddRecipientTool(ToolMessage):
49
44
  "[red]RecipientTool: "
50
45
  f"Added recipient {self.intended_recipient} to message."
51
46
  )
52
- if self.__class__.saved_content == "":
47
+ if self.__class__._saved_content == "":
53
48
  recipient_request_name = RecipientTool.default_value("request")
54
49
  content = f"""
55
50
  Recipient specified but content is empty!
@@ -58,9 +53,9 @@ class AddRecipientTool(ToolMessage):
58
53
  Resend the message using `{recipient_request_name}` tool/function.
59
54
  """
60
55
  else:
61
- content = self.__class__.saved_content # use class-level attrib value
56
+ content = self.__class__._saved_content # use class-level attrib value
62
57
  # erase content since we just used it.
63
- self.__class__.saved_content = ""
58
+ self.__class__._saved_content = ""
64
59
  return ChatDocument(
65
60
  content=content,
66
61
  metadata=ChatDocMetaData(
@@ -152,7 +147,7 @@ class RecipientTool(ToolMessage):
152
147
  # save the content as a class-variable, so that
153
148
  # we can construct the ChatDocument once the LLM specifies a recipient.
154
149
  # This avoids having to re-generate the entire message, saving time + cost.
155
- AddRecipientTool.saved_content = self.content
150
+ AddRecipientTool._saved_content = self.content
156
151
  agent.enable_message(AddRecipientTool)
157
152
  return ChatDocument(
158
153
  content="""
@@ -214,7 +209,7 @@ class RecipientTool(ToolMessage):
214
209
  # save the content as a class-variable, so that
215
210
  # we can construct the ChatDocument once the LLM specifies a recipient.
216
211
  # This avoids having to re-generate the entire message, saving time + cost.
217
- AddRecipientTool.saved_content = content
212
+ AddRecipientTool._saved_content = content
218
213
  agent.enable_message(AddRecipientTool)
219
214
  print("[red]RecipientTool: Recipient not specified, asking LLM to clarify.")
220
215
  return ChatDocument(
@@ -127,7 +127,7 @@ class RewindTool(ToolMessage):
127
127
  result_doc.metadata.msg_idx = idx
128
128
 
129
129
  # replace the message at idx with this new message
130
- agent.message_history.append(ChatDocument.to_LLMMessage(result_doc))
130
+ agent.message_history.extend(ChatDocument.to_LLMMessage(result_doc))
131
131
 
132
132
  # set the replaced doc's parent's child to this result_doc
133
133
  if parent is not None:
@@ -0,0 +1,19 @@
1
+ # from langroid.agent.tool_message import ToolMessage
2
+ # from langroid.agent.task import Task
3
+ # from typing import Any
4
+ #
5
+ # class TypedTask:
6
+ # def __init__(self, Task: Task, input_type: Any, output_type: Any):
7
+ # self.Task = Task
8
+ # self.input_type = input_type
9
+ # self.output_type = output_type
10
+ #
11
+ # def run(self, input: Any) -> Any:
12
+ # if not isinstance(input, self.input_type):
13
+ # raise ValueError(f"Input must be of type {self.input_type}")
14
+ # output = self.Task.run(input)
15
+ # if not isinstance(output, self.output_type):
16
+ # raise ValueError(f"Output must be of type {self.output_type}")
17
+ # return output
18
+ #
19
+ #
@@ -0,0 +1,121 @@
1
+ [project]
2
+ # Whether to enable telemetry (default: true). No personal data is collected.
3
+ enable_telemetry = true
4
+
5
+
6
+ # List of environment variables to be provided by each user to use the app.
7
+ user_env = []
8
+
9
+ # Duration (in seconds) during which the session is saved when the connection is lost
10
+ session_timeout = 3600
11
+
12
+ # Enable third parties caching (e.g LangChain cache)
13
+ cache = false
14
+
15
+ # Authorized origins
16
+ allow_origins = ["*"]
17
+
18
+ # Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
19
+ # follow_symlink = false
20
+
21
+ [features]
22
+ # Show the prompt playground
23
+ prompt_playground = true
24
+
25
+ # Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
26
+ unsafe_allow_html = false
27
+
28
+ # Process and display mathematical expressions. This can clash with "$" characters in messages.
29
+ latex = false
30
+
31
+ # Automatically tag threads with the current chat profile (if a chat profile is used)
32
+ auto_tag_thread = true
33
+
34
+ # Authorize users to spontaneously upload files with messages
35
+ [features.spontaneous_file_upload]
36
+ enabled = true
37
+ accept = ["*/*"]
38
+ max_files = 20
39
+ max_size_mb = 500
40
+
41
+ [features.audio]
42
+ # Threshold for audio recording
43
+ min_decibels = -45
44
+ # Delay for the user to start speaking in MS
45
+ initial_silence_timeout = 3000
46
+ # Delay for the user to continue speaking in MS. If the user stops speaking for this duration, the recording will stop.
47
+ silence_timeout = 1500
48
+ # Above this duration (MS), the recording will forcefully stop.
49
+ max_duration = 15000
50
+ # Duration of the audio chunks in MS
51
+ chunk_duration = 1000
52
+ # Sample rate of the audio
53
+ sample_rate = 44100
54
+
55
+ [UI]
56
+ # Name of the app and chatbot.
57
+ name = "Chatbot"
58
+
59
+ # Show the readme while the thread is empty.
60
+ show_readme_as_default = true
61
+
62
+ # Description of the app and chatbot. This is used for HTML tags.
63
+ # description = ""
64
+
65
+ # Large size content are by default collapsed for a cleaner ui
66
+ default_collapse_content = true
67
+
68
+ # The default value for the expand messages settings.
69
+ default_expand_messages = false
70
+
71
+ # Hide the chain of thought details from the user in the UI.
72
+ hide_cot = false
73
+
74
+ # Link to your github repo. This will add a github button in the UI's header.
75
+ # github = ""
76
+
77
+ # Specify a CSS file that can be used to customize the user interface.
78
+ # The CSS file can be served from the public directory or via an external link.
79
+ # custom_css = "/public/test.css"
80
+
81
+ # Specify a Javascript file that can be used to customize the user interface.
82
+ # The Javascript file can be served from the public directory.
83
+ # custom_js = "/public/test.js"
84
+
85
+ # Specify a custom font url.
86
+ # custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"
87
+
88
+ # Specify a custom meta image url.
89
+ # custom_meta_image_url = "https://chainlit-cloud.s3.eu-west-3.amazonaws.com/logo/chainlit_banner.png"
90
+
91
+ # Specify a custom build directory for the frontend.
92
+ # This can be used to customize the frontend code.
93
+ # Be careful: If this is a relative path, it should not start with a slash.
94
+ # custom_build = "./public/build"
95
+
96
+ [UI.theme]
97
+ #layout = "wide"
98
+ #font_family = "Inter, sans-serif"
99
+ # Override default MUI light theme. (Check theme.ts)
100
+ [UI.theme.light]
101
+ #background = "#FAFAFA"
102
+ #paper = "#FFFFFF"
103
+
104
+ [UI.theme.light.primary]
105
+ #main = "#F80061"
106
+ #dark = "#980039"
107
+ #light = "#FFE7EB"
108
+
109
+ # Override default MUI dark theme. (Check theme.ts)
110
+ [UI.theme.dark]
111
+ #background = "#FAFAFA"
112
+ #paper = "#FFFFFF"
113
+
114
+ [UI.theme.dark.primary]
115
+ #main = "#F80061"
116
+ #dark = "#980039"
117
+ #light = "#FFE7EB"
118
+
119
+
120
+ [meta]
121
+ generated_by = "1.1.202"
@@ -0,0 +1,231 @@
1
+ {
2
+ "components": {
3
+ "atoms": {
4
+ "buttons": {
5
+ "userButton": {
6
+ "menu": {
7
+ "settings": "Settings",
8
+ "settingsKey": "S",
9
+ "APIKeys": "API Keys",
10
+ "logout": "Logout"
11
+ }
12
+ }
13
+ }
14
+ },
15
+ "molecules": {
16
+ "newChatButton": {
17
+ "newChat": "New Chat"
18
+ },
19
+ "tasklist": {
20
+ "TaskList": {
21
+ "title": "\ud83d\uddd2\ufe0f Task List",
22
+ "loading": "Loading...",
23
+ "error": "An error occured"
24
+ }
25
+ },
26
+ "attachments": {
27
+ "cancelUpload": "Cancel upload",
28
+ "removeAttachment": "Remove attachment"
29
+ },
30
+ "newChatDialog": {
31
+ "createNewChat": "Create new chat?",
32
+ "clearChat": "This will clear the current messages and start a new chat.",
33
+ "cancel": "Cancel",
34
+ "confirm": "Confirm"
35
+ },
36
+ "settingsModal": {
37
+ "settings": "Settings",
38
+ "expandMessages": "Expand Messages",
39
+ "hideChainOfThought": "Hide Chain of Thought",
40
+ "darkMode": "Dark Mode"
41
+ },
42
+ "detailsButton": {
43
+ "using": "Using",
44
+ "running": "Running",
45
+ "took_one": "Took {{count}} step",
46
+ "took_other": "Took {{count}} steps"
47
+ },
48
+ "auth": {
49
+ "authLogin": {
50
+ "title": "Login to access the app.",
51
+ "form": {
52
+ "email": "Email address",
53
+ "password": "Password",
54
+ "noAccount": "Don't have an account?",
55
+ "alreadyHaveAccount": "Already have an account?",
56
+ "signup": "Sign Up",
57
+ "signin": "Sign In",
58
+ "or": "OR",
59
+ "continue": "Continue",
60
+ "forgotPassword": "Forgot password?",
61
+ "passwordMustContain": "Your password must contain:",
62
+ "emailRequired": "email is a required field",
63
+ "passwordRequired": "password is a required field"
64
+ },
65
+ "error": {
66
+ "default": "Unable to sign in.",
67
+ "signin": "Try signing in with a different account.",
68
+ "oauthsignin": "Try signing in with a different account.",
69
+ "redirect_uri_mismatch": "The redirect URI is not matching the oauth app configuration.",
70
+ "oauthcallbackerror": "Try signing in with a different account.",
71
+ "oauthcreateaccount": "Try signing in with a different account.",
72
+ "emailcreateaccount": "Try signing in with a different account.",
73
+ "callback": "Try signing in with a different account.",
74
+ "oauthaccountnotlinked": "To confirm your identity, sign in with the same account you used originally.",
75
+ "emailsignin": "The e-mail could not be sent.",
76
+ "emailverify": "Please verify your email, a new email has been sent.",
77
+ "credentialssignin": "Sign in failed. Check the details you provided are correct.",
78
+ "sessionrequired": "Please sign in to access this page."
79
+ }
80
+ },
81
+ "authVerifyEmail": {
82
+ "almostThere": "You're almost there! We've sent an email to ",
83
+ "verifyEmailLink": "Please click on the link in that email to complete your signup.",
84
+ "didNotReceive": "Can't find the email?",
85
+ "resendEmail": "Resend email",
86
+ "goBack": "Go Back",
87
+ "emailSent": "Email sent successfully.",
88
+ "verifyEmail": "Verify your email address"
89
+ },
90
+ "providerButton": {
91
+ "continue": "Continue with {{provider}}",
92
+ "signup": "Sign up with {{provider}}"
93
+ },
94
+ "authResetPassword": {
95
+ "newPasswordRequired": "New password is a required field",
96
+ "passwordsMustMatch": "Passwords must match",
97
+ "confirmPasswordRequired": "Confirm password is a required field",
98
+ "newPassword": "New password",
99
+ "confirmPassword": "Confirm password",
100
+ "resetPassword": "Reset Password"
101
+ },
102
+ "authForgotPassword": {
103
+ "email": "Email address",
104
+ "emailRequired": "email is a required field",
105
+ "emailSent": "Please check the email address {{email}} for instructions to reset your password.",
106
+ "enterEmail": "Enter your email address and we will send you instructions to reset your password.",
107
+ "resendEmail": "Resend email",
108
+ "continue": "Continue",
109
+ "goBack": "Go Back"
110
+ }
111
+ }
112
+ },
113
+ "organisms": {
114
+ "chat": {
115
+ "history": {
116
+ "index": {
117
+ "showHistory": "Show history",
118
+ "lastInputs": "Last Inputs",
119
+ "noInputs": "Such empty...",
120
+ "loading": "Loading..."
121
+ }
122
+ },
123
+ "inputBox": {
124
+ "input": {
125
+ "placeholder": "Type your message here..."
126
+ },
127
+ "speechButton": {
128
+ "start": "Start recording",
129
+ "stop": "Stop recording"
130
+ },
131
+ "SubmitButton": {
132
+ "sendMessage": "Send message",
133
+ "stopTask": "Stop Task"
134
+ },
135
+ "UploadButton": {
136
+ "attachFiles": "Attach files"
137
+ },
138
+ "waterMark": {
139
+ "text": "Built with"
140
+ }
141
+ },
142
+ "Messages": {
143
+ "index": {
144
+ "running": "Running",
145
+ "executedSuccessfully": "executed successfully",
146
+ "failed": "failed",
147
+ "feedbackUpdated": "Feedback updated",
148
+ "updating": "Updating"
149
+ }
150
+ },
151
+ "dropScreen": {
152
+ "dropYourFilesHere": "Drop your files here"
153
+ },
154
+ "index": {
155
+ "failedToUpload": "Failed to upload",
156
+ "cancelledUploadOf": "Cancelled upload of",
157
+ "couldNotReachServer": "Could not reach the server",
158
+ "continuingChat": "Continuing previous chat"
159
+ },
160
+ "settings": {
161
+ "settingsPanel": "Settings panel",
162
+ "reset": "Reset",
163
+ "cancel": "Cancel",
164
+ "confirm": "Confirm"
165
+ }
166
+ },
167
+ "threadHistory": {
168
+ "sidebar": {
169
+ "filters": {
170
+ "FeedbackSelect": {
171
+ "feedbackAll": "Feedback: All",
172
+ "feedbackPositive": "Feedback: Positive",
173
+ "feedbackNegative": "Feedback: Negative"
174
+ },
175
+ "SearchBar": {
176
+ "search": "Search"
177
+ }
178
+ },
179
+ "DeleteThreadButton": {
180
+ "confirmMessage": "This will delete the thread as well as it's messages and elements.",
181
+ "cancel": "Cancel",
182
+ "confirm": "Confirm",
183
+ "deletingChat": "Deleting chat",
184
+ "chatDeleted": "Chat deleted"
185
+ },
186
+ "index": {
187
+ "pastChats": "Past Chats"
188
+ },
189
+ "ThreadList": {
190
+ "empty": "Empty...",
191
+ "today": "Today",
192
+ "yesterday": "Yesterday",
193
+ "previous7days": "Previous 7 days",
194
+ "previous30days": "Previous 30 days"
195
+ },
196
+ "TriggerButton": {
197
+ "closeSidebar": "Close sidebar",
198
+ "openSidebar": "Open sidebar"
199
+ }
200
+ },
201
+ "Thread": {
202
+ "backToChat": "Go back to chat",
203
+ "chatCreatedOn": "This chat was created on"
204
+ }
205
+ },
206
+ "header": {
207
+ "chat": "Chat",
208
+ "readme": "Readme"
209
+ }
210
+ }
211
+ },
212
+ "hooks": {
213
+ "useLLMProviders": {
214
+ "failedToFetchProviders": "Failed to fetch providers:"
215
+ }
216
+ },
217
+ "pages": {
218
+ "Design": {},
219
+ "Env": {
220
+ "savedSuccessfully": "Saved successfully",
221
+ "requiredApiKeys": "Required API Keys",
222
+ "requiredApiKeysInfo": "To use this app, the following API keys are required. The keys are stored on your device's local storage."
223
+ },
224
+ "Page": {
225
+ "notPartOfProject": "You are not part of this project."
226
+ },
227
+ "ResumeButton": {
228
+ "resumeChat": "Resume Chat"
229
+ }
230
+ }
231
+ }