Run isolated Python data analysis
run_data_analysisRun complete Agent-generated Python in an ephemeral isolated runtime with pandas, NumPy, SciPy, and statsmodels. A retryable failed attempt below 3 is unfinished: validate the next full request using the returned failed analysisRunId and incremented attempt, then execute its NEW validatedProgram. Failed attempt 2 requires the third execution before a final failure answer; stop immediately for a concrete non-retryable safety/access error. For coverage limitations, state the returned first/last timestamps. Quantify a gap through today only when calculated against the explicit request clock; never guess the elapsed days from old observations or an example. Preserve full aware timestamps returned by price bars when publishing the comparison window. Do not convert them to date-only strings and then claim price clocks were unavailable. Keep market-price endpoints separate from account-observation and retrieval clocks. Declare the exact read-only broker, bounded internal-data, BotSpot public-data, and allowlisted HTTPS capabilities the program needs. For edits of a saved chart, first inspect_analysis_artifact with includeProgram=true and reuse its full calculation datasets; fetch only missing data. Reopening unchanged charts uses displaySavedChart=true without this execution tool. The runtime receives only a short-lived capability token: broker credentials stay in trusted server-side connectors and are never exposed to generated Python. SDK data calls return mapping-compatible payloads: use payload['bars'], payload['positions'], or payload['records'] for documented row collections. For single-symbol broker history, declare capabilities.broker.operations=['historical_prices'] and capabilities.broker.brokerCredentialIds=[the exact brokerCredentialId UUID returned by list_broker_credentials]. For two or more broker symbols requiring fresh reads and sharing asset type, quote currency, and contract terms, including pair comparisons, declare only historical_prices_many and call broker.history_many once; pass asset_type, quote_symbol, expiration, strike, right, exchange, and market as needed, then read payload['barsBySymbol']. For different asset types or distinct option strikes/futures expiries, declare historical_prices and call broker.history separately with each full contract identity. Crypto and forex require an explicit quote_symbol; futures history retains expiration and exchange. broker.quotes also accepts asset_type, quote_symbol, expiration, strike, right, exchange, and market; option quotes require the full contract terms. Never treat a crypto pair, option leg, or futures contract as a stock symbol. history_many batches complete coverage with at most four parallel reads; set batch_size at or below the runtime maxSymbols limit. Request/row/byte quotas still apply, and batchAsOf preserves the individual read timestamps. A chart with one broker symbol plus public macro data remains a single-symbol broker request and uses broker.history with historical_prices. Calculate user-defined series and conditions as pure pandas functions, and evaluate every item at the requested as-of boundary. When the user asks to find a current setup, only mark an item qualified when the condition remains active at the latest completed observation. Emit honest zero-result analyses and never create placeholder items, rows, or actions. A broker-backed call must follow list_broker_credentials in the current turn; generic source wording, labels, provider names, and placeholders are never credential IDs. For an ordinary single-result chart request, persist the complete source rows with dataset.emit, call chart.emit exactly once, and do not call analysis.emit. For table/statistic-only output, emit the requested table or statistics without a dummy chart or unrelated dataset; retain provenance for every fetched source. Emit tables with table.emit(name='...', rows=[...], columns=[...]). Use a reusable AnalysisDocument only for selectable, ranked, user-revisable results, or when a later action field must resolve from an immutable semantic element. In that branch, call dataset.emit for every full calculation dataset, then call analysis.emit exactly once with schemaVersion=1, type='analysis', sourceIds, items, views, actions, skipped, and errors. The full dataset is the durable computation source and must contain stable field definitions and primary keys. Never make sampled chart rows the source of a later value or trade. Every analysis item must reference its own dataset, semantic elements, view, and optional action by opaque ID. Each chart must declare its datasetId plus displaySampling method and sourceRowCount. Semantic elements must include structured derivations that resolve against full datasets. Do not route or alter behavior based on indicator names or user wording. chart.emit accepts only the documented runtime chart fields, never final-response source, metadata, analysis, sources, or runtime fields. The serialized chart object must be at most 256,000 UTF-8 bytes. When the user requests a cadence and range, retain every returned observation at that cadence and set displaySampling.method='none'; never sample daily observations and label the result daily. Only sample when the user did not request complete cadence, and disclose the sampling method. When comparing movement across unlike units with an indexed-to-100 transformation, index every requested numeric series, including macro and public-data series, and use source-based keys ending in _indexed. Resolve a requested session and timezone before matching account observations. Validate actual returned endpoint dates and bar completion times: an earlier available bar does not prove coverage of the requested day. Preserve a user-selected sparse account window as a labeled estimate with funding uncertainty, and omit relative-performance statistics when the benchmark covers a different interval. Portfolio comparisons use the analysisDatasetId returned by get_portfolio_series with capabilities.internalData.datasetIds and internal_data.get; tool names are not provenance IDs. Use intraday benchmark history for account observation times and align each account observation to the latest completed benchmark bar at or before it, preserving the acquisition prefix for the baseline. Matching calendar dates or plotting all raw bars inside the overall window does not perform this alignment. Derive chart captions and statistics from the same executed rows, including the current broker reading and its actual clock basis; a discovery preview can contain fewer observations. Capture each provenance source-ID delta immediately after its fetch and before the next fetch. Never derive multiple source lists after multiple queries from one old provenance snapshot, and never use a dataset ID as a chart sourceIds fallback. When the user did not request cadence or complete observations, a sampled display may be used while retaining the complete full-precision dataset. Build sampled mappings with an explicit loop over indices and source_row=full_rows[index], not a nested tuple/list comprehension. Use explicit profile, time-scale mode, interpolation, transforms, marks, panes, pane appearance, axes, reference lines, reference bands, event windows, hover fields, data-driven bar colors, controls, units, frequencies, timestamps, and source IDs. Use session time for exchange-session comparisons, calendar time for economic and mixed-frequency series, and ordinal time only for non-temporal categories. Never silently forward-fill or interpolate a lower-frequency series. The renderer uses only this declarative contract and never infers meaning from labels. OHLC market data uses candlesticks by default at every requested range; use a price line only when OHLC is unavailable or the user explicitly requests one. An event window has exactly id, paneId, xStart, xEnd, optional semanticElementId, label, and style; it never has axisId or seriesId. A marker has exactly id, paneId, seriesId, x, placement, shape, color, and label, with optional semanticElementId, value, and unit. Event-window endpoints and marker timestamps must be retained chart x values. Derive regimes and crossovers from full calculation rows before display sampling, close the final regime at the newest displayed observation, and select bounded visuals newest-first before returning them oldest-to-newest. Never keep the oldest bounded windows or markers while dropping newer ones. Set analysis.title for a new definition. To revise an existing analysis, pass its definitionId and current parentRevisionId; every edit creates an immutable revision. Corrections of the same completed analysis use that existing definition and current parent revision, so the corrected display replaces the earlier one while history remains available. Independent analyses retain separate definitions. Include only capability groups used by the program. Every present capability array must be non-empty; for example, a broker-only program must omit safeHttp rather than send safeHttp.domains=[]. Runtime gateway limits: {"maxRequests":40,"maxResponseBytes":8000000,"maxRows":50000,"maxSymbols":50}. Operator-approved safe HTTP domains: []; an empty list means direct HTTP is unavailable. For the initial call, explicitly pass attempt=1 and omit previousAnalysisRunId. An MCP input-schema rejection creates no analysis run, so correct it as another initial attempt=1 call. For a repair, pass only the analysisRunId returned by the immediately preceding persisted status=failed result and increment attempt; never use a completed prior run as a repair target. At most three persisted attempts are allowed. Set responseMode='final' only when this completed standalone chart or table is the last requested action, so the canonical artifact can be returned directly without another model copy. Set responseMode='continue' when any later tool action remains, including quote lookup, analysis inspection, resolution, or trade approval work.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Complete generated Python program. Use only preinstalled packages and botspot_analysis SDK functions for data access. | |
| attempt | No | ||
| analysis | No | Stable analysis identity. Omit definitionId and parentRevisionId for the first revision; include both when revising an existing analysis. | |
| capabilities | Yes | Exact read-only capabilities the Python program may use. Include only groups actually used by the code. Every present group requires a non-empty array; omit unused broker, publicData, internalData, and safeHttp groups entirely. | |
| responseMode | No | Set final only when this completed standalone chart or table is the last requested action. Use continue when another tool action must follow, including quote or trade approval work. | continue |
| previousAnalysisRunId | No | Use only the analysisRunId returned by the immediately preceding persisted status=failed result. Input-schema rejection creates no run ID, and completed run IDs are never repair targets. |