kensho-kfinance 1.2.2__py3-none-any.whl → 2.0.1__py3-none-any.whl

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.

Potentially problematic release.


This version of kensho-kfinance might be problematic. Click here for more details.

Files changed (35) hide show
  1. {kensho_kfinance-1.2.2.dist-info → kensho_kfinance-2.0.1.dist-info}/METADATA +5 -3
  2. kensho_kfinance-2.0.1.dist-info/RECORD +40 -0
  3. {kensho_kfinance-1.2.2.dist-info → kensho_kfinance-2.0.1.dist-info}/WHEEL +1 -1
  4. kfinance/CHANGELOG.md +6 -0
  5. kfinance/constants.py +40 -8
  6. kfinance/fetch.py +15 -9
  7. kfinance/kfinance.py +128 -38
  8. kfinance/meta_classes.py +3 -9
  9. kfinance/tests/test_fetch.py +7 -6
  10. kfinance/tests/test_tools.py +430 -0
  11. kfinance/tool_calling/README.md +38 -0
  12. kfinance/tool_calling/__init__.py +47 -0
  13. kfinance/tool_calling/get_business_relationship_from_identifier.py +28 -0
  14. kfinance/tool_calling/get_capitalization_from_identifier.py +35 -0
  15. kfinance/tool_calling/get_company_id_from_identifier.py +14 -0
  16. kfinance/tool_calling/get_cusip_from_ticker.py +18 -0
  17. kfinance/tool_calling/get_earnings_call_datetimes_from_identifier.py +17 -0
  18. kfinance/tool_calling/get_financial_line_item_from_identifier.py +45 -0
  19. kfinance/tool_calling/get_financial_statement_from_identifier.py +41 -0
  20. kfinance/tool_calling/get_history_metadata_from_identifier.py +15 -0
  21. kfinance/tool_calling/get_info_from_identifier.py +14 -0
  22. kfinance/tool_calling/get_isin_from_ticker.py +18 -0
  23. kfinance/tool_calling/get_latest.py +21 -0
  24. kfinance/tool_calling/get_n_quarters_ago.py +21 -0
  25. kfinance/tool_calling/get_prices_from_identifier.py +44 -0
  26. kfinance/tool_calling/get_security_id_from_identifier.py +14 -0
  27. kfinance/tool_calling/get_trading_item_id_from_identifier.py +14 -0
  28. kfinance/tool_calling/shared_models.py +53 -0
  29. kfinance/version.py +2 -2
  30. kensho_kfinance-1.2.2.dist-info/RECORD +0 -23
  31. kfinance/llm_tools.py +0 -747
  32. kfinance/tool_schemas.py +0 -148
  33. {kensho_kfinance-1.2.2.dist-info → kensho_kfinance-2.0.1.dist-info}/licenses/AUTHORS.md +0 -0
  34. {kensho_kfinance-1.2.2.dist-info → kensho_kfinance-2.0.1.dist-info}/licenses/LICENSE +0 -0
  35. {kensho_kfinance-1.2.2.dist-info → kensho_kfinance-2.0.1.dist-info}/top_level.txt +0 -0
