mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(yuanbao): correct AuthBind plugin_version / bot_version mapping (#2804)
This commit is contained in:
@@ -9,6 +9,22 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::errors::YuanbaoError;
|
||||
|
||||
/// Default value for `DeviceInfo.app_version` (server-side `plugin_version`).
|
||||
///
|
||||
/// In `yuanbao-openclaw-plugin`'s wire mapping, `plugin_version` represents
|
||||
/// the *plugin-layer* (npm package) version while `bot_version` represents
|
||||
/// the *framework runtime* version. OpenHuman has no separate plugin layer;
|
||||
/// we reuse this slot for the **yuanbao channel provider's** own iteration
|
||||
/// version. Bump it when the provider's protocol adapter changes in a way
|
||||
/// the server might care about. The framework runtime version is reported
|
||||
/// separately via `CARGO_PKG_VERSION` in `DeviceInfo.bot_version`.
|
||||
pub(crate) const DEFAULT_PLUGIN_VERSION: &str = "0.1.0";
|
||||
|
||||
/// Strip legacy `openhuman/` prefix from version strings in config/TOML.
|
||||
pub(crate) fn strip_version_prefix(version: &str) -> &str {
|
||||
version.strip_prefix("openhuman/").unwrap_or(version)
|
||||
}
|
||||
|
||||
/// Production environment endpoints (default).
|
||||
const PROD_API_DOMAIN: &str = "https://bot.yuanbao.tencent.com";
|
||||
const PROD_WS_URL: &str = "wss://bot-wss.yuanbao.tencent.com/wss/connection";
|
||||
@@ -46,8 +62,18 @@ pub struct YuanbaoConfig {
|
||||
/// `api_domain/api/token/sign` with `(app_key, app_secret)` to fetch one.
|
||||
#[serde(default)]
|
||||
pub token: String,
|
||||
/// Plugin/bot version reported in `AuthBindReq.DeviceInfo.bot_version`.
|
||||
#[serde(default = "default_bot_version")]
|
||||
/// Yuanbao channel-provider iteration version, reported in
|
||||
/// `AuthBindReq.DeviceInfo.app_version` (server-side `plugin_version`).
|
||||
///
|
||||
/// **NOTE:** Despite the legacy `bot_version` TOML key name, this value
|
||||
/// fills the *plugin*-version slot on the wire — see
|
||||
/// [`DEFAULT_PLUGIN_VERSION`] for the semantic mapping. The framework
|
||||
/// runtime version (`DeviceInfo.bot_version` / server `bot_version`)
|
||||
/// is sourced from `CARGO_PKG_VERSION` and is **not** user-configurable;
|
||||
/// operators who previously set this key intending to override the
|
||||
/// framework version should drop it. New configs may use the clearer
|
||||
/// `plugin_version` alias.
|
||||
#[serde(default = "default_bot_version", alias = "plugin_version")]
|
||||
pub bot_version: String,
|
||||
/// Optional bot display name — used by the `@bot` mention guard.
|
||||
#[serde(default)]
|
||||
@@ -161,8 +187,11 @@ impl YuanbaoConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Default value for [`YuanbaoConfig::bot_version`] — populates
|
||||
/// `DeviceInfo.app_version` (server `plugin_version`) when the user config
|
||||
/// omits the field.
|
||||
fn default_bot_version() -> String {
|
||||
"openhuman/0.1.0".into()
|
||||
DEFAULT_PLUGIN_VERSION.into()
|
||||
}
|
||||
|
||||
fn default_env() -> String {
|
||||
|
||||
@@ -401,15 +401,19 @@ impl YuanbaoConnection {
|
||||
// "bot" when missing (matches the plugin's static-token branch
|
||||
// and `data.source || "bot"` resolution).
|
||||
let resolved_source = if source.is_empty() { "bot" } else { source };
|
||||
// Align with yuanbao-openclaw-plugin: app_version → plugin_version,
|
||||
// DeviceInfo field 24 → bot_version (OpenHuman framework / CARGO_PKG_VERSION).
|
||||
let plugin_version = super::config::strip_version_prefix(&cfg.bot_version);
|
||||
let framework_version = env!("CARGO_PKG_VERSION");
|
||||
let frame = encode_auth_bind(
|
||||
"ybBot",
|
||||
&uid,
|
||||
resolved_source,
|
||||
token,
|
||||
&msg_id,
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
plugin_version,
|
||||
std::env::consts::OS,
|
||||
&cfg.bot_version,
|
||||
framework_version,
|
||||
&cfg.route_env,
|
||||
);
|
||||
self.send_frame(frame).await
|
||||
|
||||
@@ -599,23 +599,25 @@ mod tests {
|
||||
assert_eq!(frame.data, b"payload");
|
||||
}
|
||||
|
||||
/// Smoke-test that [`encode_auth_bind`] produces a frame round-trippable
|
||||
/// via [`decode_conn_msg`] and that the `app_version` / `bot_version`
|
||||
/// arguments land in the expected `DeviceInfo` fields (regression guard
|
||||
/// for the plugin_version/bot_version swap).
|
||||
#[test]
|
||||
fn auth_bind_smoke() {
|
||||
let buf = encode_auth_bind(
|
||||
"biz",
|
||||
"uid",
|
||||
"openclaw",
|
||||
"tok",
|
||||
"mid",
|
||||
"1.0",
|
||||
"linux",
|
||||
"openhuman/0.1.0",
|
||||
"",
|
||||
"biz", "uid", "openclaw", "tok", "mid", "0.1.0", "linux", "1.0", "",
|
||||
);
|
||||
let frame = decode_conn_msg(&buf).unwrap();
|
||||
assert_eq!(frame.cmd, cmd::AUTH_BIND);
|
||||
assert_eq!(frame.module, module::CONN_ACCESS);
|
||||
assert!(!frame.data.is_empty());
|
||||
|
||||
let req_fields = parse_fields(&frame.data).unwrap();
|
||||
let dev_buf = get_bytes(&req_fields, 3);
|
||||
let dev_fields = parse_fields(&dev_buf).unwrap();
|
||||
assert_eq!(get_string(&dev_fields, 1), "0.1.0", "app_version");
|
||||
assert_eq!(get_string(&dev_fields, 24), "1.0", "bot_version");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -65,11 +65,11 @@ pub mod tim {
|
||||
}
|
||||
|
||||
/// Fixed instance id reported in `AuthBindReq.DeviceInfo.instance_id` and
|
||||
/// the `X-Instance-Id` HTTP header. Mirrors `OPENCLAW_ID = 16` used by
|
||||
/// the `X-Instance-Id` HTTP header. Mirrors `OPENCLAW_ID = 20` used by
|
||||
/// `yuanbao-openclaw-plugin` (`src/access/ws/conn-codec.ts`) — the server
|
||||
/// keys some checks off this value, so it must match the value the sign
|
||||
/// endpoint sees when the token is minted.
|
||||
pub const OPENHUMAN_INSTANCE_ID: &str = "16";
|
||||
pub const OPENHUMAN_INSTANCE_ID: &str = "20";
|
||||
|
||||
/// Reconnect backoff schedule (seconds). Mirrors hermes-agent.
|
||||
pub const RECONNECT_DELAYS: &[u64] = &[1, 2, 5, 10, 30, 60];
|
||||
|
||||
@@ -211,13 +211,13 @@ impl SignManager {
|
||||
.post(&url)
|
||||
.timeout(Duration::from_secs(HTTP_TIMEOUT_SECS))
|
||||
.header("Content-Type", "application/json")
|
||||
.header("X-AppVersion", "openhuman/0.1.0")
|
||||
.header("X-AppVersion", super::config::DEFAULT_PLUGIN_VERSION)
|
||||
.header("X-OperationSystem", "linux")
|
||||
.header(
|
||||
"X-Instance-Id",
|
||||
super::proto_constants::OPENHUMAN_INSTANCE_ID,
|
||||
)
|
||||
.header("X-Bot-Version", "openhuman/0.1.0");
|
||||
.header("X-Bot-Version", env!("CARGO_PKG_VERSION"));
|
||||
if !route_env.is_empty() {
|
||||
req = req.header("X-Route-Env", route_env);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user