elastro-client 1.3.43__tar.gz → 1.3.45__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.
- {elastro_client-1.3.43/elastro_client.egg-info → elastro_client-1.3.45}/PKG-INFO +1 -1
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/__init__.py +1 -1
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/cli.py +4 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/__init__.py +6 -0
- elastro_client-1.3.45/elastro/cli/commands/memory.py +121 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/telemetry.py +11 -0
- elastro_client-1.3.45/elastro/cli/commands/tools.py +101 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45/elastro_client.egg-info}/PKG-INFO +1 -1
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/SOURCES.txt +2 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/pyproject.toml +1 -1
- {elastro_client-1.3.43 → elastro_client-1.3.45}/.coveragerc +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/LICENSE +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/MANIFEST.in +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/README.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/advanced_features.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/api_reference.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/cli_usage.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/commands_reference.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/getting_started.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/roadmap.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/docs/troubleshooting.md +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/advanced/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/advanced/aggregations.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/advanced/query_builder.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/advanced/scroll.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/art.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/cluster.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/config.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/daemon.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/datastream.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/document.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/gui.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/ilm.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/index.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/index_recipes.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/ingest.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/ml.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/painless_commands.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/rag.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/script.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/security.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/snapshot.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/tasks.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/template.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/commands/utils.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/completion.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/cli/output.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/config/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/config/defaults.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/config/loader.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/client.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/daemon.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/datastream.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/document.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/document_bulk.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/errors.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/ilm.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/index.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/logger.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/query_builder.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/rag/ast_parser.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/rag/ingestor.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/snapshot.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/core/validation.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/assets/index-CeUjjtn-.css +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/assets/index-DNdGuJvV.js +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/elastro.svg +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/favicon.ico +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/index.html +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/gui/vite.svg +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/py.typed +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/server.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/utils/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/utils/aliases.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/utils/health.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/utils/snapshots.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro/utils/templates.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/dependency_links.txt +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/entry_points.txt +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/requires.txt +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/top_level.txt +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/client.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/config_usage.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/datastreams.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/debug_connection.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/document_operations.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/index_management.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/examples/search.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/pytest.ini +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/requirements.txt +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/setup.cfg +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/setup.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/conftest.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/fixtures/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/fixtures/datastream_fixtures.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/fixtures/document_fixtures.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/fixtures/index_fixtures.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_aggregations_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_client_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_datastream_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_docs_quickstart.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_document_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_index_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_query_builder_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_scroll_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_workflow_integration.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/manual/test_es.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/advanced/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/advanced/test_aggregations.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/advanced/test_query_builder.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/advanced/test_scroll.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/config/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/config/test_defaults.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/config/test_loader.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_client.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_datastream.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_document.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_document_bulk.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_errors.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_index.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/core/test_validation.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/utils/__init__.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/utils/test_aliases.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/utils/test_health.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/utils/test_snapshots.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/unit/utils/test_templates.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/verify_api_actions.py +0 -0
- {elastro_client-1.3.43 → elastro_client-1.3.45}/tests/verify_cli_e2e.py +0 -0
|
@@ -109,6 +109,8 @@ from elastro.cli.commands.ml import ml_group
|
|
|
109
109
|
from elastro.cli.commands.script import script_group
|
|
110
110
|
from elastro.cli.commands.painless_commands import painless_group
|
|
111
111
|
from elastro.cli.commands.telemetry import telemetry_group
|
|
112
|
+
from elastro.cli.commands.memory import memory_group
|
|
113
|
+
from elastro.cli.commands.tools import tools_group
|
|
112
114
|
|
|
113
115
|
# Register Top-Level Groups
|
|
114
116
|
|
|
@@ -287,6 +289,8 @@ cli.add_command(ml_group)
|
|
|
287
289
|
cli.add_command(script_group)
|
|
288
290
|
cli.add_command(painless_group)
|
|
289
291
|
cli.add_command(telemetry_group)
|
|
292
|
+
cli.add_command(memory_group)
|
|
293
|
+
cli.add_command(tools_group)
|
|
290
294
|
cli.add_command(gui)
|
|
291
295
|
cli.add_command(rag_group)
|
|
292
296
|
cli.add_command(daemon_group)
|
|
@@ -41,6 +41,8 @@ from elastro.cli.commands.config import (
|
|
|
41
41
|
from elastro.cli.commands.utils import health, templates, aliases
|
|
42
42
|
from elastro.cli.commands.painless_commands import painless_group
|
|
43
43
|
from elastro.cli.commands.telemetry import telemetry_group
|
|
44
|
+
from elastro.cli.commands.memory import memory_group
|
|
45
|
+
from elastro.cli.commands.tools import tools_group
|
|
44
46
|
|
|
45
47
|
__all__ = [
|
|
46
48
|
# Index commands
|
|
@@ -81,4 +83,8 @@ __all__ = [
|
|
|
81
83
|
"painless_group",
|
|
82
84
|
# Telemetry
|
|
83
85
|
"telemetry_group",
|
|
86
|
+
# Agentic Memory
|
|
87
|
+
"memory_group",
|
|
88
|
+
# Tools Registry
|
|
89
|
+
"tools_group",
|
|
84
90
|
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory command group for Elastro CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import rich_click as click
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
|
|
8
|
+
from elastro.core.client import ElasticsearchClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group(name="memory")
|
|
12
|
+
def memory_group() -> None:
|
|
13
|
+
"""Manage semantic memory for agents."""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@memory_group.command("ingest")
|
|
18
|
+
@click.argument("note_type", type=click.Choice(["strategic", "tactical"]))
|
|
19
|
+
@click.argument("subject")
|
|
20
|
+
@click.argument("content")
|
|
21
|
+
@click.option("--tags", default="", help="Comma-separated tags")
|
|
22
|
+
@click.pass_obj
|
|
23
|
+
def ingest_memory(
|
|
24
|
+
client: ElasticsearchClient,
|
|
25
|
+
note_type: str,
|
|
26
|
+
subject: str,
|
|
27
|
+
content: str,
|
|
28
|
+
tags: str,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Ingest a semantic memory note for agent knowledge sharing.
|
|
32
|
+
|
|
33
|
+
NOTE_TYPE must be 'strategic' (telemetry/heuristics) or 'tactical' (handoffs).
|
|
34
|
+
"""
|
|
35
|
+
index_name = "agent_semantic_memory"
|
|
36
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
37
|
+
|
|
38
|
+
payload = {
|
|
39
|
+
"timestamp": timestamp,
|
|
40
|
+
"note_type": note_type,
|
|
41
|
+
"subject": subject,
|
|
42
|
+
"content": content,
|
|
43
|
+
"tags": [t.strip() for t in tags.split(",")] if tags else [],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
response = client.client.index(index=index_name, document=payload)
|
|
48
|
+
click.secho(
|
|
49
|
+
f">> Memory ingested successfully. ID: {response.get('_id', 'unknown')}",
|
|
50
|
+
fg="green",
|
|
51
|
+
)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
click.secho(f"Failed to ingest memory payload: {e}", fg="red", err=True)
|
|
54
|
+
import sys
|
|
55
|
+
|
|
56
|
+
sys.exit(1)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@memory_group.command("search")
|
|
60
|
+
@click.argument("query")
|
|
61
|
+
@click.option(
|
|
62
|
+
"--type",
|
|
63
|
+
"note_type",
|
|
64
|
+
type=click.Choice(["strategic", "tactical"]),
|
|
65
|
+
help="Filter by note type",
|
|
66
|
+
)
|
|
67
|
+
@click.option("--size", default=10, help="Number of results to return")
|
|
68
|
+
@click.pass_obj
|
|
69
|
+
def search_memory(
|
|
70
|
+
client: ElasticsearchClient,
|
|
71
|
+
query: str,
|
|
72
|
+
note_type: str,
|
|
73
|
+
size: int,
|
|
74
|
+
) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Search semantic memory notes via vector/BM25 retrieval.
|
|
77
|
+
"""
|
|
78
|
+
index_name = "agent_semantic_memory"
|
|
79
|
+
|
|
80
|
+
from typing import Dict, Any, List
|
|
81
|
+
|
|
82
|
+
bool_clause: Dict[str, List[Any]] = {
|
|
83
|
+
"must": [
|
|
84
|
+
{
|
|
85
|
+
"multi_match": {
|
|
86
|
+
"query": query,
|
|
87
|
+
"fields": ["subject^2", "content", "tags"],
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if note_type:
|
|
94
|
+
bool_clause["filter"] = [{"term": {"note_type": note_type}}]
|
|
95
|
+
|
|
96
|
+
search_body: Dict[str, Any] = {
|
|
97
|
+
"size": size,
|
|
98
|
+
"query": {"bool": bool_clause},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
response = client.client.search(index=index_name, body=search_body)
|
|
103
|
+
hits = response.get("hits", {}).get("hits", [])
|
|
104
|
+
|
|
105
|
+
click.secho(f"Found {len(hits)} memory notes:", fg="blue")
|
|
106
|
+
for hit in hits:
|
|
107
|
+
if not isinstance(hit, dict):
|
|
108
|
+
continue
|
|
109
|
+
source = hit.get("_source", {})
|
|
110
|
+
click.echo(
|
|
111
|
+
f"\n[{source.get('note_type', 'unknown').upper()}] {source.get('subject', 'Untitled')} ({hit.get('_id', '')})"
|
|
112
|
+
)
|
|
113
|
+
click.echo(f" {source.get('content', '')}")
|
|
114
|
+
if source.get("tags"):
|
|
115
|
+
click.echo(f" Tags: {', '.join(source['tags'])}")
|
|
116
|
+
|
|
117
|
+
except Exception as e:
|
|
118
|
+
click.secho(f"Search failed: {e}", fg="red", err=True)
|
|
119
|
+
import sys
|
|
120
|
+
|
|
121
|
+
sys.exit(1)
|
|
@@ -45,6 +45,11 @@ def telemetry_group() -> None:
|
|
|
45
45
|
help="Comma-separated list of executed tools",
|
|
46
46
|
)
|
|
47
47
|
@click.option("--rollback-count", type=int, default=0, help="Explicit undo rate")
|
|
48
|
+
@click.option("--diff-drift", type=float, default=0.0, help="Diff Drift Ratio")
|
|
49
|
+
@click.option(
|
|
50
|
+
"--fallback-rate", type=float, default=0.0, help="Deterministic Fallback Rate"
|
|
51
|
+
)
|
|
52
|
+
@click.option("--complexity", type=float, default=0.0, help="Complexity Score")
|
|
48
53
|
@click.pass_obj
|
|
49
54
|
def ingest_telemetry(
|
|
50
55
|
client: ElasticsearchClient,
|
|
@@ -68,6 +73,9 @@ def ingest_telemetry(
|
|
|
68
73
|
llm_model: str,
|
|
69
74
|
tools_invoked: str,
|
|
70
75
|
rollback_count: int,
|
|
76
|
+
diff_drift: float,
|
|
77
|
+
fallback_rate: float,
|
|
78
|
+
complexity: float,
|
|
71
79
|
) -> None:
|
|
72
80
|
"""
|
|
73
81
|
Ingest standardized session telemetry into the deep analytics index.
|
|
@@ -103,6 +111,9 @@ def ingest_telemetry(
|
|
|
103
111
|
[t.strip() for t in tools_invoked.split(",")] if tools_invoked else []
|
|
104
112
|
),
|
|
105
113
|
"rollback_undo_count": rollback_count,
|
|
114
|
+
"diff_drift_ratio": diff_drift,
|
|
115
|
+
"deterministic_fallback_rate": fallback_rate,
|
|
116
|
+
"complexity_score": complexity,
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
try:
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tools registry command group for Elastro CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import rich_click as click
|
|
6
|
+
from datetime import datetime, timezone
|
|
7
|
+
|
|
8
|
+
from elastro.core.client import ElasticsearchClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group(name="tools")
|
|
12
|
+
def tools_group() -> None:
|
|
13
|
+
"""Manage the Custom Agentic Toolchain registry."""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@tools_group.command("register")
|
|
18
|
+
@click.argument("tool_name")
|
|
19
|
+
@click.argument("file_path")
|
|
20
|
+
@click.argument("purpose")
|
|
21
|
+
@click.option(
|
|
22
|
+
"--parameters", default="", help="JSON string or comma-separated list of params"
|
|
23
|
+
)
|
|
24
|
+
@click.pass_obj
|
|
25
|
+
def register_tool(
|
|
26
|
+
client: ElasticsearchClient,
|
|
27
|
+
tool_name: str,
|
|
28
|
+
file_path: str,
|
|
29
|
+
purpose: str,
|
|
30
|
+
parameters: str,
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Register a custom pipeline script or CLI into the tools registry.
|
|
34
|
+
"""
|
|
35
|
+
index_name = "flow_tools"
|
|
36
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
37
|
+
|
|
38
|
+
payload = {
|
|
39
|
+
"timestamp": timestamp,
|
|
40
|
+
"tool_name": tool_name,
|
|
41
|
+
"file_path": file_path,
|
|
42
|
+
"purpose": purpose,
|
|
43
|
+
"parameters": parameters,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
response = client.client.index(index=index_name, id=tool_name, document=payload)
|
|
48
|
+
click.secho(
|
|
49
|
+
f">> Tool '{tool_name}' registered successfully.",
|
|
50
|
+
fg="green",
|
|
51
|
+
)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
click.secho(f"Failed to register tool payload: {e}", fg="red", err=True)
|
|
54
|
+
import sys
|
|
55
|
+
|
|
56
|
+
sys.exit(1)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@tools_group.command("search")
|
|
60
|
+
@click.argument("query")
|
|
61
|
+
@click.option("--size", default=10, help="Number of results to return")
|
|
62
|
+
@click.pass_obj
|
|
63
|
+
def search_tools(
|
|
64
|
+
client: ElasticsearchClient,
|
|
65
|
+
query: str,
|
|
66
|
+
size: int,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Search the flow_tools custom tool registry.
|
|
70
|
+
"""
|
|
71
|
+
index_name = "flow_tools"
|
|
72
|
+
|
|
73
|
+
search_body = {
|
|
74
|
+
"size": size,
|
|
75
|
+
"query": {
|
|
76
|
+
"multi_match": {
|
|
77
|
+
"query": query,
|
|
78
|
+
"fields": ["tool_name^3", "purpose^2", "parameters"],
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
response = client.client.search(index=index_name, body=search_body)
|
|
85
|
+
hits = response.get("hits", {}).get("hits", [])
|
|
86
|
+
|
|
87
|
+
click.secho(f"Found {len(hits)} registered tools:", fg="blue")
|
|
88
|
+
for hit in hits:
|
|
89
|
+
if not isinstance(hit, dict):
|
|
90
|
+
continue
|
|
91
|
+
source = hit.get("_source", {})
|
|
92
|
+
click.echo(f"\n[TOOL] {source.get('tool_name', 'Unknown')}")
|
|
93
|
+
click.echo(f" Path: {source.get('file_path', 'unknown')}")
|
|
94
|
+
click.echo(f" Purpose: {source.get('purpose', '')}")
|
|
95
|
+
click.echo(f" Parameters: {source.get('parameters', '')}")
|
|
96
|
+
|
|
97
|
+
except Exception as e:
|
|
98
|
+
click.secho(f"Search failed: {e}", fg="red", err=True)
|
|
99
|
+
import sys
|
|
100
|
+
|
|
101
|
+
sys.exit(1)
|
|
@@ -36,6 +36,7 @@ elastro/cli/commands/ilm.py
|
|
|
36
36
|
elastro/cli/commands/index.py
|
|
37
37
|
elastro/cli/commands/index_recipes.py
|
|
38
38
|
elastro/cli/commands/ingest.py
|
|
39
|
+
elastro/cli/commands/memory.py
|
|
39
40
|
elastro/cli/commands/ml.py
|
|
40
41
|
elastro/cli/commands/painless_commands.py
|
|
41
42
|
elastro/cli/commands/rag.py
|
|
@@ -45,6 +46,7 @@ elastro/cli/commands/snapshot.py
|
|
|
45
46
|
elastro/cli/commands/tasks.py
|
|
46
47
|
elastro/cli/commands/telemetry.py
|
|
47
48
|
elastro/cli/commands/template.py
|
|
49
|
+
elastro/cli/commands/tools.py
|
|
48
50
|
elastro/cli/commands/utils.py
|
|
49
51
|
elastro/config/__init__.py
|
|
50
52
|
elastro/config/defaults.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "elastro-client"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.45"
|
|
8
8
|
description = "A comprehensive Python library for Elasticsearch management with both programmatic and CLI interfaces"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9,<3.14"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/elastro_client.egg-info/dependency_links.txt
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
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_aggregations_integration.py
RENAMED
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_client_integration.py
RENAMED
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_datastream_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_document_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_query_builder_integration.py
RENAMED
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_scroll_integration.py
RENAMED
|
File without changes
|
{elastro_client-1.3.43 → elastro_client-1.3.45}/tests/integration/test_workflow_integration.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
|