langroid 0.20.1__tar.gz → 0.22.0__tar.gz
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.
- {langroid-0.20.1 → langroid-0.22.0}/PKG-INFO +10 -4
- {langroid-0.20.1 → langroid-0.22.0}/README.md +9 -3
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/base.py +37 -1
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/chat_agent.py +31 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/arangodb/arangodb_agent.py +34 -27
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/arangodb/system_messages.py +6 -3
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/arangodb/tools.py +5 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tool_message.py +13 -1
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/__init__.py +2 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/openai_gpt.py +24 -6
- {langroid-0.20.1 → langroid-0.22.0}/pyproject.toml +1 -1
- {langroid-0.20.1 → langroid-0.22.0}/LICENSE +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/batch.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/callbacks/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/callbacks/chainlit.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/chat_document.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/helpers.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/junk +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/openai_assistant.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/arangodb/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/arangodb/utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/doc_chat_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_rag/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/lance_tools.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/neo4j/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/neo4j/system_messages.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/neo4j/tools.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/relevance_extractor_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/retriever_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/system_message.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/tools.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/table_chat_agent.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/structured_message.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/task.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/file_tools.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/google_search_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/metaphor_search_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/orchestration.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/recipient_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/retrieval_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/rewind_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/tools/segment_extract_tool.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/typed_task.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent/xml_tool_message.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/agent_config.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/cachedb/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/cachedb/base.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/cachedb/momento_cachedb.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/cachedb/redis_cachedb.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/base.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/clustering.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/models.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/protoc/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/protoc/embeddings.proto +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/embedding_models/remote_embeds.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/exceptions.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/.chainlit/config.toml +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/.chainlit/translations/en-US.json +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/azure_openai.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/base.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/config.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/mock_lm.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/base.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/mytypes.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/agent_chats.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/code-parsing.md +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/code_parser.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/config.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/document_parser.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/image_text.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/para_sentence_split.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/parse_json.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/parser.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/repo_loader.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/routing.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/search.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/spider.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/table_loader.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/url_loader.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/url_loader_cookies.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/urls.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/parsing/web_search.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/prompts/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/prompts/dialog.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/prompts/prompts_config.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/prompts/templates.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/py.typed +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/pydantic_v1/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/pydantic_v1/main.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/.chainlit/config.toml +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/.chainlit/translations/en-US.json +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/algorithms/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/algorithms/graph.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/configuration.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/constants.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/docker.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/git_utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/globals.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/llms/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/llms/strings.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/logging.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/object_registry.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/output/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/output/citations.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/output/printing.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/output/status.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/pandas_utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/pydantic_utils.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/system.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/types.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/web/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/utils/web/login.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/__init__.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/base.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/chromadb.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/lancedb.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/meilisearch.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/momento.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/qdrant_cloud.py +0 -0
- {langroid-0.20.1 → langroid-0.22.0}/langroid/vector_store/qdrantdb.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.22.0
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
License: MIT
|
6
6
|
Author: Prasad Chalasani
|
@@ -207,7 +207,7 @@ import langroid.language_models as lm
|
|
207
207
|
# set up LLM
|
208
208
|
llm_cfg = lm.OpenAIGPTConfig( # or OpenAIAssistant to use Assistant API
|
209
209
|
# any model served via an OpenAI-compatible API
|
210
|
-
chat_model=lm.OpenAIChatModel.
|
210
|
+
chat_model=lm.OpenAIChatModel.GPT4o, # or, e.g., "ollama/mistral"
|
211
211
|
)
|
212
212
|
# use LLM directly
|
213
213
|
mdl = lm.OpenAIGPT(llm_cfg)
|
@@ -248,6 +248,12 @@ teacher_task.run()
|
|
248
248
|
<details>
|
249
249
|
<summary> <b>Click to expand</b></summary>
|
250
250
|
|
251
|
+
- **Nov 2024:**
|
252
|
+
- **[0.22.0](https://langroid.github.io/langroid/notes/large-tool-results/)**:
|
253
|
+
Optional parameters to truncate large tool results.
|
254
|
+
- **[0.21.0](https://langroid.github.io/langroid/notes/gemini/)** Direct support for Gemini models via OpenAI client instead of using LiteLLM.
|
255
|
+
- **[0.20.0](https://github.com/langroid/langroid/releases/tag/0.20.0)** Support for
|
256
|
+
ArangoDB Knowledge Graphs.
|
251
257
|
- **Oct 2024:**
|
252
258
|
- **[0.18.0]** [LLMConfig.async_stream_quiet](https://langroid.github.io/langroid/notes/async-streaming/) flag to
|
253
259
|
turn off LLM output in async + stream mode.
|
@@ -361,7 +367,7 @@ teacher_task.run()
|
|
361
367
|
decides a filter and rephrase query to send to a RAG agent.
|
362
368
|
- **[0.1.141](https://github.com/langroid/langroid/releases/tag/0.1.141):**
|
363
369
|
API Simplifications to reduce boilerplate:
|
364
|
-
auto-select an available OpenAI model (preferring gpt-
|
370
|
+
auto-select an available OpenAI model (preferring gpt-4o), simplifies defaults.
|
365
371
|
Simpler `Task` initialization with default `ChatAgent`.
|
366
372
|
- **Nov 2023:**
|
367
373
|
- **[0.1.126](https://github.com/langroid/langroid/releases/tag/0.1.126):**
|
@@ -645,7 +651,7 @@ provides more information, and you can set each environment variable as follows:
|
|
645
651
|
- `AZURE_OPENAI_API_BASE` from the value of `ENDPOINT`, typically looks like `https://your.domain.azure.com`.
|
646
652
|
- For `AZURE_OPENAI_API_VERSION`, you can use the default value in `.env-template`, and latest version can be found [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/whats-new#azure-openai-chat-completion-general-availability-ga)
|
647
653
|
- `AZURE_OPENAI_DEPLOYMENT_NAME` is the name of the deployed model, which is defined by the user during the model setup
|
648
|
-
- `AZURE_OPENAI_MODEL_NAME` Azure OpenAI allows specific model names when you select the model for your deployment. You need to put precisly the exact model name that was selected. For example, GPT-
|
654
|
+
- `AZURE_OPENAI_MODEL_NAME` Azure OpenAI allows specific model names when you select the model for your deployment. You need to put precisly the exact model name that was selected. For example, GPT-4 (should be `gpt-4-32k` or `gpt-4`).
|
649
655
|
- `AZURE_OPENAI_MODEL_VERSION` is required if `AZURE_OPENAI_MODEL_NAME = gpt=4`, which will assist Langroid to determine the cost of the model
|
650
656
|
</details>
|
651
657
|
|
@@ -94,7 +94,7 @@ import langroid.language_models as lm
|
|
94
94
|
# set up LLM
|
95
95
|
llm_cfg = lm.OpenAIGPTConfig( # or OpenAIAssistant to use Assistant API
|
96
96
|
# any model served via an OpenAI-compatible API
|
97
|
-
chat_model=lm.OpenAIChatModel.
|
97
|
+
chat_model=lm.OpenAIChatModel.GPT4o, # or, e.g., "ollama/mistral"
|
98
98
|
)
|
99
99
|
# use LLM directly
|
100
100
|
mdl = lm.OpenAIGPT(llm_cfg)
|
@@ -135,6 +135,12 @@ teacher_task.run()
|
|
135
135
|
<details>
|
136
136
|
<summary> <b>Click to expand</b></summary>
|
137
137
|
|
138
|
+
- **Nov 2024:**
|
139
|
+
- **[0.22.0](https://langroid.github.io/langroid/notes/large-tool-results/)**:
|
140
|
+
Optional parameters to truncate large tool results.
|
141
|
+
- **[0.21.0](https://langroid.github.io/langroid/notes/gemini/)** Direct support for Gemini models via OpenAI client instead of using LiteLLM.
|
142
|
+
- **[0.20.0](https://github.com/langroid/langroid/releases/tag/0.20.0)** Support for
|
143
|
+
ArangoDB Knowledge Graphs.
|
138
144
|
- **Oct 2024:**
|
139
145
|
- **[0.18.0]** [LLMConfig.async_stream_quiet](https://langroid.github.io/langroid/notes/async-streaming/) flag to
|
140
146
|
turn off LLM output in async + stream mode.
|
@@ -248,7 +254,7 @@ teacher_task.run()
|
|
248
254
|
decides a filter and rephrase query to send to a RAG agent.
|
249
255
|
- **[0.1.141](https://github.com/langroid/langroid/releases/tag/0.1.141):**
|
250
256
|
API Simplifications to reduce boilerplate:
|
251
|
-
auto-select an available OpenAI model (preferring gpt-
|
257
|
+
auto-select an available OpenAI model (preferring gpt-4o), simplifies defaults.
|
252
258
|
Simpler `Task` initialization with default `ChatAgent`.
|
253
259
|
- **Nov 2023:**
|
254
260
|
- **[0.1.126](https://github.com/langroid/langroid/releases/tag/0.1.126):**
|
@@ -532,7 +538,7 @@ provides more information, and you can set each environment variable as follows:
|
|
532
538
|
- `AZURE_OPENAI_API_BASE` from the value of `ENDPOINT`, typically looks like `https://your.domain.azure.com`.
|
533
539
|
- For `AZURE_OPENAI_API_VERSION`, you can use the default value in `.env-template`, and latest version can be found [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/whats-new#azure-openai-chat-completion-general-availability-ga)
|
534
540
|
- `AZURE_OPENAI_DEPLOYMENT_NAME` is the name of the deployed model, which is defined by the user during the model setup
|
535
|
-
- `AZURE_OPENAI_MODEL_NAME` Azure OpenAI allows specific model names when you select the model for your deployment. You need to put precisly the exact model name that was selected. For example, GPT-
|
541
|
+
- `AZURE_OPENAI_MODEL_NAME` Azure OpenAI allows specific model names when you select the model for your deployment. You need to put precisly the exact model name that was selected. For example, GPT-4 (should be `gpt-4-32k` or `gpt-4`).
|
536
542
|
- `AZURE_OPENAI_MODEL_VERSION` is required if `AZURE_OPENAI_MODEL_NAME = gpt=4`, which will assist Langroid to determine the cost of the model
|
537
543
|
</details>
|
538
544
|
|
@@ -1450,6 +1450,40 @@ class Agent(ABC):
|
|
1450
1450
|
|
1451
1451
|
return None
|
1452
1452
|
|
1453
|
+
def _maybe_truncate_result(
|
1454
|
+
self, result: str | ChatDocument | None, max_tokens: int | None
|
1455
|
+
) -> str | ChatDocument | None:
|
1456
|
+
"""
|
1457
|
+
Truncate the result string to `max_tokens` tokens.
|
1458
|
+
"""
|
1459
|
+
if result is None or max_tokens is None:
|
1460
|
+
return result
|
1461
|
+
result_str = result.content if isinstance(result, ChatDocument) else result
|
1462
|
+
num_tokens = (
|
1463
|
+
self.parser.num_tokens(result_str)
|
1464
|
+
if self.parser is not None
|
1465
|
+
else len(result_str) / 4.0
|
1466
|
+
)
|
1467
|
+
if num_tokens <= max_tokens:
|
1468
|
+
return result
|
1469
|
+
truncate_warning = f"""
|
1470
|
+
The TOOL result was large, so it was truncated to {max_tokens} tokens.
|
1471
|
+
To get the full result, the TOOL must be called again.
|
1472
|
+
"""
|
1473
|
+
if isinstance(result, str):
|
1474
|
+
return (
|
1475
|
+
self.parser.truncate_tokens(result, max_tokens)
|
1476
|
+
if self.parser is not None
|
1477
|
+
else result[: max_tokens * 4] # approx truncate
|
1478
|
+
) + truncate_warning
|
1479
|
+
elif isinstance(result, ChatDocument):
|
1480
|
+
result.content = (
|
1481
|
+
self.parser.truncate_tokens(result.content, max_tokens)
|
1482
|
+
if self.parser is not None
|
1483
|
+
else result.content[: max_tokens * 4] # approx truncate
|
1484
|
+
) + truncate_warning
|
1485
|
+
return result
|
1486
|
+
|
1453
1487
|
def handle_tool_message(
|
1454
1488
|
self,
|
1455
1489
|
tool: ToolMessage,
|
@@ -1485,7 +1519,9 @@ class Agent(ABC):
|
|
1485
1519
|
# not a pydantic validation error,
|
1486
1520
|
# which we check in `handle_message`
|
1487
1521
|
raise e
|
1488
|
-
return
|
1522
|
+
return self._maybe_truncate_result(
|
1523
|
+
result, tool._max_result_tokens
|
1524
|
+
) # type: ignore
|
1489
1525
|
|
1490
1526
|
def num_tokens(self, prompt: str | List[LLMMessage]) -> int:
|
1491
1527
|
if self.parser is None:
|
@@ -623,6 +623,33 @@ class ChatAgent(Agent):
|
|
623
623
|
self.llm_tools_usable.discard(r)
|
624
624
|
self.llm_functions_usable.discard(r)
|
625
625
|
|
626
|
+
def _reduce_raw_tool_results(self, message: ChatDocument) -> None:
|
627
|
+
"""
|
628
|
+
If message is the result of a ToolMessage that had the
|
629
|
+
flag `_retain_raw_results = False`, then we replace contents
|
630
|
+
with a placeholder message.
|
631
|
+
"""
|
632
|
+
parent_message: ChatDocument | None = message.parent
|
633
|
+
tools = [] if parent_message is None else parent_message.tool_messages
|
634
|
+
truncate_tools = [t for t in tools if t._max_retained_tokens is not None]
|
635
|
+
limiting_tool = truncate_tools[0] if len(truncate_tools) > 0 else None
|
636
|
+
if limiting_tool is not None and limiting_tool._max_retained_tokens is not None:
|
637
|
+
tool_name = limiting_tool.default_value("request")
|
638
|
+
max_tokens: int = limiting_tool._max_retained_tokens
|
639
|
+
truncation_warning = f"""
|
640
|
+
The result of the {tool_name} tool were too large,
|
641
|
+
and has been truncated to {max_tokens} tokens.
|
642
|
+
To obtain the full result, the tool needs to be re-used.
|
643
|
+
"""
|
644
|
+
llm_msg = self.message_history[message.metadata.msg_idx]
|
645
|
+
orig_content = llm_msg.content
|
646
|
+
new_content = (
|
647
|
+
self.parser.truncate_tokens(orig_content, max_tokens)
|
648
|
+
if self.parser is not None
|
649
|
+
else orig_content[: max_tokens * 4] # approx truncation
|
650
|
+
)
|
651
|
+
llm_msg.content = new_content + "\n\n" + truncation_warning
|
652
|
+
|
626
653
|
def llm_response(
|
627
654
|
self, message: Optional[str | ChatDocument] = None
|
628
655
|
) -> Optional[ChatDocument]:
|
@@ -650,6 +677,8 @@ class ChatAgent(Agent):
|
|
650
677
|
self.message_history.extend(ChatDocument.to_LLMMessage(response))
|
651
678
|
response.metadata.msg_idx = len(self.message_history) - 1
|
652
679
|
response.metadata.agent_id = self.id
|
680
|
+
if isinstance(message, ChatDocument):
|
681
|
+
self._reduce_raw_tool_results(message)
|
653
682
|
# Preserve trail of tool_ids for OpenAI Assistant fn-calls
|
654
683
|
response.metadata.tool_ids = (
|
655
684
|
[]
|
@@ -681,6 +710,8 @@ class ChatAgent(Agent):
|
|
681
710
|
self.message_history.extend(ChatDocument.to_LLMMessage(response))
|
682
711
|
response.metadata.msg_idx = len(self.message_history) - 1
|
683
712
|
response.metadata.agent_id = self.id
|
713
|
+
if isinstance(message, ChatDocument):
|
714
|
+
self._reduce_raw_tool_results(message)
|
684
715
|
# Preserve trail of tool_ids for OpenAI Assistant fn-calls
|
685
716
|
response.metadata.tool_ids = (
|
686
717
|
[]
|
@@ -94,7 +94,6 @@ class ArangoChatAgentConfig(ChatAgentConfig):
|
|
94
94
|
prepopulate_schema: bool = True
|
95
95
|
use_functions_api: bool = True
|
96
96
|
max_num_results: int = 10 # how many results to return from AQL query
|
97
|
-
max_result_tokens: int = 1000 # truncate long results to this many tokens
|
98
97
|
max_schema_fields: int = 500 # max fields to show in schema
|
99
98
|
max_tries: int = 10 # how many attempts to answer user question
|
100
99
|
use_tools: bool = False
|
@@ -118,6 +117,7 @@ class ArangoChatAgent(ChatAgent):
|
|
118
117
|
def init_state(self) -> None:
|
119
118
|
super().init_state()
|
120
119
|
self.current_retrieval_aql_query: str = ""
|
120
|
+
self.current_schema_params: ArangoSchemaTool = ArangoSchemaTool()
|
121
121
|
self.num_tries = 0 # how many attempts to answer user question
|
122
122
|
|
123
123
|
def user_response(
|
@@ -125,6 +125,8 @@ class ArangoChatAgent(ChatAgent):
|
|
125
125
|
msg: Optional[str | ChatDocument] = None,
|
126
126
|
) -> Optional[ChatDocument]:
|
127
127
|
response = super().user_response(msg)
|
128
|
+
if response is None:
|
129
|
+
return None
|
128
130
|
response_str = response.content if response is not None else ""
|
129
131
|
if response_str != "":
|
130
132
|
self.num_tries = 0 # reset number of tries if user responds
|
@@ -165,7 +167,20 @@ class ArangoChatAgent(ChatAgent):
|
|
165
167
|
"""
|
166
168
|
)
|
167
169
|
|
168
|
-
|
170
|
+
response = super().llm_response(message)
|
171
|
+
if (
|
172
|
+
response is not None
|
173
|
+
and self.config.chat_mode
|
174
|
+
and self.config.addressing_prefix in response.content
|
175
|
+
and self.has_tool_message_attempt(response)
|
176
|
+
):
|
177
|
+
# response contains both a user-addressing and a tool, which
|
178
|
+
# is not allowed, so remove the user-addressing prefix
|
179
|
+
response.content = response.content.replace(
|
180
|
+
self.config.addressing_prefix, ""
|
181
|
+
)
|
182
|
+
|
183
|
+
return response
|
169
184
|
|
170
185
|
def _validate_config(self) -> None:
|
171
186
|
assert isinstance(self.config, ArangoChatAgentConfig)
|
@@ -327,28 +342,6 @@ class ArangoChatAgent(ChatAgent):
|
|
327
342
|
success=False, data=f"Failed after max retries: {str(e)}"
|
328
343
|
)
|
329
344
|
|
330
|
-
def _limit_tokens(self, text: str) -> str:
|
331
|
-
result = text
|
332
|
-
n_toks = self.num_tokens(result)
|
333
|
-
if n_toks > self.config.max_result_tokens:
|
334
|
-
logger.warning(
|
335
|
-
f"""
|
336
|
-
Your query resulted in a large result of
|
337
|
-
{n_toks} tokens,
|
338
|
-
which will be truncated to {self.config.max_result_tokens} tokens.
|
339
|
-
If this does not give satisfactory results,
|
340
|
-
please retry with a more focused query.
|
341
|
-
"""
|
342
|
-
)
|
343
|
-
if self.parser is not None:
|
344
|
-
result = self.parser.truncate_tokens(
|
345
|
-
result,
|
346
|
-
self.config.max_result_tokens,
|
347
|
-
)
|
348
|
-
else:
|
349
|
-
result = result[: self.config.max_result_tokens * 4] # truncate roughly
|
350
|
-
return result
|
351
|
-
|
352
345
|
def aql_retrieval_tool(self, msg: AQLRetrievalTool) -> str:
|
353
346
|
"""Handle AQL query for data retrieval"""
|
354
347
|
if not self.tried_schema:
|
@@ -363,6 +356,11 @@ class ArangoChatAgent(ChatAgent):
|
|
363
356
|
"""
|
364
357
|
self.num_tries += 1
|
365
358
|
query = msg.aql_query
|
359
|
+
if query == self.current_retrieval_aql_query:
|
360
|
+
return """
|
361
|
+
You have already tried this query, so you will get the same results again!
|
362
|
+
If you need to retry, please MODIFY the query to get different results.
|
363
|
+
"""
|
366
364
|
self.current_retrieval_aql_query = query
|
367
365
|
logger.info(f"Executing AQL query: {query}")
|
368
366
|
response = self.read_query(query)
|
@@ -374,9 +372,7 @@ class ArangoChatAgent(ChatAgent):
|
|
374
372
|
Try modifying your query based on the RETRY-SUGGESTIONS
|
375
373
|
in your instructions.
|
376
374
|
"""
|
377
|
-
|
378
|
-
result = str(response.data)
|
379
|
-
return self._limit_tokens(result)
|
375
|
+
return str(response.data)
|
380
376
|
|
381
377
|
def aql_creation_tool(self, msg: AQLCreationTool) -> str:
|
382
378
|
"""Handle AQL query for creating data"""
|
@@ -399,6 +395,17 @@ class ArangoChatAgent(ChatAgent):
|
|
399
395
|
else show all properties and example-docs.
|
400
396
|
"""
|
401
397
|
|
398
|
+
if (
|
399
|
+
msg is not None
|
400
|
+
and msg.collections == self.current_schema_params.collections
|
401
|
+
and msg.properties == self.current_schema_params.properties
|
402
|
+
):
|
403
|
+
return """
|
404
|
+
You have already tried this schema TOOL, so you will get the same results
|
405
|
+
again! Please MODIFY the tool params `collections` or `properties` to get
|
406
|
+
different results.
|
407
|
+
"""
|
408
|
+
|
402
409
|
if msg is not None:
|
403
410
|
collections = msg.collections
|
404
411
|
properties = msg.properties
|
@@ -144,14 +144,17 @@ THEN make ANOTHER query, and so on, until you have the answer.
|
|
144
144
|
RETRY-SUGGESTIONS:
|
145
145
|
If you receive a null or other unexpected result,
|
146
146
|
(a) make sure you use the available TOOLs correctly,
|
147
|
-
(b)
|
148
|
-
|
147
|
+
(b) learn more about the schema using EITHER:
|
148
|
+
- `{arango_schema_tool_name}` tool/function-call to find properties of specific
|
149
|
+
collections or other parts of the schema, OR
|
150
|
+
- `{aql_retrieval_tool_name}` tool/function-call to use AQL queries to
|
151
|
+
find specific parts of the schema.
|
149
152
|
(c) Collection names are CASE-SENSITIVE -- make sure you adhere to the exact
|
150
153
|
collection name you found in the schema.
|
151
154
|
(d) see if you have made an assumption in your AQL query, and try another way,
|
152
155
|
or use `{aql_retrieval_tool_name}` to explore the database contents before
|
153
156
|
submitting your final query.
|
154
|
-
(
|
157
|
+
(e) Try APPROXIMATE or PARTIAL MATCHES to strings in the user's query,
|
155
158
|
e.g. user may ask about "Godfather" instead of "The Godfather",
|
156
159
|
or try using CASE-INSENSITIVE MATCHES.
|
157
160
|
|
@@ -13,6 +13,9 @@ class AQLRetrievalTool(ToolMessage):
|
|
13
13
|
"""
|
14
14
|
aql_query: str
|
15
15
|
|
16
|
+
_max_result_tokens = 500
|
17
|
+
_max_retained_tokens = 200
|
18
|
+
|
16
19
|
@classmethod
|
17
20
|
def examples(cls) -> List[ToolMessage | Tuple[str, ToolMessage]]:
|
18
21
|
"""Few-shot examples to include in tool instructions."""
|
@@ -98,5 +101,7 @@ class ArangoSchemaTool(ToolMessage):
|
|
98
101
|
properties: bool = True
|
99
102
|
collections: List[str] | None = None
|
100
103
|
|
104
|
+
_max_result_tokens = 500
|
105
|
+
|
101
106
|
|
102
107
|
arango_schema_tool_name = ArangoSchemaTool.default_value("request")
|
@@ -44,7 +44,19 @@ class ToolMessage(ABC, BaseModel):
|
|
44
44
|
|
45
45
|
_allow_llm_use: bool = True # allow an LLM to use (i.e. generate) this tool?
|
46
46
|
|
47
|
-
#
|
47
|
+
# Optional param to limit number of result tokens to retain in msg history.
|
48
|
+
# Some tools can have large results that we may not want to fully retain,
|
49
|
+
# e.g. result of a db query, which the LLM later reduces to a summary, so
|
50
|
+
# in subsequent dialog we may only want to retain the summary,
|
51
|
+
# and replace this raw result truncated to _max_result_tokens.
|
52
|
+
# Important to note: unlike _max_result_tokens, this param is used
|
53
|
+
# NOT used to immediately truncate the result;
|
54
|
+
# it is only used to truncate what is retained in msg history AFTER the
|
55
|
+
# response to this result.
|
56
|
+
_max_retained_tokens: int | None = None
|
57
|
+
|
58
|
+
# Optional param to limit number of tokens in the result of the tool.
|
59
|
+
_max_result_tokens: int | None = None
|
48
60
|
|
49
61
|
class Config:
|
50
62
|
extra = Extra.allow
|
@@ -17,6 +17,7 @@ from .base import (
|
|
17
17
|
from .openai_gpt import (
|
18
18
|
OpenAIChatModel,
|
19
19
|
AnthropicModel,
|
20
|
+
GeminiModel,
|
20
21
|
OpenAICompletionModel,
|
21
22
|
OpenAIGPTConfig,
|
22
23
|
OpenAIGPT,
|
@@ -41,6 +42,7 @@ __all__ = [
|
|
41
42
|
"LLMResponse",
|
42
43
|
"OpenAIChatModel",
|
43
44
|
"AnthropicModel",
|
45
|
+
"GeminiModel",
|
44
46
|
"OpenAICompletionModel",
|
45
47
|
"OpenAIGPTConfig",
|
46
48
|
"OpenAIGPT",
|
@@ -66,6 +66,7 @@ if "OLLAMA_HOST" in os.environ:
|
|
66
66
|
else:
|
67
67
|
OLLAMA_BASE_URL = "http://localhost:11434/v1"
|
68
68
|
|
69
|
+
GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/"
|
69
70
|
OLLAMA_API_KEY = "ollama"
|
70
71
|
DUMMY_API_KEY = "xxx"
|
71
72
|
|
@@ -92,6 +93,14 @@ class OpenAIChatModel(str, Enum):
|
|
92
93
|
O1_MINI = "o1-mini"
|
93
94
|
|
94
95
|
|
96
|
+
class GeminiModel(str, Enum):
|
97
|
+
"""Enum for Gemini models"""
|
98
|
+
|
99
|
+
GEMINI_1_5_FLASH = "gemini-1.5-flash"
|
100
|
+
GEMINI_1_5_FLASH_8B = "gemini-1.5-flash-8b"
|
101
|
+
GEMINI_1_5_PRO = "gemini-1.5-pro"
|
102
|
+
|
103
|
+
|
95
104
|
class OpenAICompletionModel(str, Enum):
|
96
105
|
"""Enum for OpenAI Completion models"""
|
97
106
|
|
@@ -503,6 +512,7 @@ class OpenAIGPT(LanguageModel):
|
|
503
512
|
|
504
513
|
self.is_groq = self.config.chat_model.startswith("groq/")
|
505
514
|
self.is_cerebras = self.config.chat_model.startswith("cerebras/")
|
515
|
+
self.is_gemini = self.config.chat_model.startswith("gemini/")
|
506
516
|
|
507
517
|
if self.is_groq:
|
508
518
|
self.config.chat_model = self.config.chat_model.replace("groq/", "")
|
@@ -524,6 +534,11 @@ class OpenAIGPT(LanguageModel):
|
|
524
534
|
api_key=self.api_key,
|
525
535
|
)
|
526
536
|
else:
|
537
|
+
if self.is_gemini:
|
538
|
+
self.config.chat_model = self.config.chat_model.replace("gemini/", "")
|
539
|
+
self.api_key = os.getenv("GEMINI_API_KEY", DUMMY_API_KEY)
|
540
|
+
self.api_base = GEMINI_BASE_URL
|
541
|
+
|
527
542
|
self.client = OpenAI(
|
528
543
|
api_key=self.api_key,
|
529
544
|
base_url=self.api_base,
|
@@ -623,7 +638,13 @@ class OpenAIGPT(LanguageModel):
|
|
623
638
|
Currently main troublemaker is o1* series.
|
624
639
|
"""
|
625
640
|
match self.config.chat_model:
|
626
|
-
case
|
641
|
+
case (
|
642
|
+
OpenAIChatModel.O1_MINI
|
643
|
+
| OpenAIChatModel.O1_PREVIEW
|
644
|
+
| GeminiModel.GEMINI_1_5_FLASH
|
645
|
+
| GeminiModel.GEMINI_1_5_FLASH_8B
|
646
|
+
| GeminiModel.GEMINI_1_5_PRO
|
647
|
+
):
|
627
648
|
return {"max_tokens": "max_completion_tokens"}
|
628
649
|
case _:
|
629
650
|
return {}
|
@@ -1229,13 +1250,10 @@ class OpenAIGPT(LanguageModel):
|
|
1229
1250
|
cost = 0.0
|
1230
1251
|
prompt_tokens = 0
|
1231
1252
|
completion_tokens = 0
|
1232
|
-
if not cached and not self.get_stream():
|
1253
|
+
if not cached and not self.get_stream() and response["usage"] is not None:
|
1233
1254
|
prompt_tokens = response["usage"]["prompt_tokens"]
|
1234
1255
|
completion_tokens = response["usage"]["completion_tokens"]
|
1235
|
-
cost = self._cost_chat_model(
|
1236
|
-
response["usage"]["prompt_tokens"],
|
1237
|
-
response["usage"]["completion_tokens"],
|
1238
|
-
)
|
1256
|
+
cost = self._cost_chat_model(prompt_tokens, completion_tokens)
|
1239
1257
|
|
1240
1258
|
return LLMTokenUsage(
|
1241
1259
|
prompt_tokens=prompt_tokens, completion_tokens=completion_tokens, cost=cost
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langroid-0.20.1 → langroid-0.22.0}/langroid/agent/special/sql/utils/description_extractors.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/.chainlit/translations/en-US.json
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/hf_formatter.py
RENAMED
File without changes
|
{langroid-0.20.1 → langroid-0.22.0}/langroid/language_models/prompt_formatter/llama2_formatter.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|