union-app-chat-stream 1.1.6

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.
Files changed (66) hide show
  1. package/app/__init__.py +1 -0
  2. package/app/agent/__init__.py +1 -0
  3. package/app/agent/capabilities.py +388 -0
  4. package/app/agent/coordinator/__init__.py +1 -0
  5. package/app/agent/coordinator/definition.py +50 -0
  6. package/app/agent/coordinator/output_guard.py +29 -0
  7. package/app/agent/graph.py +95 -0
  8. package/app/agent/guardrails.py +30 -0
  9. package/app/agent/routing.py +81 -0
  10. package/app/agent/runtime/__init__.py +1 -0
  11. package/app/agent/runtime/activity.py +393 -0
  12. package/app/agent/runtime/delegation.py +80 -0
  13. package/app/agent/runtime/deps.py +34 -0
  14. package/app/agent/runtime/execution.py +368 -0
  15. package/app/agent/runtime/model.py +47 -0
  16. package/app/agent/runtime/model_errors.py +24 -0
  17. package/app/agent/runtime/session.py +154 -0
  18. package/app/agent/specialists/__init__.py +1 -0
  19. package/app/agent/specialists/behavior_risk/__init__.py +1 -0
  20. package/app/agent/specialists/behavior_risk/definition.py +54 -0
  21. package/app/agent/specialists/build.py +94 -0
  22. package/app/agent/specialists/knowledge/__init__.py +1 -0
  23. package/app/agent/specialists/knowledge/definition.py +38 -0
  24. package/app/agent/specialists/personal_memory/__init__.py +1 -0
  25. package/app/agent/specialists/personal_memory/definition.py +35 -0
  26. package/app/agent/specialists/personal_memory/output_guard.py +55 -0
  27. package/app/agent/specialists/running_analysis/__init__.py +1 -0
  28. package/app/agent/specialists/running_analysis/definition.py +46 -0
  29. package/app/agent/specialists/running_analysis/output_guard.py +38 -0
  30. package/app/agent/specialists/scheduled_task_draft/__init__.py +8 -0
  31. package/app/agent/specialists/scheduled_task_draft/definition.py +142 -0
  32. package/app/agent/specialists/scheduled_task_draft/output_guard.py +81 -0
  33. package/app/asgi.py +139 -0
  34. package/app/config/__init__.py +1 -0
  35. package/app/config/settings.py +67 -0
  36. package/app/memory/__init__.py +1 -0
  37. package/app/memory/store.py +154 -0
  38. package/app/service/rag_service.py +364 -0
  39. package/app/skills/full-chain-quality-analysis/SKILL.md +22 -0
  40. package/app/tools/__init__.py +1 -0
  41. package/app/tools/business.py +183 -0
  42. package/app/utils/__init__.py +1 -0
  43. package/app/utils/api_client.py +76 -0
  44. package/app/utils/control_auth.py +35 -0
  45. package/app/utils/state_client.py +60 -0
  46. package/app/views/__init__.py +1 -0
  47. package/app/views/auth.py +189 -0
  48. package/app/views/errors.py +19 -0
  49. package/app/views/routes.py +25 -0
  50. package/app/views/run_context.py +33 -0
  51. package/app/views/streaming_runs.py +340 -0
  52. package/app/views/sync_runs.py +152 -0
  53. package/deploy/autoconf/templates/env.j2 +23 -0
  54. package/deploy/autoconf.yml +15 -0
  55. package/deploy/scripts/healthcheck.sh +12 -0
  56. package/deploy/scripts/start.sh +80 -0
  57. package/deploy/scripts/stop.sh +35 -0
  58. package/knowledge/000036-scenario-offline-function-call-mock-v1.md +134 -0
  59. package/package.json +21 -0
  60. package/requirements.txt +10 -0
  61. package/scripts/healthcheck.sh +4 -0
  62. package/scripts/start-BJ11.sh +1 -0
  63. package/scripts/start-BJ12.sh +1 -0
  64. package/scripts/start-SH20.sh +1 -0
  65. package/scripts/start-SZ31.sh +1 -0
  66. package/scripts/stop.sh +4 -0
