fix: use internal URL for AI HTTP tools
Prefer IA_WEB_INTERNAL_URL or local HOST for AI tool requests while preserving public page links for users.
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# 更新日志
|
||||
|
||||
## 0.2.16 - 2026-07-07
|
||||
|
||||
- 修复 AI 内置页面工具在配置了受保护公开地址时,请求 `/v1/web/pages` 命中 NetBird 鉴权页并返回 401 的问题。
|
||||
- `create_web_page`、`create_markdown_preview`、`query_web_pages` 的内部 HTTP 请求现在优先使用 `IA_WEB_INTERNAL_URL` 或本地 `HOST`;返回给用户的页面链接仍优先使用 `IA_WEB_BASE_URL`。
|
||||
- `query_api_docs` 同步优先使用内部地址查询 API 文档,避免内部工具调用被公开入口鉴权拦截。
|
||||
- 无数据库结构变化;新增 `0.2.16` 升级日志记录,`ias-ai` 升级至 `0.1.6`,`ias-service` 升级至 `0.1.13`。
|
||||
|
||||
## 0.2.15 - 2026-07-07
|
||||
|
||||
- 新增 Markdown 预览页面能力:`page_type=markdown` 的动态页面公开路径为 `/md/{slug}`,React 前端按 Markdown/GFM 渲染标题、列表、表格、引用、链接和代码块。
|
||||
|
||||
Generated
+3
-3
@@ -1042,7 +1042,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ias-ai"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
@@ -1120,7 +1120,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ias-main"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -1135,7 +1135,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ias-service"
|
||||
version = "0.1.12"
|
||||
version = "0.1.13"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ias-ai"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -196,8 +196,7 @@ fn validate_endpoint_id(value: &str) -> anyhow::Result<String> {
|
||||
|
||||
fn api_docs_base_url() -> String {
|
||||
std::env::var("IA_API_DOCS_BASE_URL")
|
||||
.or_else(|_| std::env::var("IA_WEB_BASE_URL"))
|
||||
.or_else(|_| std::env::var("WEB_BASE_URL"))
|
||||
.or_else(|_| std::env::var("IA_WEB_INTERNAL_URL"))
|
||||
.or_else(|_| std::env::var("HOST").map(|host| format!("http://{host}")))
|
||||
.unwrap_or_else(|_| "http://127.0.0.1:9003".to_string())
|
||||
.trim()
|
||||
|
||||
+13
-4
@@ -129,7 +129,7 @@ async fn create_markdown_preview_inner(arguments: &str) -> anyhow::Result<String
|
||||
}
|
||||
|
||||
async fn create_page_request(payload: Value) -> anyhow::Result<String> {
|
||||
let base_url = web_base_url();
|
||||
let base_url = web_request_base_url();
|
||||
let endpoint = format!("{base_url}/v1/web/pages");
|
||||
let client = reqwest::Client::new();
|
||||
let response = client
|
||||
@@ -184,7 +184,7 @@ async fn query_web_pages_inner(arguments: &str) -> anyhow::Result<String> {
|
||||
let page = args.page.unwrap_or(1).max(1);
|
||||
let per_page = args.per_page.unwrap_or(10).clamp(1, 20);
|
||||
|
||||
let mut url = reqwest::Url::parse(&format!("{}/v1/web/pages", web_base_url()))
|
||||
let mut url = reqwest::Url::parse(&format!("{}/v1/web/pages", web_request_base_url()))
|
||||
.context("构造 web 页面查询地址失败")?;
|
||||
{
|
||||
let mut query_pairs = url.query_pairs_mut();
|
||||
@@ -266,7 +266,7 @@ fn web_page_url(page: &WebPageItem) -> String {
|
||||
} else {
|
||||
format!("/web/{}/{}", page.page_type, page.slug)
|
||||
};
|
||||
format!("{}{}", web_base_url(), path)
|
||||
format!("{}{}", web_public_base_url(), path)
|
||||
}
|
||||
|
||||
fn optional_text(value: Option<String>) -> Option<String> {
|
||||
@@ -275,7 +275,16 @@ fn optional_text(value: Option<String>) -> Option<String> {
|
||||
.filter(|value| !value.is_empty())
|
||||
}
|
||||
|
||||
fn web_base_url() -> String {
|
||||
fn web_request_base_url() -> String {
|
||||
std::env::var("IA_WEB_INTERNAL_URL")
|
||||
.or_else(|_| std::env::var("HOST").map(|host| format!("http://{host}")))
|
||||
.unwrap_or_else(|_| "http://127.0.0.1:9003".to_string())
|
||||
.trim()
|
||||
.trim_end_matches('/')
|
||||
.replace("0.0.0.0", "127.0.0.1")
|
||||
}
|
||||
|
||||
fn web_public_base_url() -> String {
|
||||
std::env::var("IA_WEB_BASE_URL")
|
||||
.or_else(|_| std::env::var("WEB_BASE_URL"))
|
||||
.or_else(|_| std::env::var("HOST").map(|host| format!("http://{host}")))
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ias-main"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ias-service"
|
||||
version = "0.1.12"
|
||||
version = "0.1.13"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
INSERT INTO ias_upgrade_logs (
|
||||
version,
|
||||
released_at,
|
||||
title,
|
||||
description,
|
||||
changes,
|
||||
modules
|
||||
) VALUES (
|
||||
'0.2.16',
|
||||
'2026-07-07T00:00:00+08:00',
|
||||
'修复 AI 页面工具内部访问地址',
|
||||
'修复 AI 内置页面工具在公开地址受 NetBird 鉴权保护时无法创建 Markdown 预览页的问题,内部请求改为优先使用内部地址或本地服务地址。',
|
||||
'[
|
||||
"修复 AI 内置页面工具在配置了受保护公开地址时,请求 /v1/web/pages 命中 NetBird 鉴权页并返回 401 的问题。",
|
||||
"create_web_page、create_markdown_preview、query_web_pages 的内部 HTTP 请求现在优先使用 IA_WEB_INTERNAL_URL 或本地 HOST;返回给用户的页面链接仍优先使用 IA_WEB_BASE_URL。",
|
||||
"query_api_docs 同步优先使用内部地址查询 API 文档,避免内部工具调用被公开入口鉴权拦截。",
|
||||
"无数据库结构变化;ias-ai 升级至 0.1.6,ias-service 升级至 0.1.13。"
|
||||
]'::jsonb,
|
||||
'{
|
||||
"ias-common": "0.1.1",
|
||||
"ias-ai": "0.1.6",
|
||||
"ias-wechat": "0.1.0",
|
||||
"ias-context": "0.1.2",
|
||||
"ias-http": "0.1.9",
|
||||
"ias-mail": "0.1.15",
|
||||
"ias-service": "0.1.13",
|
||||
"ias-main": "0.2.16"
|
||||
}'::jsonb
|
||||
) ON CONFLICT (version) DO UPDATE SET
|
||||
released_at = EXCLUDED.released_at,
|
||||
title = EXCLUDED.title,
|
||||
description = EXCLUDED.description,
|
||||
changes = EXCLUDED.changes,
|
||||
modules = EXCLUDED.modules;
|
||||
Reference in New Issue
Block a user