langroid 0.1.258__tar.gz → 0.1.261__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.1.258 → langroid-0.1.261}/PKG-INFO +3 -2
- {langroid-0.1.258 → langroid-0.1.261}/README.md +2 -1
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/callbacks/chainlit.py +45 -7
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/chat_document.py +0 -2
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/task.py +51 -46
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/openai_gpt.py +3 -1
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/qdrantdb.py +1 -1
- {langroid-0.1.258 → langroid-0.1.261}/pyproject.toml +1 -1
- {langroid-0.1.258 → langroid-0.1.261}/LICENSE +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/batch.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/callbacks/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/helpers.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/junk +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/openai_assistant.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/doc_chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_rag/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/lance_tools.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/neo4j/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/neo4j/utils/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/neo4j/utils/system_message.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/relevance_extractor_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/retriever_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/utils/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/utils/system_message.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/sql/utils/tools.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/special/table_chat_agent.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tool_message.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/extract_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/generator_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/google_search_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/metaphor_search_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/recipient_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/retrieval_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/run_python_code.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent/tools/segment_extract_tool.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/agent_config.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/cachedb/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/cachedb/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/cachedb/momento_cachedb.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/cachedb/redis_cachedb.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/clustering.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/models.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/embeddings.proto +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/remote_embeds.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/exceptions.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/azure_openai.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/config.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/openai_assistants.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/prompt_formatter/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/prompt_formatter/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/utils.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/mytypes.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/agent_chats.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/code-parsing.md +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/code_parser.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/config.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/document_parser.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/image_text.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/para_sentence_split.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/parse_json.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/parser.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/parser.pyi +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/repo_loader.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/routing.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/search.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/spider.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/table_loader.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/url_loader.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/url_loader_cookies.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/urls.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/utils.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/parsing/web_search.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/dialog.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/prompts_config.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/templates.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/prompts/transforms.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/algorithms/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/algorithms/graph.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/configuration.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/constants.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/docker.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/globals.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/llms/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/llms/strings.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/logging.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/output/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/output/citations.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/output/printing.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/output/status.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/pandas_utils.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/pydantic_utils.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/system.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/web/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/utils/web/login.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/__init__.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/base.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/chromadb.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/lancedb.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/meilisearch.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/momento.py +0 -0
- {langroid-0.1.258 → langroid-0.1.261}/langroid/vector_store/qdrant_cloud.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.261
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
License: MIT
|
6
6
|
Author: Prasad Chalasani
|
@@ -110,6 +110,7 @@ Description-Content-Type: text/markdown
|
|
110
110
|
<div align="center">
|
111
111
|
|
112
112
|
[](https://pypi.org/project/langroid/)
|
113
|
+
[](https://pypi.org/project/langroid/)
|
113
114
|
[](https://github.com/langroid/langroid/actions/workflows/pytest.yml)
|
114
115
|
[](https://codecov.io/gh/langroid/langroid)
|
115
116
|
[](https://github.com/langroid/langroid/actions/workflows/docker-publish.yml)
|
@@ -436,7 +437,7 @@ section above)
|
|
436
437
|
a task of an agent can delegate to other sub-tasks: from the point of view of a Task,
|
437
438
|
sub-tasks are simply additional responders, to be used in a round-robin fashion
|
438
439
|
after the agent's own responders.
|
439
|
-
- **Modularity,
|
440
|
+
- **Modularity, Reusability, Loose coupling:** The `Agent` and `Task` abstractions allow users to design
|
440
441
|
Agents with specific skills, wrap them in Tasks, and combine tasks in a flexible way.
|
441
442
|
- **LLM Support**: Langroid supports OpenAI LLMs as well as LLMs from hundreds of
|
442
443
|
providers (local/open or remote/commercial) via proxy libraries and local model servers
|
@@ -6,6 +6,7 @@
|
|
6
6
|
<div align="center">
|
7
7
|
|
8
8
|
[](https://pypi.org/project/langroid/)
|
9
|
+
[](https://pypi.org/project/langroid/)
|
9
10
|
[](https://github.com/langroid/langroid/actions/workflows/pytest.yml)
|
10
11
|
[](https://codecov.io/gh/langroid/langroid)
|
11
12
|
[](https://github.com/langroid/langroid/actions/workflows/docker-publish.yml)
|
@@ -332,7 +333,7 @@ section above)
|
|
332
333
|
a task of an agent can delegate to other sub-tasks: from the point of view of a Task,
|
333
334
|
sub-tasks are simply additional responders, to be used in a round-robin fashion
|
334
335
|
after the agent's own responders.
|
335
|
-
- **Modularity,
|
336
|
+
- **Modularity, Reusability, Loose coupling:** The `Agent` and `Task` abstractions allow users to design
|
336
337
|
Agents with specific skills, wrap them in Tasks, and combine tasks in a flexible way.
|
337
338
|
- **LLM Support**: Langroid supports OpenAI LLMs as well as LLMs from hundreds of
|
338
339
|
providers (local/open or remote/commercial) via proxy libraries and local model servers
|
@@ -214,6 +214,7 @@ def wrap_text_preserving_structure(text: str, width: int = 90) -> str:
|
|
214
214
|
|
215
215
|
class ChainlitCallbackConfig(BaseSettings):
|
216
216
|
user_has_agent_name: bool = True # show agent name in front of "YOU" ?
|
217
|
+
show_subtask_response: bool = True # show sub-task response as a step?
|
217
218
|
|
218
219
|
|
219
220
|
class ChainlitAgentCallbacks:
|
@@ -277,12 +278,6 @@ class ChainlitAgentCallbacks:
|
|
277
278
|
|
278
279
|
def start_llm_stream(self) -> Callable[[str], None]:
|
279
280
|
"""Returns a streaming fn that can be passed to the LLM class"""
|
280
|
-
logger.info(
|
281
|
-
f"""
|
282
|
-
Starting LLM stream for {self.agent.config.name}
|
283
|
-
under parent {self._get_parent_id()}
|
284
|
-
"""
|
285
|
-
)
|
286
281
|
self.stream = cl.Step(
|
287
282
|
id=self.curr_step.id if self.curr_step is not None else None,
|
288
283
|
name=self._entity_name("llm"),
|
@@ -291,6 +286,13 @@ class ChainlitAgentCallbacks:
|
|
291
286
|
)
|
292
287
|
self.last_step = self.stream
|
293
288
|
self.curr_step = None
|
289
|
+
logger.info(
|
290
|
+
f"""
|
291
|
+
Starting LLM stream for {self.agent.config.name}
|
292
|
+
id = {self.stream.id}
|
293
|
+
under parent {self._get_parent_id()}
|
294
|
+
"""
|
295
|
+
)
|
294
296
|
run_sync(self.stream.send()) # type: ignore
|
295
297
|
|
296
298
|
def stream_token(t: str) -> None:
|
@@ -323,6 +325,13 @@ class ChainlitAgentCallbacks:
|
|
323
325
|
language="json" if is_tool else None,
|
324
326
|
)
|
325
327
|
step.output = textwrap.dedent(content) or NO_ANSWER
|
328
|
+
logger.info(
|
329
|
+
f"""
|
330
|
+
Finish STREAM LLM response for {self.agent.config.name}
|
331
|
+
id = {step.id}
|
332
|
+
under parent {self._get_parent_id()}
|
333
|
+
"""
|
334
|
+
)
|
326
335
|
run_sync(step.update()) # type: ignore
|
327
336
|
|
328
337
|
def show_llm_response(
|
@@ -343,6 +352,13 @@ class ChainlitAgentCallbacks:
|
|
343
352
|
self.last_step = step
|
344
353
|
self.curr_step = None
|
345
354
|
step.output = textwrap.dedent(content) or NO_ANSWER
|
355
|
+
logger.info(
|
356
|
+
f"""
|
357
|
+
Showing NON-STREAM LLM response for {self.agent.config.name}
|
358
|
+
id = {step.id}
|
359
|
+
under parent {self._get_parent_id()}
|
360
|
+
"""
|
361
|
+
)
|
346
362
|
run_sync(step.send()) # type: ignore
|
347
363
|
|
348
364
|
def show_error_message(self, error: str) -> None:
|
@@ -374,6 +390,13 @@ class ChainlitAgentCallbacks:
|
|
374
390
|
self.last_step = step
|
375
391
|
self.curr_step = None
|
376
392
|
step.output = content
|
393
|
+
logger.info(
|
394
|
+
f"""
|
395
|
+
Showing AGENT response for {self.agent.config.name}
|
396
|
+
id = {step.id}
|
397
|
+
under parent {self._get_parent_id()}
|
398
|
+
"""
|
399
|
+
)
|
377
400
|
run_sync(step.send()) # type: ignore
|
378
401
|
|
379
402
|
def show_start_response(self, entity: str) -> None:
|
@@ -390,6 +413,13 @@ class ChainlitAgentCallbacks:
|
|
390
413
|
step.output = ""
|
391
414
|
self.last_step = step
|
392
415
|
self.curr_step = step
|
416
|
+
logger.info(
|
417
|
+
f"""
|
418
|
+
Showing START response for {self.agent.config.name} ({entity})
|
419
|
+
id = {step.id}
|
420
|
+
under parent {self._get_parent_id()}
|
421
|
+
"""
|
422
|
+
)
|
393
423
|
run_sync(step.send()) # type: ignore
|
394
424
|
|
395
425
|
def _entity_name(
|
@@ -459,6 +489,13 @@ class ChainlitAgentCallbacks:
|
|
459
489
|
parent_id=self._get_parent_id(),
|
460
490
|
)
|
461
491
|
step.output = message
|
492
|
+
logger.info(
|
493
|
+
f"""
|
494
|
+
Showing USER response for {self.agent.config.name}
|
495
|
+
id = {step.id}
|
496
|
+
under parent {self._get_parent_id()}
|
497
|
+
"""
|
498
|
+
)
|
462
499
|
run_sync(step.send())
|
463
500
|
|
464
501
|
def show_first_user_message(self, msg: cl.Message):
|
@@ -575,7 +612,8 @@ class ChainlitTaskCallbacks(ChainlitAgentCallbacks):
|
|
575
612
|
super().__init__(task.agent, msg, config)
|
576
613
|
self._inject_callbacks(task)
|
577
614
|
self.task = task
|
578
|
-
|
615
|
+
if config.show_subtask_response:
|
616
|
+
self.task.callbacks.show_subtask_response = self.show_subtask_response
|
579
617
|
|
580
618
|
@classmethod
|
581
619
|
def _inject_callbacks(
|
@@ -45,8 +45,6 @@ class ChatDocMetaData(DocMetaData):
|
|
45
45
|
parent: Optional["ChatDocument"] = None
|
46
46
|
sender: Entity
|
47
47
|
tool_ids: List[str] = [] # stack of tool_ids; used by OpenAIAssistant
|
48
|
-
# when result returns to parent, pretend message is from this entity
|
49
|
-
parent_responder: None | Entity = None
|
50
48
|
block: None | Entity = None
|
51
49
|
sender_name: str = ""
|
52
50
|
recipient: str = ""
|
@@ -72,7 +72,7 @@ class TaskConfig(BaseModel):
|
|
72
72
|
|
73
73
|
inf_loop_cycle_len: int = 10
|
74
74
|
inf_loop_dominance_factor: float = 1.5
|
75
|
-
inf_loop_wait_factor:
|
75
|
+
inf_loop_wait_factor: int = 5
|
76
76
|
|
77
77
|
|
78
78
|
class Task:
|
@@ -156,6 +156,11 @@ class Task:
|
|
156
156
|
interactive (bool): if true, wait for human input after each non-human
|
157
157
|
response (prevents infinite loop of non-human responses).
|
158
158
|
Default is true. If false, then `default_human_response` is set to ""
|
159
|
+
Note: When interactive = False, the one exception is when the user
|
160
|
+
is explicitly addressed, via "@user" or using RecipientTool, in which
|
161
|
+
case the system will wait for a user response. In other words, use
|
162
|
+
`interactive=False` when you want a "largely non-interactive"
|
163
|
+
run, with the exception of explicit user addressing.
|
159
164
|
only_user_quits_root (bool): if true, only user can quit the root task.
|
160
165
|
[This param is ignored & deprecated; Keeping for backward compatibility.
|
161
166
|
Instead of this, setting `interactive` suffices]
|
@@ -185,7 +190,11 @@ class Task:
|
|
185
190
|
# counts of distinct pending messages in history,
|
186
191
|
# to help detect (exact) infinite loops
|
187
192
|
self.message_counter: Counter[str] = Counter()
|
188
|
-
self.
|
193
|
+
self._init_message_counter()
|
194
|
+
|
195
|
+
self.history: Deque[str] = deque(
|
196
|
+
maxlen=self.config.inf_loop_cycle_len * self.config.inf_loop_wait_factor
|
197
|
+
)
|
189
198
|
# copy the agent's config, so that we don't modify the original agent's config,
|
190
199
|
# which may be shared by other agents.
|
191
200
|
try:
|
@@ -329,6 +338,12 @@ class Task:
|
|
329
338
|
def __str__(self) -> str:
|
330
339
|
return f"{self.name}"
|
331
340
|
|
341
|
+
def _init_message_counter(self) -> None:
|
342
|
+
self.message_counter.clear()
|
343
|
+
# create a unique string that will not likely be in any message,
|
344
|
+
# so we always have a message with count=1
|
345
|
+
self.message_counter.update([hash("___NO_MESSAGE___")])
|
346
|
+
|
332
347
|
def _cache_session_store(self, key: str, value: str) -> None:
|
333
348
|
"""
|
334
349
|
Cache a key-value pair for the current session.
|
@@ -440,7 +455,7 @@ class Task:
|
|
440
455
|
),
|
441
456
|
)
|
442
457
|
else:
|
443
|
-
self.pending_message = msg
|
458
|
+
self.pending_message = copy.deepcopy(msg)
|
444
459
|
if self.pending_message is not None and self.caller is not None:
|
445
460
|
# msg may have come from `caller`, so we pretend this is from
|
446
461
|
# the CURRENT task's USER entity
|
@@ -480,8 +495,8 @@ class Task:
|
|
480
495
|
self.max_tokens = max_tokens
|
481
496
|
self.session_id = session_id
|
482
497
|
self._set_alive()
|
483
|
-
self.
|
484
|
-
self.
|
498
|
+
self._init_message_counter()
|
499
|
+
self.history.clear()
|
485
500
|
|
486
501
|
assert (
|
487
502
|
msg is None or isinstance(msg, str) or isinstance(msg, ChatDocument)
|
@@ -580,8 +595,8 @@ class Task:
|
|
580
595
|
self.max_tokens = max_tokens
|
581
596
|
self.session_id = session_id
|
582
597
|
self._set_alive()
|
583
|
-
self.
|
584
|
-
self.
|
598
|
+
self._init_message_counter()
|
599
|
+
self.history.clear()
|
585
600
|
|
586
601
|
if (
|
587
602
|
isinstance(msg, ChatDocument)
|
@@ -661,9 +676,7 @@ class Task:
|
|
661
676
|
)
|
662
677
|
# TODO decide on whether or not to print, based on is_async
|
663
678
|
llm_model = (
|
664
|
-
"no-LLM"
|
665
|
-
if self.agent.config.llm is None
|
666
|
-
else self.agent.config.llm.chat_model
|
679
|
+
"no-LLM" if self.agent.llm is None else self.agent.llm.config.chat_model
|
667
680
|
)
|
668
681
|
if not settings.quiet:
|
669
682
|
print(
|
@@ -774,7 +787,7 @@ class Task:
|
|
774
787
|
# skip trying other responders in this step
|
775
788
|
break
|
776
789
|
if not found_response:
|
777
|
-
self._process_invalid_step_result(
|
790
|
+
self._process_invalid_step_result()
|
778
791
|
self._show_pending_message_if_debug()
|
779
792
|
return self.pending_message
|
780
793
|
|
@@ -866,7 +879,7 @@ class Task:
|
|
866
879
|
# skip trying other responders in this step
|
867
880
|
break
|
868
881
|
if not found_response:
|
869
|
-
self._process_invalid_step_result(
|
882
|
+
self._process_invalid_step_result()
|
870
883
|
self._show_pending_message_if_debug()
|
871
884
|
return self.pending_message
|
872
885
|
|
@@ -901,30 +914,13 @@ class Task:
|
|
901
914
|
if self.pending_message is not None:
|
902
915
|
hashed_msg = hash(str(self.pending_message))
|
903
916
|
self.message_counter.update([hashed_msg])
|
904
|
-
self.
|
917
|
+
self.history.append(hashed_msg)
|
905
918
|
|
906
|
-
def _process_invalid_step_result(self
|
919
|
+
def _process_invalid_step_result(self) -> None:
|
907
920
|
"""
|
908
|
-
|
909
|
-
self.pending_message to a NO_ANSWER message from the opposite entity,
|
910
|
-
or leave it as is.
|
911
|
-
Args:
|
912
|
-
parent (ChatDocument|None): parent message of the current message
|
921
|
+
No valid result from any responder => increment stalled counter.
|
913
922
|
"""
|
914
923
|
self.n_stalled_steps += 1
|
915
|
-
if (not self.task_progress or self.allow_null_result) and not self.is_pass_thru:
|
916
|
-
# There has been no progress at all in this task, so we
|
917
|
-
# update the pending_message to a dummy NO_ANSWER msg
|
918
|
-
# from the entity 'opposite' to the current pending_sender,
|
919
|
-
# so we show "progress" and avoid getting stuck in an infinite loop.
|
920
|
-
responder = (
|
921
|
-
Entity.LLM if self.pending_sender == Entity.USER else Entity.USER
|
922
|
-
)
|
923
|
-
self.pending_message = ChatDocument(
|
924
|
-
content=NO_ANSWER,
|
925
|
-
metadata=ChatDocMetaData(sender=responder, parent=parent),
|
926
|
-
)
|
927
|
-
self.pending_sender = responder
|
928
924
|
self.log_message(self.pending_sender, self.pending_message, mark=True)
|
929
925
|
|
930
926
|
def _show_pending_message_if_debug(self) -> None:
|
@@ -1059,7 +1055,6 @@ class Task:
|
|
1059
1055
|
tool_messages = result_msg.tool_messages if result_msg else []
|
1060
1056
|
block = result_msg.metadata.block if result_msg else None
|
1061
1057
|
recipient = result_msg.metadata.recipient if result_msg else None
|
1062
|
-
responder = result_msg.metadata.parent_responder if result_msg else None
|
1063
1058
|
tool_ids = result_msg.metadata.tool_ids if result_msg else []
|
1064
1059
|
status = result_msg.metadata.status if result_msg else None
|
1065
1060
|
|
@@ -1075,7 +1070,6 @@ class Task:
|
|
1075
1070
|
sender=Entity.USER,
|
1076
1071
|
block=block,
|
1077
1072
|
status=status,
|
1078
|
-
parent_responder=responder,
|
1079
1073
|
sender_name=self.name,
|
1080
1074
|
recipient=recipient,
|
1081
1075
|
tool_ids=tool_ids,
|
@@ -1145,9 +1139,9 @@ class Task:
|
|
1145
1139
|
So if you plot these frequencies in decreasing order,
|
1146
1140
|
you will see a big drop in the plot, from m to m+1.
|
1147
1141
|
We call the freqs until m the "dominant" freqs.
|
1148
|
-
2. Say we found m such dominant
|
1149
|
-
If
|
1150
|
-
then we are likely in a loop.
|
1142
|
+
2. Say we found m such dominant messages
|
1143
|
+
If the set of last (W * m) messages are the same as the
|
1144
|
+
set of m dominant messages, then we are likely in a loop.
|
1151
1145
|
"""
|
1152
1146
|
max_cycle_len = self.config.inf_loop_cycle_len
|
1153
1147
|
if max_cycle_len <= 0:
|
@@ -1158,6 +1152,7 @@ class Task:
|
|
1158
1152
|
# we haven't seen enough messages to detect a loop
|
1159
1153
|
return False
|
1160
1154
|
|
1155
|
+
# recall there's always a dummy msg with freq = 1
|
1161
1156
|
most_common_msg_counts: List[Tuple[str, int]] = (
|
1162
1157
|
self.message_counter.most_common(max_cycle_len + 1)
|
1163
1158
|
)
|
@@ -1170,7 +1165,7 @@ class Task:
|
|
1170
1165
|
ratios = counts[:-1] / counts[1:]
|
1171
1166
|
diffs = counts[:-1] - counts[1:]
|
1172
1167
|
indices = np.where((ratios > F) & (diffs > wait_factor))[0]
|
1173
|
-
m = indices[
|
1168
|
+
m = indices[-1] if indices.size > 0 else -1
|
1174
1169
|
if m < 0:
|
1175
1170
|
# no dominance found, but...
|
1176
1171
|
if len(most_common_msg_counts) <= max_cycle_len:
|
@@ -1186,12 +1181,13 @@ class Task:
|
|
1186
1181
|
return False
|
1187
1182
|
|
1188
1183
|
dominant_msg_counts = most_common_msg_counts[: m + 1]
|
1189
|
-
# if the dominant m
|
1190
|
-
#
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1184
|
+
# if the SET of dominant m messages is the same as the
|
1185
|
+
# the SET of last m*w messages, (where w = config.inf_loop_wait_factor),
|
1186
|
+
# then we are likely in a loop
|
1187
|
+
dominant_msgs = set([msg for msg, _ in dominant_msg_counts])
|
1188
|
+
lookback = wait_factor * (m + 1)
|
1189
|
+
recent_msgs = set(list(self.history)[-lookback:])
|
1190
|
+
return dominant_msgs == recent_msgs
|
1195
1191
|
|
1196
1192
|
def done(
|
1197
1193
|
self, result: ChatDocument | None = None, r: Responder | None = None
|
@@ -1375,9 +1371,18 @@ class Task:
|
|
1375
1371
|
)
|
1376
1372
|
|
1377
1373
|
def _can_respond(self, e: Responder) -> bool:
|
1378
|
-
|
1379
|
-
#
|
1374
|
+
user_can_respond = self.interactive or (
|
1375
|
+
# regardless of self.interactive, if a msg is explicitly addressed to
|
1376
|
+
# user, then wait for user response
|
1377
|
+
self.pending_message is not None
|
1378
|
+
and self.pending_message.metadata.recipient == Entity.USER
|
1379
|
+
)
|
1380
|
+
|
1381
|
+
if self.pending_sender == e or (e == Entity.USER and not user_can_respond):
|
1382
|
+
# sender is same as e (an entity cannot respond to its own msg),
|
1383
|
+
# or user cannot respond
|
1380
1384
|
return False
|
1385
|
+
|
1381
1386
|
if self.pending_message is None:
|
1382
1387
|
return True
|
1383
1388
|
if self._recipient_mismatch(e):
|
@@ -421,7 +421,9 @@ class OpenAIGPT(LanguageModel):
|
|
421
421
|
self.api_base = "http://" + self.api_base
|
422
422
|
elif self.config.chat_model.startswith("ollama/"):
|
423
423
|
self.config.ollama = True
|
424
|
-
|
424
|
+
|
425
|
+
# use api_base from config if set, else fall back on OLLAMA_BASE_URL
|
426
|
+
self.api_base = self.config.api_base or OLLAMA_BASE_URL
|
425
427
|
self.api_key = OLLAMA_API_KEY
|
426
428
|
self.config.chat_model = self.config.chat_model.replace("ollama/", "")
|
427
429
|
else:
|
@@ -68,7 +68,7 @@ class QdrantDBConfig(VectorStoreConfig):
|
|
68
68
|
embedding: EmbeddingModelsConfig = OpenAIEmbeddingsConfig()
|
69
69
|
distance: str = Distance.COSINE
|
70
70
|
use_sparse_embeddings: bool = False
|
71
|
-
sparse_embedding_model: str = ""
|
71
|
+
sparse_embedding_model: str = "naver/splade-v3-distilbert"
|
72
72
|
sparse_limit: int = 3
|
73
73
|
|
74
74
|
|
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.1.258 → langroid-0.1.261}/langroid/agent/special/lance_rag/query_planner_agent.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
|
{langroid-0.1.258 → langroid-0.1.261}/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
|
{langroid-0.1.258 → langroid-0.1.261}/langroid/embedding_models/protoc/embeddings_pb2_grpc.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
|
{langroid-0.1.258 → langroid-0.1.261}/langroid/language_models/prompt_formatter/hf_formatter.py
RENAMED
File without changes
|
{langroid-0.1.258 → langroid-0.1.261}/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
|