@@ -0,0 +1,152 @@
1
+ """处理 CAS 同步运行与定时任务同步适配入口。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ from datetime import datetime
8
+ from typing import Any
9
+ from zoneinfo import ZoneInfo
10
+
11
+ from pydantic import BaseModel
12
+ from pydantic_ai.exceptions import ModelHTTPError
13
+ from starlette.requests import Request
14
+ from starlette.responses import JSONResponse
15
+
16
+ from app.agent.runtime.model_errors import model_http_error_details
17
+ from app.utils.control_auth import ControlAuth
18
+ from app.views.auth import (
19
+ authenticate_scheduled_run,
20
+ authenticate_user,
21
+ reject_scheduled_on_cas_endpoint,
22
+ scheduled_token,
23
+ strict_scheduled_body,
24
+ )
25
+ from app.views.errors import RouteError
26
+ from app.views.run_context import build_run_deps, build_state_client
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ async def sync_run(request: Request):
32
+ runtime = request.app.state.runtime
33
+ reject_scheduled_on_cas_endpoint(request)
34
+ user = await authenticate_user(request, runtime)
35
+ try:
36
+ payload = await request.json()
37
+ question = str(payload["question"]).strip()
38
+ input_data = payload["input"]
39
+ except (KeyError, TypeError, ValueError, json.JSONDecodeError):
40
+ return JSONResponse({"error": "invalid sync request"}, status_code=422)
41
+ if not question or not isinstance(input_data, dict):
42
+ return JSONResponse({"error": "invalid sync request"}, status_code=422)
43
+ return await _sync_response(
44
+ runtime,
45
+ user,
46
+ question,
47
+ input_data,
48
+ effective_context=_effective_time_context(request),
49
+ )
50
+
51
+
52
+ async def scheduled_run(request: Request):
53
+ runtime = request.app.state.runtime
54
+ token = scheduled_token(request)
55
+ await strict_scheduled_body(request)
56
+ identity = await authenticate_scheduled_run(runtime, token)
57
+ input_data = {
58
+ "scheduledTaskId": identity.task_id,
59
+ "scheduledRunId": identity.run_id,
60
+ "scheduledAt": identity.scheduled_at.isoformat().replace("+00:00", "Z"),
61
+ "timezone": identity.timezone,
62
+ }
63
+ return await _sync_response(
64
+ runtime,
65
+ {
66
+ "authentication_type": "SCHEDULED",
67
+ "user_id": identity.user_id,
68
+ "org_code": identity.org_code,
69
+ "scheduled_run_id": identity.run_id,
70
+ "control_auth": ControlAuth.scheduled(token),
71
+ },
72
+ identity.prompt,
73
+ input_data,
74
+ effective_context=(input_data["scheduledAt"], identity.timezone),
75
+ )
76
+
77
+
78
+ async def _sync_response(
79
+ runtime,
80
+ user: dict[str, Any],
81
+ question: str,
82
+ input_data: dict[str, Any],
83
+ *,
84
+ effective_context: tuple[str, str] | None = None,
85
+ ) -> JSONResponse:
86
+ try:
87
+ content = await _run_sync(
88
+ runtime,
89
+ user,
90
+ question,
91
+ input_data,
92
+ effective_context=effective_context,
93
+ )
94
+ except ModelHTTPError as exc:
95
+ status, code, message, model_name = model_http_error_details(exc)
96
+ logger.error(
97
+ "Sync model request failed status=%s model=%s code=%s message=%s",
98
+ status,
99
+ model_name,
100
+ code,
101
+ message,
102
+ )
103
+ return JSONResponse(
104
+ {"error": message, "code": code, "model": model_name},
105
+ status_code=status,
106
+ )
107
+ return JSONResponse({"content": content})
108
+
109
+
110
+ async def _run_sync(
111
+ runtime,
112
+ user: dict[str, Any],
113
+ question: str,
114
+ input_data: Any,
115
+ *,
116
+ effective_context: tuple[str, str] | None = None,
117
+ ):
118
+ state_client = build_state_client(runtime, user)
119
+ deps = build_run_deps(runtime, user, state_client)
120
+ if effective_context is not None:
121
+ deps.effective_at, deps.effective_timezone = effective_context
122
+ prompt = f"{question}\n\n输入数据:{json.dumps(input_data, ensure_ascii=False)}"
123
+ decision = await runtime.graph.router.run(
124
+ prompt,
125
+ deps=deps,
126
+ usage_limits=runtime.graph.usage_limits,
127
+ )
128
+ agent = runtime.graph.resolve_root(decision.output)
129
+ result = await agent.run(
130
+ prompt,
131
+ deps=deps,
132
+ usage_limits=runtime.graph.usage_limits,
133
+ )
134
+ output = result.output
135
+ return output.model_dump(by_alias=True) if isinstance(output, BaseModel) else output
136
+
137
+
138
+ def _effective_time_context(request: Request) -> tuple[str, str] | None:
139
+ effective_at = request.headers.get("x-agent-effective-at")
140
+ timezone = request.headers.get("x-agent-effective-timezone")
141
+ if effective_at is None and timezone is None:
142
+ return None
143
+ if not effective_at or not timezone:
144
+ raise RouteError(422, "invalid effective time context")
145
+ try:
146
+ parsed = datetime.fromisoformat(effective_at.replace("Z", "+00:00"))
147
+ if parsed.tzinfo is None:
148
+ raise ValueError
149
+ ZoneInfo(timezone)
150
+ except (KeyError, ValueError):
151
+ raise RouteError(422, "invalid effective time context")
152
+ return effective_at, timezone
@@ -0,0 +1,23 @@
1
+ APP_ENV={{APP_ENV}}
2
+ CONSOLE_STDOUT={{CONSOLE_STDOUT}}
3
+ LOG_LEVEL={{LOG_LEVEL}}
4
+ LOG_DIR={{LOG_DIR}}
5
+ # 联合运维服务
6
+ UNION_BASE_URL={{UNION_BASE_URL}}
7
+ PERMISSIONS={{PERMISSIONS}}
8
+
9
+ # 大模型地址
10
+ LLM_URL={{LLM_URL}}
11
+ LLM_KEY={{LLM_KEY}}
12
+ LLM_MODEL={{LLM_MODEL}}
13
+ LLM_CONTEXT_WINDOW={{LLM_CONTEXT_WINDOW}}
14
+ AGENT_MAX_RUN_SECONDS={{AGENT_MAX_RUN_SECONDS | default('900')}}
15
+ SUBAGENT_TIMEOUT_SECONDS={{SUBAGENT_TIMEOUT_SECONDS | default('900')}}
16
+
17
+ # 向量模型地址(OpenAI-compatible embeddings API)
18
+ RAG_ENABLED=true
19
+ RAG_KNOWLEDGE_DIR=knowledge
20
+ RAG_COLLECTION=ops_knowledge
21
+ RAG_EMBEDDING_MODEL={{RAG_EMBEDDING_MODEL}}
22
+ RAG_TOP_K=5
23
+ RAG_CHUNK_SIZE=1200
@@ -0,0 +1,15 @@
1
+ union-py-app:
2
+ test:
3
+ test:
4
+ - template: deploy/autoconf/templates/env.j2
5
+ dest: app/config/env/.env.test.bj12
6
+ prod:
7
+ bj11:
8
+ - template: deploy/autoconf/templates/env.j2
9
+ dest: app/config/env/.env.prod.bj11
10
+ sh20:
11
+ - template: deploy/autoconf/templates/env.j2
12
+ dest: app/config/env/.env.prod.sh20
13
+ sz31:
14
+ - template: deploy/autoconf/templates/env.j2
15
+ dest: app/config/env/.env.prod.sz31
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -u
4
+
5
+ TIMEOUT_SECONDS="${HEALTHCHECK_TIMEOUT_SECONDS:-5}"
6
+
7
+ probe_http() {
8
+ local url="$1"
9
+ curl --fail --silent --show-error --max-time "$TIMEOUT_SECONDS" "$url" >/dev/null
10
+ }
11
+
12
+ probe_http "${APP_HEALTHCHECK_URL:-http://127.0.0.1:${APP_PORT:-8080}/healthcheck.html}" || exit 1
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ # 脚本:启动 ASGI 应用
3
+ # 功能:
4
+ # 1.删除旧的union-py虚拟环境
5
+ # 2.创建新venv环境并安装依赖
6
+ # 3.启动ASGI服务
7
+ ASGI_APP="app.asgi:app"
8
+ PYTHON="python"
9
+ LOG_ACCESS_FILE="/data/dataLogs/hypercorn_$(date '+%Y-%m-%d_%H_%M_%S').log"
10
+
11
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
12
+ VENV_DIR="$ROOT_DIR/union_py"
13
+ REQUIREMENTS="$ROOT_DIR/requirements.txt"
14
+ OFFLINK_PKGS="$ROOT_DIR/deploy/offline-packages"
15
+ PID_FILE="$ROOT_DIR/deploy/scripts/pid"
16
+ STARTUP_TIMEOUT_SECONDS="${APP_STARTUP_TIMEOUT_SECONDS:-300}"
17
+ export PYTHONUNBUFFERED=1
18
+ export APP_ENV="${APP_ENV:-dev}"
19
+ mkdir -p "$(dirname "$LOG_ACCESS_FILE")"
20
+ echo "切换到项目目录$ROOT_DIR 并设置APP_ENV环境变量:$APP_ENV" >> "$LOG_ACCESS_FILE"
21
+ BIND_HOST="127.0.0.1"
22
+ if [[ "$APP_ENV" == *test* ]]; then
23
+ BIND_HOST="0.0.0.0"
24
+ fi
25
+ echo "开始启动,当前目录:$(pwd)...." >> "$LOG_ACCESS_FILE"
26
+ if [ -d "$VENV_DIR" ]; then
27
+ echo "删除现有环境:$VENV_DIR" >> "$LOG_ACCESS_FILE"
28
+ rm -rf "$VENV_DIR"
29
+ else
30
+ echo "虚拟环境$VENV_DIR 不存在,跳过删除" >> "$LOG_ACCESS_FILE"
31
+ fi
32
+ echo "开始创建虚拟环境$VENV_DIR " >> "$LOG_ACCESS_FILE"
33
+ $PYTHON -m venv "$VENV_DIR"
34
+ if [ $? -ne 0 ]; then
35
+ echo "创建虚拟环境$VENV_DIR 失败,请检查python3 和venv命令是否可用" >> "$LOG_ACCESS_FILE"
36
+ exit 1
37
+ fi
38
+ source "$VENV_DIR/bin/activate"
39
+ echo "虚拟环境$VENV_DIR 创建成功.并已激活虚拟环境$VENV_DIR" >> "$LOG_ACCESS_FILE"
40
+
41
+ echo "安装依赖 from $REQUIREMENTS 文件" >> "$LOG_ACCESS_FILE"
42
+ if [ ! -f "$REQUIREMENTS" ]; then
43
+ echo "$REQUIREMENTS 文件不存在,退出" >> "$LOG_ACCESS_FILE"
44
+ exit 1
45
+ fi
46
+ pip install \
47
+ --no-index \
48
+ --find-links "$OFFLINK_PKGS" \
49
+ --no-cache-dir \
50
+ -r "$REQUIREMENTS" || { echo "依赖安装失败,请检查离线包是否完整" >> "$LOG_ACCESS_FILE"; exit 1 ;}
51
+
52
+ echo "安装依赖完成。启动ASGI应用:$ASGI_APP" >> "$LOG_ACCESS_FILE"
53
+ cd "$ROOT_DIR"
54
+ hypercorn \
55
+ --workers 1 \
56
+ --bind "$BIND_HOST":8080 \
57
+ --keep-alive 2 \
58
+ --pid "$PID_FILE" \
59
+ "$ASGI_APP" \
60
+ >> "$LOG_ACCESS_FILE" 2>&1 &
61
+ echo $! >> "$LOG_ACCESS_FILE"
62
+
63
+ for i in $(seq 1 "$STARTUP_TIMEOUT_SECONDS");do
64
+ if [ -f "$PID_FILE" ] ;then
65
+ PID=$(cat "$PID_FILE" 2>/dev/null)
66
+ if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null ; then
67
+ if HEALTHCHECK_TIMEOUT_SECONDS=1 bash "$ROOT_DIR/deploy/scripts/healthcheck.sh"; then
68
+ echo "hypercorn 已就绪(PID:$PID)"
69
+ exit 0
70
+ fi
71
+ else
72
+ break
73
+ fi
74
+ fi
75
+ sleep 1
76
+ done
77
+
78
+ echo "hypercorn 未在 ${STARTUP_TIMEOUT_SECONDS}s 内就绪" >> "$LOG_ACCESS_FILE"
79
+ bash "$ROOT_DIR/deploy/scripts/stop.sh"
80
+ exit 1
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
4
+
5
+ PID_FILE="$ROOT_DIR/deploy/scripts/pid"
6
+
7
+ quiet_stop(){
8
+ local pid_file="$1"
9
+ local name="$2"
10
+ if [ ! -f "$pid_file" ];then
11
+ return 0
12
+ fi
13
+ PID=$(cat "$pid_file" 2>/dev/null)
14
+ if [ -z "$PID" ];then
15
+ rm -f "$pid_file"
16
+ return 0
17
+ fi
18
+ if kill -0 "$PID" 2>/dev/null; then
19
+ echo "正在停止 $name(PID:$PID)..."
20
+ kill "$PID" >/dev/null 2>&1
21
+ for i in {1..5}; do
22
+ if ! kill -0 "$PID" 2>/dev/null; then
23
+ echo "$name(PID:$PID) 已停止"
24
+ rm -f "$pid_file"
25
+ return 0
26
+ fi
27
+ sleep 1
28
+ done
29
+ echo "兜底,强制停止"
30
+ kill -9 "$PID" 2>/dev/null
31
+ fi
32
+ rm -f "$pid_file"
33
+ }
34
+
35
+ quiet_stop "$PID_FILE" "hypercorn"
@@ -0,0 +1,134 @@
1
+ ---
2
+ kb_id: scenario-offline-function-call-mock-v1
3
+ title: 成员机构运行质量分析场景指南
4
+ doc_type: scenario
5
+ domain: 联合运维
6
+ category: 运行质量分析
7
+ category_description: 指导模型在联合运维场景中围绕成员机构运行质量调用工具、组织证据并形成分析结论。
8
+ category_keywords:
9
+ - 运行质量
10
+ - 成员机构
11
+ - 系统成功率
12
+ - 平均耗时
13
+ - 交易量
14
+ - 失败率
15
+ - 变更报备
16
+ - Jira故障
17
+ - 根因辅助分析
18
+ status: active
19
+ ---
20
+
21
+ # 成员机构运行质量分析场景指南
22
+
23
+ 当用户询问某家成员机构“近期运行质量如何”“过去一段时间运行表现怎样”“有没有影响运行质量的因素”时,应把问题识别为成员机构运行质量分析场景。
24
+
25
+ 运行质量不是单一系统成功率指标。系统成功率是核心指标,但平均耗时、交易量、失败笔数、失败率、同期变更、同期故障都会影响对运行质量的判断。
26
+
27
+ ## 默认时间范围
28
+
29
+ 用户没有明确时间范围时,使用近 30 天作为默认分析窗口,并在回答中说明“按近 30 天分析”。
30
+
31
+ 常见时间表达处理规则:
32
+
33
+ - “近期”“最近”“过去一段时间”:近 30 天。
34
+ - “本月”:当前自然月开始日至当前日期。
35
+ - “上月”:上一自然月。
36
+ - “过去 N 天”:按用户给出的 N 天。
37
+ - “过去 N 个月”:按用户给出的 N 个月。
38
+ - 如果用户给出明确日期,以用户日期为准。
39
+
40
+ 工具入参中的日期优先使用 `yyyyMMdd` 格式,例如 `20260513`。
41
+
42
+ ## 推荐工具调用顺序
43
+
44
+ 分析某家机构时,优先按以下顺序调用工具:
45
+
46
+ 1. `runningAnalysis.resolve_member_org`
47
+
48
+ 根据用户输入的机构名称、简称或别名识别标准机构和 `orgCode`。例如用户说“中国银行”“中行”“BOC”,不要直接猜测机构编码。
49
+
50
+ 2. `runningAnalysis.query_member_metrics`
51
+
52
+ 使用 `orgCodeList + startDate + endDate` 查询一个或多个机构每日运行指标;单机构也传数组,例如 `["C100000000"]`。重点关注系统成功率、平均耗时、交易笔数、失败笔数、失败率。
53
+
54
+ 3. `runningAnalysis.query_changes`
55
+
56
+ 使用同一机构和同一时间窗口查询变更报备。重点关注计划开始时间、计划结束时间、变更状态、执行评价、影响范围。
57
+
58
+ 4. `runningAnalysis.query_faults`
59
+
60
+ 使用同一机构和同一时间窗口查询 Jira 故障工单。重点关注故障时间、恢复时间、故障等级、影响范围、影响描述、故障原因。
61
+
62
+ 5. `runningAnalysis.query_chain_metrics`
63
+
64
+ 当需要判断某机构异常是否具有全局背景时,可查询同一时间窗口的全链路指标作为对照。如果全链路整体稳定而单机构异常,更偏向机构侧因素;如果全链路同时波动,更偏向平台或公共链路因素。
65
+
66
+ ## 运行指标分析方法
67
+
68
+ 应综合判断以下指标:
69
+
70
+ - 系统成功率:核心稳定性指标。下降代表交易成功能力变弱。
71
+ - 失败率和失败笔数:用于判断成功率变化背后的实际影响。低交易量下成功率波动可能被放大,高交易量下少量成功率下降也可能代表大量失败交易。
72
+ - 平均耗时:核心性能指标。成功率稳定但耗时明显上升,说明用户体验和处理性能可能劣化。
73
+ - 交易笔数:核心业务流量指标。成功率稳定但交易量异常下降,可能代表业务流量、接入、路由或前置系统存在问题。
74
+ - 连续性:单日尖峰和连续多日劣化含义不同。连续多日成功率下降、耗时上升或失败率升高,风险更高。
75
+
76
+ 分析时不要只看单个日期,也要观察趋势:
77
+
78
+ - 成功率是否低于近期均值。
79
+ - 平均耗时是否持续升高。
80
+ - 失败笔数是否集中在某几天。
81
+ - 交易笔数是否突然下降或突然放大。
82
+ - 成员机构指标是否明显偏离全链路指标。
83
+
84
+ ## 变更关联分析方法
85
+
86
+ 变更可能影响运行质量,但不能仅凭时间接近就断言变更导致异常。应做相关性判断:
87
+
88
+ - 如果运行指标劣化时间与变更计划开始时间、执行时间高度重合,标记为“变更相关性较高”。
89
+ - 如果变更执行评价为异常、失败、回退、部分成功,且同日或次日运行指标劣化,标记为重点关注。
90
+ - 如果变更影响范围包含核心支付链路、前置系统、网络策略、清算链路、接入链路,相关性高于普通配置或低风险变更。
91
+ - 如果变更时间远离指标波动时间,或变更执行评价正常且影响范围较小,应降低变更相关性。
92
+
93
+ 回答时使用“可能相关”“相关性较高”“需要进一步核实”,不要直接说“由该变更导致”。
94
+
95
+ ## 故障关联分析方法
96
+
97
+ Jira 故障是解释运行质量波动的重要证据:
98
+
99
+ - 如果故障发生时间与成功率下降、失败率升高、耗时上升时间重合,故障相关性较高。
100
+ - 高等级故障、影响范围涉及该成员机构核心交易链路时,应提高风险判断。
101
+ - 故障恢复时间之后指标恢复,说明故障与运行质量波动可能存在较强关联。
102
+ - 故障原因如果指向网络、前置系统、核心支付链路、数据库、中间件、限流、超时,与耗时和失败率变化更相关。
103
+ - 多个低等级故障集中发生,也可能形成累计影响。
104
+
105
+ 同样不能直接断言因果。应说明证据链:故障时间、故障等级、影响范围、指标变化之间是否吻合。
106
+
107
+ ## 总体运行质量判断
108
+
109
+ 可以使用以下分层:
110
+
111
+ - 良好:成功率稳定,耗时稳定,交易量无异常,失败笔数和失败率低,未发现相关变更或故障影响。
112
+ - 基本稳定但需关注:核心指标总体正常,但存在单日波动、耗时上升、交易量异常、轻微故障或近期变更。
113
+ - 有波动:成功率或失败率出现明显波动,或耗时/交易量有异常,同时存在同期变更或故障。
114
+ - 明显异常:成功率下降、失败率上升、耗时明显恶化或交易量异常,并且故障或异常变更与波动时间高度重合。
115
+
116
+ ## 输出建议结构
117
+
118
+ 回答运行质量分析问题时,建议使用以下结构:
119
+
120
+ 1. 总体判断:一句话说明运行质量是良好、基本稳定、有波动还是明显异常。
121
+ 2. 运行指标表现:说明成功率、平均耗时、交易量、失败笔数、失败率的主要变化。
122
+ 3. 变更关联分析:列出同期变更及其计划时间、状态、执行评价、影响范围,并判断相关性。
123
+ 4. 故障关联分析:列出同期故障及故障时间、等级、影响范围、原因、恢复情况,并判断相关性。
124
+ 5. 可能影响因素排序:按证据强弱排序,例如故障影响、变更影响、交易量变化、全链路背景等。
125
+ 6. 不确定性:说明哪些结论只是相关性判断,哪些需要进一步查看日志、监控或工单详情。
126
+ 7. 建议动作:例如关注后续指标、复核变更执行记录、跟进未关闭故障、对异常日期做链路排查。
127
+
128
+ ## 重要约束
129
+
130
+ - 不要编造机构编码。缺少 `orgCode` 时先调用 `runningAnalysis.resolve_member_org`。
131
+ - 不要只基于系统成功率下结论。
132
+ - 不要把变更或故障直接断定为根因,除非工具返回中已有明确结论。
133
+ - 如果工具数据为空,应明确说明“未查询到相关数据”,不要补造。
134
+ - 如果运行指标、变更、故障之间结论冲突,应分别说明证据,并给出保守判断。
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "union-app-chat-stream",
3
+ "version": "1.1.6",
4
+ "description": "Union operations PydanticAI ASGI service package.",
5
+ "license": "UNLICENSED",
6
+ "files": [
7
+ "app",
8
+ "!app/config/env/.env",
9
+ "!app/config/env/.env.*",
10
+ "!app/**/__pycache__",
11
+ "!app/**/*.pyc",
12
+ "deploy",
13
+ "!deploy/**/__pycache__",
14
+ "!deploy/**/*.pyc",
15
+ "!deploy/offline-packages",
16
+ "!deploy/offline-packages/**",
17
+ "scripts",
18
+ "knowledge",
19
+ "requirements.txt"
20
+ ]
21
+ }
@@ -0,0 +1,10 @@
1
+ pydantic-ai-slim[ag-ui,logfire,openai,zai]==2.18.0
2
+ pydantic-ai-harness[skills]==0.12.0
3
+ openai==2.45.0
4
+ ag-ui-protocol==0.1.19
5
+ python-dotenv==1.2.3
6
+ httpx==0.28.1
7
+ Hypercorn==0.17.3
8
+ chromadb==1.5.9
9
+ numpy==2.2.6
10
+ pyyaml==6.0.3
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4
+ exec bash "$ROOT_DIR/deploy/scripts/healthcheck.sh" "$@"
@@ -0,0 +1 @@
1
+ prod.bj11
@@ -0,0 +1 @@
1
+ test.bj12
@@ -0,0 +1 @@
1
+ prod.sh20
@@ -0,0 +1 @@
1
+ prod.sz31
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
4
+ exec bash "$ROOT_DIR/deploy/scripts/stop.sh" "$@"