kfinance/llm_tools.py DELETED
@@ -1,747 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import copy
4
- import datetime
5
- from enum import Enum
6
- from functools import partial
7
- from typing import TYPE_CHECKING, Callable, Literal
8
-
9
- from langchain_core.tools import StructuredTool
10
-
11
- from . import tool_schemas
12
- from .constants import (
13
- LINE_ITEM_NAMES_AND_ALIASES,
14
- BusinessRelationshipType,
15
- HistoryMetadata,
16
- LatestPeriods,
17
- YearAndQuarter,
18
- )
19
-
20
-
21
- if TYPE_CHECKING:
22
- from .kfinance import BusinessRelationships, Client
23
-
24
-
25
- class Model(Enum):
26
- """Enum with values ANTHROPIC, GEMINI, OPENAI"""
27
-
28
- ANTHROPIC = 1
29
- GEMINI = 2
30
- OPENAI = 3
31
-
32
-
33
- def get_latest(use_local_timezone: bool = True) -> LatestPeriods:
34
- """Get the latest annual reporting year, latest quarterly reporting quarter and year, and current date.
35
-
36
- The output is a dictionary with the following schema::
37
-
38
- {
39
- "annual": {
40
- "latest_year": int
41
- },
42
- "quarterly": {
43
- "latest_quarter": int,
44
- "latest_year": int
45
- },
46
- "now": {
47
- "current_year": int,
48
- "current_quarter": int,
49
- "current_month": int,
50
- "current_date": str # in format Y-m-d
51
- }
52
- }
53
-
54
- Args:
55
- use_local_timezone: whether to use the local timezone of the user
56
- """
57
- datetime_now = (
58
- datetime.datetime.now()
59
- if use_local_timezone
60
- else datetime.datetime.now(datetime.timezone.utc)
61
- )
62
-
63
- current_year = datetime_now.year
64
- current_qtr = (datetime_now.month - 1) // 3 + 1
65
- # Quarterly data most recent year and quarter
66
- if current_qtr == 1:
67
- most_recent_year_qtrly = current_year - 1
68
- most_recent_qtr = 4
69
- else:
70
- most_recent_year_qtrly = current_year
71
- most_recent_qtr = current_qtr - 1
72
-
73
- # Annual data most recent year
74
- most_recent_year_annual = current_year - 1
75
-
76
- current_month = datetime_now.month
77
- latest: LatestPeriods = {
78
- "annual": {"latest_year": most_recent_year_annual},
79
- "quarterly": {"latest_quarter": most_recent_qtr, "latest_year": most_recent_year_qtrly},
80
- "now": {
81
- "current_year": current_year,
82
- "current_quarter": current_qtr,
83
- "current_month": current_month,
84
- "current_date": datetime_now.strftime("%Y-%m-%d"),
85
- },
86
- }
87
- return latest
88
-
89
-
90
- def get_n_quarters_ago(n: int) -> YearAndQuarter:
91
- """Get the year and quarter corresponding to [n] quarters before the current quarter.
92
-
93
- The output is a dictionary with the following schema::
94
-
95
- {
96
- "year": int,
97
- "quarter": int
98
- }
99
-
100
- Args:
101
- n: number of quarters before the current quarter
102
- """
103
- datetime_now = datetime.datetime.now()
104
- current_qtr = (datetime_now.month - 1) // 3 + 1
105
- total_quarters_completed = datetime_now.year * 4 + current_qtr - 1
106
- total_quarters_completed_n_quarters_ago = total_quarters_completed - n
107
-
108
- year_n_quarters_ago = total_quarters_completed_n_quarters_ago // 4
109
- quarter_n_quarters_ago = total_quarters_completed_n_quarters_ago % 4 + 1
110
-
111
- year_quarter_n_quarters_ago: YearAndQuarter = {
112
- "year": year_n_quarters_ago,
113
- "quarter": quarter_n_quarters_ago,
114
- }
115
-
116
- return year_quarter_n_quarters_ago
117
-
118
-
119
- def get_company_id_from_identifier(self: Client, identifier: str) -> int:
120
- """Get the company id associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
121
-
122
- Args:
123
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
124
- """
125
- return self.ticker(identifier).company_id
126
-
127
-
128
- def get_security_id_from_identifier(self: Client, identifier: str) -> int:
129
- """Get the security id associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
130
-
131
- Args:
132
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
133
- """
134
- return self.ticker(identifier).security_id
135
-
136
-
137
- def get_trading_item_id_from_identifier(self: Client, identifier: str) -> int:
138
- """Get the trading item id associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
139
-
140
- Args:
141
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
142
- """
143
- return self.ticker(identifier).trading_item_id
144
-
145
-
146
- def get_isin_from_ticker(self: Client, ticker_str: str) -> str:
147
- """Get the ISIN associated with a ticker, can also be CUSIP.
148
-
149
- Args:
150
- ticker_str: The ticker
151
- """
152
- return self.ticker(ticker_str).isin
153
-
154
-
155
- def get_cusip_from_ticker(self: Client, ticker_str: str) -> str:
156
- """Get the CUSIP associated with a ticker, can also be an ISIN.
157
-
158
- Args:
159
- ticker_str: The ticker
160
- """
161
- return self.ticker(ticker_str).cusip
162
-
163
-
164
- def get_info_from_identifier(self: Client, identifier: str) -> str:
165
- """Get the information associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
166
-
167
- Info includes company name, status, type, simple industry, number of employees, founding date, webpage, HQ address, HQ city, HQ zip code, HQ state, HQ country, and HQ country iso code
168
-
169
- Args:
170
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
171
- """
172
- return str(self.ticker(identifier).info)
173
-
174
-
175
- def get_earnings_call_datetimes_from_identifier(self: Client, identifier: str) -> str:
176
- """Get earnings call datetimes associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
177
-
178
- Args:
179
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
180
- """
181
- return str(self.ticker(identifier).earnings_call_datetimes)
182
-
183
-
184
- def get_history_metadata_from_identifier(self: Client, identifier: str) -> HistoryMetadata:
185
- """Get the history metadata associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
186
-
187
- History metadata includes currency, symbol, exchange name, instrument type, and first trade date
188
-
189
- Args:
190
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
191
- """
192
- return self.ticker(identifier).history_metadata
193
-
194
-
195
- def get_prices_from_identifier(
196
- self: Client,
197
- identifier: str,
198
- periodicity: str = "day",
199
- adjusted: bool = True,
200
- start_date: str | None = None,
201
- end_date: str | None = None,
202
- ) -> str:
203
- """Get the historical open, high, low, and close prices, and volume of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.
204
-
205
- Args:
206
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
207
- start_date: The start date for historical price retrieval in format YYYY-MM-DD
208
- end_date: The end date for historical price retrieval in format YYYY-MM-DD
209
- periodicity: The frequency or interval at which the historical data points are sampled or aggregated. Periodicity is not the same as the date range. The date range specifies the time span over which the data is retrieved, while periodicity determines how the data within that date range is aggregated, valid inputs are ["day", "week", "month", "year"].
210
- adjusted: Whether to retrieve adjusted prices that account for corporate actions such as dividends and splits.
211
- """
212
- return (
213
- self.ticker(identifier).history(periodicity, adjusted, start_date, end_date).to_markdown()
214
- )
215
-
216
-
217
- def get_capitalization_from_identifier(
218
- self: Client,
219
- identifier: str,
220
- capitalization: Literal["market_cap", "tev", "shares_outstanding"],
221
- start_date: str | None = None,
222
- end_date: str | None = None,
223
- ) -> str:
224
- """Get the historical market cap, tev (Total Enterprise Value), or shares outstanding of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.
225
-
226
- Args:
227
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
228
- capitalization: The capitalization to retrieve (market_cap, tev, or shares_outstanding)
229
- start_date: The start date for historical price retrieval in format YYYY-MM-DD
230
- end_date: The end date for historical price retrieval in format YYYY-MM-DD
231
- """
232
- ticker = self.ticker(identifier)
233
- capitalization_to_func: dict[Literal["market_cap", "tev", "shares_outstanding"], Callable] = {
234
- "market_cap": ticker.market_cap,
235
- "tev": ticker.tev,
236
- "shares_outstanding": ticker.shares_outstanding,
237
- }
238
- func = capitalization_to_func[capitalization]
239
- return func(start_date=start_date, end_date=end_date).to_markdown()
240
-
241
-
242
- def get_financial_statement_from_identifier(
243
- self: Client,
244
- identifier: str,
245
- statement: str,
246
- period_type: str | None = None,
247
- start_year: int | None = None,
248
- end_year: int | None = None,
249
- start_quarter: int | None = None,
250
- end_quarter: int | None = None,
251
- ) -> str:
252
- """Get the financial statement associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
253
-
254
- Args:
255
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
256
- statement: The type of financial statement, valid inputs are ["balance_sheet", "income_statement", "cashflow"]
257
- period_type: time period type, valid inputs are ["annual", "quarterly", "ltm", "ytd"].
258
- start_quarter: starting quarter, valid inputs are [1, 2, 3, 4]
259
- end_quarter: ending quarter, valid inputs are [1, 2, 3, 4]
260
- start_year: The starting year for the data range.
261
- end_year: The ending year for the data range.
262
- """
263
- return getattr(self.ticker(identifier), statement)(
264
- period_type, start_year, end_year, start_quarter, end_quarter
265
- ).to_markdown()
266
-
267
-
268
- def get_financial_line_item_from_identifier(
269
- self: Client,
270
- identifier: str,
271
- line_item: str,
272
- period_type: str | None = None,
273
- start_year: int | None = None,
274
- end_year: int | None = None,
275
- start_quarter: int | None = None,
276
- end_quarter: int | None = None,
277
- ) -> str:
278
- """Get the financial line item associated with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
279
-
280
- Args:
281
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
282
- line_item: The type of financial line_item requested
283
- period_type: time period type, valid inputs are ["annual", "quarterly", "ltm", "ytd"]
284
- start_quarter: starting quarter, valid inputs are [1, 2, 3, 4]
285
- end_quarter: ending quarter, valid inputs are [1, 2, 3, 4]
286
- start_year: The starting year for the data range.
287
- end_year: The ending year for the data range.
288
- """
289
- return getattr(self.ticker(identifier), line_item)(
290
- period_type, start_year, end_year, start_quarter, end_quarter
291
- ).to_markdown()
292
-
293
-
294
- def get_business_relationship_from_identifier(
295
- self: Client, identifier: str, business_relationship: str
296
- ) -> dict:
297
- """Get the current and previous company IDs having a business relationship with an identifier, where the identifier can be a ticker, ISIN or CUSIP.
298
-
299
- Args:
300
- identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
301
- business_relationship: the type of business relationship requested
302
- """
303
- business_relationship_obj: "BusinessRelationships" = getattr(
304
- self.ticker(identifier), business_relationship
305
- )
306
- return {
307
- "current": [company.company_id for company in business_relationship_obj.current],
308
- "previous": [company.company_id for company in business_relationship_obj.previous],
309
- }
310
-
311
-
312
- def _llm_tools(self: Client) -> dict[str, Callable]:
313
- """Get AI tools initiated with Client. Outputs a dictionary mapping a function name to function"""
314
-
315
- return {
316
- "get_latest": get_latest,
317
- "get_n_quarters_ago": get_n_quarters_ago,
318
- "get_company_id_from_identifier": partial(get_company_id_from_identifier, self),
319
- "get_security_id_from_identifier": partial(get_security_id_from_identifier, self),
320
- "get_trading_item_id_from_identifier": partial(get_trading_item_id_from_identifier, self),
321
- "get_isin_from_ticker": partial(get_isin_from_ticker, self),
322
- "get_cusip_from_ticker": partial(get_cusip_from_ticker, self),
323
- "get_info_from_identifier": partial(get_info_from_identifier, self),
324
- "get_earnings_call_datetimes_from_identifier": partial(
325
- get_earnings_call_datetimes_from_identifier, self
326
- ),
327
- "get_history_metadata_from_identifier": partial(get_history_metadata_from_identifier, self),
328
- "get_prices_from_identifier": partial(get_prices_from_identifier, self),
329
- "get_capitalization_from_identifier": partial(get_capitalization_from_identifier, self),
330
- "get_financial_statement_from_identifier": partial(
331
- get_financial_statement_from_identifier, self
332
- ),
333
- "get_financial_line_item_from_identifier": partial(
334
- get_financial_line_item_from_identifier, self
335
- ),
336
- "get_business_relationship_from_identifier": partial(
337
- get_business_relationship_from_identifier, self
338
- ),
339
- }
340
-
341
-
342
- def _llm_tool_metadata() -> dict:
343
- """The Argument schema for each of the LLM Tools"""
344
- return {
345
- "get_latest": tool_schemas.GetLatestInput,
346
- "get_n_quarters_ago": tool_schemas.GetNQuartersAgoInput,
347
- "get_company_id_from_identifier": tool_schemas.GetCompanyIdFromIdentifier,
348
- "get_security_id_from_identifier": tool_schemas.GetSecurityIdFromIdentifier,
349
- "get_trading_item_id_from_identifier": tool_schemas.GetTradingItemIdFromIdentifier,
350
- "get_isin_from_ticker": tool_schemas.GetIsinFromTicker,
351
- "get_cusip_from_ticker": tool_schemas.GetCusipFromTicker,
352
- "get_info_from_identifier": tool_schemas.GetInfoFromIdentifier,
353
- "get_earnings_call_datetimes_from_identifier": tool_schemas.GetEarningsCallDatetimesFromIdentifier,
354
- "get_history_metadata_from_identifier": tool_schemas.GetHistoryMetadataFromIdentifier,
355
- "get_prices_from_identifier": tool_schemas.GetPricesFromIdentifier,
356
- "get_capitalization_from_identifier": tool_schemas.GetCapitalizationFromIdentifier,
357
- "get_financial_statement_from_identifier": tool_schemas.GetFinancialStatementFromIdentifier,
358
- "get_financial_line_item_from_identifier": tool_schemas.GetFinancialLineItemFromIdentifier,
359
- "get_business_relationship_from_identifier": tool_schemas.GetBusinessRelationshipFromIdentifier,
360
- }
361
-
362
-
363
- _base_tool_descriptions = [
364
- {
365
- "name": "get_latest",
366
- "description": """Get the latest annual reporting year, latest quarterly reporting quarter and year, and current date. The output is a dictionary with the following schema:
367
- {
368
- "annual": {
369
- "latest_year": int
370
- },
371
- "quarterly": {
372
- "latest_quarter": int,
373
- "latest_year": int
374
- },
375
- "now": {
376
- "current_year": int,
377
- "current_quarter": int,
378
- "current_month": int,
379
- "current_date": str # in format Y-m-d
380
- }
381
- }""",
382
- "input_schema": {"type": "object", "properties": {}},
383
- },
384
- {
385
- "name": "get_n_quarters_ago",
386
- "description": """Get the year and quarter corresponding to [n] quarters before the current quarter. The output is a dictionary with the following schema::
387
- {
388
- "year": int,
389
- "quarter": int
390
- }
391
- """,
392
- "input_schema": {
393
- "type": "object",
394
- "properties": {
395
- "n": {
396
- "type": "integer",
397
- "description": "The number of quarters before the current quarter to retrieve the corresponding year and quarter",
398
- },
399
- },
400
- "required": ["n"],
401
- "additionalProperties": False,
402
- },
403
- },
404
- {
405
- "name": "get_company_id_from_identifier",
406
- "description": "Get the company id associated with an identifier",
407
- "input_schema": {
408
- "type": "object",
409
- "properties": {
410
- "identifier": {
411
- "type": "string",
412
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
413
- },
414
- },
415
- "required": ["identifier"],
416
- "additionalProperties": False,
417
- },
418
- },
419
- {
420
- "name": "get_security_id_from_ticker",
421
- "description": "Get the security id associated with an identifier",
422
- "input_schema": {
423
- "type": "object",
424
- "properties": {
425
- "identifier": {
426
- "type": "string",
427
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
428
- },
429
- },
430
- "required": ["identifier"],
431
- "additionalProperties": False,
432
- },
433
- },
434
- {
435
- "name": "get_trading_item_id_from_ticker",
436
- "description": "Get the trading item id associated with an identifier",
437
- "input_schema": {
438
- "type": "object",
439
- "properties": {
440
- "identifier": {
441
- "type": "string",
442
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
443
- },
444
- },
445
- "required": ["identifier"],
446
- "additionalProperties": False,
447
- },
448
- },
449
- {
450
- "name": "get_isin_from_ticker",
451
- "description": "Get the ISIN associated with a ticker",
452
- "input_schema": {
453
- "type": "object",
454
- "properties": {
455
- "ticker_str": {"type": "string", "description": "The ticker"},
456
- },
457
- "required": ["ticker_str"],
458
- "additionalProperties": False,
459
- },
460
- },
461
- {
462
- "name": "get_cusip_from_ticker",
463
- "description": "Get the CUSIP associated with a ticker",
464
- "input_schema": {
465
- "type": "object",
466
- "properties": {
467
- "ticker_str": {"type": "string", "description": "The ticker"},
468
- },
469
- "required": ["ticker_str"],
470
- "additionalProperties": False,
471
- },
472
- },
473
- {
474
- "name": "get_info_from_identifier",
475
- "description": "Get the information associated with an identifier. Info includes company name, status, type, simple industry, number of employees, founding date, webpage, HQ address, HQ city, HQ zip code, HQ state, HQ country, and HQ country iso code",
476
- "input_schema": {
477
- "type": "object",
478
- "properties": {
479
- "identifier": {
480
- "type": "string",
481
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
482
- },
483
- },
484
- "required": ["identifier"],
485
- "additionalProperties": False,
486
- },
487
- },
488
- {
489
- "name": "get_earnings_call_datetimes_from_identifier",
490
- "description": "Get the earnings call datetimes of an identifier.",
491
- "input_schema": {
492
- "type": "object",
493
- "properties": {
494
- "identifier": {
495
- "type": "string",
496
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
497
- },
498
- },
499
- "required": ["identifier"],
500
- "additionalProperties": False,
501
- },
502
- },
503
- {
504
- "name": "get_history_metadata_from_identifier",
505
- "description": "Get the history metadata associated with an identifier. History metadata includes currency, symbol, exchange name, instrument type, and first trade date",
506
- "input_schema": {
507
- "type": "object",
508
- "properties": {
509
- "identifier": {
510
- "type": "string",
511
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
512
- },
513
- },
514
- "required": ["identifier"],
515
- "additionalProperties": False,
516
- },
517
- },
518
- {
519
- "name": "get_prices_from_identifier",
520
- "description": "Get the historical open, high, low, and close prices, and volume of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.",
521
- "input_schema": {
522
- "type": "object",
523
- "properties": {
524
- "identifier": {
525
- "type": "string",
526
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
527
- },
528
- "start_date": {
529
- "type": "string",
530
- "description": "The start date for historical price retrieval in format YYYY-MM-DD",
531
- },
532
- "end_date": {
533
- "type": "string",
534
- "description": "The end date for historical price retrieval in format YYYY-MM-DD",
535
- },
536
- "periodicity": {
537
- "type": "string",
538
- "description": "The frequency or interval at which the historical data points are sampled or aggregated. Periodicity is not the same as the date range. The date range specifies the time span over which the data is retrieved, while periodicity determines how the data within that date range is aggregated.",
539
- "enum": ["day", "week", "month", "year", "none"],
540
- },
541
- "adjusted": {
542
- "type": "boolean",
543
- "description": "Whether to retrieve adjusted prices that account for corporate actions such as dividends and splits.",
544
- },
545
- },
546
- "required": ["identifier"],
547
- "additionalProperties": False,
548
- },
549
- },
550
- {
551
- "name": "get_capitalization_from_identifier",
552
- "description": "Get the historical market cap, tev (Total Enterprise Value), or shares outstanding of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.",
553
- "input_schema": {
554
- "type": "object",
555
- "properties": {
556
- "identifier": {
557
- "type": "string",
558
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
559
- },
560
- "capitalization": {
561
- "type": "string",
562
- "description": "The capitalization to retrieve (market_cap, tev, or shares_outstanding).",
563
- "enum": ["market_cap", "tev", "shares_outstanding"],
564
- },
565
- "start_date": {
566
- "type": "string",
567
- "description": "The start date for historical price retrieval in format YYYY-MM-DD",
568
- },
569
- "end_date": {
570
- "type": "string",
571
- "description": "The end date for historical price retrieval in format YYYY-MM-DD",
572
- },
573
- },
574
- "required": ["identifier", "capitalization"],
575
- "additionalProperties": False,
576
- },
577
- },
578
- {
579
- "name": "get_financial_statement_from_identifier",
580
- "description": "Get the financial statement associated with an identifier",
581
- "input_schema": {
582
- "type": "object",
583
- "properties": {
584
- "identifier": {
585
- "type": "string",
586
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
587
- },
588
- "statement": {
589
- "type": "string",
590
- "description": "The type of financial statement",
591
- "enum": ["balance_sheet", "income_statement", "cashflow"],
592
- },
593
- "period_type": {
594
- "type": "string",
595
- "enum": ["annual", "quarterly", "ltm", "ytd"],
596
- },
597
- "start_quarter": {"type": "integer", "enum": [1, 2, 3, 4]},
598
- "end_quarter": {"type": "integer", "enum": [1, 2, 3, 4]},
599
- "start_year": {
600
- "type": "integer",
601
- "description": "The starting year for the data range.",
602
- },
603
- "end_year": {
604
- "type": "integer",
605
- "description": "The ending year for the data range.",
606
- },
607
- },
608
- "required": ["identifier", "statement"],
609
- "additionalProperties": False,
610
- },
611
- },
612
- {
613
- "name": "get_financial_line_item_from_identifier",
614
- "description": 'Get the financial line item associated with an identifier. Used to answer questions about specific line items. For example, "Honda\'s finance division other non-current assets at the year-end 2021." or "Builders FirstSource\'s repayments of long-term debt in 2022 and impact on debt-to-equity" ',
615
- "input_schema": {
616
- "type": "object",
617
- "properties": {
618
- "identifier": {
619
- "type": "string",
620
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
621
- },
622
- "line_item": {
623
- "type": "string",
624
- "description": "The type of financial line_item requested",
625
- "enum": LINE_ITEM_NAMES_AND_ALIASES,
626
- },
627
- "period_type": {
628
- "type": "string",
629
- "enum": ["annual", "quarterly", "ltm", "ytd"],
630
- },
631
- "start_quarter": {"type": "integer", "enum": [1, 2, 3, 4]},
632
- "end_quarter": {"type": "integer", "enum": [1, 2, 3, 4]},
633
- "start_year": {
634
- "type": "integer",
635
- "description": "The starting year for the data range.",
636
- },
637
- "end_year": {
638
- "type": "integer",
639
- "description": "The ending year for the data range.",
640
- },
641
- },
642
- "required": ["identifier", "line_item"],
643
- "additionalProperties": False,
644
- },
645
- },
646
- {
647
- "name": "get_business_relationship_from_identifier",
648
- "description": 'Get the current and previous company IDs that are relationship_type of a given identifier. For example, "What are the current distributors of SPGI?" or "What are the previous borrowers of JPM?" ',
649
- "input_schema": {
650
- "type": "object",
651
- "properties": {
652
- "identifier": {
653
- "type": "string",
654
- "description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
655
- },
656
- "business_relationship": {
657
- "type": "string",
658
- "description": "The type of business relationship requested",
659
- "enum": list(BusinessRelationshipType.__members__.keys()),
660
- },
661
- },
662
- "required": ["identifier", "business_relationship"],
663
- "additionalProperties": False,
664
- },
665
- },
666
- ]
667
-
668
-
669
- def _get_tool_dict_description(tool_name: str) -> str:
670
- """Extracts description from the llm tool dict matching the input name"""
671
- for tool_dict in _base_tool_descriptions:
672
- if tool_dict["name"] == tool_name:
673
- return str(tool_dict["description"])
674
- return ""
675
-
676
-
677
- def _tool_descriptions(model: Model) -> list[dict]:
678
- """Get tool descriptions for a model"""
679
-
680
- def change_base_tool_descriptions_schema_for_openai(tool_description: dict) -> dict:
681
- new_tool_description = copy.deepcopy(tool_description)
682
- new_tool_description["parameters"] = new_tool_description.pop("input_schema")
683
- return {"type": "function", "function": new_tool_description}
684
-
685
- def change_base_tool_descriptions_schema_for_gemini(tool_description: dict) -> dict:
686
- new_tool_description = copy.deepcopy(tool_description)
687
- new_tool_description["parameters"] = new_tool_description.pop("input_schema")
688
- if "additionalProperties" in new_tool_description["parameters"].keys():
689
- del new_tool_description["parameters"]["additionalProperties"]
690
- for tool_property in new_tool_description["parameters"]["properties"].values():
691
- if "enum" in tool_property.keys() and tool_property["type"] == "integer":
692
- del tool_property["enum"]
693
- if new_tool_description["parameters"]["properties"] == {}:
694
- del new_tool_description["parameters"]
695
- return new_tool_description
696
-
697
- if model == Model.OPENAI:
698
- return list(
699
- map(
700
- change_base_tool_descriptions_schema_for_openai,
701
- _base_tool_descriptions,
702
- )
703
- )
704
- elif model == Model.GEMINI:
705
- return [
706
- {
707
- "function_declarations": list(
708
- map(change_base_tool_descriptions_schema_for_gemini, _base_tool_descriptions)
709
- )
710
- }
711
- ]
712
-
713
- elif model == Model.ANTHROPIC:
714
- return _base_tool_descriptions
715
- else:
716
- raise NotImplementedError(f"tool descriptions for model: {model} have not been implemented")
717
-
718
-
719
- def langchain_tools(tools: dict[str, Callable]) -> list[StructuredTool]:
720
- """Returns Langchain Tool callables
721
-
722
- The Tool names and descriptions sent to the LLM are taken from the base tool dict.
723
- The Tool arguments and arg descriptions are taken from the Pydantic models with an
724
- input model corresponding to each tool. Any change to the base tool dict must be reflected
725
- in the input model
726
-
727
- Args:
728
- tools: mapping of tool names and tool callables, to be converted to langchain tools
729
- """
730
- all_tools = []
731
- for tool_name, tool_callable in tools.items():
732
- schemas = _llm_tool_metadata()
733
- tool_description = _get_tool_dict_description(tool_name=tool_name)
734
- langchain_tool = StructuredTool.from_function(
735
- func=tool_callable,
736
- name=tool_name,
737
- description=tool_description,
738
- args_schema=schemas[tool_name],
739
- infer_schema=False,
740
- )
741
- all_tools.append(langchain_tool)
742
- return all_tools
743
-
744
-
745
- gemini_tool_descriptions = _tool_descriptions(Model.GEMINI)
746
- openai_tool_descriptions = _tool_descriptions(Model.OPENAI)
747
- anthropic_tool_descriptions = _tool_descriptions(Model.ANTHROPIC)