@roll-agent/octopus-agent 0.0.10 → 0.0.11
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.
- package/README.md +1 -0
- package/SKILL.md +25 -1
- package/package.json +1 -1
- package/pyproject.toml +4 -2
- package/references/env.yaml +17 -0
- package/scripts/refresh_dictionary.py +67 -0
- package/scripts/verify_binding.py +47 -0
- package/src/octopus_skill/_version.py +1 -1
- package/src/octopus_skill/agent.py +1099 -146
- package/src/octopus_skill/config.py +58 -10
- package/src/octopus_skill/entity_binding.py +523 -0
- package/src/octopus_skill/entity_dictionary.py +59 -0
- package/src/octopus_skill/entity_resolver.py +446 -0
- package/src/octopus_skill/llm_sql_generator.py +3 -0
- package/src/octopus_skill/mcp_client.py +16 -0
- package/src/octopus_skill/octopus_run.py +369 -17
- package/src/octopus_skill/prompt_builder.py +74 -31
- package/src/octopus_skill/schema_context_retriever.py +199 -150
- package/src/octopus_skill/sql_generator.py +432 -801
- package/src/octopus_skill/query_sql_cache.py +0 -72
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import hashlib
|
|
4
|
-
import json
|
|
5
|
-
import re
|
|
6
|
-
import time
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
SQL_GENERATION_CACHE_VERSION = "v9"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class QuerySqlCache:
|
|
17
|
-
path: Path
|
|
18
|
-
ttl_minutes: int
|
|
19
|
-
|
|
20
|
-
def get(self, *, question: str, schema_version: str | None) -> str | None:
|
|
21
|
-
if self.ttl_minutes <= 0:
|
|
22
|
-
return None
|
|
23
|
-
entry = self._entries().get(_cache_key(question, schema_version))
|
|
24
|
-
if not isinstance(entry, dict):
|
|
25
|
-
return None
|
|
26
|
-
created_at = entry.get("createdAt")
|
|
27
|
-
sql = entry.get("sql")
|
|
28
|
-
if not isinstance(created_at, (int, float)) or not isinstance(sql, str):
|
|
29
|
-
return None
|
|
30
|
-
if time.time() - float(created_at) > self.ttl_minutes * 60:
|
|
31
|
-
return None
|
|
32
|
-
return sql
|
|
33
|
-
|
|
34
|
-
def delete(self, *, question: str, schema_version: str | None) -> None:
|
|
35
|
-
entries = self._entries()
|
|
36
|
-
key = _cache_key(question, schema_version)
|
|
37
|
-
if key not in entries:
|
|
38
|
-
return
|
|
39
|
-
del entries[key]
|
|
40
|
-
self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
41
|
-
self.path.write_text(json.dumps(entries, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
42
|
-
|
|
43
|
-
def set(self, *, question: str, schema_version: str | None, sql: str) -> None:
|
|
44
|
-
if self.ttl_minutes <= 0:
|
|
45
|
-
return
|
|
46
|
-
entries = self._entries()
|
|
47
|
-
entries[_cache_key(question, schema_version)] = {
|
|
48
|
-
"questionKey": _normalize_question(question),
|
|
49
|
-
"schemaVersion": schema_version,
|
|
50
|
-
"sql": sql,
|
|
51
|
-
"createdAt": time.time(),
|
|
52
|
-
}
|
|
53
|
-
self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
54
|
-
self.path.write_text(json.dumps(entries, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
55
|
-
|
|
56
|
-
def _entries(self) -> dict[str, Any]:
|
|
57
|
-
if not self.path.exists():
|
|
58
|
-
return {}
|
|
59
|
-
try:
|
|
60
|
-
data = json.loads(self.path.read_text(encoding="utf-8"))
|
|
61
|
-
except json.JSONDecodeError:
|
|
62
|
-
return {}
|
|
63
|
-
return data if isinstance(data, dict) else {}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def _cache_key(question: str, schema_version: str | None) -> str:
|
|
67
|
-
raw = f"{SQL_GENERATION_CACHE_VERSION}:{schema_version or ''}:{_normalize_question(question)}"
|
|
68
|
-
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def _normalize_question(question: str) -> str:
|
|
72
|
-
return re.sub(r"\s+", "", question.strip().lower())
|