union-app-chat-stream 1.0.6 → 1.0.7
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/app/.env +44 -44
- package/app/.env.dev +44 -44
- package/app/.env.prod.bj11 +44 -44
- package/app/.env.prod.sh20 +44 -44
- package/app/.env.prod.sz31 +44 -44
- package/app/.env.test.bj12 +44 -44
- package/app/service/chat_service.py +1 -1
- package/app/utils/function_utils.py +91 -0
- package/package.json +1 -1
- package/tools/field_dictionary.yaml +28 -0
- package/tools/tool_definitions.yaml +374 -302
|
@@ -14,6 +14,7 @@ import yaml
|
|
|
14
14
|
|
|
15
15
|
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
16
16
|
DEFAULT_TOOL_DEFINITIONS_PATH = PROJECT_ROOT / "tools" / "tool_definitions.yaml"
|
|
17
|
+
FIELD_DICTIONARY_PATH = PROJECT_ROOT / "tools" / "field_dictionary.yaml"
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@dataclass
|
|
@@ -47,6 +48,44 @@ def _load_yaml(path: Path) -> Dict[str, Any]:
|
|
|
47
48
|
return data if isinstance(data, dict) else {}
|
|
48
49
|
|
|
49
50
|
|
|
51
|
+
def _normalize_field_name(name: str) -> str:
|
|
52
|
+
return re.sub(r"[\s_-]+", "", str(name)).lower()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@lru_cache(maxsize=1)
|
|
56
|
+
def _field_dictionary_index() -> Dict[str, Any]:
|
|
57
|
+
if not FIELD_DICTIONARY_PATH.exists():
|
|
58
|
+
return {"fallback_description": "", "exact": {}, "normalized": {}, "relations": []}
|
|
59
|
+
|
|
60
|
+
config = _load_yaml(FIELD_DICTIONARY_PATH)
|
|
61
|
+
if not isinstance(config, dict):
|
|
62
|
+
config = {}
|
|
63
|
+
|
|
64
|
+
exact: Dict[str, Dict[str, Any]] = {}
|
|
65
|
+
normalized: Dict[str, Dict[str, Any]] = {}
|
|
66
|
+
fields = config.get("fields") if isinstance(config.get("fields"), dict) else {}
|
|
67
|
+
for canonical, raw_info in fields.items():
|
|
68
|
+
if not isinstance(raw_info, dict):
|
|
69
|
+
continue
|
|
70
|
+
info = {key: value for key, value in raw_info.items() if key not in {"aliases", "patterns"}}
|
|
71
|
+
info["canonical"] = canonical
|
|
72
|
+
exact[canonical] = info
|
|
73
|
+
normalized[_normalize_field_name(canonical)] = info
|
|
74
|
+
aliases = raw_info.get("aliases") if isinstance(raw_info.get("aliases"), list) else []
|
|
75
|
+
for alias in aliases:
|
|
76
|
+
alias = str(alias)
|
|
77
|
+
exact[alias] = info
|
|
78
|
+
normalized[_normalize_field_name(alias)] = info
|
|
79
|
+
|
|
80
|
+
relations = config.get("relations") if isinstance(config.get("relations"), list) else []
|
|
81
|
+
return {
|
|
82
|
+
"fallback_description": str(config.get("fallback_description") or ""),
|
|
83
|
+
"exact": exact,
|
|
84
|
+
"normalized": normalized,
|
|
85
|
+
"relations": relations,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
50
89
|
@lru_cache(maxsize=1)
|
|
51
90
|
def _tool_definition_config() -> Dict[str, Any]:
|
|
52
91
|
path = Path(os.environ.get("TOOL_DEFINITIONS_PATH", DEFAULT_TOOL_DEFINITIONS_PATH))
|
|
@@ -55,6 +94,7 @@ def _tool_definition_config() -> Dict[str, Any]:
|
|
|
55
94
|
|
|
56
95
|
def reload_tool_configs():
|
|
57
96
|
_tool_definition_config.cache_clear()
|
|
97
|
+
_field_dictionary_index.cache_clear()
|
|
58
98
|
|
|
59
99
|
|
|
60
100
|
def _raw_tool_definitions() -> List[Dict[str, Any]]:
|
|
@@ -178,6 +218,56 @@ def _render_value(value: Any, args: Dict[str, Any], *, allow_missing: bool = Fal
|
|
|
178
218
|
return value
|
|
179
219
|
|
|
180
220
|
|
|
221
|
+
def _collect_data_fields(data: Any, sample_size: int = 5) -> List[str]:
|
|
222
|
+
if not isinstance(data, list):
|
|
223
|
+
return []
|
|
224
|
+
fields: List[str] = []
|
|
225
|
+
seen = set()
|
|
226
|
+
for item in data[:sample_size]:
|
|
227
|
+
if not isinstance(item, dict):
|
|
228
|
+
continue
|
|
229
|
+
for key in item:
|
|
230
|
+
key = str(key)
|
|
231
|
+
if key not in seen:
|
|
232
|
+
seen.add(key)
|
|
233
|
+
fields.append(key)
|
|
234
|
+
return fields
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _build_field_context(data: Any) -> Dict[str, Any]:
|
|
238
|
+
fields = _collect_data_fields(data)
|
|
239
|
+
if not fields:
|
|
240
|
+
return {}
|
|
241
|
+
|
|
242
|
+
index = _field_dictionary_index()
|
|
243
|
+
fallback = index["fallback_description"]
|
|
244
|
+
descriptions: Dict[str, Dict[str, Any]] = {}
|
|
245
|
+
canonical_fields = set()
|
|
246
|
+
for field in fields:
|
|
247
|
+
info = index["exact"].get(field) or index["normalized"].get(_normalize_field_name(field))
|
|
248
|
+
if info:
|
|
249
|
+
descriptions[field] = dict(info)
|
|
250
|
+
canonical_fields.add(str(info["canonical"]))
|
|
251
|
+
elif fallback:
|
|
252
|
+
descriptions[field] = {"description": fallback}
|
|
253
|
+
|
|
254
|
+
relations = []
|
|
255
|
+
for relation in index["relations"]:
|
|
256
|
+
if not isinstance(relation, dict):
|
|
257
|
+
continue
|
|
258
|
+
when_all = relation.get("when_all")
|
|
259
|
+
description = relation.get("description")
|
|
260
|
+
if isinstance(when_all, list) and description and all(str(field) in canonical_fields for field in when_all):
|
|
261
|
+
relations.append(str(description))
|
|
262
|
+
|
|
263
|
+
context: Dict[str, Any] = {}
|
|
264
|
+
if descriptions:
|
|
265
|
+
context["field_descriptions"] = descriptions
|
|
266
|
+
if relations:
|
|
267
|
+
context["field_relations"] = relations
|
|
268
|
+
return context
|
|
269
|
+
|
|
270
|
+
|
|
181
271
|
def _base_result(spec: Dict[str, Any], args: Dict[str, Any]) -> Dict[str, Any]:
|
|
182
272
|
result = {
|
|
183
273
|
"tool_name": spec["name"],
|
|
@@ -242,6 +332,7 @@ def _run_backend_tool(
|
|
|
242
332
|
})
|
|
243
333
|
if path:
|
|
244
334
|
result["backend"]["path"] = path
|
|
335
|
+
result.update(_build_field_context(data))
|
|
245
336
|
return result
|
|
246
337
|
|
|
247
338
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
fallback_description: 字段未命中全局字段字典。请结合字段名、字段值和上下文谨慎理解,不要编造枚举含义。
|
|
2
|
+
fields:
|
|
3
|
+
sysSuccessPercent:
|
|
4
|
+
meaning: 系统成功率,表示成功交易占总交易的比例,通常越高越好。
|
|
5
|
+
aliases:
|
|
6
|
+
- sysSuccessPercent
|
|
7
|
+
- avgSuccessPercent
|
|
8
|
+
- avg_success_percent
|
|
9
|
+
- successPer
|
|
10
|
+
failRate:
|
|
11
|
+
meaning: 失败率,通常表示失败交易笔数占总交易笔数的比例。
|
|
12
|
+
aliases:
|
|
13
|
+
- failRate
|
|
14
|
+
- fail_rate
|
|
15
|
+
faultLevel:
|
|
16
|
+
meaning: 故障等级,表示故障严重程度。
|
|
17
|
+
enum:
|
|
18
|
+
P1: 重大故障
|
|
19
|
+
P2: 较大故障
|
|
20
|
+
P3: 一般故障
|
|
21
|
+
aliases:
|
|
22
|
+
- faultLevel
|
|
23
|
+
- fault_level
|
|
24
|
+
relations:
|
|
25
|
+
- when_all:
|
|
26
|
+
- sysSuccessPercent
|
|
27
|
+
- failRate
|
|
28
|
+
description: 系统成功率和失败率通常反向相关。成功率下降时,应同时检查失败率是否上升。
|