Skip to content

Commit

Permalink
Merge branch 'fix/runtime-error' into deploy/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
zxhlyh committed Oct 18, 2023
2 parents 2f63700 + 41a5af2 commit e660275
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 37 deletions.
2 changes: 1 addition & 1 deletion api/core/agent/agent/multi_dataset_router_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def plan(
agent_decision = self.real_plan(intermediate_steps, callbacks, **kwargs)
if isinstance(agent_decision, AgentAction):
tool_inputs = agent_decision.tool_input
if isinstance(tool_inputs, dict) and 'query' in tool_inputs:
if isinstance(tool_inputs, dict) and 'query' in tool_inputs and 'chat_history' not in kwargs:
tool_inputs['query'] = kwargs['input']
agent_decision.tool_input = tool_inputs
else:
Expand Down
90 changes: 80 additions & 10 deletions api/core/agent/agent/structed_multi_dataset_router_agent.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from typing import List, Tuple, Any, Union, Sequence, Optional, cast

from langchain import BasePromptTemplate
from langchain import BasePromptTemplate, PromptTemplate
from langchain.agents import StructuredChatAgent, AgentOutputParser, Agent
from langchain.agents.structured_chat.base import HUMAN_MESSAGE_TEMPLATE
from langchain.callbacks.base import BaseCallbackManager
Expand All @@ -12,6 +12,7 @@
from langchain.agents.structured_chat.prompt import PREFIX, SUFFIX

from core.chain.llm_chain import LLMChain
from core.model_providers.models.entity.model_params import ModelMode
from core.model_providers.models.llm.base import BaseLLM
from core.tool.dataset_retriever_tool import DatasetRetrieverTool

Expand Down Expand Up @@ -92,6 +93,10 @@ def plan(
rst = tool.run(tool_input={'query': kwargs['input']})
return AgentFinish(return_values={"output": rst}, log=rst)

if intermediate_steps:
_, observation = intermediate_steps[-1]
return AgentFinish(return_values={"output": observation}, log=observation)

full_inputs = self.get_full_inputs(intermediate_steps, **kwargs)

try:
Expand All @@ -107,6 +112,8 @@ def plan(
if isinstance(tool_inputs, dict) and 'query' in tool_inputs:
tool_inputs['query'] = kwargs['input']
agent_decision.tool_input = tool_inputs
elif isinstance(tool_inputs, str):
agent_decision.tool_input = kwargs['input']
else:
agent_decision.return_values['output'] = ''
return agent_decision
Expand Down Expand Up @@ -143,6 +150,61 @@ def create_prompt(
]
return ChatPromptTemplate(input_variables=input_variables, messages=messages)

@classmethod
def create_completion_prompt(
cls,
tools: Sequence[BaseTool],
prefix: str = PREFIX,
format_instructions: str = FORMAT_INSTRUCTIONS,
input_variables: Optional[List[str]] = None,
) -> PromptTemplate:
"""Create prompt in the style of the zero shot agent.
Args:
tools: List of tools the agent will have access to, used to format the
prompt.
prefix: String to put before the list of tools.
input_variables: List of input variables the final prompt will expect.
Returns:
A PromptTemplate with the template assembled from the pieces here.
"""
suffix = """Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.
Question: {input}
Thought: {agent_scratchpad}
"""

tool_strings = "\n".join([f"{tool.name}: {tool.description}" for tool in tools])
tool_names = ", ".join([tool.name for tool in tools])
format_instructions = format_instructions.format(tool_names=tool_names)
template = "\n\n".join([prefix, tool_strings, format_instructions, suffix])
if input_variables is None:
input_variables = ["input", "agent_scratchpad"]
return PromptTemplate(template=template, input_variables=input_variables)

def _construct_scratchpad(
self, intermediate_steps: List[Tuple[AgentAction, str]]
) -> str:
agent_scratchpad = ""
for action, observation in intermediate_steps:
agent_scratchpad += action.log
agent_scratchpad += f"\n{self.observation_prefix}{observation}\n{self.llm_prefix}"

if not isinstance(agent_scratchpad, str):
raise ValueError("agent_scratchpad should be of type string.")
if agent_scratchpad:
llm_chain = cast(LLMChain, self.llm_chain)
if llm_chain.model_instance.model_mode == ModelMode.CHAT:
return (
f"This was your previous work "
f"(but I haven't seen any of it! I only see what "
f"you return as final answer):\n{agent_scratchpad}"
)
else:
return agent_scratchpad
else:
return agent_scratchpad

@classmethod
def from_llm_and_tools(
cls,
Expand All @@ -160,15 +222,23 @@ def from_llm_and_tools(
) -> Agent:
"""Construct an agent from an LLM and tools."""
cls._validate_tools(tools)
prompt = cls.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
human_message_template=human_message_template,
format_instructions=format_instructions,
input_variables=input_variables,
memory_prompts=memory_prompts,
)
if model_instance.model_mode == ModelMode.CHAT:
prompt = cls.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
human_message_template=human_message_template,
format_instructions=format_instructions,
input_variables=input_variables,
memory_prompts=memory_prompts,
)
else:
prompt = cls.create_completion_prompt(
tools,
prefix=prefix,
format_instructions=format_instructions,
input_variables=input_variables
)
llm_chain = LLMChain(
model_instance=model_instance,
prompt=prompt,
Expand Down
86 changes: 75 additions & 11 deletions api/core/agent/agent/structured_chat.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from typing import List, Tuple, Any, Union, Sequence, Optional
from typing import List, Tuple, Any, Union, Sequence, Optional, cast

from langchain import BasePromptTemplate
from langchain import BasePromptTemplate, PromptTemplate
from langchain.agents import StructuredChatAgent, AgentOutputParser, Agent
from langchain.agents.structured_chat.base import HUMAN_MESSAGE_TEMPLATE
from langchain.callbacks.base import BaseCallbackManager
Expand All @@ -15,6 +15,7 @@

from core.agent.agent.calc_token_mixin import CalcTokenMixin, ExceededLLMTokensLimitError
from core.chain.llm_chain import LLMChain
from core.model_providers.models.entity.model_params import ModelMode
from core.model_providers.models.llm.base import BaseLLM

FORMAT_INSTRUCTIONS = """Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).
Expand Down Expand Up @@ -184,6 +185,61 @@ def create_prompt(
]
return ChatPromptTemplate(input_variables=input_variables, messages=messages)

@classmethod
def create_completion_prompt(
cls,
tools: Sequence[BaseTool],
prefix: str = PREFIX,
format_instructions: str = FORMAT_INSTRUCTIONS,
input_variables: Optional[List[str]] = None,
) -> PromptTemplate:
"""Create prompt in the style of the zero shot agent.
Args:
tools: List of tools the agent will have access to, used to format the
prompt.
prefix: String to put before the list of tools.
input_variables: List of input variables the final prompt will expect.
Returns:
A PromptTemplate with the template assembled from the pieces here.
"""
suffix = """Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.
Question: {input}
Thought: {agent_scratchpad}
"""

tool_strings = "\n".join([f"{tool.name}: {tool.description}" for tool in tools])
tool_names = ", ".join([tool.name for tool in tools])
format_instructions = format_instructions.format(tool_names=tool_names)
template = "\n\n".join([prefix, tool_strings, format_instructions, suffix])
if input_variables is None:
input_variables = ["input", "agent_scratchpad"]
return PromptTemplate(template=template, input_variables=input_variables)

def _construct_scratchpad(
self, intermediate_steps: List[Tuple[AgentAction, str]]
) -> str:
agent_scratchpad = ""
for action, observation in intermediate_steps:
agent_scratchpad += action.log
agent_scratchpad += f"\n{self.observation_prefix}{observation}\n{self.llm_prefix}"

if not isinstance(agent_scratchpad, str):
raise ValueError("agent_scratchpad should be of type string.")
if agent_scratchpad:
llm_chain = cast(LLMChain, self.llm_chain)
if llm_chain.model_instance.model_mode == ModelMode.CHAT:
return (
f"This was your previous work "
f"(but I haven't seen any of it! I only see what "
f"you return as final answer):\n{agent_scratchpad}"
)
else:
return agent_scratchpad
else:
return agent_scratchpad

@classmethod
def from_llm_and_tools(
cls,
Expand All @@ -201,15 +257,23 @@ def from_llm_and_tools(
) -> Agent:
"""Construct an agent from an LLM and tools."""
cls._validate_tools(tools)
prompt = cls.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
human_message_template=human_message_template,
format_instructions=format_instructions,
input_variables=input_variables,
memory_prompts=memory_prompts,
)
if model_instance.model_mode == ModelMode.CHAT:
prompt = cls.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
human_message_template=human_message_template,
format_instructions=format_instructions,
input_variables=input_variables,
memory_prompts=memory_prompts,
)
else:
prompt = cls.create_completion_prompt(
tools,
prefix=prefix,
format_instructions=format_instructions,
input_variables=input_variables,
)
llm_chain = LLMChain(
model_instance=model_instance,
prompt=prompt,
Expand Down
4 changes: 2 additions & 2 deletions api/services/completion_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def completion(cls, app_model: App, user: Union[Account | EndUser], args: Any,
'flask_app': current_app._get_current_object(),
'generate_task_id': generate_task_id,
'detached_app_model': app_model,
'app_model_config': app_model_config,
'app_model_config': app_model_config.copy(),
'query': query,
'inputs': inputs,
'detached_user': user,
Expand Down Expand Up @@ -284,7 +284,7 @@ def generate_more_like_this(cls, app_model: App, user: Union[Account | EndUser],
'flask_app': current_app._get_current_object(),
'generate_task_id': generate_task_id,
'detached_app_model': app_model,
'app_model_config': app_model_config,
'app_model_config': app_model_config.copy(),
'query': message.query,
'inputs': message.inputs,
'detached_user': user,
Expand Down
4 changes: 2 additions & 2 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ services:
# The milvus password.
MILVUS_PASSWORD: Milvus
# The milvus tls switch.
MILVUS_SECURE: false
MILVUS_SECURE: 'false'
# Mail configuration, support: resend
MAIL_TYPE: ''
# default send from email address, if not specified
Expand Down Expand Up @@ -176,7 +176,7 @@ services:
# The milvus password.
MILVUS_PASSWORD: Milvus
# The milvus tls switch.
MILVUS_SECURE: false
MILVUS_SECURE: 'false'
# Mail configuration, support: resend
MAIL_TYPE: ''
# default send from email address, if not specified
Expand Down
2 changes: 0 additions & 2 deletions web/app/components/i18n-server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import { ToastProvider } from './base/toast'
import { getDictionary, getLocaleOnServer } from '@/i18n/server'

export type II18NServerProps = {
// locale: Locale
children: React.ReactNode
}

const I18NServer = async ({
// locale,
children,
}: II18NServerProps) => {
const locale = getLocaleOnServer()
Expand Down
13 changes: 8 additions & 5 deletions web/app/components/i18n.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
'use client'

import type { FC } from 'react'
import React from 'react'
import '@/i18n/i18next-config'
import React, { useEffect } from 'react'
import { changeLanguage } from '@/i18n/i18next-config'
import I18NContext from '@/context/i18n'
import type { Locale } from '@/i18n'
import { getLocaleOnClient, setLocaleOnClient } from '@/i18n/client'
import { setLocaleOnClient } from '@/i18n/client'

export type II18nProps = {
locale: Locale
dictionary: Record<string, any>
children: React.ReactNode
setLocaleOnClient: (locale: Locale) => void
}
const I18n: FC<II18nProps> = ({
locale,
dictionary,
children,
}) => {
const locale = getLocaleOnClient()
useEffect(() => {
changeLanguage(locale)
}, [locale])

return (
<I18NContext.Provider value={{
locale,
Expand Down
5 changes: 1 addition & 4 deletions web/i18n/i18next-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ import datasetCreationEn from './lang/dataset-creation.en'
import datasetCreationZh from './lang/dataset-creation.zh'
import exploreEn from './lang/explore.en'
import exploreZh from './lang/explore.zh'
import { getLocaleOnClient } from '@/i18n/client'

const localLng = getLocaleOnClient()

const resources = {
'en': {
Expand Down Expand Up @@ -88,7 +85,7 @@ i18n.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
lng: localLng,
lng: undefined,
fallbackLng: 'en',
// debug: true,
resources,
Expand Down

0 comments on commit e660275

Please sign in to comment.