refactor: 重构 Tool Result 契约,移除 ui_hints 统一使用 result 字段
- ToolAgentOutput 移除 result_summary 和 ui_hints,统一使用 result 字段 - 日历/用户查找工具移除 ui_hints 输出,改为机器可读的结构化结果 - Agent History 移除 tool 消息的 ui_hints 处理逻辑 - App 版本检查改为 manifest.json 方式,支持多渠道发布 - 更新 settings 配置和测试用例适配新结构
This commit is contained in:
Executable
+178
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(git rev-parse --show-toplevel)"
|
||||
APPS_DIR="$ROOT_DIR/apps"
|
||||
OUTPUT_APK="$APPS_DIR/build/app/outputs/flutter-apk/app-release.apk"
|
||||
RELEASES_DIR="$ROOT_DIR/deploy/static/releases"
|
||||
MANIFEST_FILE="$RELEASES_DIR/manifest.json"
|
||||
|
||||
BACKEND_HOST=""
|
||||
CHANNEL="release"
|
||||
RELEASE_NOTES=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--backend-host)
|
||||
BACKEND_HOST="$2"
|
||||
shift 2
|
||||
;;
|
||||
--channel)
|
||||
CHANNEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--release-notes)
|
||||
RELEASE_NOTES="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
printf 'Unknown arg: %s\n' "$1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "$BACKEND_HOST" ]]; then
|
||||
printf 'Usage: %s --backend-host <ip-or-domain> [--channel release] [--release-notes "..."]\n' "$0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$BACKEND_HOST" == *":"* ]]; then
|
||||
printf 'Invalid backend host: do not include port (%s)\n' "$BACKEND_HOST" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ "$CHANNEL" =~ ^[a-z0-9_-]+$ ]]; then
|
||||
printf 'Invalid channel: %s\n' "$CHANNEL" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKEND_URL="http://$BACKEND_HOST"
|
||||
|
||||
readarray -t VERSION_INFO < <(
|
||||
python - <<'PY'
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
text = Path("apps/pubspec.yaml").read_text(encoding="utf-8")
|
||||
match = re.search(r"^version:\s*([0-9]+\.[0-9]+\.[0-9]+)\+([0-9]+)\s*$", text, re.MULTILINE)
|
||||
if not match:
|
||||
raise SystemExit("pubspec.yaml version format invalid")
|
||||
print(match.group(1))
|
||||
print(match.group(2))
|
||||
PY
|
||||
)
|
||||
|
||||
VERSION_NAME="${VERSION_INFO[0]}"
|
||||
CURRENT_VERSION_CODE="${VERSION_INFO[1]}"
|
||||
NEXT_VERSION_CODE="$((CURRENT_VERSION_CODE + 1))"
|
||||
FILE_NAME="social-app-android-v${VERSION_NAME}+${NEXT_VERSION_CODE}-${CHANNEL}.apk"
|
||||
TARGET_APK="$RELEASES_DIR/$FILE_NAME"
|
||||
|
||||
mkdir -p "$RELEASES_DIR"
|
||||
|
||||
pushd "$APPS_DIR" >/dev/null
|
||||
flutter build apk --release \
|
||||
--build-name="$VERSION_NAME" \
|
||||
--build-number="$NEXT_VERSION_CODE" \
|
||||
--dart-define="BACKEND_URL=$BACKEND_URL" \
|
||||
--target-platform=android-arm64 \
|
||||
--split-per-abi \
|
||||
--target "lib/main.dart"
|
||||
popd >/dev/null
|
||||
|
||||
SOURCE_APK="$APPS_DIR/build/app/outputs/flutter-apk/app-arm64-v8a-release.apk"
|
||||
if [[ ! -f "$SOURCE_APK" ]]; then
|
||||
SOURCE_APK="$OUTPUT_APK"
|
||||
fi
|
||||
|
||||
cp "$SOURCE_APK" "$TARGET_APK"
|
||||
|
||||
FILE_SIZE="$(stat -c%s "$TARGET_APK")"
|
||||
SHA256="$(sha256sum "$TARGET_APK" | cut -d' ' -f1)"
|
||||
|
||||
python - <<'PY' "$ROOT_DIR/apps/pubspec.yaml" "$VERSION_NAME" "$NEXT_VERSION_CODE"
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
pubspec_path = Path(sys.argv[1])
|
||||
version_name = sys.argv[2]
|
||||
version_code = sys.argv[3]
|
||||
|
||||
content = pubspec_path.read_text(encoding="utf-8")
|
||||
updated, count = re.subn(
|
||||
r"^version:\s*[0-9]+\.[0-9]+\.[0-9]+\+[0-9]+\s*$",
|
||||
f"version: {version_name}+{version_code}",
|
||||
content,
|
||||
count=1,
|
||||
flags=re.MULTILINE,
|
||||
)
|
||||
if count != 1:
|
||||
raise SystemExit("failed to update version in pubspec.yaml")
|
||||
pubspec_path.write_text(updated, encoding="utf-8")
|
||||
PY
|
||||
|
||||
RELEASE_NOTES="$RELEASE_NOTES" python - <<'PY' "$MANIFEST_FILE" "$FILE_NAME" "$VERSION_NAME" "$NEXT_VERSION_CODE" "$CHANNEL" "$FILE_SIZE" "$SHA256"
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
manifest_path = Path(sys.argv[1])
|
||||
file_name = sys.argv[2]
|
||||
version_name = sys.argv[3]
|
||||
version_code = int(sys.argv[4])
|
||||
channel = sys.argv[5]
|
||||
file_size = int(sys.argv[6])
|
||||
sha256 = sys.argv[7]
|
||||
release_notes = os.environ.get("RELEASE_NOTES", "")
|
||||
|
||||
if manifest_path.is_file():
|
||||
data = json.loads(manifest_path.read_text(encoding="utf-8"))
|
||||
else:
|
||||
data = {"releases": []}
|
||||
|
||||
releases = data.get("releases") or []
|
||||
releases = [
|
||||
item
|
||||
for item in releases
|
||||
if not (
|
||||
item.get("platform") == "android"
|
||||
and item.get("channel") == channel
|
||||
and item.get("version_code") == version_code
|
||||
)
|
||||
]
|
||||
releases.append(
|
||||
{
|
||||
"platform": "android",
|
||||
"channel": channel,
|
||||
"version_name": version_name,
|
||||
"version_code": version_code,
|
||||
"min_supported_version_code": version_code,
|
||||
"file_name": file_name,
|
||||
"release_notes": release_notes or None,
|
||||
"file_size": file_size,
|
||||
"sha256": sha256,
|
||||
}
|
||||
)
|
||||
releases.sort(
|
||||
key=lambda item: (
|
||||
item.get("platform", ""),
|
||||
item.get("channel", ""),
|
||||
item.get("version_code", 0),
|
||||
)
|
||||
)
|
||||
|
||||
manifest_path.write_text(
|
||||
json.dumps({"releases": releases}, indent=2, ensure_ascii=True) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
PY
|
||||
|
||||
printf 'Build completed\n'
|
||||
printf 'Version: %s+%s\n' "$VERSION_NAME" "$NEXT_VERSION_CODE"
|
||||
printf 'Previous buildNumber: %s\n' "$CURRENT_VERSION_CODE"
|
||||
printf 'Backend URL: %s\n' "$BACKEND_URL"
|
||||
printf 'Package: %s\n' "$TARGET_APK"
|
||||
printf 'SHA256: %s\n' "$SHA256"
|
||||
Reference in New Issue
Block a user