StockAnalysis / agents.md
igardner's picture
docs: spell out agent boundaries and response promises
4567005
|
Raw History Blame Contribute Delete
8.12 kB
To use this application (igardner/StockAnalysis: Structured stock analysis as JSON for agents):
API schema: GET https://igardner-stockanalysis.hf.space/gradio_api/info
Call endpoint: POST https://igardner-stockanalysis.hf.space/gradio_api/call/v2/analyze {"ticker": "AAPL", "horizon": "3 months", "risk_profile": "balanced", "question": ""}
Poll result: GET https://igardner-stockanalysis.hf.space/gradio_api/call/analyze/{event_id}
File inputs: none - all inputs are JSON scalars.
Auth: Bearer $HF_TOKEN (https://huggingface.co/settings/tokens)
# StockAnalysis agent contract
This file is the concrete contract for agents. The Hub also generates a live
`agents.md` at `https://huggingface.co/spaces/igardner/StockAnalysis/agents.md`.
Always fetch `/gradio_api/info` before calling. The live schema is the runtime
contract; this file explains the boundaries and the expected response shapes.
## What this Space does
- Accepts a ticker, horizon, risk profile, and optional question.
- Sends that request to a separate stock-analysis project.
- Returns three outputs in order: JSON, the raw upstream body, and a short
human-readable status string.
- If the upstream returns text and a local parser is configured, converts that
text to JSON without inventing prices, targets, or recommendations.
The Analyze request is read-only. It does not place trades, move funds, or
connect to a brokerage account.
## Boundaries: what this Space will not do
- It is not financial advice and is not a substitute for a licensed advisor.
- It does not guarantee returns, accuracy, completeness, availability, or
latency. Do not represent it as promising 10x gains or any other return.
- It does not execute trades or manage money.
- It does not verify the external project's claims or data.
- It does not provide personalized advice. Treat output as research material
that a human reviews.
- It does not accept file inputs. Do not call `/gradio_api/upload`.
- It does not expose the smoke test as part of the agent contract. The smoke
test events are marked private; do not call them.
- It does not promise uptime. This is a CPU-basic Space and can sleep, restart,
or be rebuilt.
- It does not intentionally persist Analyze requests. The external project may
have its own retention policy.
## Promises: what agents can rely on
- When the Gradio call completes, it returns exactly three outputs in this
order: JSON result, raw upstream body, status string.
- The first output is JSON-serializable. Error and configuration failures are
returned as JSON objects instead of a successful-looking analysis.
- Expected failures use these `status` values: `not_configured`,
`invalid_input`, or `error`. A text-to-JSON wrapper uses `status: "ok"` plus
`source: "external+local_parser"`.
- An upstream JSON response is passed through unchanged. Its shape is defined by
the external project, not by this Space.
- Missing or empty tickers return `invalid_input`. Unknown horizon or risk
values are coerced to `3 months` and `balanced`.
- The Space never returns `HF_TOKEN` or any server secret in its outputs.
- Private smoke-test outputs are not part of the Analyze response.
## Inputs
| Name | Type | Required | Default | Rules |
|---|---|---|---|---|
| `ticker` | string | yes | none | Uppercased and trimmed. Maximum 24 characters. Empty is rejected. |
| `horizon` | string | no | `3 months` | `1 week`, `1 month`, `3 months`, `6 months`, or `1 year`. Unknown values become `3 months`. |
| `risk_profile` | string | no | `balanced` | `conservative`, `balanced`, or `aggressive`. Unknown values become `balanced`. |
| `question` | string | no | empty | Optional. Truncated to 2000 characters. Do not put secrets or personal data here. |
There are no file inputs.
## Outputs
1. JSON result. Read this first.
2. Raw upstream response as text. May be empty.
3. Human-readable status string. Do not parse this as machine data.
The JSON result can be one of these shapes:
- Upstream JSON, passed through unchanged.
- `{"status": "ok", "ticker": "...", "http_status": 200, "content_type": "...", "raw": "..."}`
when the upstream returned text and no parser was configured.
- `{"status": "ok", "ticker": "...", "source": "external+local_parser", "parser": {"model": "..."}, "analysis": <JSON>, "raw": "..."}`
when the local parser succeeded.
- `{"status": "not_configured", "message": "..."}` when `EXTERNAL_API_URL` is
unset.
- `{"status": "invalid_input", "error": "..."}` for bad input.
- `{"status": "error", "http_status": ..., "error": "...", "raw": "..."}` for
upstream failures.
- The text-wrapper shape plus `parse_error` when the local parser failed.
Check for the `status` field before treating a result as analysis. Our error
envelopes include `ticker` and an `error` or `message` field. Upstream JSON is
not wrapped, so its own fields are whatever the external project returns.
## Call with curl
```bash
EVENT_ID=$(curl -sS -X POST \
"https://igardner-stockanalysis.hf.space/gradio_api/call/v2/analyze" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $HF_TOKEN" \
-d '{"ticker":"AAPL","horizon":"3 months","risk_profile":"balanced","question":""}' \
| python -c 'import json,sys; print(json.load(sys.stdin)["event_id"])')
curl -sS -N \
"https://igardner-stockanalysis.hf.space/gradio_api/call/analyze/$EVENT_ID" \
-H "Authorization: Bearer $HF_TOKEN"
```
The POST returns `{"event_id": "..."}`. The GET streams Server-Sent Events. The
final event is `complete` and its `data` field is the three-element output list.
An `error` event means the call failed; a stream that ends without `complete`
should be treated as a failure.
If a client only supports the older call shape, send the same inputs as a
positional list to `/gradio_api/call/analyze`:
```json
{"data": ["AAPL", "3 months", "balanced", ""]}
```
## Call with the Python client
```python
import os
from gradio_client import Client
client = Client("igardner/StockAnalysis", token=os.environ["HF_TOKEN"])
result = client.predict(
"AAPL",
"3 months",
"balanced",
"",
api_name="/analyze",
)
print(result)
```
## Error handling and retries
- Check the JSON result's `status` before using any analysis fields.
- Do not retry `invalid_input` or `not_configured`. Fix the input or ask the
Space owner to set `EXTERNAL_API_URL`.
- For HTTP 429, 5xx, network errors, or a stream without `complete`, retry with
exponential backoff and a small retry cap (for example, three attempts).
Honor `Retry-After` when it is present.
- Do not retry a `parse_error` blindly. The raw upstream body is still in the
second output, so use that if your client can parse it.
- The server allows up to four concurrent Analyze events. Stay below that, and
do not flood the Space with parallel requests.
## Auth and data handling
- Send `Authorization: Bearer $HF_TOKEN` on both the POST and the poll GET.
- Never put the token in the JSON body, the `question` field, or a URL query
string.
- `HF_TOKEN` is for Space authentication and rate limits. The Space's own
outbound token is a Space secret and is never returned to clients.
- The ticker and question are sent to the external project. Do not send
secrets, credentials, or personal data.
- The Space does not intentionally store Analyze requests. The external project
may log or retain them under its own policy.
## Discovery and versioning
- Fetch `GET /gradio_api/info` at the start of a session. Do not hardcode
parameter names, return counts, or endpoint paths beyond the documented
fallback.
- The live `/agents.md` route is generated by Hugging Face from Space metadata.
This repository copy is documentation, not a replacement for the live schema.
- The external project and the custom model can change independently. The custom
model is configured with `STOCK_MODEL_ID` and is currently blank.
## Disclaimer
This is research tooling, not financial advice. Output may be incomplete or
wrong. No return is guaranteed, and you can lose money. Nothing in this contract
promises a specific gain, including 10x.