mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
fix(mcp): hand a call's warnings to the agent
idx-core reports what it works around (history falling back to yahoo when Stockbit refuses the session, a stale cache served after a failed fetch, a movements query cut short) as warnings on stderr. An agent never reads idx-mcp's stderr, so it saw `source: "yahoo"` or `stale: true` with no reason. - Each tool call collects its warnings with runtime::on_warning and returns them as `warnings` on the answer or the error, when there are any. - The stale-cache warning names the failure behind it. - The mock's session API 403 is the real session API's block message; the public page's block names IDX_PROVIDER=msn as well as `--provider msn`. Goldens: error-intraday-blocked (json, table) carry the reworded block hint. Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
parent
e739ee3c20
commit
9b46161566
10 changed files with 145 additions and 18 deletions
|
|
@ -187,6 +187,10 @@ impl MockStockbitProvider {
|
|||
"Stockbit rejected the session; run `idx stockbit login` again".to_string(),
|
||||
));
|
||||
}
|
||||
// The session API's own block, as `exodus::fetch` reports it.
|
||||
if std::env::var("IDX_MOCK_STOCKBIT_STATUS").as_deref() == Ok("403") {
|
||||
return Err(stockbit::exodus::blocked());
|
||||
}
|
||||
if let Some(err) = self.failure(symbol) {
|
||||
return Err(err);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,11 +257,7 @@ fn classify(reply: Reply, subject: &str) -> Result<String, IdxError> {
|
|||
Err(IdxError::SymbolNotFound(subject.to_string()))
|
||||
}
|
||||
429 => Err(IdxError::RateLimited),
|
||||
403 => Err(IdxError::UpstreamBlocked(
|
||||
"exodus.stockbit.com refused this client (HTTP 403 from its CDN); idx does not \
|
||||
retry a block. Try again later or from another network"
|
||||
.to_string(),
|
||||
)),
|
||||
403 => Err(blocked()),
|
||||
status => Err(IdxError::Http(format!(
|
||||
"stockbit api: HTTP {status}{}",
|
||||
message(&reply.body)
|
||||
|
|
@ -497,6 +493,16 @@ fn trim_to_period(mut bars: Vec<Ohlc>, period: &Period) -> Vec<Ohlc> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A 403 from the CDN in front of the session API: a block, not a refused
|
||||
/// session, so nothing is retried.
|
||||
pub(crate) fn blocked() -> IdxError {
|
||||
IdxError::UpstreamBlocked(
|
||||
"exodus.stockbit.com refused this client (HTTP 403 from its CDN); idx does not \
|
||||
retry a block. Try again later or from another network"
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ pub fn status_error(status: u16, resolved: &str) -> IdxError {
|
|||
match status {
|
||||
403 => IdxError::UpstreamBlocked(
|
||||
"stockbit.com refused this client (HTTP 403 from its CDN); idx does not retry a \
|
||||
block. Try again later or from another network; `--provider msn` serves quotes \
|
||||
without Stockbit"
|
||||
block. Try again later or from another network; the msn provider (`--provider msn`, \
|
||||
or IDX_PROVIDER=msn for idx-mcp) serves quotes without Stockbit"
|
||||
.to_string(),
|
||||
),
|
||||
404 => IdxError::SymbolNotFound(resolved.to_string()),
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ where
|
|||
Err(err) => {
|
||||
if use_cache && let Some(stale) = cache.any::<T>(spec.bucket, spec.key)? {
|
||||
runtime::warn(format!(
|
||||
"network failed, serving stale cache for {}",
|
||||
"network failed ({err}), serving stale cache for {}",
|
||||
spec.subject
|
||||
));
|
||||
return Ok(hit(stale, true));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue