@xbbg/langgraph 1.2.7 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +667 -645
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -65,6 +65,13 @@ var DEFAULT_MAX_BQL_QUERY_CHARS = 4e3;
|
|
|
65
65
|
var DEFAULT_MAX_SEARCH_SPEC_CHARS = 1e3;
|
|
66
66
|
var DEFAULT_MAX_STREAM_UPDATES = 10;
|
|
67
67
|
var DEFAULT_MAX_STREAM_WAIT_MS = 15e3;
|
|
68
|
+
var DEFAULT_ENGINE_REQUEST_TIMEOUT_MS = 6e4;
|
|
69
|
+
function engineConfigWithDefaults(config) {
|
|
70
|
+
if (config?.requestTimeoutMs !== void 0) {
|
|
71
|
+
return config;
|
|
72
|
+
}
|
|
73
|
+
return { ...config, requestTimeoutMs: DEFAULT_ENGINE_REQUEST_TIMEOUT_MS };
|
|
74
|
+
}
|
|
68
75
|
function positiveInteger(value, fallback, name) {
|
|
69
76
|
if (value === void 0) {
|
|
70
77
|
return fallback;
|
|
@@ -82,7 +89,7 @@ function normalizeBloombergToolsOptions(options = {}) {
|
|
|
82
89
|
core: options.core,
|
|
83
90
|
disabledTools: disabledToolSet(options.disabledTools),
|
|
84
91
|
engine: options.engine,
|
|
85
|
-
engineConfig: options.engineConfig,
|
|
92
|
+
engineConfig: engineConfigWithDefaults(options.engineConfig),
|
|
86
93
|
maxBqlQueryChars: positiveInteger(
|
|
87
94
|
options.maxBqlQueryChars,
|
|
88
95
|
DEFAULT_MAX_BQL_QUERY_CHARS,
|
|
@@ -167,180 +174,6 @@ function createCoreResolver(options = {}) {
|
|
|
167
174
|
options: normalized
|
|
168
175
|
};
|
|
169
176
|
}
|
|
170
|
-
function inputJsonSchema(schema) {
|
|
171
|
-
const jsonSchema = zodToJsonSchema.zodToJsonSchema(schema, {
|
|
172
|
-
$refStrategy: "none",
|
|
173
|
-
effectStrategy: "input",
|
|
174
|
-
pipeStrategy: "input"
|
|
175
|
-
});
|
|
176
|
-
delete jsonSchema.$schema;
|
|
177
|
-
delete jsonSchema.definitions;
|
|
178
|
-
return jsonSchema;
|
|
179
|
-
}
|
|
180
|
-
function createBloombergStructuredTool(func, fields) {
|
|
181
|
-
const providerToolDefinition = {
|
|
182
|
-
type: "function",
|
|
183
|
-
function: {
|
|
184
|
-
description: fields.description,
|
|
185
|
-
name: fields.name,
|
|
186
|
-
parameters: inputJsonSchema(fields.schema)
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
return tools.tool(
|
|
190
|
-
func,
|
|
191
|
-
{
|
|
192
|
-
...fields,
|
|
193
|
-
extras: { providerToolDefinition }
|
|
194
|
-
}
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// src/cdx-fields.ts
|
|
199
|
-
var CDX_INFO_FIELDS = Object.freeze([
|
|
200
|
-
"ROLLING_SERIES",
|
|
201
|
-
"VERSION",
|
|
202
|
-
"ON_THE_RUN_CURRENT_BD_INDICATOR",
|
|
203
|
-
"CDS_FIRST_ACCRUAL_START_DATE",
|
|
204
|
-
"NAME",
|
|
205
|
-
"NUM_CURRENT_COMPANIES_CCY_TKR",
|
|
206
|
-
"NUM_ORIG_COMPANIES_CRNCY_TKR",
|
|
207
|
-
"PX_LAST"
|
|
208
|
-
]);
|
|
209
|
-
var CDX_PRICING_FIELDS = Object.freeze([
|
|
210
|
-
"PX_LAST",
|
|
211
|
-
"PX_BID",
|
|
212
|
-
"PX_ASK",
|
|
213
|
-
"UPFRONT_LAST",
|
|
214
|
-
"UPFRONT_BID",
|
|
215
|
-
"UPFRONT_ASK",
|
|
216
|
-
"CDS_FLAT_SPREAD",
|
|
217
|
-
"UPFRONT_FEE",
|
|
218
|
-
"PV_CDS_PREMIUM_LEG",
|
|
219
|
-
"PV_CDS_DEFAULT_LEG"
|
|
220
|
-
]);
|
|
221
|
-
var CDX_RISK_FIELDS = Object.freeze([
|
|
222
|
-
"SW_CNV_BPV",
|
|
223
|
-
"SW_EQV_BPV",
|
|
224
|
-
"CDS_SPREAD_MID_MODIFIED_DURATION",
|
|
225
|
-
"CDS_SPREAD_MID_CONVEXITY",
|
|
226
|
-
"RECOVERY_RATE_SEN",
|
|
227
|
-
"CDS_RECOVERY_RT"
|
|
228
|
-
]);
|
|
229
|
-
|
|
230
|
-
// src/descriptions.ts
|
|
231
|
-
var REQUIRED_TOOL_INSTRUCTIONS = [
|
|
232
|
-
"# Bloomberg tool usage",
|
|
233
|
-
"- Use these tools only for server-side Bloomberg data access through @xbbg/core. Never imply Bloomberg data was retrieved unless a tool call actually returned it.",
|
|
234
|
-
"- Ask a clarifying question before calling a tool when any security identity, field mnemonic, date range, currency, periodicity, intraday interval, timezone, override, or universe is ambiguous.",
|
|
235
|
-
"- Do not invent Bloomberg tickers, field mnemonics, overrides, or BQL functions. If the user gives a field description rather than a confident mnemonic, call xbbg_bflds first.",
|
|
236
|
-
"",
|
|
237
|
-
"## Security identifiers",
|
|
238
|
-
"- Prefer fully qualified Bloomberg securities supplied by the user, such as <TICKER> <MARKET_SECTOR>, <INDEX_TICKER> <MARKET_SECTOR>, or <CREDIT_INDEX_TICKER> <MARKET_SECTOR>.",
|
|
239
|
-
"- For raw security identifiers, request or pass Bloomberg identifier syntax directly: /isin/<ISIN> for ISINs or /cusip/<CUSIP> for CUSIPs.",
|
|
240
|
-
"- Do not pass raw ISIN or CUSIP strings when the request is meant to identify a security. Do not use xbbg_bsrch as a replacement for a known ticker, ISIN, or CUSIP.",
|
|
241
|
-
"- For dealer quote / BQR workflows, use xbbg_bqr with a fixed-income identifier plus a dealer quote source such as /isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>. For raw intraday ticks, use xbbg_bdtick.",
|
|
242
|
-
"",
|
|
243
|
-
"## Core request tools",
|
|
244
|
-
"- xbbg_bdp: current or reference point-in-time fields. Use a small explicit securities list and a small explicit fields list. Use includeSecurityErrors only when the caller wants Bloomberg security errors in the response.",
|
|
245
|
-
"- xbbg_bdh: historical daily or periodic time series. Always provide explicit start and end dates in YYYY-MM-DD or YYYYMMDD form. Ask before choosing periodicity, currency, fill behavior, adjustment overrides, or a wide output table.",
|
|
246
|
-
"- xbbg_bds: Bloomberg bulk/table fields. Provide exactly one bulk field; do not use bds for ordinary multi-field reference data.",
|
|
247
|
-
"- xbbg_bdib: intraday bars only. Provide one ticker, explicit ISO start/end datetimes with time components, a positive interval in minutes, and timezone context when datetimes are naive.",
|
|
248
|
-
"- xbbg_bdtick: intraday tick data. Provide one ticker, explicit ISO start/end datetimes with time components, and explicit eventTypes unless the default event stream is intended. Use includeBrokerCodes or includeConditionCodes only when those columns are needed.",
|
|
249
|
-
"- xbbg_bql: BQL expressions only when the user asks for BQL or the request is naturally expressed as a bounded BQL query. Keep queries short, explicit, and scoped to the requested universe.",
|
|
250
|
-
"- xbbg_bsrch: Bloomberg search-grid or saved-search workflows only. Do not use it for ordinary security lookup.",
|
|
251
|
-
"- xbbg_bqr: Bloomberg Quote Request / dealer quotes. Prefer fixed-income identifier inputs with a dealer quote source such as /isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>, explicit start/end datetimes with time components, and explicit event types.",
|
|
252
|
-
"- xbbg_bflds: Bloomberg field metadata/search. Provide exactly one of fields or searchSpec; use searchSpec for natural-language field names and fields for known mnemonics.",
|
|
253
|
-
"- xbbg_beqs: Bloomberg equity screening by named BEQS screen. Prefer this over hand-written BQL when the user names an existing Bloomberg screen.",
|
|
254
|
-
"- xbbg_yas: fixed-income YAS recipe fields. Prefer this over manual YAS-style BDP requests when the user asks for yield, duration, spread, or price analytics.",
|
|
255
|
-
"- xbbg_preferreds: preferred stock discovery from an equity ticker. Prefer this over xbbg_ext_bql_builder plus xbbg_bql when the user wants the actual preferreds result.",
|
|
256
|
-
"- xbbg_corporate_bonds: bounded corporate bond universe query for a company ticker. Prefer this over generic BQL for company debt discovery.",
|
|
257
|
-
"- xbbg_index_members: index constituents through the core index recipe. Prefer this over generic BDS/BQL members when the user asks for constituents.",
|
|
258
|
-
"- xbbg_resolve_isins: resolves supplied ISIN strings to Bloomberg securities. Pass raw ISIN strings only for this recipe; otherwise use /isin/<ISIN> syntax with data tools.",
|
|
259
|
-
"- xbbg_issuer_isins: issuer/bond ISIN workflow for supplied bond ISIN strings.",
|
|
260
|
-
"- xbbg_etf_holdings: ETF holdings recipe for a single ETF ticker. Prefer this over generic BQL holdings when the user asks for ETF constituents.",
|
|
261
|
-
"- xbbg_stream_snapshot: bounded live market-data observation from //blp/mktdata. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
262
|
-
"- xbbg_mktbar_snapshot: bounded live market-bar observation from //blp/mktbar for one ticker. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
263
|
-
"- xbbg_depth_snapshot: bounded market-depth observation from //blp/mktdepthdata for one ticker. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
264
|
-
"",
|
|
265
|
-
"## BQL guidance",
|
|
266
|
-
"- BQL is a complete Bloomberg Query Language expression sent as one query string; the tool does not assemble get/for/with clauses for you.",
|
|
267
|
-
"- Basic shape: get(<FIELD_1>, <FIELD_2>) for(<UNIVERSE>). Use placeholders such as '<TICKER> <MARKET_SECTOR>', holdings('<ETF_TICKER> <MARKET_SECTOR>'), or members('<INDEX_TICKER> <MARKET_SECTOR>') until the user supplies real inputs.",
|
|
268
|
-
"- Use BQL for universe-oriented analytics and screens only when the user provides a bounded universe, filters, and date range.",
|
|
269
|
-
"- Prefer xbbg_ext_bql_builder instead of hand-writing BQL for supported workflows: preferred stocks, corporate bonds, and ETF holdings.",
|
|
270
|
-
"- Do not use BQL just because the user asks for normal reference data; xbbg_bdp is simpler for current fields and xbbg_bdh is simpler for historical time series.",
|
|
271
|
-
"",
|
|
272
|
-
"## Output handling",
|
|
273
|
-
"- Tool results use LangChain content_and_artifact output: content starts with a compact summary and then includes bounded model-readable JSON; artifact is the structured bounded envelope with tool, rowCount, truncated, and data for application code.",
|
|
274
|
-
"- If a response is empty, truncated, or contains Bloomberg/security errors, say that directly. Do not fill gaps from memory or assumptions."
|
|
275
|
-
];
|
|
276
|
-
var OPTIONAL_EXTENSION_INSTRUCTIONS = [
|
|
277
|
-
"",
|
|
278
|
-
"## Extension helper tools",
|
|
279
|
-
"- xbbg_ext_ticker: ticker hygiene before live calls. parse_ticker splits a Bloomberg ticker, normalize_tickers trims/canonicalizes lists, filter_equity_tickers keeps equity-like tickers, is_specific_contract checks futures specificity, and validate_generic_ticker rejects malformed generic futures tickers.",
|
|
280
|
-
"- xbbg_ext_futures: futures contract construction and selection. Use build_futures_ticker for root/month/year/asset assembly, get_futures_months for month-code lookup, generate_candidates for generic-to-specific candidates, contract_index for generic contract rank, filter_candidates_by_cycle for HMUZ/quarterly cycles, and filter_valid_contracts to keep contracts valid for a date.",
|
|
281
|
-
"- xbbg_ext_cdx: CDX ticker workflow support. Use parse_cdx_ticker to understand a CDX ticker, previous_cdx_series to roll back a series, cdx_gen_to_specific to resolve a generic CDX to a target series, and cdx_info/cdx_pricing/cdx_risk for predefined BDP field bundles. cdx_pricing and cdx_risk accept recoveryRate, which becomes the CDS_RR override.",
|
|
282
|
-
"- xbbg_ext_currency: currency-planning helpers. build_fx_pair constructs the Bloomberg FX pair and conversion factor, same_currency avoids unnecessary conversion, and currencies_needing_conversion identifies which currencies differ from a target before requesting converted values.",
|
|
283
|
-
"- xbbg_ext_bql_builder: safe BQL generators for common xbbg workflows. Use build_preferreds_query for preferred-stock discovery from an equity, build_corporate_bonds_query for company bond universes with optional currency/active filters, and build_etf_holdings_query for ETF constituents. Prefer these builders over hand-writing those BQL shapes.",
|
|
284
|
-
"- xbbg_ext_market_session: exchange calendar/timezone support. derive_sessions turns day session times into session blocks, infer_timezone maps country codes to timezones, session_times_to_utc converts local sessions to UTC, get_market_rule gets MIC/exchange rules, default_turnover_dates and default_bqr_datetimes provide bounded defaults, and get/list_exchange_override inspect configured exchange metadata.",
|
|
285
|
-
"- xbbg_ext_yas_overrides: builds flat YAS override maps for fixed-income BDP requests when the lower-level BDP workflow is required. Prefer xbbg_yas for actual YAS recipe fields.",
|
|
286
|
-
"- xbbg_ext_constants: static lookup/format helpers for date parsing/formatting, futures month code/name mappings, dividend type mappings, and known dividend/ETF output columns.",
|
|
287
|
-
"- xbbg_ext_columns: post-processing helpers for Bloomberg-shaped tables. Use rename_dividend_columns, rename_etf_columns, or build_earning_header_rename when explaining or normalizing response column names after a request.",
|
|
288
|
-
"- xbbg_ext_calculate: small numeric helper for Bloomberg workflows. calculate_level_percentages pairs observed values with levels; values and levels must have the same length."
|
|
289
|
-
];
|
|
290
|
-
var OPTIONAL_LIMIT_INSTRUCTIONS = [
|
|
291
|
-
"",
|
|
292
|
-
"## Request limits and inputs",
|
|
293
|
-
"- Keep Bloomberg requests bounded: explicit securities, explicit fields, explicit dates, limited rows, and no broad exploratory pulls unless the user narrows the universe.",
|
|
294
|
-
"- Respect configured tool limits for securities, fields, rows, string size, BQL length, and search spec length. Ask the user to narrow the request rather than exceeding them.",
|
|
295
|
-
"- Use flat primitive overrides and kwargs only: string, number, or boolean values. Do not send nested objects, arrays, or inferred defaults as overrides."
|
|
296
|
-
];
|
|
297
|
-
var BLOOMBERG_TOOL_INSTRUCTIONS = [
|
|
298
|
-
...REQUIRED_TOOL_INSTRUCTIONS,
|
|
299
|
-
...OPTIONAL_EXTENSION_INSTRUCTIONS,
|
|
300
|
-
...OPTIONAL_LIMIT_INSTRUCTIONS
|
|
301
|
-
].join("\n");
|
|
302
|
-
function getBloombergToolInstructions(options = {}) {
|
|
303
|
-
const includeExtensionGuidance = options.includeExtensionGuidance ?? true;
|
|
304
|
-
const includeLimitReminder = options.includeLimitReminder ?? true;
|
|
305
|
-
const lines = [...REQUIRED_TOOL_INSTRUCTIONS];
|
|
306
|
-
if (includeExtensionGuidance) {
|
|
307
|
-
lines.push(...OPTIONAL_EXTENSION_INSTRUCTIONS);
|
|
308
|
-
}
|
|
309
|
-
if (includeLimitReminder) {
|
|
310
|
-
lines.push(...OPTIONAL_LIMIT_INSTRUCTIONS);
|
|
311
|
-
}
|
|
312
|
-
return lines.join("\n");
|
|
313
|
-
}
|
|
314
|
-
var BDP_DESCRIPTION = 'Bloomberg reference data for current or point-in-time fields. Use for a small bounded list of fully qualified securities. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<TICKER> <MARKET_SECTOR>"], fields ["<FIELD>"].';
|
|
315
|
-
var BDH_DESCRIPTION = 'Bloomberg historical time series. Requires explicit start and end dates; ask before using if the date range or periodicity is ambiguous. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<TICKER> <MARKET_SECTOR>"], fields ["<FIELD>"], start "<START_DATE>", end "<END_DATE>".';
|
|
316
|
-
var BDS_DESCRIPTION = 'Bloomberg bulk/table reference data. Requires exactly one bulk field, not a field list. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<INDEX_TICKER> <MARKET_SECTOR>"], field "<BULK_FIELD>".';
|
|
317
|
-
var BDIB_DESCRIPTION = 'Bloomberg intraday bars. Requires one ticker plus explicit ISO start/end datetimes with time components and a positive interval in minutes. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: ticker "<TICKER> <MARKET_SECTOR>", start "<START_DATETIME>", end "<END_DATETIME>", interval <MINUTES>.';
|
|
318
|
-
var BDTICK_DESCRIPTION = 'Bloomberg intraday tick data. Requires one ticker plus explicit ISO start/end datetimes with time components. Set eventTypes explicitly, for example ["<EVENT_TYPE>"], and includeBrokerCodes/includeConditionCodes only when needed.';
|
|
319
|
-
var BQL_DESCRIPTION = "Bloomberg Query Language expression sent as one complete query string. Use for bounded universe analytics with placeholder-shaped syntax such as get(<FIELD>) for('<TICKER> <MARKET_SECTOR>'), holdings('<ETF_TICKER> <MARKET_SECTOR>'), members('<INDEX_TICKER> <MARKET_SECTOR>'), filters with with(...), or dates=range(...). Prefer xbbg_bdp/xbbg_bdh for simple reference or historical requests.";
|
|
320
|
-
var BSRCH_DESCRIPTION = 'Bloomberg search/grid request. Use for saved-search or ExcelGetGrid-style Bloomberg searches, not ordinary security lookup. Example searchSpec "<SEARCH_SPEC>".';
|
|
321
|
-
var BQR_DESCRIPTION = 'Bloomberg Quote Request / dealer quotes. Use for fixed-income dealer quote ticks, preferably with an ISIN plus dealer source such as "/isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>"; requires explicit ISO start/end datetimes with time components. Set eventTypes explicitly, for example ["<EVENT_TYPE>"].';
|
|
322
|
-
var BFLDS_DESCRIPTION = 'Bloomberg field metadata and field search. Use first when a field mnemonic is uncertain. Provide exactly one of fields or searchSpec. Example: fields ["<FIELD>"] or searchSpec "<FIELD_SEARCH_TEXT>".';
|
|
323
|
-
var BEQS_DESCRIPTION = "Bloomberg equity screening by named BEQS screen. Use when the user names an existing Bloomberg screen and wants its bounded result set. Prefer this over hand-written BQL for saved Bloomberg screens.";
|
|
324
|
-
var YAS_DESCRIPTION = "Bloomberg fixed-income YAS recipe fields for one or more bonds. Use for yield, duration, spread, benchmark, or price analytics; provide explicit fields and optional settlement/yield/price inputs.";
|
|
325
|
-
var PREFERREDS_DESCRIPTION = "Preferred stock discovery for one equity ticker. Use when the user asks for preferred shares or preferred stock securities related to an issuer.";
|
|
326
|
-
var CORPORATE_BONDS_DESCRIPTION = "Corporate bond universe query for one issuer/company ticker, with optional currency, active-only filter, and result fields. Prefer this over generic BQL for company debt discovery.";
|
|
327
|
-
var INDEX_MEMBERS_DESCRIPTION = "Index constituent recipe for one Bloomberg index. Use for bounded member lists and optional historical/as-of constituent membership.";
|
|
328
|
-
var RESOLVE_ISINS_DESCRIPTION = "Resolve raw ISIN strings to Bloomberg securities through the core ISIN recipe. Do not add /isin/ prefixes in this tool; pass the exact ISIN strings supplied by the user.";
|
|
329
|
-
var ISSUER_ISINS_DESCRIPTION = "Issuer/bond ISIN workflow for supplied bond ISIN strings. Use for issuer-level ISIN discovery starting from known bond ISINs.";
|
|
330
|
-
var ETF_HOLDINGS_DESCRIPTION = "ETF holdings recipe for one ETF ticker. Use when the user asks for ETF constituents or holdings and wants the bounded holdings result.";
|
|
331
|
-
var STREAM_SNAPSHOT_DESCRIPTION = "Bounded live market-data snapshot from //blp/mktdata. Collects at most maxUpdates updates until timeout/done, then always unsubscribes; use for finite observations, not open subscriptions.";
|
|
332
|
-
var MKTBAR_SNAPSHOT_DESCRIPTION = "Bounded live market-bar snapshot from //blp/mktbar for one ticker. Collects at most maxUpdates updates until timeout/done, then always unsubscribes.";
|
|
333
|
-
var DEPTH_SNAPSHOT_DESCRIPTION = "Bounded live market-depth snapshot from //blp/mktdepthdata for one ticker. Collects at most maxUpdates updates until timeout/done, then always unsubscribes.";
|
|
334
|
-
var EXT_TICKER_DESCRIPTION = "Ticker hygiene helpers: parse_ticker, normalize_tickers, filter_equity_tickers, is_specific_contract, and validate_generic_ticker.";
|
|
335
|
-
var EXT_FUTURES_DESCRIPTION = "Futures helpers for contract construction and selection: build_futures_ticker, generate_candidates, contract_index, filter_candidates_by_cycle, filter_valid_contracts, and get_futures_months.";
|
|
336
|
-
var EXT_CDX_DESCRIPTION = "CDX helpers for parsing, series rolling/resolution, and predefined info/pricing/risk BDP field bundles.";
|
|
337
|
-
var EXT_CURRENCY_DESCRIPTION = "Currency planning helpers: build FX pairs, test same-currency requests, and find currencies needing conversion.";
|
|
338
|
-
var EXT_BQL_BUILDER_DESCRIPTION = "BQL builders for preferred stocks, corporate bonds, and ETF holdings. Prefer to construct those bounded BQL shapes before xbbg_bql.";
|
|
339
|
-
var EXT_MARKET_SESSION_DESCRIPTION = "Market session and timezone helpers for deriving sessions, UTC windows, market rules, exchange metadata, turnover defaults, and BQR datetime defaults.";
|
|
340
|
-
var EXT_YAS_OVERRIDES_DESCRIPTION = "Build flat Bloomberg YAS override maps for fixed-income analytics fields.";
|
|
341
|
-
var EXT_CONSTANTS_DESCRIPTION = "Static Bloomberg helper constants for date parsing/formatting, futures months, dividend types, and ETF/dividend columns.";
|
|
342
|
-
var EXT_COLUMNS_DESCRIPTION = "Column rename helpers for dividend, ETF, and earnings-shaped Bloomberg responses.";
|
|
343
|
-
var EXT_CALCULATE_DESCRIPTION = "Small numeric helper operations for Bloomberg workflows, including level percentage calculations.";
|
|
344
177
|
|
|
345
178
|
// src/result-limits.ts
|
|
346
179
|
var MAX_RESULT_DEPTH = 32;
|
|
@@ -383,7 +216,16 @@ function limitValue(value, maxRows, maxStringChars, state, depth = 0, seen = /*
|
|
|
383
216
|
state.truncated = true;
|
|
384
217
|
return "[Circular]";
|
|
385
218
|
}
|
|
219
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
220
|
+
state.truncated = true;
|
|
221
|
+
return `[binary data: ${value.byteLength} bytes]`;
|
|
222
|
+
}
|
|
386
223
|
if (!isPlainObject(value)) {
|
|
224
|
+
const toJSON = value.toJSON;
|
|
225
|
+
if (typeof toJSON === "function") {
|
|
226
|
+
seen.add(value);
|
|
227
|
+
return limitValue(toJSON.call(value), maxRows, maxStringChars, state, depth + 1, seen);
|
|
228
|
+
}
|
|
387
229
|
return value;
|
|
388
230
|
}
|
|
389
231
|
seen.add(value);
|
|
@@ -462,8 +304,10 @@ function limitResult(value, maxRows, maxStringChars) {
|
|
|
462
304
|
function summarizeEnvelope(envelope) {
|
|
463
305
|
const rowText = envelope.rowCount === null ? "row count unknown" : `${envelope.rowCount} row${envelope.rowCount === 1 ? "" : "s"}`;
|
|
464
306
|
const notes = [];
|
|
465
|
-
if (envelope.rowCount === 0) {
|
|
466
|
-
notes.push(
|
|
307
|
+
if (envelope.rowCount === 0 || envelope.data === null || envelope.data === void 0) {
|
|
308
|
+
notes.push(
|
|
309
|
+
"empty result; verify identifiers, fields, and date range before concluding no data exists"
|
|
310
|
+
);
|
|
467
311
|
}
|
|
468
312
|
if (envelope.truncated) {
|
|
469
313
|
notes.push("artifact truncated to configured limits");
|
|
@@ -478,41 +322,236 @@ function resultJsonReplacer(_key, value) {
|
|
|
478
322
|
if (typeof value === "bigint") {
|
|
479
323
|
return value.toString();
|
|
480
324
|
}
|
|
481
|
-
return value;
|
|
482
|
-
}
|
|
483
|
-
function formatToolContent(envelope) {
|
|
484
|
-
const payload = {
|
|
485
|
-
tool: envelope.tool,
|
|
486
|
-
rowCount: envelope.rowCount,
|
|
487
|
-
truncated: envelope.truncated,
|
|
488
|
-
data: envelope.data
|
|
489
|
-
};
|
|
490
|
-
return `${summarizeEnvelope(envelope)}
|
|
491
|
-
${JSON.stringify(payload, resultJsonReplacer)}`;
|
|
492
|
-
}
|
|
493
|
-
function createToolResult(tool2, value, maxRows, maxStringChars) {
|
|
494
|
-
const limited = limitResult(value, maxRows, maxStringChars);
|
|
495
|
-
const envelope = {
|
|
496
|
-
tool: tool2,
|
|
497
|
-
rowCount: limited.rowCount,
|
|
498
|
-
truncated: limited.truncated,
|
|
499
|
-
data: limited.value
|
|
500
|
-
};
|
|
501
|
-
return [formatToolContent(envelope), envelope];
|
|
502
|
-
}
|
|
503
|
-
function throwWithToolContext(tool2, error) {
|
|
504
|
-
const prefix = `${tool2} failed`;
|
|
505
|
-
if (error instanceof Error) {
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
325
|
+
return value;
|
|
326
|
+
}
|
|
327
|
+
function formatToolContent(envelope) {
|
|
328
|
+
const payload = {
|
|
329
|
+
tool: envelope.tool,
|
|
330
|
+
rowCount: envelope.rowCount,
|
|
331
|
+
truncated: envelope.truncated,
|
|
332
|
+
data: envelope.data
|
|
333
|
+
};
|
|
334
|
+
return `${summarizeEnvelope(envelope)}
|
|
335
|
+
${JSON.stringify(payload, resultJsonReplacer)}`;
|
|
336
|
+
}
|
|
337
|
+
function createToolResult(tool2, value, maxRows, maxStringChars) {
|
|
338
|
+
const limited = limitResult(value, maxRows, maxStringChars);
|
|
339
|
+
const envelope = {
|
|
340
|
+
tool: tool2,
|
|
341
|
+
rowCount: limited.rowCount,
|
|
342
|
+
truncated: limited.truncated,
|
|
343
|
+
data: limited.value
|
|
344
|
+
};
|
|
345
|
+
return [formatToolContent(envelope), envelope];
|
|
346
|
+
}
|
|
347
|
+
function throwWithToolContext(tool2, error) {
|
|
348
|
+
const prefix = `${tool2} failed`;
|
|
349
|
+
if (error instanceof Error) {
|
|
350
|
+
if (error.message.startsWith(prefix)) {
|
|
351
|
+
throw error;
|
|
352
|
+
}
|
|
353
|
+
const wrapped = new Error(`${prefix}: ${error.message}`, { cause: error });
|
|
354
|
+
wrapped.name = error.name;
|
|
355
|
+
throw wrapped;
|
|
356
|
+
}
|
|
357
|
+
throw new Error(`${prefix}: ${String(error)}`);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/langchain-tool.ts
|
|
361
|
+
function inputJsonSchema(schema) {
|
|
362
|
+
const jsonSchema = zodToJsonSchema.zodToJsonSchema(schema, {
|
|
363
|
+
$refStrategy: "none",
|
|
364
|
+
effectStrategy: "input",
|
|
365
|
+
pipeStrategy: "input"
|
|
366
|
+
});
|
|
367
|
+
delete jsonSchema.$schema;
|
|
368
|
+
delete jsonSchema.definitions;
|
|
369
|
+
return jsonSchema;
|
|
370
|
+
}
|
|
371
|
+
function toolParameterJsonSchema(toolInstance) {
|
|
372
|
+
const schema = toolInstance.schema;
|
|
373
|
+
if (schema !== null && typeof schema === "object" && !("safeParse" in schema)) {
|
|
374
|
+
return schema;
|
|
375
|
+
}
|
|
376
|
+
return inputJsonSchema(schema);
|
|
377
|
+
}
|
|
378
|
+
function createBloombergStructuredTool(func, fields) {
|
|
379
|
+
const providerToolDefinition = {
|
|
380
|
+
type: "function",
|
|
381
|
+
function: {
|
|
382
|
+
description: fields.description,
|
|
383
|
+
name: fields.name,
|
|
384
|
+
parameters: inputJsonSchema(fields.schema)
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
const guarded = async (input, config) => {
|
|
388
|
+
try {
|
|
389
|
+
config?.signal?.throwIfAborted();
|
|
390
|
+
} catch (error) {
|
|
391
|
+
throwWithToolContext(fields.name, error);
|
|
392
|
+
}
|
|
393
|
+
return await func(input, config);
|
|
394
|
+
};
|
|
395
|
+
return tools.tool(
|
|
396
|
+
guarded,
|
|
397
|
+
{
|
|
398
|
+
...fields,
|
|
399
|
+
extras: { providerToolDefinition }
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// src/cdx-fields.ts
|
|
405
|
+
var CDX_INFO_FIELDS = Object.freeze([
|
|
406
|
+
"ROLLING_SERIES",
|
|
407
|
+
"VERSION",
|
|
408
|
+
"ON_THE_RUN_CURRENT_BD_INDICATOR",
|
|
409
|
+
"CDS_FIRST_ACCRUAL_START_DATE",
|
|
410
|
+
"NAME",
|
|
411
|
+
"NUM_CURRENT_COMPANIES_CCY_TKR",
|
|
412
|
+
"NUM_ORIG_COMPANIES_CRNCY_TKR",
|
|
413
|
+
"PX_LAST"
|
|
414
|
+
]);
|
|
415
|
+
var CDX_PRICING_FIELDS = Object.freeze([
|
|
416
|
+
"PX_LAST",
|
|
417
|
+
"PX_BID",
|
|
418
|
+
"PX_ASK",
|
|
419
|
+
"UPFRONT_LAST",
|
|
420
|
+
"UPFRONT_BID",
|
|
421
|
+
"UPFRONT_ASK",
|
|
422
|
+
"CDS_FLAT_SPREAD",
|
|
423
|
+
"UPFRONT_FEE",
|
|
424
|
+
"PV_CDS_PREMIUM_LEG",
|
|
425
|
+
"PV_CDS_DEFAULT_LEG"
|
|
426
|
+
]);
|
|
427
|
+
var CDX_RISK_FIELDS = Object.freeze([
|
|
428
|
+
"SW_CNV_BPV",
|
|
429
|
+
"SW_EQV_BPV",
|
|
430
|
+
"CDS_SPREAD_MID_MODIFIED_DURATION",
|
|
431
|
+
"CDS_SPREAD_MID_CONVEXITY",
|
|
432
|
+
"RECOVERY_RATE_SEN",
|
|
433
|
+
"CDS_RECOVERY_RT"
|
|
434
|
+
]);
|
|
435
|
+
|
|
436
|
+
// src/descriptions.ts
|
|
437
|
+
var REQUIRED_TOOL_INSTRUCTIONS = [
|
|
438
|
+
"# Bloomberg tool usage",
|
|
439
|
+
"- Use these tools only for server-side Bloomberg data access through @xbbg/core. Never imply Bloomberg data was retrieved unless a tool call actually returned it.",
|
|
440
|
+
"- Ask a clarifying question before calling a tool when any security identity, field mnemonic, date range, currency, periodicity, intraday interval, timezone, override, or universe is ambiguous.",
|
|
441
|
+
"- Do not invent Bloomberg tickers, field mnemonics, overrides, or BQL functions. If the user gives a field description rather than a confident mnemonic, call xbbg_bflds first.",
|
|
442
|
+
"- Issue one tool call per dataset and read any error before retrying; never probe parameter variants in parallel. Omit optional output-shape parameters such as format unless the user asked for a specific shape.",
|
|
443
|
+
"",
|
|
444
|
+
"## Security identifiers",
|
|
445
|
+
"- Pass each security in the form the user supplied it; never translate between identifier kinds on your own.",
|
|
446
|
+
"- User supplied a Bloomberg ticker: pass it through fully qualified as <TICKER> <MARKET_SECTOR>, for example <TICKER> <EXCHANGE> Equity, <INDEX_TICKER> Index, or <CCY_PAIR> Curncy.",
|
|
447
|
+
"- The market sector ending (Bloomberg yellow key) is part of the security string. The sectors are: Equity, Index, Curncy, Comdty, Corp, Govt, Muni, Mtge, M-Mkt, and Pfd. Equity securities carry an exchange or composite code before the sector (<TICKER> <EXCHANGE> Equity); preferred securities use the Pfd sector; corporate and government bonds use Corp and Govt. Request tools pass the security through to Bloomberg without validating the sector, so copy it exactly as the user supplied it.",
|
|
448
|
+
"- User supplied a raw ISIN or CUSIP: pass Bloomberg identifier syntax directly: /isin/<ISIN> or /cusip/<CUSIP>. Never pass the bare identifier without its prefix, except to xbbg_resolve_isins and xbbg_issuer_isins, which take raw ISIN strings.",
|
|
449
|
+
"- <TICKER> <MARKET_SECTOR> is a format template, not authorization to construct a ticker. Never invent, recall from memory, or guess the Bloomberg ticker behind an identifier the user gave; identifier syntax is already a complete, valid security input. Use xbbg_resolve_isins only when the user wants the resolved Bloomberg security itself.",
|
|
450
|
+
"- Recipe tools that take tickers (xbbg_preferreds, xbbg_corporate_bonds, xbbg_index_members, xbbg_etf_holdings) do not accept identifier syntax. When the user supplied an ISIN or CUSIP for those workflows, resolve it with xbbg_resolve_isins first and use the returned Bloomberg security; never guess the ticker.",
|
|
451
|
+
"- Do not use xbbg_bsrch as a replacement for a known ticker, ISIN, or CUSIP.",
|
|
452
|
+
"- For dealer quote / BQR workflows, use xbbg_bqr with a fixed-income identifier plus a dealer quote source such as /isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>. For raw intraday ticks, use xbbg_bdtick.",
|
|
453
|
+
"",
|
|
454
|
+
"## Core request tools",
|
|
455
|
+
"- xbbg_bdp: current or reference point-in-time fields. Use a small explicit securities list and a small explicit fields list. Use includeSecurityErrors only when the caller wants Bloomberg security errors in the response.",
|
|
456
|
+
"- xbbg_bdh: historical daily or periodic time series. Always provide explicit start and end dates in YYYY-MM-DD or YYYYMMDD form. Ask before choosing periodicity, currency, fill behavior, adjustment overrides, or a wide output table.",
|
|
457
|
+
"- xbbg_bds: Bloomberg bulk/table fields. Provide exactly one bulk field; do not use bds for ordinary multi-field reference data.",
|
|
458
|
+
"- xbbg_bdib: intraday bars only. Provide one ticker, explicit ISO start/end datetimes with time components, a positive interval in minutes, and timezone context when datetimes are naive.",
|
|
459
|
+
"- xbbg_bdtick: intraday tick data. Provide one ticker, explicit ISO start/end datetimes with time components, and explicit eventTypes unless the default event stream is intended. Use includeBrokerCodes or includeConditionCodes only when those columns are needed.",
|
|
460
|
+
"- xbbg_bql: BQL expressions only when the user asks for BQL or the request is naturally expressed as a bounded BQL query. Keep queries short, explicit, and scoped to the requested universe.",
|
|
461
|
+
"- xbbg_bsrch: Bloomberg search-grid or saved-search workflows only. Do not use it for ordinary security lookup.",
|
|
462
|
+
"- xbbg_bqr: Bloomberg Quote Request / dealer quotes. Prefer fixed-income identifier inputs with a dealer quote source such as /isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>, explicit start/end datetimes with time components, and explicit event types.",
|
|
463
|
+
"- xbbg_bflds: Bloomberg field metadata/search. Provide exactly one of fields or searchSpec; use searchSpec for natural-language field names and fields for known mnemonics.",
|
|
464
|
+
"- xbbg_beqs: Bloomberg equity screening by named BEQS screen. Prefer this over hand-written BQL when the user names an existing Bloomberg screen.",
|
|
465
|
+
"- xbbg_yas: fixed-income YAS recipe fields. Prefer this over manual YAS-style BDP requests when the user asks for yield, duration, spread, or price analytics.",
|
|
466
|
+
"- xbbg_preferreds: preferred stock discovery from the issuer's common equity ticker, never a guessed preferred ('Pfd') ticker. Resolve a supplied ISIN/CUSIP with xbbg_resolve_isins first. Prefer this over xbbg_ext_bql_builder plus xbbg_bql when the user wants the actual preferreds result.",
|
|
467
|
+
"- xbbg_corporate_bonds: bounded corporate bond universe query for a company ticker. Prefer this over generic BQL for company debt discovery.",
|
|
468
|
+
"- xbbg_index_members: index constituents through the core index recipe. Prefer this over generic BDS/BQL members when the user asks for constituents.",
|
|
469
|
+
"- xbbg_resolve_isins: resolves supplied ISIN strings to Bloomberg securities. Pass raw ISIN strings only for this recipe; otherwise use /isin/<ISIN> syntax with data tools.",
|
|
470
|
+
"- xbbg_issuer_isins: issuer/bond ISIN workflow for supplied bond ISIN strings.",
|
|
471
|
+
"- xbbg_etf_holdings: ETF holdings recipe for a single ETF ticker. Prefer this over generic BQL holdings when the user asks for ETF constituents.",
|
|
472
|
+
"- xbbg_stream_snapshot: bounded live market-data observation from //blp/mktdata. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
473
|
+
"- xbbg_mktbar_snapshot: bounded live market-bar observation from //blp/mktbar for one ticker. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
474
|
+
"- xbbg_depth_snapshot: bounded market-depth observation from //blp/mktdepthdata for one ticker. Requires explicit maxUpdates and always terminates/unsubscribes.",
|
|
475
|
+
"",
|
|
476
|
+
"## BQL guidance",
|
|
477
|
+
"- BQL is a complete Bloomberg Query Language expression sent as one query string; the tool does not assemble get/for/with clauses for you.",
|
|
478
|
+
"- Basic shape: get(<FIELD_1>, <FIELD_2>) for(<UNIVERSE>). Use placeholders such as '<TICKER> <MARKET_SECTOR>', holdings('<ETF_TICKER> <MARKET_SECTOR>'), or members('<INDEX_TICKER> <MARKET_SECTOR>') until the user supplies real inputs.",
|
|
479
|
+
"- Use BQL for universe-oriented analytics and screens only when the user provides a bounded universe, filters, and date range.",
|
|
480
|
+
"- Prefer xbbg_ext_bql_builder instead of hand-writing BQL for supported workflows: preferred stocks, corporate bonds, and ETF holdings.",
|
|
481
|
+
"- Do not use BQL just because the user asks for normal reference data; xbbg_bdp is simpler for current fields and xbbg_bdh is simpler for historical time series.",
|
|
482
|
+
"",
|
|
483
|
+
"## Output handling",
|
|
484
|
+
"- Tool results use LangChain content_and_artifact output: content starts with a compact summary and then includes bounded model-readable JSON; artifact is the structured bounded envelope with tool, rowCount, truncated, and data for application code.",
|
|
485
|
+
"- If a response is empty, truncated, or contains Bloomberg/security errors, say that directly. Do not fill gaps from memory or assumptions."
|
|
486
|
+
];
|
|
487
|
+
var OPTIONAL_EXTENSION_INSTRUCTIONS = [
|
|
488
|
+
"",
|
|
489
|
+
"## Extension helper tools",
|
|
490
|
+
"- xbbg_ext_ticker: ticker hygiene before live calls. parse_ticker splits generic futures-style tickers only \u2014 asset endings Index, Curncy, Comdty, or Corp as <ROOT><N> <ASSET>, or <ROOT><N> <EXCHANGE> Equity \u2014 and rejects other market sectors (Pfd, Govt, Muni, Mtge, M-Mkt) and non-futures securities. normalize_tickers trims/canonicalizes lists, filter_equity_tickers keeps equity-like tickers, is_specific_contract checks futures specificity, and validate_generic_ticker rejects malformed generic futures tickers.",
|
|
491
|
+
"- xbbg_ext_futures: futures contract construction and selection. Use build_futures_ticker for root/month/year/asset assembly, get_futures_months for month-code lookup, generate_candidates for generic-to-specific candidates, contract_index for generic contract rank, filter_candidates_by_cycle for HMUZ/quarterly cycles, and filter_valid_contracts to keep contracts valid for a date.",
|
|
492
|
+
"- xbbg_ext_cdx: CDX ticker workflow support. Use parse_cdx_ticker to understand a CDX ticker, previous_cdx_series to roll back a series, cdx_gen_to_specific to resolve a generic CDX to a target series, and cdx_info/cdx_pricing/cdx_risk for predefined BDP field bundles. cdx_pricing and cdx_risk accept recoveryRate, which becomes the CDS_RR override.",
|
|
493
|
+
"- xbbg_ext_currency: currency-planning helpers. build_fx_pair constructs the Bloomberg FX pair and conversion factor, same_currency avoids unnecessary conversion, and currencies_needing_conversion identifies which currencies differ from a target before requesting converted values.",
|
|
494
|
+
"- xbbg_ext_bql_builder: safe BQL generators for common xbbg workflows. Use build_preferreds_query for preferred-stock discovery from an equity, build_corporate_bonds_query for company bond universes with optional currency/active filters, and build_etf_holdings_query for ETF constituents. Prefer these builders over hand-writing those BQL shapes.",
|
|
495
|
+
"- xbbg_ext_market_session: exchange calendar/timezone support. derive_sessions turns day session times into session blocks, infer_timezone maps country codes to timezones, session_times_to_utc converts local sessions to UTC, get_market_rule gets MIC/exchange rules, default_turnover_dates and default_bqr_datetimes provide bounded defaults, and get/list_exchange_override inspect configured exchange metadata.",
|
|
496
|
+
"- xbbg_ext_yas_overrides: builds flat YAS override maps for fixed-income BDP requests when the lower-level BDP workflow is required. Prefer xbbg_yas for actual YAS recipe fields.",
|
|
497
|
+
"- xbbg_ext_constants: static lookup/format helpers for date parsing/formatting, futures month code/name mappings, dividend type mappings, and known dividend/ETF output columns.",
|
|
498
|
+
"- xbbg_ext_columns: post-processing helpers for Bloomberg-shaped tables. Use rename_dividend_columns, rename_etf_columns, or build_earning_header_rename when explaining or normalizing response column names after a request.",
|
|
499
|
+
"- xbbg_ext_calculate: small numeric helper for Bloomberg workflows. calculate_level_percentages pairs observed values with levels; values and levels must have the same length."
|
|
500
|
+
];
|
|
501
|
+
var OPTIONAL_LIMIT_INSTRUCTIONS = [
|
|
502
|
+
"",
|
|
503
|
+
"## Request limits and inputs",
|
|
504
|
+
"- Keep Bloomberg requests bounded: explicit securities, explicit fields, explicit dates, limited rows, and no broad exploratory pulls unless the user narrows the universe.",
|
|
505
|
+
"- Respect configured tool limits for securities, fields, rows, string size, BQL length, and search spec length. Ask the user to narrow the request rather than exceeding them.",
|
|
506
|
+
"- Use flat primitive overrides and kwargs only: string, number, or boolean values. Do not send nested objects, arrays, or inferred defaults as overrides."
|
|
507
|
+
];
|
|
508
|
+
var BLOOMBERG_TOOL_INSTRUCTIONS = [
|
|
509
|
+
...REQUIRED_TOOL_INSTRUCTIONS,
|
|
510
|
+
...OPTIONAL_EXTENSION_INSTRUCTIONS,
|
|
511
|
+
...OPTIONAL_LIMIT_INSTRUCTIONS
|
|
512
|
+
].join("\n");
|
|
513
|
+
function getBloombergToolInstructions(options = {}) {
|
|
514
|
+
const includeExtensionGuidance = options.includeExtensionGuidance ?? true;
|
|
515
|
+
const includeLimitReminder = options.includeLimitReminder ?? true;
|
|
516
|
+
const lines = [...REQUIRED_TOOL_INSTRUCTIONS];
|
|
517
|
+
if (includeExtensionGuidance) {
|
|
518
|
+
lines.push(...OPTIONAL_EXTENSION_INSTRUCTIONS);
|
|
519
|
+
}
|
|
520
|
+
if (includeLimitReminder) {
|
|
521
|
+
lines.push(...OPTIONAL_LIMIT_INSTRUCTIONS);
|
|
513
522
|
}
|
|
514
|
-
|
|
523
|
+
return lines.join("\n");
|
|
515
524
|
}
|
|
525
|
+
var BDP_DESCRIPTION = 'Bloomberg reference data for current or point-in-time fields. Use for a small bounded list of fully qualified securities. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<TICKER> <MARKET_SECTOR>"], fields ["<FIELD>"].';
|
|
526
|
+
var BDH_DESCRIPTION = 'Bloomberg historical time series. Requires explicit start and end dates; ask before using if the date range or periodicity is ambiguous. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<TICKER> <MARKET_SECTOR>"], fields ["<FIELD>"], start "<START_DATE>", end "<END_DATE>".';
|
|
527
|
+
var BDS_DESCRIPTION = 'Bloomberg bulk/table reference data. Requires exactly one bulk field, not a field list. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: securities ["<INDEX_TICKER> <MARKET_SECTOR>"], field "<BULK_FIELD>".';
|
|
528
|
+
var BDIB_DESCRIPTION = 'Bloomberg intraday bars. Requires one ticker plus explicit ISO start/end datetimes with time components and a positive interval in minutes. Use /isin/<ISIN> for ISINs and /cusip/<CUSIP> for CUSIPs. Example: ticker "<TICKER> <MARKET_SECTOR>", start "<START_DATETIME>", end "<END_DATETIME>", interval <MINUTES>.';
|
|
529
|
+
var BDTICK_DESCRIPTION = 'Bloomberg intraday tick data. Requires one ticker plus explicit ISO start/end datetimes with time components. Set eventTypes explicitly, for example ["<EVENT_TYPE>"], and includeBrokerCodes/includeConditionCodes only when needed.';
|
|
530
|
+
var BQL_DESCRIPTION = "Bloomberg Query Language expression sent as one complete query string. Use for bounded universe analytics with placeholder-shaped syntax such as get(<FIELD>) for('<TICKER> <MARKET_SECTOR>'), holdings('<ETF_TICKER> <MARKET_SECTOR>'), members('<INDEX_TICKER> <MARKET_SECTOR>'), filters with with(...), or dates=range(...). Prefer xbbg_bdp/xbbg_bdh for simple reference or historical requests.";
|
|
531
|
+
var BSRCH_DESCRIPTION = 'Bloomberg search/grid request. Use for saved-search or ExcelGetGrid-style Bloomberg searches, not ordinary security lookup. Example searchSpec "<SEARCH_SPEC>".';
|
|
532
|
+
var BQR_DESCRIPTION = 'Bloomberg Quote Request / dealer quotes. Use for fixed-income dealer quote ticks, preferably with an ISIN plus dealer source such as "/isin/<ISIN>@<QUOTE_SOURCE> <MARKET_SECTOR>"; requires explicit ISO start/end datetimes with time components. Set eventTypes explicitly, for example ["<EVENT_TYPE>"].';
|
|
533
|
+
var BFLDS_DESCRIPTION = 'Bloomberg field metadata and field search. Use first when a field mnemonic is uncertain. Provide exactly one of fields or searchSpec. Example: fields ["<FIELD>"] or searchSpec "<FIELD_SEARCH_TEXT>".';
|
|
534
|
+
var BEQS_DESCRIPTION = "Bloomberg equity screening by named BEQS screen. Use when the user names an existing Bloomberg screen and wants its bounded result set. Prefer this over hand-written BQL for saved Bloomberg screens.";
|
|
535
|
+
var YAS_DESCRIPTION = "Bloomberg fixed-income YAS recipe fields for one or more bonds. Use for yield, duration, spread, benchmark, or price analytics; provide explicit fields and optional settlement/yield/price inputs. Pass securities as supplied: '<TICKER> <MARKET_SECTOR>' or identifier syntax such as '/isin/<ISIN> <MARKET_SECTOR>'.";
|
|
536
|
+
var PREFERREDS_DESCRIPTION = "Preferred stock discovery for one issuer. Takes the issuer's common equity ticker such as '<TICKER> US Equity', never a preferred ('Pfd') ticker and never a guessed one. If the user supplied an ISIN or CUSIP, resolve it with xbbg_resolve_isins first.";
|
|
537
|
+
var CORPORATE_BONDS_DESCRIPTION = "Corporate bond universe query for one issuer/company equity ticker, with optional currency, active-only filter, and result fields. Prefer this over generic BQL for company debt discovery. If the user supplied an ISIN or CUSIP, resolve it with xbbg_resolve_isins first; never guess the ticker.";
|
|
538
|
+
var INDEX_MEMBERS_DESCRIPTION = "Index constituent recipe for one Bloomberg index ticker such as '<INDEX_TICKER> Index'. Use for bounded member lists and optional historical/as-of constituent membership; never guess index tickers.";
|
|
539
|
+
var RESOLVE_ISINS_DESCRIPTION = "Resolve raw ISIN strings to Bloomberg securities through the core ISIN recipe. Do not add /isin/ prefixes in this tool; pass the exact ISIN strings supplied by the user.";
|
|
540
|
+
var ISSUER_ISINS_DESCRIPTION = "Issuer/bond ISIN workflow for supplied bond ISIN strings. Use for issuer-level ISIN discovery starting from known bond ISINs.";
|
|
541
|
+
var ETF_HOLDINGS_DESCRIPTION = "ETF holdings recipe for one ETF ticker such as '<ETF_TICKER> <MARKET_SECTOR>'. Use when the user asks for ETF constituents or holdings and wants the bounded holdings result. Resolve a supplied ISIN/CUSIP with xbbg_resolve_isins first; never guess the ticker.";
|
|
542
|
+
var STREAM_SNAPSHOT_DESCRIPTION = "Bounded live market-data snapshot from //blp/mktdata. Collects at most maxUpdates updates until timeout/done, then always unsubscribes; use for finite observations, not open subscriptions.";
|
|
543
|
+
var MKTBAR_SNAPSHOT_DESCRIPTION = "Bounded live market-bar snapshot from //blp/mktbar for one ticker. Collects at most maxUpdates updates until timeout/done, then always unsubscribes.";
|
|
544
|
+
var DEPTH_SNAPSHOT_DESCRIPTION = "Bounded live market-depth snapshot from //blp/mktdepthdata for one ticker. Collects at most maxUpdates updates until timeout/done, then always unsubscribes.";
|
|
545
|
+
var EXT_TICKER_DESCRIPTION = "Ticker hygiene helpers: parse_ticker (generic futures-style tickers ending in Index, Curncy, Comdty, or Corp, or <ROOT><N> <EXCHANGE> Equity; other market sectors are rejected), normalize_tickers, filter_equity_tickers, is_specific_contract, and validate_generic_ticker.";
|
|
546
|
+
var EXT_FUTURES_DESCRIPTION = "Futures helpers for contract construction and selection: build_futures_ticker, generate_candidates, contract_index, filter_candidates_by_cycle, filter_valid_contracts, and get_futures_months.";
|
|
547
|
+
var EXT_CDX_DESCRIPTION = "CDX helpers for parsing, series rolling/resolution, and predefined info/pricing/risk BDP field bundles.";
|
|
548
|
+
var EXT_CURRENCY_DESCRIPTION = "Currency planning helpers: build FX pairs, test same-currency requests, and find currencies needing conversion.";
|
|
549
|
+
var EXT_BQL_BUILDER_DESCRIPTION = "BQL builders for preferred stocks, corporate bonds, and ETF holdings. Prefer to construct those bounded BQL shapes before xbbg_bql.";
|
|
550
|
+
var EXT_MARKET_SESSION_DESCRIPTION = "Market session and timezone helpers for deriving sessions, UTC windows, market rules, exchange metadata, turnover defaults, and BQR datetime defaults.";
|
|
551
|
+
var EXT_YAS_OVERRIDES_DESCRIPTION = "Build flat Bloomberg YAS override maps for fixed-income analytics fields.";
|
|
552
|
+
var EXT_CONSTANTS_DESCRIPTION = "Static Bloomberg helper constants for date parsing/formatting, futures months, dividend types, and ETF/dividend columns.";
|
|
553
|
+
var EXT_COLUMNS_DESCRIPTION = "Column rename helpers for dividend, ETF, and earnings-shaped Bloomberg responses.";
|
|
554
|
+
var EXT_CALCULATE_DESCRIPTION = "Small numeric helper operations for Bloomberg workflows, including level percentage calculations.";
|
|
516
555
|
var stringPairSchema = z__namespace.object({
|
|
517
556
|
key: z__namespace.string().trim().min(1).describe("String pair key."),
|
|
518
557
|
value: z__namespace.string().trim().min(1).describe("String pair value.")
|
|
@@ -534,7 +573,7 @@ function optionalString(options, description) {
|
|
|
534
573
|
function tickerSchema(options) {
|
|
535
574
|
const ticker = nonEmptyString(
|
|
536
575
|
options,
|
|
537
|
-
"One Bloomberg ticker
|
|
576
|
+
"One generic futures-style Bloomberg ticker: <ROOT><N> ending in Index, Curncy, Comdty, or Corp, or <ROOT><N> <EXCHANGE> Equity. parse_ticker rejects other market sectors (Pfd, Govt, Muni, Mtge, M-Mkt) and non-futures securities."
|
|
538
577
|
);
|
|
539
578
|
const tickers = stringArray(
|
|
540
579
|
options,
|
|
@@ -550,94 +589,151 @@ function tickerSchema(options) {
|
|
|
550
589
|
]);
|
|
551
590
|
}
|
|
552
591
|
function futuresSchema(options) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
"
|
|
567
|
-
"
|
|
568
|
-
"
|
|
569
|
-
"
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
592
|
+
const genTicker = nonEmptyString(
|
|
593
|
+
options,
|
|
594
|
+
"Generic Bloomberg futures ticker, for example ES1 Index."
|
|
595
|
+
);
|
|
596
|
+
const year = z__namespace.number().int().describe("Contract year, for example 2024.");
|
|
597
|
+
const month = z__namespace.number().int().min(1).max(12).describe("Month number, 1-12.");
|
|
598
|
+
const day = z__namespace.number().int().min(1).max(31).describe("Day number, 1-31.");
|
|
599
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
600
|
+
z__namespace.object({
|
|
601
|
+
asset: nonEmptyString(
|
|
602
|
+
options,
|
|
603
|
+
"Bloomberg asset class suffix, for example Index or Comdty."
|
|
604
|
+
),
|
|
605
|
+
monthCode: nonEmptyString(options, "Bloomberg futures month code, for example H."),
|
|
606
|
+
operation: z__namespace.literal("build_futures_ticker"),
|
|
607
|
+
prefix: nonEmptyString(options, "Futures ticker root prefix, for example ES."),
|
|
608
|
+
year: z__namespace.union([z__namespace.string().trim().min(1), z__namespace.number().int().transform(String)]).describe("Contract year, full or abbreviated, as a string or integer.")
|
|
609
|
+
}).strict(),
|
|
610
|
+
z__namespace.object({
|
|
611
|
+
count: z__namespace.number().int().positive().optional().describe("Maximum number of futures candidates to generate."),
|
|
612
|
+
day,
|
|
613
|
+
freq: optionalString(options, "Futures frequency/cycle hint."),
|
|
614
|
+
genTicker,
|
|
615
|
+
month,
|
|
616
|
+
operation: z__namespace.literal("generate_candidates"),
|
|
617
|
+
year
|
|
618
|
+
}).strict(),
|
|
619
|
+
z__namespace.object({ genTicker, operation: z__namespace.literal("contract_index") }).strict(),
|
|
620
|
+
z__namespace.object({
|
|
621
|
+
candidates: z__namespace.array(futuresCandidateSchema).min(1).max(options.maxFields).describe("Candidate futures contracts."),
|
|
622
|
+
cycle: nonEmptyString(options, "Futures cycle code to filter candidates by."),
|
|
623
|
+
operation: z__namespace.literal("filter_candidates_by_cycle")
|
|
624
|
+
}).strict(),
|
|
625
|
+
z__namespace.object({
|
|
626
|
+
contracts: z__namespace.array(stringPairSchema).min(1).max(options.maxFields).describe("Contract pairs for validity filtering."),
|
|
627
|
+
day,
|
|
628
|
+
month,
|
|
629
|
+
operation: z__namespace.literal("filter_valid_contracts"),
|
|
630
|
+
year
|
|
631
|
+
}).strict(),
|
|
632
|
+
z__namespace.object({ operation: z__namespace.literal("get_futures_months") }).strict()
|
|
633
|
+
]);
|
|
575
634
|
}
|
|
576
635
|
function cdxSchema(options) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
636
|
+
const ticker = nonEmptyString(options, "CDX ticker, generic or specific.");
|
|
637
|
+
const recoveryRate = z__namespace.number().min(0).max(1).optional().describe("Decimal recovery rate override, e.g. 0.4 for 40%; sent as the CDS_RR override.");
|
|
638
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
639
|
+
z__namespace.object({ operation: z__namespace.literal("parse_cdx_ticker"), ticker }).strict(),
|
|
640
|
+
z__namespace.object({ operation: z__namespace.literal("previous_cdx_series"), ticker }).strict(),
|
|
641
|
+
z__namespace.object({ operation: z__namespace.literal("cdx_info"), ticker }).strict(),
|
|
642
|
+
z__namespace.object({ operation: z__namespace.literal("cdx_pricing"), recoveryRate, ticker }).strict(),
|
|
643
|
+
z__namespace.object({ operation: z__namespace.literal("cdx_risk"), recoveryRate, ticker }).strict(),
|
|
644
|
+
z__namespace.object({
|
|
645
|
+
genTicker: nonEmptyString(
|
|
646
|
+
options,
|
|
647
|
+
"Generic CDX ticker, for example CDX IG CDSI GEN 5Y Corp."
|
|
648
|
+
),
|
|
649
|
+
operation: z__namespace.literal("cdx_gen_to_specific"),
|
|
650
|
+
series: z__namespace.number().int().positive().describe("Specific CDX series number.")
|
|
651
|
+
}).strict()
|
|
652
|
+
]);
|
|
591
653
|
}
|
|
592
654
|
function currencySchema(options) {
|
|
593
|
-
return z__namespace.
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
655
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
656
|
+
z__namespace.object({
|
|
657
|
+
fromCcy: nonEmptyString(options, "Source ISO currency code."),
|
|
658
|
+
operation: z__namespace.literal("build_fx_pair"),
|
|
659
|
+
toCcy: nonEmptyString(options, "Destination ISO currency code.")
|
|
660
|
+
}).strict(),
|
|
661
|
+
z__namespace.object({
|
|
662
|
+
ccy1: nonEmptyString(options, "First ISO currency code."),
|
|
663
|
+
ccy2: nonEmptyString(options, "Second ISO currency code."),
|
|
664
|
+
operation: z__namespace.literal("same_currency")
|
|
665
|
+
}).strict(),
|
|
666
|
+
z__namespace.object({
|
|
667
|
+
currencies: stringArray(options, "ISO currency codes to check."),
|
|
668
|
+
operation: z__namespace.literal("currencies_needing_conversion"),
|
|
669
|
+
target: nonEmptyString(options, "Target ISO currency code.")
|
|
670
|
+
}).strict()
|
|
671
|
+
]);
|
|
602
672
|
}
|
|
603
673
|
function bqlBuilderSchema(options) {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
674
|
+
const extraFields = stringArray(options, "Extra BQL fields to include.").optional();
|
|
675
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
676
|
+
z__namespace.object({
|
|
677
|
+
equityTicker: nonEmptyString(options, "Equity ticker for preferreds query."),
|
|
678
|
+
extraFields,
|
|
679
|
+
operation: z__namespace.literal("build_preferreds_query")
|
|
680
|
+
}).strict(),
|
|
681
|
+
z__namespace.object({
|
|
682
|
+
activeOnly: z__namespace.boolean().optional().describe("Restrict corporate bond query to active bonds."),
|
|
683
|
+
ccy: optionalString(options, "Currency filter for corporate bond query."),
|
|
684
|
+
extraFields,
|
|
685
|
+
operation: z__namespace.literal("build_corporate_bonds_query"),
|
|
686
|
+
ticker: nonEmptyString(options, "Ticker for corporate bond query.")
|
|
687
|
+
}).strict(),
|
|
688
|
+
z__namespace.object({
|
|
689
|
+
etfTicker: nonEmptyString(options, "ETF ticker for holdings query."),
|
|
690
|
+
extraFields,
|
|
691
|
+
operation: z__namespace.literal("build_etf_holdings_query")
|
|
692
|
+
}).strict()
|
|
693
|
+
]);
|
|
613
694
|
}
|
|
614
695
|
function marketSessionSchema(options) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
"
|
|
628
|
-
"
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
"
|
|
632
|
-
"
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
696
|
+
const mic = optionalString(options, "Market Identifier Code, for example XNYS.");
|
|
697
|
+
const exchCode = optionalString(options, "Bloomberg exchange code.");
|
|
698
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
699
|
+
z__namespace.object({
|
|
700
|
+
dayEnd: nonEmptyString(options, "Exchange day end time, for example 16:00."),
|
|
701
|
+
dayStart: nonEmptyString(options, "Exchange day start time, for example 09:30."),
|
|
702
|
+
exchCode,
|
|
703
|
+
mic,
|
|
704
|
+
operation: z__namespace.literal("derive_sessions")
|
|
705
|
+
}).strict(),
|
|
706
|
+
z__namespace.object({ exchCode, mic, operation: z__namespace.literal("get_market_rule") }).strict(),
|
|
707
|
+
z__namespace.object({
|
|
708
|
+
countryIso: nonEmptyString(options, "ISO country code for timezone inference."),
|
|
709
|
+
operation: z__namespace.literal("infer_timezone")
|
|
710
|
+
}).strict(),
|
|
711
|
+
z__namespace.object({
|
|
712
|
+
date: nonEmptyString(options, "Date for UTC session conversion, YYYY-MM-DD or YYYYMMDD."),
|
|
713
|
+
endTime: nonEmptyString(options, "Session end time, for example 16:00."),
|
|
714
|
+
exchangeTz: nonEmptyString(
|
|
715
|
+
options,
|
|
716
|
+
"IANA exchange timezone, for example America/New_York."
|
|
717
|
+
),
|
|
718
|
+
operation: z__namespace.literal("session_times_to_utc"),
|
|
719
|
+
startTime: nonEmptyString(options, "Session start time, for example 09:30.")
|
|
720
|
+
}).strict(),
|
|
721
|
+
z__namespace.object({
|
|
722
|
+
endDate: optionalString(options, "Optional end date."),
|
|
723
|
+
operation: z__namespace.literal("default_turnover_dates"),
|
|
724
|
+
startDate: optionalString(options, "Optional start date.")
|
|
725
|
+
}).strict(),
|
|
726
|
+
z__namespace.object({
|
|
727
|
+
endDatetime: optionalString(options, "Optional end datetime."),
|
|
728
|
+
operation: z__namespace.literal("default_bqr_datetimes"),
|
|
729
|
+
startDatetime: optionalString(options, "Optional start datetime.")
|
|
730
|
+
}).strict(),
|
|
731
|
+
z__namespace.object({
|
|
732
|
+
operation: z__namespace.literal("get_exchange_override"),
|
|
733
|
+
ticker: nonEmptyString(options, "Ticker for exchange override lookup.")
|
|
734
|
+
}).strict(),
|
|
735
|
+
z__namespace.object({ operation: z__namespace.literal("list_exchange_overrides") }).strict()
|
|
736
|
+
]);
|
|
641
737
|
}
|
|
642
738
|
function yasOverridesSchema(options) {
|
|
643
739
|
return z__namespace.object({
|
|
@@ -647,94 +743,67 @@ function yasOverridesSchema(options) {
|
|
|
647
743
|
spread: z__namespace.number().optional().describe("YAS spread override."),
|
|
648
744
|
yieldType: z__namespace.number().int().optional().describe("YAS yield type override."),
|
|
649
745
|
yieldVal: z__namespace.number().optional().describe("YAS yield value override.")
|
|
650
|
-
});
|
|
746
|
+
}).strict();
|
|
651
747
|
}
|
|
652
748
|
function constantsSchema(options) {
|
|
653
|
-
return z__namespace.
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
"
|
|
663
|
-
"
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
"
|
|
667
|
-
"
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
"
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
749
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
750
|
+
z__namespace.object({
|
|
751
|
+
dateStr: nonEmptyString(options, "Date string to parse."),
|
|
752
|
+
operation: z__namespace.literal("parse_date")
|
|
753
|
+
}).strict(),
|
|
754
|
+
z__namespace.object({
|
|
755
|
+
day: z__namespace.number().int().min(1).max(31).describe("Day number, 1-31."),
|
|
756
|
+
fmt: optionalString(options, "Date output format."),
|
|
757
|
+
month: z__namespace.number().int().min(1).max(12).describe("Month number, 1-12."),
|
|
758
|
+
operation: z__namespace.literal("fmt_date"),
|
|
759
|
+
year: z__namespace.number().int().min(1).describe("Year number.")
|
|
760
|
+
}).strict(),
|
|
761
|
+
z__namespace.object({
|
|
762
|
+
monthName: nonEmptyString(options, "Month name, for example March."),
|
|
763
|
+
operation: z__namespace.literal("get_month_code")
|
|
764
|
+
}).strict(),
|
|
765
|
+
z__namespace.object({
|
|
766
|
+
code: nonEmptyString(options, "Month code, for example H."),
|
|
767
|
+
operation: z__namespace.literal("get_month_name")
|
|
768
|
+
}).strict(),
|
|
769
|
+
z__namespace.object({
|
|
770
|
+
dvdType: nonEmptyString(options, "Dividend type code or label."),
|
|
771
|
+
operation: z__namespace.literal("get_dvd_type")
|
|
772
|
+
}).strict(),
|
|
773
|
+
z__namespace.object({ operation: z__namespace.literal("get_futures_months") }).strict(),
|
|
774
|
+
z__namespace.object({ operation: z__namespace.literal("get_dvd_types") }).strict(),
|
|
775
|
+
z__namespace.object({ operation: z__namespace.literal("get_dvd_cols") }).strict(),
|
|
776
|
+
z__namespace.object({ operation: z__namespace.literal("get_etf_cols") }).strict()
|
|
777
|
+
]);
|
|
674
778
|
}
|
|
675
779
|
function columnsSchema(options) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
780
|
+
const columns = stringArray(options, "Column names to rename.");
|
|
781
|
+
return z__namespace.discriminatedUnion("operation", [
|
|
782
|
+
z__namespace.object({ columns, operation: z__namespace.literal("rename_dividend_columns") }).strict(),
|
|
783
|
+
z__namespace.object({ columns, operation: z__namespace.literal("rename_etf_columns") }).strict(),
|
|
784
|
+
z__namespace.object({
|
|
785
|
+
dataColumns: stringArray(options, "Earnings data column names."),
|
|
786
|
+
headerRow: z__namespace.array(stringPairSchema).min(1).max(options.maxFields).describe("Earnings header row key/value pairs."),
|
|
787
|
+
operation: z__namespace.literal("build_earning_header_rename")
|
|
788
|
+
}).strict()
|
|
789
|
+
]);
|
|
682
790
|
}
|
|
683
791
|
function calculateSchema(options) {
|
|
684
792
|
return z__namespace.object({
|
|
685
793
|
levels: z__namespace.array(z__namespace.number().nullable()).min(1).max(options.maxFields).describe("Reference level values."),
|
|
686
794
|
operation: z__namespace.literal("calculate_level_percentages").describe("Numeric helper operation to run."),
|
|
687
795
|
values: z__namespace.array(z__namespace.number().nullable()).min(1).max(options.maxFields).describe("Observed values.")
|
|
796
|
+
}).strict().superRefine((input, ctx) => {
|
|
797
|
+
if (input.values.length !== input.levels.length) {
|
|
798
|
+
ctx.addIssue({
|
|
799
|
+
code: z__namespace.ZodIssueCode.custom,
|
|
800
|
+
message: "values and levels must have the same length"
|
|
801
|
+
});
|
|
802
|
+
}
|
|
688
803
|
});
|
|
689
804
|
}
|
|
690
805
|
|
|
691
806
|
// src/ext-tools.ts
|
|
692
|
-
function asRecord(value) {
|
|
693
|
-
return value;
|
|
694
|
-
}
|
|
695
|
-
function requireString(toolName, input, field) {
|
|
696
|
-
const value = input[field];
|
|
697
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
698
|
-
throw new TypeError(`${toolName}: ${field} is required and must be a non-empty string`);
|
|
699
|
-
}
|
|
700
|
-
return value.trim();
|
|
701
|
-
}
|
|
702
|
-
function requireNumber(toolName, input, field) {
|
|
703
|
-
const value = input[field];
|
|
704
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
705
|
-
throw new TypeError(`${toolName}: ${field} is required and must be a finite number`);
|
|
706
|
-
}
|
|
707
|
-
return value;
|
|
708
|
-
}
|
|
709
|
-
function requireInteger(toolName, input, field) {
|
|
710
|
-
const value = requireNumber(toolName, input, field);
|
|
711
|
-
if (!Number.isInteger(value)) {
|
|
712
|
-
throw new TypeError(`${toolName}: ${field} must be an integer`);
|
|
713
|
-
}
|
|
714
|
-
return value;
|
|
715
|
-
}
|
|
716
|
-
function requireYearString(toolName, input, field) {
|
|
717
|
-
const value = input[field];
|
|
718
|
-
if (typeof value === "number" && Number.isInteger(value)) {
|
|
719
|
-
return String(value);
|
|
720
|
-
}
|
|
721
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
722
|
-
return value.trim();
|
|
723
|
-
}
|
|
724
|
-
throw new TypeError(`${toolName}: ${field} is required and must be a year string or integer`);
|
|
725
|
-
}
|
|
726
|
-
function requireStringArray(toolName, input, field) {
|
|
727
|
-
const value = input[field];
|
|
728
|
-
if (!Array.isArray(value) || value.length === 0) {
|
|
729
|
-
throw new TypeError(`${toolName}: ${field} is required and must be a non-empty string array`);
|
|
730
|
-
}
|
|
731
|
-
return value.map((entry) => {
|
|
732
|
-
if (typeof entry !== "string" || entry.trim().length === 0) {
|
|
733
|
-
throw new TypeError(`${toolName}: ${field} entries must be non-empty strings`);
|
|
734
|
-
}
|
|
735
|
-
return entry.trim();
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
807
|
function resultString(resolver, name, value) {
|
|
739
808
|
return createToolResult(name, value, resolver.options.maxRows, resolver.options.maxStringChars);
|
|
740
809
|
}
|
|
@@ -762,37 +831,18 @@ function extTickerWithResolver(resolver) {
|
|
|
762
831
|
async (input) => {
|
|
763
832
|
try {
|
|
764
833
|
const core = await resolver.getCore();
|
|
765
|
-
const args = asRecord(input);
|
|
766
834
|
switch (input.operation) {
|
|
767
835
|
case "parse_ticker":
|
|
768
|
-
return resultString(
|
|
769
|
-
resolver,
|
|
770
|
-
name,
|
|
771
|
-
core.ext.parseTicker(requireString(name, args, "ticker"))
|
|
772
|
-
);
|
|
836
|
+
return resultString(resolver, name, core.ext.parseTicker(input.ticker));
|
|
773
837
|
case "normalize_tickers":
|
|
774
|
-
return resultString(
|
|
775
|
-
resolver,
|
|
776
|
-
name,
|
|
777
|
-
core.ext.normalizeTickers(requireStringArray(name, args, "tickers"))
|
|
778
|
-
);
|
|
838
|
+
return resultString(resolver, name, core.ext.normalizeTickers(input.tickers));
|
|
779
839
|
case "filter_equity_tickers":
|
|
780
|
-
return resultString(
|
|
781
|
-
resolver,
|
|
782
|
-
name,
|
|
783
|
-
core.ext.filterEquityTickers(requireStringArray(name, args, "tickers"))
|
|
784
|
-
);
|
|
840
|
+
return resultString(resolver, name, core.ext.filterEquityTickers(input.tickers));
|
|
785
841
|
case "is_specific_contract":
|
|
786
|
-
return resultString(
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
);
|
|
791
|
-
case "validate_generic_ticker": {
|
|
792
|
-
const ticker = requireString(name, args, "ticker");
|
|
793
|
-
core.ext.validateGenericTicker(ticker);
|
|
794
|
-
return resultString(resolver, name, { ticker, valid: true });
|
|
795
|
-
}
|
|
842
|
+
return resultString(resolver, name, core.ext.isSpecificContract(input.ticker));
|
|
843
|
+
case "validate_generic_ticker":
|
|
844
|
+
core.ext.validateGenericTicker(input.ticker);
|
|
845
|
+
return resultString(resolver, name, { ticker: input.ticker, valid: true });
|
|
796
846
|
}
|
|
797
847
|
} catch (error) {
|
|
798
848
|
throwWithToolContext(name, error);
|
|
@@ -812,63 +862,39 @@ function extFuturesWithResolver(resolver) {
|
|
|
812
862
|
async (input) => {
|
|
813
863
|
try {
|
|
814
864
|
const core = await resolver.getCore();
|
|
815
|
-
const args = asRecord(input);
|
|
816
865
|
switch (input.operation) {
|
|
817
866
|
case "build_futures_ticker":
|
|
818
867
|
return resultString(
|
|
819
868
|
resolver,
|
|
820
869
|
name,
|
|
821
|
-
core.ext.buildFuturesTicker(
|
|
822
|
-
requireString(name, args, "prefix"),
|
|
823
|
-
requireString(name, args, "monthCode"),
|
|
824
|
-
requireYearString(name, args, "year"),
|
|
825
|
-
requireString(name, args, "asset")
|
|
826
|
-
)
|
|
870
|
+
core.ext.buildFuturesTicker(input.prefix, input.monthCode, input.year, input.asset)
|
|
827
871
|
);
|
|
828
872
|
case "generate_candidates":
|
|
829
873
|
return resultString(
|
|
830
874
|
resolver,
|
|
831
875
|
name,
|
|
832
876
|
core.ext.generateFuturesCandidates(
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
877
|
+
input.genTicker,
|
|
878
|
+
input.year,
|
|
879
|
+
input.month,
|
|
880
|
+
input.day,
|
|
837
881
|
input.freq,
|
|
838
882
|
input.count
|
|
839
883
|
)
|
|
840
884
|
);
|
|
841
885
|
case "contract_index":
|
|
842
|
-
return resultString(
|
|
843
|
-
resolver,
|
|
844
|
-
name,
|
|
845
|
-
core.ext.contractIndex(requireString(name, args, "genTicker"))
|
|
846
|
-
);
|
|
886
|
+
return resultString(resolver, name, core.ext.contractIndex(input.genTicker));
|
|
847
887
|
case "filter_candidates_by_cycle":
|
|
848
|
-
if (input.candidates === void 0) {
|
|
849
|
-
throw new TypeError(`${name}: candidates is required`);
|
|
850
|
-
}
|
|
851
888
|
return resultString(
|
|
852
889
|
resolver,
|
|
853
890
|
name,
|
|
854
|
-
core.ext.filterCandidatesByCycle(
|
|
855
|
-
input.candidates,
|
|
856
|
-
requireString(name, args, "cycle")
|
|
857
|
-
)
|
|
891
|
+
core.ext.filterCandidatesByCycle(input.candidates, input.cycle)
|
|
858
892
|
);
|
|
859
893
|
case "filter_valid_contracts":
|
|
860
|
-
if (input.contracts === void 0) {
|
|
861
|
-
throw new TypeError(`${name}: contracts is required`);
|
|
862
|
-
}
|
|
863
894
|
return resultString(
|
|
864
895
|
resolver,
|
|
865
896
|
name,
|
|
866
|
-
core.ext.filterValidContracts(
|
|
867
|
-
input.contracts,
|
|
868
|
-
requireInteger(name, args, "year"),
|
|
869
|
-
requireInteger(name, args, "month"),
|
|
870
|
-
requireInteger(name, args, "day")
|
|
871
|
-
)
|
|
897
|
+
core.ext.filterValidContracts(input.contracts, input.year, input.month, input.day)
|
|
872
898
|
);
|
|
873
899
|
case "get_futures_months":
|
|
874
900
|
return resultString(resolver, name, core.ext.getFuturesMonths());
|
|
@@ -888,41 +914,31 @@ function extFuturesWithResolver(resolver) {
|
|
|
888
914
|
function extCdxWithResolver(resolver) {
|
|
889
915
|
const name = "xbbg_ext_cdx";
|
|
890
916
|
return createBloombergStructuredTool(
|
|
891
|
-
async (input) => {
|
|
917
|
+
async (input, config) => {
|
|
892
918
|
try {
|
|
893
|
-
|
|
919
|
+
config?.signal?.throwIfAborted();
|
|
894
920
|
if (input.operation === "cdx_info" || input.operation === "cdx_pricing" || input.operation === "cdx_risk") {
|
|
895
921
|
const engine = await resolver.getEngine();
|
|
896
|
-
const ticker = requireString(name, args, "ticker");
|
|
897
922
|
const fields = input.operation === "cdx_info" ? CDX_INFO_FIELDS : input.operation === "cdx_pricing" ? CDX_PRICING_FIELDS : CDX_RISK_FIELDS;
|
|
898
|
-
const result = await engine.bdp([ticker], fields, {
|
|
923
|
+
const result = await engine.bdp([input.ticker], fields, {
|
|
899
924
|
backend: "json",
|
|
900
|
-
overrides: recoveryOverrides(
|
|
925
|
+
overrides: recoveryOverrides(
|
|
926
|
+
input.operation === "cdx_pricing" || input.operation === "cdx_risk" ? input.recoveryRate : void 0
|
|
927
|
+
)
|
|
901
928
|
});
|
|
902
929
|
return resultString(resolver, name, result);
|
|
903
930
|
}
|
|
904
931
|
const core = await resolver.getCore();
|
|
905
932
|
switch (input.operation) {
|
|
906
933
|
case "parse_cdx_ticker":
|
|
907
|
-
return resultString(
|
|
908
|
-
resolver,
|
|
909
|
-
name,
|
|
910
|
-
core.ext.parseCdxTicker(requireString(name, args, "ticker"))
|
|
911
|
-
);
|
|
934
|
+
return resultString(resolver, name, core.ext.parseCdxTicker(input.ticker));
|
|
912
935
|
case "previous_cdx_series":
|
|
913
|
-
return resultString(
|
|
914
|
-
resolver,
|
|
915
|
-
name,
|
|
916
|
-
core.ext.previousCdxSeries(requireString(name, args, "ticker"))
|
|
917
|
-
);
|
|
936
|
+
return resultString(resolver, name, core.ext.previousCdxSeries(input.ticker));
|
|
918
937
|
case "cdx_gen_to_specific":
|
|
919
938
|
return resultString(
|
|
920
939
|
resolver,
|
|
921
940
|
name,
|
|
922
|
-
core.ext.cdxGenToSpecific(
|
|
923
|
-
requireString(name, args, "genTicker"),
|
|
924
|
-
requireInteger(name, args, "series")
|
|
925
|
-
)
|
|
941
|
+
core.ext.cdxGenToSpecific(input.genTicker, input.series)
|
|
926
942
|
);
|
|
927
943
|
}
|
|
928
944
|
} catch (error) {
|
|
@@ -943,34 +959,16 @@ function extCurrencyWithResolver(resolver) {
|
|
|
943
959
|
async (input) => {
|
|
944
960
|
try {
|
|
945
961
|
const core = await resolver.getCore();
|
|
946
|
-
const args = asRecord(input);
|
|
947
962
|
switch (input.operation) {
|
|
948
963
|
case "build_fx_pair":
|
|
949
|
-
return resultString(
|
|
950
|
-
resolver,
|
|
951
|
-
name,
|
|
952
|
-
core.ext.buildFxPair(
|
|
953
|
-
requireString(name, args, "fromCcy"),
|
|
954
|
-
requireString(name, args, "toCcy")
|
|
955
|
-
)
|
|
956
|
-
);
|
|
964
|
+
return resultString(resolver, name, core.ext.buildFxPair(input.fromCcy, input.toCcy));
|
|
957
965
|
case "same_currency":
|
|
958
|
-
return resultString(
|
|
959
|
-
resolver,
|
|
960
|
-
name,
|
|
961
|
-
core.ext.sameCurrency(
|
|
962
|
-
requireString(name, args, "ccy1"),
|
|
963
|
-
requireString(name, args, "ccy2")
|
|
964
|
-
)
|
|
965
|
-
);
|
|
966
|
+
return resultString(resolver, name, core.ext.sameCurrency(input.ccy1, input.ccy2));
|
|
966
967
|
case "currencies_needing_conversion":
|
|
967
968
|
return resultString(
|
|
968
969
|
resolver,
|
|
969
970
|
name,
|
|
970
|
-
core.ext.currenciesNeedingConversion(
|
|
971
|
-
requireStringArray(name, args, "currencies"),
|
|
972
|
-
requireString(name, args, "target")
|
|
973
|
-
)
|
|
971
|
+
core.ext.currenciesNeedingConversion(input.currencies, input.target)
|
|
974
972
|
);
|
|
975
973
|
}
|
|
976
974
|
} catch (error) {
|
|
@@ -991,23 +989,19 @@ function extBqlBuilderWithResolver(resolver) {
|
|
|
991
989
|
async (input) => {
|
|
992
990
|
try {
|
|
993
991
|
const core = await resolver.getCore();
|
|
994
|
-
const args = asRecord(input);
|
|
995
992
|
switch (input.operation) {
|
|
996
993
|
case "build_preferreds_query":
|
|
997
994
|
return resultString(
|
|
998
995
|
resolver,
|
|
999
996
|
name,
|
|
1000
|
-
core.ext.buildPreferredsQuery(
|
|
1001
|
-
requireString(name, args, "equityTicker"),
|
|
1002
|
-
input.extraFields
|
|
1003
|
-
)
|
|
997
|
+
core.ext.buildPreferredsQuery(input.equityTicker, input.extraFields)
|
|
1004
998
|
);
|
|
1005
999
|
case "build_corporate_bonds_query":
|
|
1006
1000
|
return resultString(
|
|
1007
1001
|
resolver,
|
|
1008
1002
|
name,
|
|
1009
1003
|
core.ext.buildCorporateBondsQuery(
|
|
1010
|
-
|
|
1004
|
+
input.ticker,
|
|
1011
1005
|
input.ccy,
|
|
1012
1006
|
input.extraFields,
|
|
1013
1007
|
input.activeOnly
|
|
@@ -1017,10 +1011,7 @@ function extBqlBuilderWithResolver(resolver) {
|
|
|
1017
1011
|
return resultString(
|
|
1018
1012
|
resolver,
|
|
1019
1013
|
name,
|
|
1020
|
-
core.ext.buildEtfHoldingsQuery(
|
|
1021
|
-
requireString(name, args, "etfTicker"),
|
|
1022
|
-
input.extraFields
|
|
1023
|
-
)
|
|
1014
|
+
core.ext.buildEtfHoldingsQuery(input.etfTicker, input.extraFields)
|
|
1024
1015
|
);
|
|
1025
1016
|
}
|
|
1026
1017
|
} catch (error) {
|
|
@@ -1041,36 +1032,26 @@ function extMarketSessionWithResolver(resolver) {
|
|
|
1041
1032
|
async (input) => {
|
|
1042
1033
|
try {
|
|
1043
1034
|
const core = await resolver.getCore();
|
|
1044
|
-
const args = asRecord(input);
|
|
1045
1035
|
switch (input.operation) {
|
|
1046
1036
|
case "derive_sessions":
|
|
1047
1037
|
return resultString(
|
|
1048
1038
|
resolver,
|
|
1049
1039
|
name,
|
|
1050
|
-
core.ext.deriveSessions(
|
|
1051
|
-
requireString(name, args, "dayStart"),
|
|
1052
|
-
requireString(name, args, "dayEnd"),
|
|
1053
|
-
input.mic,
|
|
1054
|
-
input.exchCode
|
|
1055
|
-
)
|
|
1040
|
+
core.ext.deriveSessions(input.dayStart, input.dayEnd, input.mic, input.exchCode)
|
|
1056
1041
|
);
|
|
1057
1042
|
case "get_market_rule":
|
|
1058
1043
|
return resultString(resolver, name, core.ext.getMarketRule(input.mic, input.exchCode));
|
|
1059
1044
|
case "infer_timezone":
|
|
1060
|
-
return resultString(
|
|
1061
|
-
resolver,
|
|
1062
|
-
name,
|
|
1063
|
-
core.ext.inferTimezone(requireString(name, args, "countryIso"))
|
|
1064
|
-
);
|
|
1045
|
+
return resultString(resolver, name, core.ext.inferTimezone(input.countryIso));
|
|
1065
1046
|
case "session_times_to_utc":
|
|
1066
1047
|
return resultString(
|
|
1067
1048
|
resolver,
|
|
1068
1049
|
name,
|
|
1069
1050
|
core.ext.sessionTimesToUtc(
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1051
|
+
input.startTime,
|
|
1052
|
+
input.endTime,
|
|
1053
|
+
input.exchangeTz,
|
|
1054
|
+
input.date
|
|
1074
1055
|
)
|
|
1075
1056
|
);
|
|
1076
1057
|
case "default_turnover_dates":
|
|
@@ -1086,11 +1067,7 @@ function extMarketSessionWithResolver(resolver) {
|
|
|
1086
1067
|
core.ext.defaultBqrDatetimes(input.startDatetime, input.endDatetime)
|
|
1087
1068
|
);
|
|
1088
1069
|
case "get_exchange_override":
|
|
1089
|
-
return resultString(
|
|
1090
|
-
resolver,
|
|
1091
|
-
name,
|
|
1092
|
-
core.ext.getExchangeOverride(requireString(name, args, "ticker"))
|
|
1093
|
-
);
|
|
1070
|
+
return resultString(resolver, name, core.ext.getExchangeOverride(input.ticker));
|
|
1094
1071
|
case "list_exchange_overrides":
|
|
1095
1072
|
return resultString(resolver, name, core.ext.listExchangeOverrides());
|
|
1096
1073
|
}
|
|
@@ -1142,45 +1119,23 @@ function extConstantsWithResolver(resolver) {
|
|
|
1142
1119
|
async (input) => {
|
|
1143
1120
|
try {
|
|
1144
1121
|
const core = await resolver.getCore();
|
|
1145
|
-
const args = asRecord(input);
|
|
1146
1122
|
switch (input.operation) {
|
|
1147
1123
|
case "parse_date":
|
|
1148
|
-
return resultString(
|
|
1149
|
-
resolver,
|
|
1150
|
-
name,
|
|
1151
|
-
core.ext.parseDate(requireString(name, args, "dateStr"))
|
|
1152
|
-
);
|
|
1124
|
+
return resultString(resolver, name, core.ext.parseDate(input.dateStr));
|
|
1153
1125
|
case "fmt_date":
|
|
1154
1126
|
return resultString(
|
|
1155
1127
|
resolver,
|
|
1156
1128
|
name,
|
|
1157
|
-
core.ext.fmtDate(
|
|
1158
|
-
requireInteger(name, args, "year"),
|
|
1159
|
-
requireInteger(name, args, "month"),
|
|
1160
|
-
requireInteger(name, args, "day"),
|
|
1161
|
-
input.fmt
|
|
1162
|
-
)
|
|
1129
|
+
core.ext.fmtDate(input.year, input.month, input.day, input.fmt)
|
|
1163
1130
|
);
|
|
1164
1131
|
case "get_month_code":
|
|
1165
|
-
return resultString(
|
|
1166
|
-
resolver,
|
|
1167
|
-
name,
|
|
1168
|
-
core.ext.getMonthCode(requireString(name, args, "monthName"))
|
|
1169
|
-
);
|
|
1132
|
+
return resultString(resolver, name, core.ext.getMonthCode(input.monthName));
|
|
1170
1133
|
case "get_month_name":
|
|
1171
|
-
return resultString(
|
|
1172
|
-
resolver,
|
|
1173
|
-
name,
|
|
1174
|
-
core.ext.getMonthName(requireString(name, args, "code"))
|
|
1175
|
-
);
|
|
1134
|
+
return resultString(resolver, name, core.ext.getMonthName(input.code));
|
|
1176
1135
|
case "get_futures_months":
|
|
1177
1136
|
return resultString(resolver, name, core.ext.getFuturesMonths());
|
|
1178
1137
|
case "get_dvd_type":
|
|
1179
|
-
return resultString(
|
|
1180
|
-
resolver,
|
|
1181
|
-
name,
|
|
1182
|
-
core.ext.getDvdType(requireString(name, args, "dvdType"))
|
|
1183
|
-
);
|
|
1138
|
+
return resultString(resolver, name, core.ext.getDvdType(input.dvdType));
|
|
1184
1139
|
case "get_dvd_types":
|
|
1185
1140
|
return resultString(resolver, name, core.ext.getDvdTypes());
|
|
1186
1141
|
case "get_dvd_cols":
|
|
@@ -1206,31 +1161,16 @@ function extColumnsWithResolver(resolver) {
|
|
|
1206
1161
|
async (input) => {
|
|
1207
1162
|
try {
|
|
1208
1163
|
const core = await resolver.getCore();
|
|
1209
|
-
const args = asRecord(input);
|
|
1210
1164
|
switch (input.operation) {
|
|
1211
1165
|
case "rename_dividend_columns":
|
|
1212
|
-
return resultString(
|
|
1213
|
-
resolver,
|
|
1214
|
-
name,
|
|
1215
|
-
core.ext.renameDividendColumns(requireStringArray(name, args, "columns"))
|
|
1216
|
-
);
|
|
1166
|
+
return resultString(resolver, name, core.ext.renameDividendColumns(input.columns));
|
|
1217
1167
|
case "rename_etf_columns":
|
|
1218
|
-
return resultString(
|
|
1219
|
-
resolver,
|
|
1220
|
-
name,
|
|
1221
|
-
core.ext.renameEtfColumns(requireStringArray(name, args, "columns"))
|
|
1222
|
-
);
|
|
1168
|
+
return resultString(resolver, name, core.ext.renameEtfColumns(input.columns));
|
|
1223
1169
|
case "build_earning_header_rename":
|
|
1224
|
-
if (input.headerRow === void 0) {
|
|
1225
|
-
throw new TypeError(`${name}: headerRow is required`);
|
|
1226
|
-
}
|
|
1227
1170
|
return resultString(
|
|
1228
1171
|
resolver,
|
|
1229
1172
|
name,
|
|
1230
|
-
core.ext.buildEarningHeaderRename(
|
|
1231
|
-
input.headerRow,
|
|
1232
|
-
requireStringArray(name, args, "dataColumns")
|
|
1233
|
-
)
|
|
1173
|
+
core.ext.buildEarningHeaderRename(input.headerRow, input.dataColumns)
|
|
1234
1174
|
);
|
|
1235
1175
|
}
|
|
1236
1176
|
} catch (error) {
|
|
@@ -1250,9 +1190,6 @@ function extCalculateWithResolver(resolver) {
|
|
|
1250
1190
|
return createBloombergStructuredTool(
|
|
1251
1191
|
async (input) => {
|
|
1252
1192
|
try {
|
|
1253
|
-
if (input.values.length !== input.levels.length) {
|
|
1254
|
-
throw new TypeError(`${name}: values and levels must have the same length`);
|
|
1255
|
-
}
|
|
1256
1193
|
const core = await resolver.getCore();
|
|
1257
1194
|
return resultString(
|
|
1258
1195
|
resolver,
|
|
@@ -1321,6 +1258,9 @@ var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/u;
|
|
|
1321
1258
|
var BBG_DATE_RE = /^\d{8}$/u;
|
|
1322
1259
|
var AMBIGUOUS_DATE_RE = /^\d{1,2}[-/]\d{1,2}[-/]\d{2,4}([T \D]|$)/u;
|
|
1323
1260
|
var ISO_DATE_TIME_RE = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?$/u;
|
|
1261
|
+
var MIN_NUMERIC_BBG_DATE = 19000101;
|
|
1262
|
+
var MAX_NUMERIC_BBG_DATE = 29991231;
|
|
1263
|
+
var MIN_EPOCH_MS = 1e11;
|
|
1324
1264
|
var primitiveSchema = z__namespace.union([
|
|
1325
1265
|
z__namespace.string().transform((value) => value.trim()),
|
|
1326
1266
|
z__namespace.number(),
|
|
@@ -1335,18 +1275,30 @@ function dateFromParts(year, month, day) {
|
|
|
1335
1275
|
return formatted;
|
|
1336
1276
|
}
|
|
1337
1277
|
function dateToBbg(value) {
|
|
1338
|
-
const
|
|
1339
|
-
if (Number.isNaN(
|
|
1278
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1279
|
+
if (Number.isNaN(date.getTime())) {
|
|
1340
1280
|
throw new TypeError("Invalid date value; expected YYYY-MM-DD, YYYYMMDD, Date, or epoch ms");
|
|
1341
1281
|
}
|
|
1342
|
-
const year = String(
|
|
1343
|
-
const month = String(
|
|
1344
|
-
const day = String(
|
|
1282
|
+
const year = String(date.getUTCFullYear()).padStart(4, "0");
|
|
1283
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
1284
|
+
const day = String(date.getUTCDate()).padStart(2, "0");
|
|
1345
1285
|
return `${year}${month}${day}`;
|
|
1346
1286
|
}
|
|
1287
|
+
function numericDateToBbg(value, unit) {
|
|
1288
|
+
if (Number.isFinite(value) && value >= MIN_EPOCH_MS) {
|
|
1289
|
+
return new Date(value);
|
|
1290
|
+
}
|
|
1291
|
+
throw new TypeError(
|
|
1292
|
+
`Ambiguous numeric ${unit} ${String(value)}; use "YYYY-MM-DD" text or epoch milliseconds`
|
|
1293
|
+
);
|
|
1294
|
+
}
|
|
1347
1295
|
function normalizeDate(value) {
|
|
1348
|
-
if (
|
|
1349
|
-
|
|
1296
|
+
if (typeof value === "number") {
|
|
1297
|
+
if (Number.isInteger(value) && value >= MIN_NUMERIC_BBG_DATE && value <= MAX_NUMERIC_BBG_DATE) {
|
|
1298
|
+
const text2 = String(value);
|
|
1299
|
+
return dateFromParts(text2.slice(0, 4), text2.slice(4, 6), text2.slice(6, 8));
|
|
1300
|
+
}
|
|
1301
|
+
return dateToBbg(numericDateToBbg(value, "date"));
|
|
1350
1302
|
}
|
|
1351
1303
|
const text = value.trim();
|
|
1352
1304
|
if (text.length === 0) {
|
|
@@ -1364,12 +1316,13 @@ function normalizeDate(value) {
|
|
|
1364
1316
|
throw new TypeError(`Invalid date ${JSON.stringify(text)}; use YYYY-MM-DD or YYYYMMDD`);
|
|
1365
1317
|
}
|
|
1366
1318
|
function normalizeDateTime(value) {
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1319
|
+
if (typeof value === "number") {
|
|
1320
|
+
if (Number.isInteger(value) && value >= MIN_NUMERIC_BBG_DATE && value <= MAX_NUMERIC_BBG_DATE) {
|
|
1321
|
+
throw new TypeError(
|
|
1322
|
+
`Invalid numeric datetime ${String(value)}; include an explicit time component such as "2024-01-02T09:30:00"`
|
|
1323
|
+
);
|
|
1371
1324
|
}
|
|
1372
|
-
return
|
|
1325
|
+
return numericDateToBbg(value, "datetime").toISOString();
|
|
1373
1326
|
}
|
|
1374
1327
|
const text = value.trim();
|
|
1375
1328
|
if (text.length === 0) {
|
|
@@ -1399,8 +1352,15 @@ function nonEmptyString2(tool2, field, maxChars, example) {
|
|
|
1399
1352
|
function stringArray2(tool2, field, maxItems, maxChars, example) {
|
|
1400
1353
|
return z__namespace.array(nonEmptyString2(tool2, field, maxChars, example)).min(1, `${tool2}: ${field} must contain at least one non-empty string. Example: ${example}`).max(maxItems, `${tool2}: ${field} can contain at most ${maxItems} values`);
|
|
1401
1354
|
}
|
|
1355
|
+
function normalizationIssue(context, tool2, field, error) {
|
|
1356
|
+
context.addIssue({
|
|
1357
|
+
code: "custom",
|
|
1358
|
+
message: `${tool2}: ${field}: ${error instanceof Error ? error.message : String(error)}`
|
|
1359
|
+
});
|
|
1360
|
+
return z__namespace.NEVER;
|
|
1361
|
+
}
|
|
1402
1362
|
function primitiveMap(tool2, field) {
|
|
1403
|
-
return z__namespace.record(z__namespace.string().min(1), primitiveSchema).optional().transform((value) => {
|
|
1363
|
+
return z__namespace.record(z__namespace.string().min(1), primitiveSchema).optional().transform((value, context) => {
|
|
1404
1364
|
if (value === void 0) {
|
|
1405
1365
|
return void 0;
|
|
1406
1366
|
}
|
|
@@ -1408,10 +1368,15 @@ function primitiveMap(tool2, field) {
|
|
|
1408
1368
|
for (const [key, entry] of Object.entries(value)) {
|
|
1409
1369
|
const normalizedKey = key.trim();
|
|
1410
1370
|
if (normalizedKey.length === 0) {
|
|
1411
|
-
|
|
1371
|
+
return normalizationIssue(context, tool2, field, new TypeError("contains an empty key"));
|
|
1412
1372
|
}
|
|
1413
1373
|
if (typeof entry === "string" && entry.length === 0) {
|
|
1414
|
-
|
|
1374
|
+
return normalizationIssue(
|
|
1375
|
+
context,
|
|
1376
|
+
tool2,
|
|
1377
|
+
field,
|
|
1378
|
+
new TypeError(`${normalizedKey} must not be an empty string`)
|
|
1379
|
+
);
|
|
1415
1380
|
}
|
|
1416
1381
|
normalized[normalizedKey] = entry;
|
|
1417
1382
|
}
|
|
@@ -1419,12 +1384,18 @@ function primitiveMap(tool2, field) {
|
|
|
1419
1384
|
});
|
|
1420
1385
|
}
|
|
1421
1386
|
function dateField(tool2, field) {
|
|
1422
|
-
return z__namespace.union([z__namespace.string(), z__namespace.
|
|
1387
|
+
return z__namespace.union([z__namespace.string(), z__namespace.number()]).transform((value, context) => {
|
|
1388
|
+
try {
|
|
1389
|
+
return normalizeDate(value);
|
|
1390
|
+
} catch (error) {
|
|
1391
|
+
return normalizationIssue(context, tool2, field, error);
|
|
1392
|
+
}
|
|
1393
|
+
}).describe(
|
|
1423
1394
|
`${field} date. Use YYYY-MM-DD or Bloomberg-native YYYYMMDD, never ambiguous MM/DD/YYYY.`
|
|
1424
1395
|
);
|
|
1425
1396
|
}
|
|
1426
1397
|
function dateTimeField(tool2, field) {
|
|
1427
|
-
return z__namespace.union([z__namespace.string(), z__namespace.
|
|
1398
|
+
return z__namespace.union([z__namespace.string(), z__namespace.number()]).superRefine((value, context) => {
|
|
1428
1399
|
if (typeof value !== "string") {
|
|
1429
1400
|
return;
|
|
1430
1401
|
}
|
|
@@ -1435,7 +1406,13 @@ function dateTimeField(tool2, field) {
|
|
|
1435
1406
|
message: `${tool2}: ${field} datetime requires an explicit time component; use ISO 8601 such as YYYY-MM-DDT09:30:00`
|
|
1436
1407
|
});
|
|
1437
1408
|
}
|
|
1438
|
-
}).transform((value) =>
|
|
1409
|
+
}).transform((value, context) => {
|
|
1410
|
+
try {
|
|
1411
|
+
return normalizeDateTime(value);
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
return normalizationIssue(context, tool2, field, error);
|
|
1414
|
+
}
|
|
1415
|
+
}).describe(`${field} datetime. Use ISO 8601 with an explicit time component.`);
|
|
1439
1416
|
}
|
|
1440
1417
|
function referenceFormat(tool2) {
|
|
1441
1418
|
return z__namespace.enum(REFERENCE_FORMATS, {
|
|
@@ -1478,7 +1455,7 @@ function createBdpSchema(options) {
|
|
|
1478
1455
|
options.maxStringChars,
|
|
1479
1456
|
'["<TICKER> <MARKET_SECTOR>"]'
|
|
1480
1457
|
).describe(
|
|
1481
|
-
"
|
|
1458
|
+
"Securities exactly as the user supplied them: '<TICKER> <MARKET_SECTOR>' for Bloomberg tickers, '/isin/<ISIN>' for raw ISINs, '/cusip/<CUSIP>' for raw CUSIPs. Never invent, guess, or convert identifiers into tickers."
|
|
1482
1459
|
),
|
|
1483
1460
|
validateFields: z__namespace.boolean().optional().describe("Override field validation for this request.")
|
|
1484
1461
|
});
|
|
@@ -1510,7 +1487,7 @@ function createBdhSchema(options) {
|
|
|
1510
1487
|
options.maxStringChars,
|
|
1511
1488
|
'["<TICKER> <MARKET_SECTOR>"]'
|
|
1512
1489
|
).describe(
|
|
1513
|
-
"
|
|
1490
|
+
"Securities exactly as the user supplied them: '<TICKER> <MARKET_SECTOR>' for Bloomberg tickers, '/isin/<ISIN>' for raw ISINs, '/cusip/<CUSIP>' for raw CUSIPs. Never invent, guess, or convert identifiers into tickers."
|
|
1514
1491
|
),
|
|
1515
1492
|
start: dateField(tool2, "start").describe("Required start date. Use YYYY-MM-DD or YYYYMMDD."),
|
|
1516
1493
|
validateFields: z__namespace.boolean().optional().describe("Override field validation for this request.")
|
|
@@ -1530,7 +1507,6 @@ function createBdsSchema(options) {
|
|
|
1530
1507
|
field: nonEmptyString2(tool2, "field", options.maxStringChars, "<BULK_FIELD>").describe(
|
|
1531
1508
|
"Exactly one Bloomberg bulk/table field supplied by the user."
|
|
1532
1509
|
),
|
|
1533
|
-
format: referenceFormat(tool2).describe("JSON output shape. Usually omit."),
|
|
1534
1510
|
kwargs: primitiveMap(tool2, "kwargs").describe(
|
|
1535
1511
|
"Advanced Bloomberg request kwargs as flat string/number/boolean values only."
|
|
1536
1512
|
),
|
|
@@ -1544,7 +1520,7 @@ function createBdsSchema(options) {
|
|
|
1544
1520
|
options.maxStringChars,
|
|
1545
1521
|
'["<INDEX_TICKER> <MARKET_SECTOR>"]'
|
|
1546
1522
|
).describe(
|
|
1547
|
-
"
|
|
1523
|
+
"Securities exactly as the user supplied them: '<TICKER> <MARKET_SECTOR>' for Bloomberg tickers, '/isin/<ISIN>' for raw ISINs, '/cusip/<CUSIP>' for raw CUSIPs. Never invent, guess, or convert identifiers into tickers."
|
|
1548
1524
|
),
|
|
1549
1525
|
validateFields: z__namespace.boolean().optional().describe("Override field validation for this request.")
|
|
1550
1526
|
});
|
|
@@ -1571,7 +1547,7 @@ function createBdibSchema(options) {
|
|
|
1571
1547
|
options.maxStringChars,
|
|
1572
1548
|
"<TICKER> <MARKET_SECTOR>"
|
|
1573
1549
|
).describe(
|
|
1574
|
-
"One
|
|
1550
|
+
"One security exactly as the user supplied it: '<TICKER> <MARKET_SECTOR>', '/isin/<ISIN>', or '/cusip/<CUSIP>'. Never invent, guess, or convert identifiers into tickers."
|
|
1575
1551
|
)
|
|
1576
1552
|
});
|
|
1577
1553
|
}
|
|
@@ -1610,14 +1586,13 @@ function createBdtickSchema(options) {
|
|
|
1610
1586
|
options.maxStringChars,
|
|
1611
1587
|
"<TICKER> <MARKET_SECTOR>"
|
|
1612
1588
|
).describe(
|
|
1613
|
-
"One
|
|
1589
|
+
"One security exactly as the user supplied it: '<TICKER> <MARKET_SECTOR>', '/isin/<ISIN>', or '/cusip/<CUSIP>'. Never invent, guess, or convert identifiers into tickers."
|
|
1614
1590
|
)
|
|
1615
1591
|
});
|
|
1616
1592
|
}
|
|
1617
1593
|
function createBqlSchema(options) {
|
|
1618
1594
|
const tool2 = "xbbg_bql";
|
|
1619
1595
|
return z__namespace.object({
|
|
1620
|
-
format: referenceFormat(tool2).describe("JSON output shape. Usually omit."),
|
|
1621
1596
|
kwargs: primitiveMap(tool2, "kwargs").describe(
|
|
1622
1597
|
"Advanced Bloomberg request kwargs as flat string/number/boolean values only."
|
|
1623
1598
|
),
|
|
@@ -1656,7 +1631,6 @@ function createBqrSchema(options) {
|
|
|
1656
1631
|
function createBsrchSchema(options) {
|
|
1657
1632
|
const tool2 = "xbbg_bsrch";
|
|
1658
1633
|
return z__namespace.object({
|
|
1659
|
-
format: referenceFormat(tool2).describe("JSON output shape. Usually omit."),
|
|
1660
1634
|
kwargs: primitiveMap(tool2, "kwargs").describe(
|
|
1661
1635
|
"Search-grid kwargs as flat string/number/boolean values only."
|
|
1662
1636
|
),
|
|
@@ -1679,7 +1653,6 @@ function createBfldsSchema(options) {
|
|
|
1679
1653
|
fields: stringArray2(tool2, "fields", options.maxFields, options.maxStringChars, '["<FIELD>"]').optional().describe(
|
|
1680
1654
|
"Specific field mnemonics to inspect. Provide either fields or searchSpec, not both."
|
|
1681
1655
|
),
|
|
1682
|
-
format: referenceFormat(tool2).describe("JSON output shape. Usually omit."),
|
|
1683
1656
|
kwargs: primitiveMap(tool2, "kwargs").describe(
|
|
1684
1657
|
"Advanced Bloomberg request kwargs as flat string/number/boolean values only."
|
|
1685
1658
|
),
|
|
@@ -1707,7 +1680,6 @@ function createBeqsSchema(options) {
|
|
|
1707
1680
|
const tool2 = "xbbg_beqs";
|
|
1708
1681
|
return z__namespace.object({
|
|
1709
1682
|
asof: dateField(tool2, "asof").optional().describe("Optional as-of date for the screen."),
|
|
1710
|
-
format: referenceFormat(tool2).describe("JSON output shape. Usually omit."),
|
|
1711
1683
|
group: nonEmptyString2(tool2, "group", options.maxStringChars, "<BEQS_GROUP>").optional().describe("Bloomberg BEQS group when required by the screen."),
|
|
1712
1684
|
kwargs: primitiveMap(tool2, "kwargs").describe(
|
|
1713
1685
|
"Advanced BEQS request kwargs as flat string/number/boolean values only."
|
|
@@ -1741,7 +1713,9 @@ function createYasSchema(options) {
|
|
|
1741
1713
|
options.maxSecurities,
|
|
1742
1714
|
options.maxStringChars,
|
|
1743
1715
|
'["/isin/<ISIN> <MARKET_SECTOR>"]'
|
|
1744
|
-
).describe(
|
|
1716
|
+
).describe(
|
|
1717
|
+
"Fixed-income securities exactly as the user supplied them: '<TICKER> <MARKET_SECTOR>' or identifier syntax such as '/isin/<ISIN> <MARKET_SECTOR>'. Never invent or guess tickers."
|
|
1718
|
+
),
|
|
1745
1719
|
yieldType: z__namespace.number().int().optional().describe("Optional YAS yield type."),
|
|
1746
1720
|
yieldVal: z__namespace.number().optional().describe("Optional YAS yield value input.")
|
|
1747
1721
|
});
|
|
@@ -1754,7 +1728,9 @@ function createPreferredsSchema(options) {
|
|
|
1754
1728
|
"equityTicker",
|
|
1755
1729
|
options.maxStringChars,
|
|
1756
1730
|
"<ISSUER_TICKER> <MARKET_SECTOR>"
|
|
1757
|
-
).describe(
|
|
1731
|
+
).describe(
|
|
1732
|
+
"The issuer's common equity ticker as '<TICKER> <MARKET_SECTOR>', never a preferred ('Pfd') ticker and never a guessed one. Resolve a supplied ISIN/CUSIP with xbbg_resolve_isins first."
|
|
1733
|
+
),
|
|
1758
1734
|
fields: stringArray2(tool2, "fields", options.maxFields, options.maxStringChars, '["<FIELD>"]').optional().describe("Optional fields to include in the preferreds recipe result.")
|
|
1759
1735
|
});
|
|
1760
1736
|
}
|
|
@@ -1769,7 +1745,9 @@ function createCorporateBondsSchema(options) {
|
|
|
1769
1745
|
"ticker",
|
|
1770
1746
|
options.maxStringChars,
|
|
1771
1747
|
"<ISSUER_TICKER> <MARKET_SECTOR>"
|
|
1772
|
-
).describe(
|
|
1748
|
+
).describe(
|
|
1749
|
+
"The issuer/company equity ticker as '<TICKER> <MARKET_SECTOR>' supplied by the user. Resolve a supplied ISIN/CUSIP with xbbg_resolve_isins first; never guess tickers."
|
|
1750
|
+
)
|
|
1773
1751
|
});
|
|
1774
1752
|
}
|
|
1775
1753
|
function createIndexMembersSchema(options) {
|
|
@@ -1782,7 +1760,9 @@ function createIndexMembersSchema(options) {
|
|
|
1782
1760
|
"index",
|
|
1783
1761
|
options.maxStringChars,
|
|
1784
1762
|
"<INDEX_TICKER> <MARKET_SECTOR>"
|
|
1785
|
-
).describe(
|
|
1763
|
+
).describe(
|
|
1764
|
+
"One Bloomberg index ticker as '<INDEX_TICKER> <MARKET_SECTOR>' supplied by the user; never guess index tickers."
|
|
1765
|
+
)
|
|
1786
1766
|
});
|
|
1787
1767
|
}
|
|
1788
1768
|
function createResolveIsinsSchema(options) {
|
|
@@ -1817,7 +1797,9 @@ function createEtfHoldingsSchema(options) {
|
|
|
1817
1797
|
"etfTicker",
|
|
1818
1798
|
options.maxStringChars,
|
|
1819
1799
|
"<ETF_TICKER> <MARKET_SECTOR>"
|
|
1820
|
-
).describe(
|
|
1800
|
+
).describe(
|
|
1801
|
+
"One Bloomberg ETF ticker as '<ETF_TICKER> <MARKET_SECTOR>' supplied by the user. Resolve a supplied ISIN/CUSIP with xbbg_resolve_isins first; never guess tickers."
|
|
1802
|
+
),
|
|
1821
1803
|
fields: stringArray2(tool2, "fields", options.maxFields, options.maxStringChars, '["<FIELD>"]').optional().describe("Optional fields to include in the ETF holdings recipe result.")
|
|
1822
1804
|
});
|
|
1823
1805
|
}
|
|
@@ -1826,7 +1808,7 @@ function snapshotControlFields(tool2, options) {
|
|
|
1826
1808
|
allFields: z__namespace.boolean().optional().describe("Request all Bloomberg fields when supported."),
|
|
1827
1809
|
conflate: z__namespace.boolean().optional().describe("Enable Bloomberg conflated streaming when supported."),
|
|
1828
1810
|
drain: z__namespace.boolean().optional().describe(
|
|
1829
|
-
"
|
|
1811
|
+
"Flush buffered backlog while closing the subscription. The subscription always closes; collected output stays bounded either way. Defaults to false."
|
|
1830
1812
|
),
|
|
1831
1813
|
flushThreshold: z__namespace.number().int().positive().optional().describe("Optional stream flush threshold."),
|
|
1832
1814
|
maxUpdates: z__namespace.number().int(`${tool2}: maxUpdates must be a positive integer.`).positive(`${tool2}: maxUpdates must be greater than zero.`).max(
|
|
@@ -1861,7 +1843,9 @@ function createStreamSnapshotSchema(options) {
|
|
|
1861
1843
|
options.maxSecurities,
|
|
1862
1844
|
options.maxStringChars,
|
|
1863
1845
|
'["<TICKER> <MARKET_SECTOR>"]'
|
|
1864
|
-
).describe(
|
|
1846
|
+
).describe(
|
|
1847
|
+
"Securities to observe, exactly as the user supplied them: '<TICKER> <MARKET_SECTOR>', '/isin/<ISIN>', or '/cusip/<CUSIP>'. Never invent or guess tickers."
|
|
1848
|
+
),
|
|
1865
1849
|
...snapshotControlFields(tool2, options)
|
|
1866
1850
|
});
|
|
1867
1851
|
}
|
|
@@ -1874,7 +1858,9 @@ function createMktbarSnapshotSchema(options) {
|
|
|
1874
1858
|
"ticker",
|
|
1875
1859
|
options.maxStringChars,
|
|
1876
1860
|
"<TICKER> <MARKET_SECTOR>"
|
|
1877
|
-
).describe(
|
|
1861
|
+
).describe(
|
|
1862
|
+
"One security to observe, exactly as the user supplied it: '<TICKER> <MARKET_SECTOR>', '/isin/<ISIN>', or '/cusip/<CUSIP>'. Never invent or guess tickers."
|
|
1863
|
+
),
|
|
1878
1864
|
...snapshotControlFields(tool2, options)
|
|
1879
1865
|
});
|
|
1880
1866
|
}
|
|
@@ -1887,7 +1873,9 @@ function createDepthSnapshotSchema(options) {
|
|
|
1887
1873
|
"ticker",
|
|
1888
1874
|
options.maxStringChars,
|
|
1889
1875
|
"<TICKER> <MARKET_SECTOR>"
|
|
1890
|
-
).describe(
|
|
1876
|
+
).describe(
|
|
1877
|
+
"One security to observe, exactly as the user supplied it: '<TICKER> <MARKET_SECTOR>', '/isin/<ISIN>', or '/cusip/<CUSIP>'. Never invent or guess tickers."
|
|
1878
|
+
),
|
|
1891
1879
|
...snapshotControlFields(tool2, options)
|
|
1892
1880
|
});
|
|
1893
1881
|
}
|
|
@@ -1897,17 +1885,24 @@ function resultString2(resolver, name, value) {
|
|
|
1897
1885
|
return createToolResult(name, value, resolver.options.maxRows, resolver.options.maxStringChars);
|
|
1898
1886
|
}
|
|
1899
1887
|
var STREAM_TIMEOUT = /* @__PURE__ */ Symbol("stream_timeout");
|
|
1888
|
+
var STREAM_ABORTED = /* @__PURE__ */ Symbol("stream_aborted");
|
|
1889
|
+
function abortError(signal) {
|
|
1890
|
+
const reason = signal?.reason;
|
|
1891
|
+
return reason instanceof Error ? reason : new Error("Tool call aborted");
|
|
1892
|
+
}
|
|
1900
1893
|
function streamOptions(input) {
|
|
1901
1894
|
return {
|
|
1902
1895
|
allFields: input.allFields,
|
|
1903
1896
|
conflate: input.conflate,
|
|
1904
|
-
fields: input.fields,
|
|
1905
1897
|
flushThreshold: input.flushThreshold,
|
|
1906
1898
|
options: input.options,
|
|
1907
1899
|
overflowPolicy: input.overflowPolicy,
|
|
1908
1900
|
streamCapacity: input.streamCapacity
|
|
1909
1901
|
};
|
|
1910
1902
|
}
|
|
1903
|
+
function singleTickerStreamOptions(input) {
|
|
1904
|
+
return { ...streamOptions(input), fields: input.fields };
|
|
1905
|
+
}
|
|
1911
1906
|
function isRecord(value) {
|
|
1912
1907
|
return typeof value === "object" && value !== null;
|
|
1913
1908
|
}
|
|
@@ -1963,42 +1958,55 @@ function normalizeStreamUpdate(value) {
|
|
|
1963
1958
|
const rows = rowsFromArrowTable(value);
|
|
1964
1959
|
return rows === void 0 ? jsonCompatible(value) : rows.map(jsonCompatible);
|
|
1965
1960
|
}
|
|
1966
|
-
async function nextWithinTimeout(iterator, deadlineMs) {
|
|
1961
|
+
async function nextWithinTimeout(iterator, deadlineMs, signal) {
|
|
1962
|
+
if (signal?.aborted === true) {
|
|
1963
|
+
return STREAM_ABORTED;
|
|
1964
|
+
}
|
|
1967
1965
|
const remainingMs = deadlineMs - Date.now();
|
|
1968
1966
|
if (remainingMs <= 0) {
|
|
1969
1967
|
return STREAM_TIMEOUT;
|
|
1970
1968
|
}
|
|
1971
1969
|
const nextPromise = iterator.next();
|
|
1972
1970
|
let timer;
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1971
|
+
let onAbort;
|
|
1972
|
+
const racers = [
|
|
1973
|
+
nextPromise,
|
|
1974
|
+
new Promise((resolve) => {
|
|
1975
|
+
timer = setTimeout(() => resolve(STREAM_TIMEOUT), remainingMs);
|
|
1976
|
+
})
|
|
1977
|
+
];
|
|
1978
|
+
if (signal !== void 0) {
|
|
1979
|
+
racers.push(
|
|
1980
|
+
new Promise((resolve) => {
|
|
1981
|
+
onAbort = () => resolve(STREAM_ABORTED);
|
|
1982
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1983
|
+
})
|
|
1984
|
+
);
|
|
1985
|
+
}
|
|
1986
|
+
const result = await Promise.race(racers);
|
|
1977
1987
|
if (timer !== void 0) {
|
|
1978
1988
|
clearTimeout(timer);
|
|
1979
1989
|
}
|
|
1980
|
-
if (
|
|
1990
|
+
if (signal !== void 0 && onAbort !== void 0) {
|
|
1991
|
+
signal.removeEventListener("abort", onAbort);
|
|
1992
|
+
}
|
|
1993
|
+
if (result === STREAM_TIMEOUT || result === STREAM_ABORTED) {
|
|
1981
1994
|
void nextPromise.catch(() => void 0);
|
|
1982
1995
|
}
|
|
1983
1996
|
return result;
|
|
1984
1997
|
}
|
|
1985
|
-
async function
|
|
1986
|
-
try {
|
|
1987
|
-
await subscription.unsubscribe(drain);
|
|
1988
|
-
} catch (error) {
|
|
1989
|
-
if (priorError === void 0) {
|
|
1990
|
-
throw error;
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
async function collectSnapshot(subscription, input) {
|
|
1998
|
+
async function collectSnapshot(subscription, input, signal) {
|
|
1995
1999
|
const updates = [];
|
|
1996
2000
|
const deadlineMs = Date.now() + input.timeoutMs;
|
|
1997
2001
|
let reason = "max_updates";
|
|
2002
|
+
let failed = false;
|
|
1998
2003
|
let caught;
|
|
1999
2004
|
try {
|
|
2000
2005
|
while (updates.length < input.maxUpdates) {
|
|
2001
|
-
const next = await nextWithinTimeout(subscription, deadlineMs);
|
|
2006
|
+
const next = await nextWithinTimeout(subscription, deadlineMs, signal);
|
|
2007
|
+
if (next === STREAM_ABORTED) {
|
|
2008
|
+
throw abortError(signal);
|
|
2009
|
+
}
|
|
2002
2010
|
if (next === STREAM_TIMEOUT) {
|
|
2003
2011
|
reason = "timeout";
|
|
2004
2012
|
break;
|
|
@@ -2009,26 +2017,34 @@ async function collectSnapshot(subscription, input) {
|
|
|
2009
2017
|
}
|
|
2010
2018
|
updates.push(normalizeStreamUpdate(next.value));
|
|
2011
2019
|
}
|
|
2012
|
-
return {
|
|
2013
|
-
maxUpdates: input.maxUpdates,
|
|
2014
|
-
reason,
|
|
2015
|
-
timeoutMs: input.timeoutMs,
|
|
2016
|
-
updateCount: updates.length,
|
|
2017
|
-
updates
|
|
2018
|
-
};
|
|
2019
2020
|
} catch (error) {
|
|
2021
|
+
failed = true;
|
|
2020
2022
|
caught = error;
|
|
2021
|
-
throw error;
|
|
2022
|
-
} finally {
|
|
2023
|
-
await unsubscribeSnapshot(subscription, input.drain === true, caught);
|
|
2024
2023
|
}
|
|
2024
|
+
const drain = input.drain === true && signal?.aborted !== true;
|
|
2025
|
+
let unsubscribeError;
|
|
2026
|
+
try {
|
|
2027
|
+
await subscription.unsubscribe(drain);
|
|
2028
|
+
} catch (error) {
|
|
2029
|
+
if (!failed) {
|
|
2030
|
+
unsubscribeError = error instanceof Error ? error.message : String(error);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (failed) {
|
|
2034
|
+
throw caught;
|
|
2035
|
+
}
|
|
2036
|
+
return {
|
|
2037
|
+
maxUpdates: input.maxUpdates,
|
|
2038
|
+
reason,
|
|
2039
|
+
timeoutMs: input.timeoutMs,
|
|
2040
|
+
updateCount: updates.length,
|
|
2041
|
+
updates,
|
|
2042
|
+
...unsubscribeError === void 0 ? {} : { unsubscribeError }
|
|
2043
|
+
};
|
|
2025
2044
|
}
|
|
2026
2045
|
function validationSetting(resolver, value) {
|
|
2027
2046
|
return value ?? resolver.options.validateFields;
|
|
2028
2047
|
}
|
|
2029
|
-
function enabledTool(resolver, name, creator) {
|
|
2030
|
-
return isToolDisabled(resolver.options, name) ? [] : [creator(resolver)];
|
|
2031
|
-
}
|
|
2032
2048
|
function bdpWithResolver(resolver) {
|
|
2033
2049
|
const name = "xbbg_bdp";
|
|
2034
2050
|
return createBloombergStructuredTool(
|
|
@@ -2092,7 +2108,6 @@ function bdsWithResolver(resolver) {
|
|
|
2092
2108
|
const engine = await resolver.getEngine();
|
|
2093
2109
|
const result = await engine.bds(input.securities, [input.field], {
|
|
2094
2110
|
backend: "json",
|
|
2095
|
-
format: input.format,
|
|
2096
2111
|
kwargs: input.kwargs,
|
|
2097
2112
|
overrides: input.overrides,
|
|
2098
2113
|
validateFields: validationSetting(resolver, input.validateFields)
|
|
@@ -2182,7 +2197,6 @@ function bqlWithResolver(resolver) {
|
|
|
2182
2197
|
const engine = await resolver.getEngine();
|
|
2183
2198
|
const result = await engine.bql(input.query, {
|
|
2184
2199
|
backend: "json",
|
|
2185
|
-
format: input.format,
|
|
2186
2200
|
kwargs: input.kwargs
|
|
2187
2201
|
});
|
|
2188
2202
|
return resultString2(resolver, name, result);
|
|
@@ -2206,7 +2220,6 @@ function bsrchWithResolver(resolver) {
|
|
|
2206
2220
|
const engine = await resolver.getEngine();
|
|
2207
2221
|
const result = await engine.bsrch(input.searchSpec, {
|
|
2208
2222
|
backend: "json",
|
|
2209
|
-
format: input.format,
|
|
2210
2223
|
kwargs: input.kwargs,
|
|
2211
2224
|
overrides: input.overrides
|
|
2212
2225
|
});
|
|
@@ -2258,7 +2271,6 @@ function bfldsWithResolver(resolver) {
|
|
|
2258
2271
|
const result = await engine.bflds({
|
|
2259
2272
|
backend: "json",
|
|
2260
2273
|
fields: input.fields,
|
|
2261
|
-
format: input.format,
|
|
2262
2274
|
kwargs: input.kwargs,
|
|
2263
2275
|
searchSpec: input.searchSpec
|
|
2264
2276
|
});
|
|
@@ -2284,7 +2296,6 @@ function beqsWithResolver(resolver) {
|
|
|
2284
2296
|
const result = await engine.beqs(input.screen, {
|
|
2285
2297
|
asof: input.asof,
|
|
2286
2298
|
backend: "json",
|
|
2287
|
-
format: input.format,
|
|
2288
2299
|
group: input.group,
|
|
2289
2300
|
kwargs: input.kwargs,
|
|
2290
2301
|
overrides: input.overrides,
|
|
@@ -2469,11 +2480,13 @@ function etfHoldingsWithResolver(resolver) {
|
|
|
2469
2480
|
function streamSnapshotWithResolver(resolver) {
|
|
2470
2481
|
const name = "xbbg_stream_snapshot";
|
|
2471
2482
|
return createBloombergStructuredTool(
|
|
2472
|
-
async (input) => {
|
|
2483
|
+
async (input, config) => {
|
|
2484
|
+
const signal = config?.signal;
|
|
2473
2485
|
try {
|
|
2474
2486
|
const engine = await resolver.getEngine();
|
|
2487
|
+
signal?.throwIfAborted();
|
|
2475
2488
|
const subscription = await engine.stream(input.tickers, input.fields, streamOptions(input));
|
|
2476
|
-
const result = await collectSnapshot(subscription, input);
|
|
2489
|
+
const result = await collectSnapshot(subscription, input, signal);
|
|
2477
2490
|
return resultString2(resolver, name, result);
|
|
2478
2491
|
} catch (error) {
|
|
2479
2492
|
throwWithToolContext(name, error);
|
|
@@ -2490,11 +2503,13 @@ function streamSnapshotWithResolver(resolver) {
|
|
|
2490
2503
|
function mktbarSnapshotWithResolver(resolver) {
|
|
2491
2504
|
const name = "xbbg_mktbar_snapshot";
|
|
2492
2505
|
return createBloombergStructuredTool(
|
|
2493
|
-
async (input) => {
|
|
2506
|
+
async (input, config) => {
|
|
2507
|
+
const signal = config?.signal;
|
|
2494
2508
|
try {
|
|
2495
2509
|
const engine = await resolver.getEngine();
|
|
2496
|
-
|
|
2497
|
-
const
|
|
2510
|
+
signal?.throwIfAborted();
|
|
2511
|
+
const subscription = await engine.mktbar(input.ticker, singleTickerStreamOptions(input));
|
|
2512
|
+
const result = await collectSnapshot(subscription, input, signal);
|
|
2498
2513
|
return resultString2(resolver, name, result);
|
|
2499
2514
|
} catch (error) {
|
|
2500
2515
|
throwWithToolContext(name, error);
|
|
@@ -2511,11 +2526,13 @@ function mktbarSnapshotWithResolver(resolver) {
|
|
|
2511
2526
|
function depthSnapshotWithResolver(resolver) {
|
|
2512
2527
|
const name = "xbbg_depth_snapshot";
|
|
2513
2528
|
return createBloombergStructuredTool(
|
|
2514
|
-
async (input) => {
|
|
2529
|
+
async (input, config) => {
|
|
2530
|
+
const signal = config?.signal;
|
|
2515
2531
|
try {
|
|
2516
2532
|
const engine = await resolver.getEngine();
|
|
2517
|
-
|
|
2518
|
-
const
|
|
2533
|
+
signal?.throwIfAborted();
|
|
2534
|
+
const subscription = await engine.depth(input.ticker, singleTickerStreamOptions(input));
|
|
2535
|
+
const result = await collectSnapshot(subscription, input, signal);
|
|
2519
2536
|
return resultString2(resolver, name, result);
|
|
2520
2537
|
} catch (error) {
|
|
2521
2538
|
throwWithToolContext(name, error);
|
|
@@ -2589,29 +2606,32 @@ function createMktbarSnapshotTool(options = {}) {
|
|
|
2589
2606
|
function createDepthSnapshotTool(options = {}) {
|
|
2590
2607
|
return depthSnapshotWithResolver(createCoreResolver(options));
|
|
2591
2608
|
}
|
|
2609
|
+
var CORE_TOOL_DEFINITIONS = Object.freeze([
|
|
2610
|
+
{ create: bdpWithResolver, name: "xbbg_bdp" },
|
|
2611
|
+
{ create: bdhWithResolver, name: "xbbg_bdh" },
|
|
2612
|
+
{ create: bdsWithResolver, name: "xbbg_bds" },
|
|
2613
|
+
{ create: bdibWithResolver, name: "xbbg_bdib" },
|
|
2614
|
+
{ create: bdtickWithResolver, name: "xbbg_bdtick" },
|
|
2615
|
+
{ create: bqlWithResolver, name: "xbbg_bql" },
|
|
2616
|
+
{ create: bsrchWithResolver, name: "xbbg_bsrch" },
|
|
2617
|
+
{ create: bqrWithResolver, name: "xbbg_bqr" },
|
|
2618
|
+
{ create: bfldsWithResolver, name: "xbbg_bflds" },
|
|
2619
|
+
{ create: beqsWithResolver, name: "xbbg_beqs" },
|
|
2620
|
+
{ create: yasWithResolver, name: "xbbg_yas" },
|
|
2621
|
+
{ create: preferredsWithResolver, name: "xbbg_preferreds" },
|
|
2622
|
+
{ create: corporateBondsWithResolver, name: "xbbg_corporate_bonds" },
|
|
2623
|
+
{ create: indexMembersWithResolver, name: "xbbg_index_members" },
|
|
2624
|
+
{ create: resolveIsinsWithResolver, name: "xbbg_resolve_isins" },
|
|
2625
|
+
{ create: issuerIsinsWithResolver, name: "xbbg_issuer_isins" },
|
|
2626
|
+
{ create: etfHoldingsWithResolver, name: "xbbg_etf_holdings" },
|
|
2627
|
+
{ create: streamSnapshotWithResolver, name: "xbbg_stream_snapshot" },
|
|
2628
|
+
{ create: mktbarSnapshotWithResolver, name: "xbbg_mktbar_snapshot" },
|
|
2629
|
+
{ create: depthSnapshotWithResolver, name: "xbbg_depth_snapshot" }
|
|
2630
|
+
]);
|
|
2592
2631
|
function createBloombergToolsForResolver(resolver) {
|
|
2593
|
-
return
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
...enabledTool(resolver, "xbbg_bds", bdsWithResolver),
|
|
2597
|
-
...enabledTool(resolver, "xbbg_bdib", bdibWithResolver),
|
|
2598
|
-
...enabledTool(resolver, "xbbg_bdtick", bdtickWithResolver),
|
|
2599
|
-
...enabledTool(resolver, "xbbg_bql", bqlWithResolver),
|
|
2600
|
-
...enabledTool(resolver, "xbbg_bsrch", bsrchWithResolver),
|
|
2601
|
-
...enabledTool(resolver, "xbbg_bqr", bqrWithResolver),
|
|
2602
|
-
...enabledTool(resolver, "xbbg_bflds", bfldsWithResolver),
|
|
2603
|
-
...enabledTool(resolver, "xbbg_beqs", beqsWithResolver),
|
|
2604
|
-
...enabledTool(resolver, "xbbg_yas", yasWithResolver),
|
|
2605
|
-
...enabledTool(resolver, "xbbg_preferreds", preferredsWithResolver),
|
|
2606
|
-
...enabledTool(resolver, "xbbg_corporate_bonds", corporateBondsWithResolver),
|
|
2607
|
-
...enabledTool(resolver, "xbbg_index_members", indexMembersWithResolver),
|
|
2608
|
-
...enabledTool(resolver, "xbbg_resolve_isins", resolveIsinsWithResolver),
|
|
2609
|
-
...enabledTool(resolver, "xbbg_issuer_isins", issuerIsinsWithResolver),
|
|
2610
|
-
...enabledTool(resolver, "xbbg_etf_holdings", etfHoldingsWithResolver),
|
|
2611
|
-
...enabledTool(resolver, "xbbg_stream_snapshot", streamSnapshotWithResolver),
|
|
2612
|
-
...enabledTool(resolver, "xbbg_mktbar_snapshot", mktbarSnapshotWithResolver),
|
|
2613
|
-
...enabledTool(resolver, "xbbg_depth_snapshot", depthSnapshotWithResolver)
|
|
2614
|
-
];
|
|
2632
|
+
return CORE_TOOL_DEFINITIONS.filter(
|
|
2633
|
+
(definition) => !isToolDisabled(resolver.options, definition.name)
|
|
2634
|
+
).map((definition) => definition.create(resolver));
|
|
2615
2635
|
}
|
|
2616
2636
|
function createBloombergTools(options = {}) {
|
|
2617
2637
|
return createBloombergToolsForResolver(createCoreResolver(options));
|
|
@@ -2629,6 +2649,7 @@ function createAllBloombergTools(options = {}) {
|
|
|
2629
2649
|
exports.BLOOMBERG_EXT_TOOL_NAMES = BLOOMBERG_EXT_TOOL_NAMES;
|
|
2630
2650
|
exports.BLOOMBERG_TOOL_INSTRUCTIONS = BLOOMBERG_TOOL_INSTRUCTIONS;
|
|
2631
2651
|
exports.BLOOMBERG_TOOL_NAMES = BLOOMBERG_TOOL_NAMES;
|
|
2652
|
+
exports.DEFAULT_ENGINE_REQUEST_TIMEOUT_MS = DEFAULT_ENGINE_REQUEST_TIMEOUT_MS;
|
|
2632
2653
|
exports.createAllBloombergTools = createAllBloombergTools;
|
|
2633
2654
|
exports.createBdhTool = createBdhTool;
|
|
2634
2655
|
exports.createBdibTool = createBdibTool;
|
|
@@ -2663,5 +2684,6 @@ exports.createResolveIsinsTool = createResolveIsinsTool;
|
|
|
2663
2684
|
exports.createStreamSnapshotTool = createStreamSnapshotTool;
|
|
2664
2685
|
exports.createYasTool = createYasTool;
|
|
2665
2686
|
exports.getBloombergToolInstructions = getBloombergToolInstructions;
|
|
2687
|
+
exports.toolParameterJsonSchema = toolParameterJsonSchema;
|
|
2666
2688
|
//# sourceMappingURL=index.js.map
|
|
2667
2689
|
//# sourceMappingURL=index.js.map
|