///|
const MOONGATE_CODING_PLAN_TOOL = "coding_plan"
///|
const MOONGATE_TIER_WEEKLY_LIMIT = "weekly_limit"
///|
priv enum MoonCodingPlanProvider {
Kimi
ZhipuCn
ZhipuEn
MiniMaxCn
MiniMaxEn
ZenMux
}
///|
priv enum MoonZhipuWindow {
FiveHour
Weekly
}
///|
priv struct MoonZhipuEntry {
reset_ms : Int64?
percentage : Double
resets_at : String?
}
///|
priv struct MoonCodingPlanHttpRequest {
url : String
headers : Map[String, String]
}
///|
fn moon_detect_coding_plan_provider(
base_url : String,
) -> MoonCodingPlanProvider? {
let url = base_url.to_lower()
if url.contains("api.kimi.com/coding") {
Some(Kimi)
} else if url.contains("open.bigmodel.cn") || url.contains("bigmodel.cn") {
Some(ZhipuCn)
} else if url.contains("api.z.ai") {
Some(ZhipuEn)
} else if url.contains("api.minimaxi.com") {
Some(MiniMaxCn)
} else if url.contains("api.minimax.io") {
Some(MiniMaxEn)
} else if url.contains("zenmux") {
Some(ZenMux)
} else {
None
}
}
///|
async fn moon_get_coding_plan_quota(
base_url : String,
api_key : String,
coding_plan_provider? : String? = None,
team_organization_id? : String? = None,
team_project_id? : String? = None,
) -> SubscriptionQuota {
if coding_plan_provider.unwrap_or("").trim().to_lower() == "zhipu_team" {
let organization_id = team_organization_id.unwrap_or("").trim().to_owned()
let project_id = team_project_id.unwrap_or("").trim().to_owned()
if api_key.trim().is_empty() ||
organization_id.is_empty() ||
project_id.is_empty() {
return moon_quota_error(
MOONGATE_CODING_PLAN_TOOL,
NotFound,
"Zhipu team plan needs the API key + organization ID + project ID",
)
}
return moon_query_zhipu_team_coding_plan(
api_key, organization_id, project_id,
)
}
if api_key.trim().is_empty() {
return SubscriptionQuota::not_found(MOONGATE_CODING_PLAN_TOOL)
}
match moon_detect_coding_plan_provider(base_url) {
Some(Kimi) => moon_query_kimi_coding_plan(api_key)
Some(ZhipuCn) | Some(ZhipuEn) =>
moon_query_zhipu_coding_plan(base_url, api_key)
Some(MiniMaxCn) => moon_query_minimax_coding_plan(api_key, true)
Some(MiniMaxEn) => moon_query_minimax_coding_plan(api_key, false)
Some(ZenMux) => moon_query_zenmux_coding_plan(base_url, api_key)
None => SubscriptionQuota::not_found(MOONGATE_CODING_PLAN_TOOL)
}
}
///|
fn moon_coding_plan_error(message : String) -> SubscriptionQuota {
moon_quota_error(MOONGATE_CODING_PLAN_TOOL, Valid, message)
}
///|
fn moon_coding_plan_auth_error(status_code : Int) -> SubscriptionQuota {
SubscriptionQuota::new(
MOONGATE_CODING_PLAN_TOOL,
credential_status=Expired,
credential_message=Some("Invalid API key"),
success=false,
error=Some("Authentication failed (HTTP \{status_code})"),
queried_at=Some(moon_quota_now_millis()),
)
}
///|
async fn moon_query_kimi_coding_plan(api_key : String) -> SubscriptionQuota {
match
moon_fetch_json_get(
"https://api.kimi.com/coding/v1/usages",
{ "Authorization": "Bearer \{api_key}", "Accept": "application/json" },
expired_message="Authentication failed",
) {
Err(error) =>
if error.status == Expired {
moon_coding_plan_auth_error(
moon_status_code_from_message(error.message),
)
} else {
moon_coding_plan_error(error.message)
}
Ok(body) => moon_parse_kimi_coding_plan(body)
}
}
///|
fn moon_parse_kimi_coding_plan(body : Json) -> SubscriptionQuota {
let tiers : Array[Json] = []
guard body is Object(obj) else {
return moon_coding_plan_error("Failed to parse response: expected object")
}
match obj.get("limits") {
Some(Array(limits)) =>
for item in limits {
guard item is Object(limit_item) else { continue }
guard limit_item.get("detail") is Some(Object(detail)) else { continue }
let limit = moon_json_double_from_map(detail, "limit").unwrap_or(1.0)
let remaining = moon_json_double_from_map(detail, "remaining").unwrap_or(
0.0,
)
let used = (limit - remaining).max(0.0)
tiers.push(
moon_quota_tier_json(
MOON_QUOTA_TIER_FIVE_HOUR,
if limit > 0.0 {
used / limit * 100.0
} else {
0.0
},
resets_at=moon_extract_reset_time(detail.get("resetTime")),
),
)
}
_ => ()
}
match obj.get("usage") {
Some(Object(usage)) => {
let limit = moon_json_double_from_map(usage, "limit").unwrap_or(1.0)
let remaining = moon_json_double_from_map(usage, "remaining").unwrap_or(
0.0,
)
let used = (limit - remaining).max(0.0)
tiers.push(
moon_quota_tier_json(
MOONGATE_TIER_WEEKLY_LIMIT,
if limit > 0.0 {
used / limit * 100.0
} else {
0.0
},
resets_at=moon_extract_reset_time(usage.get("resetTime")),
),
)
}
_ => ()
}
SubscriptionQuota::new(
MOONGATE_CODING_PLAN_TOOL,
tiers~,
queried_at=Some(moon_quota_now_millis()),
)
}
///|
async fn moon_query_zhipu_coding_plan(
base_url : String,
api_key : String,
) -> SubscriptionQuota {
let url = "\{moon_zhipu_quota_base(base_url)}/api/monitor/usage/quota/limit"
match
moon_fetch_json_get(
url,
{
"Authorization": api_key,
"Content-Type": "application/json",
"Accept-Language": "en-US,en",
},
expired_message="Authentication failed",
) {
Err(error) =>
if error.status == Expired {
moon_coding_plan_auth_error(
moon_status_code_from_message(error.message),
)
} else {
moon_coding_plan_error(error.message)
}
Ok(body) => moon_parse_zhipu_coding_plan(body)
}
}
///|
fn moon_zhipu_quota_base(base_url : String) -> String {
if base_url.to_lower().contains("bigmodel.cn") {
"https://open.bigmodel.cn"
} else {
"https://api.z.ai"
}
}
///|
fn moon_zhipu_team_quota_request(
api_key : String,
organization_id : String,
project_id : String,
quota_url? : String = "https://open.bigmodel.cn/api/monitor/usage/quota/limit",
) -> MoonCodingPlanHttpRequest {
{
url: "\{quota_url}?type=2",
headers: {
"Authorization": api_key,
"bigmodel-organization": organization_id,
"bigmodel-project": project_id,
"Content-Type": "application/json",
"Accept-Language": "en-US,en",
},
}
}
///|
async fn moon_query_zhipu_team_coding_plan(
api_key : String,
organization_id : String,
project_id : String,
) -> SubscriptionQuota {
let request = moon_zhipu_team_quota_request(
api_key, organization_id, project_id,
)
match
moon_fetch_json_get(
request.url,
request.headers,
expired_message="Authentication failed",
) {
Err(error) =>
if error.status == Expired {
moon_coding_plan_auth_error(
moon_status_code_from_message(error.message),
)
} else {
moon_coding_plan_error(error.message)
}
Ok(body) => moon_parse_zhipu_coding_plan(body)
}
}
///|
fn moon_parse_zhipu_coding_plan(body : Json) -> SubscriptionQuota {
guard body is Object(obj) else {
return moon_coding_plan_error("Failed to parse response: expected object")
}
match obj.get("success") {
Some(False) => {
let msg = json_string_from_map(obj, "msg").unwrap_or("Unknown error")
return moon_coding_plan_error("API error: \{msg}")
}
_ => ()
}
guard obj.get("data") is Some(data) else {
return moon_coding_plan_error("Missing 'data' field in response")
}
let level = match data {
Object(data_obj) => json_string_from_map(data_obj, "level")
_ => None
}
SubscriptionQuota::new(
MOONGATE_CODING_PLAN_TOOL,
credential_message=level,
tiers=moon_parse_zhipu_token_tiers(data),
queried_at=Some(moon_quota_now_millis()),
)
}
///|
fn moon_parse_zhipu_token_tiers(data : Json) -> Array[Json] {
let mut five_hour : MoonZhipuEntry? = None
let mut weekly : MoonZhipuEntry? = None
let unclassified : Array[MoonZhipuEntry] = []
guard data is Object(data_obj) else { return [] }
match data_obj.get("limits") {
Some(Array(limits)) =>
for item in limits {
guard item is Object(limit_item) else { continue }
let limit_type = json_string_from_map(limit_item, "type").unwrap_or("")
if limit_type.to_lower() != "tokens_limit" {
continue
}
let reset_ms = json_int64_from_map(limit_item, "nextResetTime")
let entry : MoonZhipuEntry = {
reset_ms,
percentage: moon_json_double_from_map(limit_item, "percentage").unwrap_or(
0.0,
),
resets_at: match reset_ms {
Some(ms) => Some(@os.local_rfc3339(ms / 1000L))
None => None
},
}
match moon_classify_zhipu_window(limit_item) {
Some(FiveHour) if five_hour is None => five_hour = Some(entry)
Some(Weekly) if weekly is None => weekly = Some(entry)
_ => unclassified.push(entry)
}
}
_ => ()
}
moon_sort_zhipu_entries(unclassified)
for entry in unclassified {
if five_hour is None {
five_hour = Some(entry)
} else if weekly is None {
weekly = Some(entry)
}
}
let tiers : Array[Json] = []
match five_hour {
Some(entry) =>
tiers.push(
moon_quota_tier_json(
MOON_QUOTA_TIER_FIVE_HOUR,
entry.percentage,
resets_at=entry.resets_at,
),
)
None => ()
}
match weekly {
Some(entry) =>
tiers.push(
moon_quota_tier_json(
MOONGATE_TIER_WEEKLY_LIMIT,
entry.percentage,
resets_at=entry.resets_at,
),
)
None => ()
}
tiers
}
///|
fn moon_classify_zhipu_window(item : Map[String, Json]) -> MoonZhipuWindow? {
match json_int64_from_map(item, "unit") {
Some(3L) => Some(FiveHour)
Some(6L) => Some(Weekly)
_ => None
}
}
///|
fn moon_zhipu_entry_sort_key(entry : MoonZhipuEntry) -> Int64 {
match entry.reset_ms {
Some(ms) => ms
None => -9223372036854775808L
}
}
///|
fn moon_sort_zhipu_entries(entries : Array[MoonZhipuEntry]) -> Unit {
let mut i = 0
while i < entries.length() {
let mut j = i + 1
while j < entries.length() {
if moon_zhipu_entry_sort_key(entries[j]) <
moon_zhipu_entry_sort_key(entries[i]) {
let current = entries[i]
entries[i] = entries[j]
entries[j] = current
}
j = j + 1
}
i = i + 1
}
}
///|
async fn moon_query_minimax_coding_plan(
api_key : String,
is_cn : Bool,
) -> SubscriptionQuota {
let domain = if is_cn { "api.minimaxi.com" } else { "api.minimax.io" }
match
moon_fetch_json_get(
"https://\{domain}/v1/api/openplatform/coding_plan/remains",
{
"Authorization": "Bearer \{api_key}",
"Content-Type": "application/json",
},
expired_message="Authentication failed",
) {
Err(error) =>
if error.status == Expired {
moon_coding_plan_auth_error(
moon_status_code_from_message(error.message),
)
} else {
moon_coding_plan_error(error.message)
}
Ok(body) => moon_parse_minimax_coding_plan(body)
}
}
///|
fn moon_parse_minimax_coding_plan(body : Json) -> SubscriptionQuota {
guard body is Object(obj) else {
return moon_coding_plan_error("Failed to parse response: expected object")
}
match obj.get("base_resp") {
Some(Object(base_resp)) => {
let status_code = json_int64_from_map(base_resp, "status_code").unwrap_or(
-1L,
)
if status_code != 0L {
let msg = json_string_from_map(base_resp, "status_msg").unwrap_or(
"Unknown error",
)
return moon_coding_plan_error("API error (code \{status_code}): \{msg}")
}
}
_ => ()
}
SubscriptionQuota::new(
MOONGATE_CODING_PLAN_TOOL,
tiers=moon_parse_minimax_tiers(body),
queried_at=Some(moon_quota_now_millis()),
)
}
///|
fn moon_parse_minimax_tiers(body : Json) -> Array[Json] {
guard body is Object(obj) else { return [] }
guard obj.get("model_remains") is Some(Array(model_remains)) else {
return []
}
let mut general : Map[String, Json]? = None
for item in model_remains {
guard item is Object(item_obj) else { continue }
if json_string_from_map(item_obj, "model_name") == Some("general") {
general = Some(item_obj)
break
}
}
guard general is Some(item) else { return [] }
let tiers : Array[Json] = []
match moon_json_double_from_map(item, "current_interval_remaining_percent") {
Some(remain_pct) =>
tiers.push(
moon_quota_tier_json(
MOON_QUOTA_TIER_FIVE_HOUR,
100.0 - remain_pct,
resets_at=match json_int64_from_map(item, "end_time") {
Some(ms) => Some(@os.local_rfc3339(ms / 1000L))
None => None
},
),
)
None => ()
}
if json_int64_from_map(item, "current_weekly_status") == Some(1L) {
match moon_json_double_from_map(item, "current_weekly_remaining_percent") {
Some(remain_pct) =>
tiers.push(
moon_quota_tier_json(
MOONGATE_TIER_WEEKLY_LIMIT,
100.0 - remain_pct,
resets_at=match json_int64_from_map(item, "weekly_end_time") {
Some(ms) => Some(@os.local_rfc3339(ms / 1000L))
None => None
},
),
)
None => ()
}
}
tiers
}
///|
async fn moon_query_zenmux_coding_plan(
base_url : String,
api_key : String,
) -> SubscriptionQuota {
match
moon_fetch_json_get(
base_url,
{ "Authorization": "Bearer \{api_key}", "Accept": "application/json" },
expired_message="Authentication failed",
) {
Err(error) =>
if error.status == Expired {
moon_coding_plan_auth_error(
moon_status_code_from_message(error.message),
)
} else {
moon_coding_plan_error(error.message)
}
Ok(body) => moon_parse_zenmux_coding_plan(body)
}
}
///|
fn moon_parse_zenmux_coding_plan(body : Json) -> SubscriptionQuota {
guard body is Object(obj) else {
return moon_coding_plan_error("Failed to parse response: expected object")
}
if obj.get("success") != Some(Json::boolean(true)) {
let msg = json_string_from_map(obj, "message").unwrap_or("Unknown error")
return moon_coding_plan_error("API error: \{msg}")
}
guard obj.get("data") is Some(Object(data)) else {
return moon_coding_plan_error("Missing 'data' field in response")
}
let tiers : Array[Json] = []
match data.get("quota_5_hour") {
Some(Object(row)) =>
tiers.push(
moon_quota_tier_json(
MOON_QUOTA_TIER_FIVE_HOUR,
moon_json_double_from_map(row, "usage_percentage").unwrap_or(0.0) *
100.0,
resets_at=json_string_from_map(row, "resets_at"),
used_value_usd=moon_json_double_from_map(row, "used_value_usd"),
max_value_usd=moon_json_double_from_map(row, "max_value_usd"),
),
)
_ => ()
}
match data.get("quota_7_day") {
Some(Object(row)) =>
tiers.push(
moon_quota_tier_json(
MOONGATE_TIER_WEEKLY_LIMIT,
moon_json_double_from_map(row, "usage_percentage").unwrap_or(0.0) *
100.0,
resets_at=json_string_from_map(row, "resets_at"),
used_value_usd=moon_json_double_from_map(row, "used_value_usd"),
max_value_usd=moon_json_double_from_map(row, "max_value_usd"),
),
)
_ => ()
}
let plan_tier = match data.get("plan") {
Some(Object(plan)) => json_string_from_map(plan, "tier").unwrap_or("")
_ => ""
}
let account_status = json_string_from_map(data, "account_status").unwrap_or(
"",
)
let plan_info = if !plan_tier.is_empty() {
"\{plan_tier} (\{account_status})"
} else {
""
}
SubscriptionQuota::new(
MOONGATE_CODING_PLAN_TOOL,
credential_message=if plan_info.is_empty() { None } else { Some(plan_info) },
tiers~,
queried_at=Some(moon_quota_now_millis()),
)
}
///|
fn moon_extract_reset_time(value : Json?) -> String? {
match value {
Some(String(s)) => Some(s)
Some(Number(n, ..)) => {
let raw = n.to_int64()
let ms = if raw < 1000000000000L { raw * 1000L } else { raw }
Some(@os.local_rfc3339(ms / 1000L))
}
_ => None
}
}
///|
fn moon_status_code_from_message(message : String) -> Int {
if message.contains("HTTP 401") {
401
} else if message.contains("HTTP 403") {
403
} else {
0
}
}