@multiplayer-app/agent 0.1.8 → 0.1.10

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.
Files changed (232) hide show
  1. package/README.md +106 -0
  2. package/dist/agent/definition.d.ts +22 -0
  3. package/dist/agent/definition.d.ts.map +1 -0
  4. package/dist/agent/definition.js +3 -0
  5. package/dist/agent/definition.js.map +1 -0
  6. package/dist/agent/definition.test.d.ts +2 -0
  7. package/dist/agent/definition.test.d.ts.map +1 -0
  8. package/dist/agent/definition.test.js +40 -0
  9. package/dist/agent/definition.test.js.map +1 -0
  10. package/dist/agent/profiles/coding.d.ts +4 -0
  11. package/dist/agent/profiles/coding.d.ts.map +1 -0
  12. package/dist/agent/profiles/coding.js +17 -0
  13. package/dist/agent/profiles/coding.js.map +1 -0
  14. package/dist/agent/profiles/index.d.ts +4 -0
  15. package/dist/agent/profiles/index.d.ts.map +1 -0
  16. package/dist/agent/profiles/index.js +9 -0
  17. package/dist/agent/profiles/index.js.map +1 -0
  18. package/dist/agent/profiles/research.d.ts +4 -0
  19. package/dist/agent/profiles/research.d.ts.map +1 -0
  20. package/dist/agent/profiles/research.js +43 -0
  21. package/dist/agent/profiles/research.js.map +1 -0
  22. package/dist/agent/turn-runner.d.ts +37 -0
  23. package/dist/agent/turn-runner.d.ts.map +1 -0
  24. package/dist/agent/turn-runner.js +94 -0
  25. package/dist/agent/turn-runner.js.map +1 -0
  26. package/dist/agent/turn-runner.test.d.ts +2 -0
  27. package/dist/agent/turn-runner.test.d.ts.map +1 -0
  28. package/dist/agent/turn-runner.test.js +181 -0
  29. package/dist/agent/turn-runner.test.js.map +1 -0
  30. package/dist/index.d.ts +11 -6
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +18 -10
  33. package/dist/index.js.map +1 -1
  34. package/dist/models/attribution.d.ts.map +1 -0
  35. package/dist/models/attribution.js.map +1 -0
  36. package/dist/{model.d.ts → models/resolve-model.d.ts} +2 -2
  37. package/dist/models/resolve-model.d.ts.map +1 -0
  38. package/dist/{model.js → models/resolve-model.js} +1 -1
  39. package/dist/models/resolve-model.js.map +1 -0
  40. package/dist/models/usage.d.ts +7 -0
  41. package/dist/models/usage.d.ts.map +1 -0
  42. package/dist/models/usage.js +13 -0
  43. package/dist/models/usage.js.map +1 -0
  44. package/dist/{git-sync.d.ts → persistence/git-sync.d.ts} +1 -1
  45. package/dist/persistence/git-sync.d.ts.map +1 -0
  46. package/dist/persistence/git-sync.js.map +1 -0
  47. package/dist/persistence/git-sync.test.d.ts.map +1 -0
  48. package/dist/{git-sync.test.js → persistence/git-sync.test.js} +2 -2
  49. package/dist/persistence/git-sync.test.js.map +1 -0
  50. package/dist/{session-storage-sync.d.ts → persistence/snapshot-sync.d.ts} +2 -2
  51. package/dist/persistence/snapshot-sync.d.ts.map +1 -0
  52. package/dist/{session-storage-sync.js → persistence/snapshot-sync.js} +1 -1
  53. package/dist/persistence/snapshot-sync.js.map +1 -0
  54. package/dist/persistence/snapshot-sync.test.d.ts +2 -0
  55. package/dist/persistence/snapshot-sync.test.d.ts.map +1 -0
  56. package/dist/{session-storage-sync.test.js → persistence/snapshot-sync.test.js} +3 -3
  57. package/dist/persistence/snapshot-sync.test.js.map +1 -0
  58. package/dist/persistence/workspace.d.ts +17 -0
  59. package/dist/persistence/workspace.d.ts.map +1 -0
  60. package/dist/persistence/workspace.js +26 -0
  61. package/dist/persistence/workspace.js.map +1 -0
  62. package/dist/persistence/workspace.test.d.ts +2 -0
  63. package/dist/persistence/workspace.test.d.ts.map +1 -0
  64. package/dist/persistence/workspace.test.js +38 -0
  65. package/dist/persistence/workspace.test.js.map +1 -0
  66. package/dist/research/extraction-tool.d.ts +6 -0
  67. package/dist/research/extraction-tool.d.ts.map +1 -0
  68. package/dist/research/extraction-tool.js +67 -0
  69. package/dist/research/extraction-tool.js.map +1 -0
  70. package/dist/research/extraction-tool.test.d.ts +2 -0
  71. package/dist/research/extraction-tool.test.d.ts.map +1 -0
  72. package/dist/research/extraction-tool.test.js +100 -0
  73. package/dist/research/extraction-tool.test.js.map +1 -0
  74. package/dist/research/filingramp/attachment-tools.d.ts +4 -0
  75. package/dist/research/filingramp/attachment-tools.d.ts.map +1 -0
  76. package/dist/research/filingramp/attachment-tools.js +99 -0
  77. package/dist/research/filingramp/attachment-tools.js.map +1 -0
  78. package/dist/research/filingramp/document-search-tool.d.ts +4 -0
  79. package/dist/research/filingramp/document-search-tool.d.ts.map +1 -0
  80. package/dist/research/filingramp/document-search-tool.js +173 -0
  81. package/dist/research/filingramp/document-search-tool.js.map +1 -0
  82. package/dist/research/filingramp/filing-detail-tool.d.ts +4 -0
  83. package/dist/research/filingramp/filing-detail-tool.d.ts.map +1 -0
  84. package/dist/research/filingramp/filing-detail-tool.js +114 -0
  85. package/dist/research/filingramp/filing-detail-tool.js.map +1 -0
  86. package/dist/research/filingramp/filing-search-tools.d.ts +4 -0
  87. package/dist/research/filingramp/filing-search-tools.d.ts.map +1 -0
  88. package/dist/research/filingramp/filing-search-tools.js +207 -0
  89. package/dist/research/filingramp/filing-search-tools.js.map +1 -0
  90. package/dist/research/filingramp/shared.d.ts +48 -0
  91. package/dist/research/filingramp/shared.d.ts.map +1 -0
  92. package/dist/research/filingramp/shared.js +58 -0
  93. package/dist/research/filingramp/shared.js.map +1 -0
  94. package/dist/research/filingramp-client.d.ts +1 -1
  95. package/dist/research/filingramp-client.d.ts.map +1 -1
  96. package/dist/research/filingramp-tools.d.ts +3 -8
  97. package/dist/research/filingramp-tools.d.ts.map +1 -1
  98. package/dist/research/filingramp-tools.js +14 -565
  99. package/dist/research/filingramp-tools.js.map +1 -1
  100. package/dist/research/filingramp-tools.test.js +45 -2
  101. package/dist/research/filingramp-tools.test.js.map +1 -1
  102. package/dist/research/prompt.d.ts +1 -1
  103. package/dist/research/prompt.d.ts.map +1 -1
  104. package/dist/research/scope.d.ts +1 -1
  105. package/dist/research/scope.d.ts.map +1 -1
  106. package/dist/runtime/cli.d.ts.map +1 -0
  107. package/dist/{cli.js → runtime/cli.js} +3 -3
  108. package/dist/runtime/cli.js.map +1 -0
  109. package/dist/{config.d.ts → runtime/config.d.ts} +1 -1
  110. package/dist/runtime/config.d.ts.map +1 -0
  111. package/dist/{config.js → runtime/config.js} +1 -1
  112. package/dist/runtime/config.js.map +1 -0
  113. package/dist/{runtime.d.ts → runtime/index.d.ts} +2 -2
  114. package/dist/runtime/index.d.ts.map +1 -0
  115. package/dist/{runtime.js → runtime/index.js} +7 -7
  116. package/dist/runtime/index.js.map +1 -0
  117. package/dist/runtime/lambda-microvm.d.ts +3 -0
  118. package/dist/runtime/lambda-microvm.d.ts.map +1 -0
  119. package/dist/{lambda-microvm-entrypoint.js → runtime/lambda-microvm.js} +4 -4
  120. package/dist/runtime/lambda-microvm.js.map +1 -0
  121. package/dist/runtime/lifecycle.test.d.ts.map +1 -0
  122. package/dist/{lifecycle.test.js → runtime/lifecycle.test.js} +5 -5
  123. package/dist/runtime/lifecycle.test.js.map +1 -0
  124. package/dist/session/checkpoint-timer.test.d.ts.map +1 -0
  125. package/dist/{checkpoint-timer.test.js → session/checkpoint-timer.test.js} +8 -8
  126. package/dist/session/checkpoint-timer.test.js.map +1 -0
  127. package/dist/session/conversation.d.ts +15 -0
  128. package/dist/session/conversation.d.ts.map +1 -0
  129. package/dist/session/conversation.js +61 -0
  130. package/dist/session/conversation.js.map +1 -0
  131. package/dist/session/conversation.test.d.ts +2 -0
  132. package/dist/session/conversation.test.d.ts.map +1 -0
  133. package/dist/session/conversation.test.js +53 -0
  134. package/dist/session/conversation.test.js.map +1 -0
  135. package/dist/session/idle-checkpoint.test.d.ts.map +1 -0
  136. package/dist/{idle-checkpoint.test.js → session/idle-checkpoint.test.js} +8 -4
  137. package/dist/session/idle-checkpoint.test.js.map +1 -0
  138. package/dist/session/index.d.ts +7 -0
  139. package/dist/session/index.d.ts.map +1 -0
  140. package/dist/session/index.js +16 -0
  141. package/dist/session/index.js.map +1 -0
  142. package/dist/{session.d.ts → session/runtime.d.ts} +20 -16
  143. package/dist/session/runtime.d.ts.map +1 -0
  144. package/dist/session/runtime.js +251 -0
  145. package/dist/session/runtime.js.map +1 -0
  146. package/dist/session/runtime.test.d.ts +2 -0
  147. package/dist/session/runtime.test.d.ts.map +1 -0
  148. package/dist/session/runtime.test.js +201 -0
  149. package/dist/session/runtime.test.js.map +1 -0
  150. package/dist/session/tool-context.d.ts +12 -0
  151. package/dist/session/tool-context.d.ts.map +1 -0
  152. package/dist/session/tool-context.js +3 -0
  153. package/dist/session/tool-context.js.map +1 -0
  154. package/dist/session/tools.d.ts +6 -0
  155. package/dist/session/tools.d.ts.map +1 -0
  156. package/dist/session/tools.js +97 -0
  157. package/dist/session/tools.js.map +1 -0
  158. package/dist/session/tools.test.d.ts +2 -0
  159. package/dist/session/tools.test.d.ts.map +1 -0
  160. package/dist/session/tools.test.js +55 -0
  161. package/dist/session/tools.test.js.map +1 -0
  162. package/dist/task/loop.d.ts +6 -0
  163. package/dist/task/loop.d.ts.map +1 -0
  164. package/dist/{loop.js → task/loop.js} +6 -6
  165. package/dist/task/loop.js.map +1 -0
  166. package/dist/transport/link.d.ts.map +1 -0
  167. package/dist/transport/link.js.map +1 -0
  168. package/dist/transport/protocol.d.ts.map +1 -0
  169. package/dist/transport/protocol.js.map +1 -0
  170. package/dist/transport/protocol.test.d.ts.map +1 -0
  171. package/dist/transport/protocol.test.js.map +1 -0
  172. package/dist/{report.d.ts → transport/reporter.d.ts} +1 -1
  173. package/dist/transport/reporter.d.ts.map +1 -0
  174. package/dist/{report.js → transport/reporter.js} +1 -1
  175. package/dist/transport/reporter.js.map +1 -0
  176. package/package.json +11 -11
  177. package/dist/attribution.d.ts.map +0 -1
  178. package/dist/attribution.js.map +0 -1
  179. package/dist/checkpoint-timer.test.d.ts.map +0 -1
  180. package/dist/checkpoint-timer.test.js.map +0 -1
  181. package/dist/cli.d.ts.map +0 -1
  182. package/dist/cli.js.map +0 -1
  183. package/dist/config.d.ts.map +0 -1
  184. package/dist/config.js.map +0 -1
  185. package/dist/git-sync.d.ts.map +0 -1
  186. package/dist/git-sync.js.map +0 -1
  187. package/dist/git-sync.test.d.ts.map +0 -1
  188. package/dist/git-sync.test.js.map +0 -1
  189. package/dist/idle-checkpoint.test.d.ts.map +0 -1
  190. package/dist/idle-checkpoint.test.js.map +0 -1
  191. package/dist/lambda-microvm-entrypoint.d.ts +0 -3
  192. package/dist/lambda-microvm-entrypoint.d.ts.map +0 -1
  193. package/dist/lambda-microvm-entrypoint.js.map +0 -1
  194. package/dist/lifecycle.test.d.ts.map +0 -1
  195. package/dist/lifecycle.test.js.map +0 -1
  196. package/dist/link.d.ts.map +0 -1
  197. package/dist/link.js.map +0 -1
  198. package/dist/loop.d.ts +0 -6
  199. package/dist/loop.d.ts.map +0 -1
  200. package/dist/loop.js.map +0 -1
  201. package/dist/model.d.ts.map +0 -1
  202. package/dist/model.js.map +0 -1
  203. package/dist/protocol.d.ts.map +0 -1
  204. package/dist/protocol.js.map +0 -1
  205. package/dist/protocol.test.d.ts.map +0 -1
  206. package/dist/protocol.test.js.map +0 -1
  207. package/dist/report.d.ts.map +0 -1
  208. package/dist/report.js.map +0 -1
  209. package/dist/runtime.d.ts.map +0 -1
  210. package/dist/runtime.js.map +0 -1
  211. package/dist/session-storage-sync.d.ts.map +0 -1
  212. package/dist/session-storage-sync.js.map +0 -1
  213. package/dist/session-storage-sync.test.d.ts +0 -2
  214. package/dist/session-storage-sync.test.d.ts.map +0 -1
  215. package/dist/session-storage-sync.test.js.map +0 -1
  216. package/dist/session.d.ts.map +0 -1
  217. package/dist/session.js +0 -512
  218. package/dist/session.js.map +0 -1
  219. /package/dist/{attribution.d.ts → models/attribution.d.ts} +0 -0
  220. /package/dist/{attribution.js → models/attribution.js} +0 -0
  221. /package/dist/{git-sync.js → persistence/git-sync.js} +0 -0
  222. /package/dist/{git-sync.test.d.ts → persistence/git-sync.test.d.ts} +0 -0
  223. /package/dist/{cli.d.ts → runtime/cli.d.ts} +0 -0
  224. /package/dist/{lifecycle.test.d.ts → runtime/lifecycle.test.d.ts} +0 -0
  225. /package/dist/{checkpoint-timer.test.d.ts → session/checkpoint-timer.test.d.ts} +0 -0
  226. /package/dist/{idle-checkpoint.test.d.ts → session/idle-checkpoint.test.d.ts} +0 -0
  227. /package/dist/{link.d.ts → transport/link.d.ts} +0 -0
  228. /package/dist/{link.js → transport/link.js} +0 -0
  229. /package/dist/{protocol.d.ts → transport/protocol.d.ts} +0 -0
  230. /package/dist/{protocol.js → transport/protocol.js} +0 -0
  231. /package/dist/{protocol.test.d.ts → transport/protocol.test.d.ts} +0 -0
  232. /package/dist/{protocol.test.js → transport/protocol.test.js} +0 -0
@@ -1,573 +1,22 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.createFilingRampTools = createFilingRampTools;
7
- // FilingRamp tools for the research profile. Design rule: token cost first. Every tool
8
- // returns a lean projection and writes anything bulky (document text, downloaded files,
9
- // full result pages) to the workspace, where grep / DuckDB / Python work on it for free.
10
- // The session scope (scope.ts) is applied server-side here, before the model's own filters.
11
- const child_process_1 = require("child_process");
12
- const fs_1 = require("fs");
13
- const path_1 = __importDefault(require("path"));
14
- const util_1 = require("util");
15
- const ai_1 = require("ai");
16
- const zod_1 = require("zod");
17
- const filingramp_client_1 = require("./filingramp-client");
18
- const filingramp_contract_1 = require("./filingramp-contract");
19
- const scope_1 = require("./scope");
20
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
21
- const DEFAULT_FILING_FIELDS = [
22
- '_id',
23
- 'trackingNumber',
24
- 'state',
25
- 'statusId',
26
- 'status',
27
- 'filingType',
28
- 'typeOfInsurance',
29
- 'subTypeOfInsurance',
30
- 'dateSubmitted',
31
- 'product',
32
- 'project',
33
- ];
34
- /** Filing fields the v2 search accepts (FilingRamp's Filing shape); unknown names fail the whole call. */
35
- const FILING_FIELDS = [
36
- '_id', 'accountId', 'trackingNumber', 'customTrackingNumber', 'resourceId', 'state', 'statusId', 'status', 'filingType',
37
- 'businessType', 'typeOfInsurance', 'subTypeOfInsurance', 'dateSubmitted', 'serffDateLastModified', 'source', 'projectId',
38
- 'productId', 'product', 'project', 'companies', 'authors', 'reviewers', 'objections', 'dispositions', 'generalInformation',
39
- 'stateSpecifics', 'hasPreviousVersion', 'associatedFilings', 'createdAt', 'updatedAt',
40
- ];
41
- const MAX_PAGE = 200;
42
- const MAX_DOC_HITS = 100;
43
- const MAX_HIGHLIGHTS = 3;
44
- const MAX_INLINE_TEXT_CHARS = 4000;
45
- // What the model may pass. The contract (filingramp-contract.ts) wraps single values, picks the
46
- // operator a field accepts and rejects unknown fields before the request leaves the VM.
47
- const filterInputSchema = zod_1.z.object({
48
- field: zod_1.z.string().min(1).max(100),
49
- comparisonOperator: zod_1.z
50
- .enum(['cn', 'in', 'eq', 'gt', 'gte', 'lt', 'lte', 'ex'])
51
- .optional()
52
- .describe('Omit to let the field decide: cn (contains) for names, lines and authors; in (exact) for codes; eq/gt/gte/lt/lte for dates; ex for hasObjection'),
53
- value: zod_1.z
54
- .union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean(), zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number()]))])
55
- .describe('A string array for list fields (a bare string is wrapped), one date string for date fields, a boolean for hasObjection'),
56
- });
57
- const filingsFilterSchema = filterInputSchema.extend({
58
- field: zod_1.z.string().min(1).max(100).describe('Filings filter (plural): states, typeOfInsurances, subTypeOfInsurances, filingTypes, statusIds, statuses, companies, authors, reviewers, productNames, projectNames, trackingNumbers, form.formNumbers, rate.ruleNumbers, dateSubmitted, createdAt, updatedAt, hasObjection. Singular record names are converted. Not a result field or groupBy.'),
59
- });
60
- const searchTypeSchema = zod_1.z.enum(['ACCOUNT', 'INDUSTRY']).optional().describe('Defaults to the session scope. INDUSTRY needs the industry-data entitlement.');
61
- /** Joi-style message: `"body.fields[7]" must be one of [a, b, c, …]` → the accepted values. */
62
- function allowedValuesFromError(error) {
63
- const message = error instanceof Error ? error.message : String(error);
64
- const match = message.match(/must be one of \[([^\]]*)/);
65
- if (!match)
66
- return undefined;
67
- return new Set(match[1].split(',').map((item) => item.trim()).filter((item) => item && item !== '…'));
68
- }
69
- function safeName(value) {
70
- return value.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^_+|_+$/g, '').slice(0, 120) || 'item';
71
- }
72
- function pick(record, fields) {
73
- const out = {};
74
- for (const field of fields) {
75
- if (record[field] !== undefined)
76
- out[field] = record[field];
77
- }
78
- return out;
79
- }
80
- function asRecordList(payload) {
81
- if (Array.isArray(payload))
82
- return payload;
83
- if (payload && typeof payload === 'object' && Array.isArray(payload.items)) {
84
- return payload.items;
85
- }
86
- return [];
87
- }
88
- async function writeWorkspaceFile(workspaceDir, relativePath, content) {
89
- const target = path_1.default.resolve(workspaceDir, relativePath);
90
- if (!target.startsWith(path_1.default.resolve(workspaceDir) + path_1.default.sep))
91
- throw new Error(`path escapes the workspace: ${relativePath}`);
92
- await fs_1.promises.mkdir(path_1.default.dirname(target), { recursive: true });
93
- const buffer = typeof content === 'string' ? Buffer.from(content, 'utf8') : content;
94
- await fs_1.promises.writeFile(target, buffer);
95
- return { path: relativePath, bytes: buffer.byteLength };
96
- }
97
- /** PDF → text with whatever the image has (mupdf first, poppler second). Empty text = scanned or protected. */
98
- async function extractPdfText(file, output) {
99
- const attempts = [
100
- ['mutool', ['draw', '-F', 'txt', '-o', output, file]],
101
- ['pdftotext', ['-layout', file, output]],
102
- ];
103
- for (const [bin, args] of attempts) {
104
- try {
105
- await execFileAsync(bin, args, { timeout: 120000 });
106
- const stat = await fs_1.promises.stat(output);
107
- return stat.size;
108
- }
109
- catch (_b) {
110
- /* try the next extractor */
111
- }
112
- }
113
- return 0;
114
- }
115
- /** Walks a filing record and lists every attachment with where it sits in the filing. */
116
- function collectAttachments(filing) {
117
- var _b, _c;
118
- const out = [];
119
- const sections = [
120
- ['forms', 'formNumber'],
121
- ['rates', 'name'],
122
- ['supportings', 'name'],
123
- ['dispositions', 'status'],
124
- ];
125
- for (const [section, labelField] of sections) {
126
- const items = filing[section];
127
- if (!Array.isArray(items))
128
- continue;
129
- for (const item of items) {
130
- const attachments = Array.isArray(item.attachments) ? item.attachments : [];
131
- for (const attachment of attachments) {
132
- out.push({
133
- section,
134
- item: (_c = (_b = item[labelField]) !== null && _b !== void 0 ? _b : item.name) !== null && _c !== void 0 ? _c : item.title,
135
- itemId: item._id,
136
- action: item.action,
137
- key: attachment.key,
138
- name: attachment.name,
139
- type: attachment.type,
140
- size: attachment.size,
141
- });
142
- }
143
- }
144
- }
145
- const objections = Array.isArray(filing.objections) ? filing.objections : [];
146
- for (const letter of objections) {
147
- for (const attachment of Array.isArray(letter.attachments) ? letter.attachments : []) {
148
- out.push({ section: 'objections', item: letter.letterDate, key: attachment.key, name: attachment.name, size: attachment.size });
149
- }
150
- }
151
- return out;
152
- }
4
+ const attachment_tools_1 = require("./filingramp/attachment-tools");
5
+ const document_search_tool_1 = require("./filingramp/document-search-tool");
6
+ const filing_detail_tool_1 = require("./filingramp/filing-detail-tool");
7
+ const filing_search_tools_1 = require("./filingramp/filing-search-tools");
153
8
  function createFilingRampTools(options) {
154
- const { client, workspaceDir, scope } = options;
155
- const industryData = client.industryData;
156
- const searchFilings = (0, ai_1.tool)({
157
- description: 'List filings matching filters (account filings by default). Lean rows: pass `fields` for exactly what you need. Page with lastItemId (sortKey "_id") until a page is shorter than limit. For counts or breakdowns use count_filings / summarize_filings instead — never page to count.',
158
- inputSchema: zod_1.z.object({
159
- text: zod_1.z.string().max(500).optional().describe('Free-text match over filing metadata'),
160
- filters: zod_1.z.array(filingsFilterSchema).max(30).optional(),
161
- fields: zod_1.z
162
- .array(zod_1.z.string().max(100))
163
- .max(40)
164
- .optional()
165
- .describe(`Filing fields to return, from: ${FILING_FIELDS.join(', ')}. Default ${DEFAULT_FILING_FIELDS.join(', ')}`),
166
- limit: zod_1.z.number().int().min(1).max(MAX_PAGE).optional(),
167
- lastItemId: zod_1.z.string().optional(),
168
- lastItemSortValue: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional(),
169
- sortKey: zod_1.z.string().max(60).optional(),
170
- sortDirection: zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]).optional(),
171
- searchType: searchTypeSchema,
172
- saveAs: zod_1.z.string().max(200).optional().describe('Also write the full page as JSON to this workspace path (e.g. data/filings/page-1.json)'),
173
- }),
174
- execute: async (input) => {
175
- var _b, _c, _d, _e;
176
- const searchType = (0, scope_1.resolveSearchType)(scope, industryData, input.searchType);
177
- const filters = (0, scope_1.scopeFilingsFilters)(scope, (0, filingramp_contract_1.normalizeFilingsFilters)(input.filters, 'search'));
178
- const fields = ((_b = input.fields) === null || _b === void 0 ? void 0 : _b.length) ? [...new Set(['_id', ...input.fields])] : DEFAULT_FILING_FIELDS;
179
- const limit = (_c = input.limit) !== null && _c !== void 0 ? _c : 100;
180
- let items;
181
- if (searchType === 'INDUSTRY') {
182
- // v2 has no industry search; v1 pages by offset. lastItemSortValue carries the offset here.
183
- const offset = typeof input.lastItemSortValue === 'number' ? input.lastItemSortValue : 0;
184
- const payload = await client.request('/v1/search/filings', {
185
- method: 'POST',
186
- body: { text: input.text, filters, limit, offset, searchType, sortKey: (_d = input.sortKey) !== null && _d !== void 0 ? _d : '_id', sortDirection: (_e = input.sortDirection) !== null && _e !== void 0 ? _e : 1 },
187
- });
188
- items = asRecordList(payload);
189
- }
190
- else {
191
- const requestPage = (fieldList) => {
192
- var _b, _c;
193
- return client.request('/v2/search/filings', {
194
- method: 'POST',
195
- body: {
196
- text: input.text,
197
- filters,
198
- fields: fieldList,
199
- limit,
200
- lastItemId: input.lastItemId,
201
- lastItemSortValue: input.lastItemSortValue,
202
- sortKey: (_b = input.sortKey) !== null && _b !== void 0 ? _b : '_id',
203
- sortDirection: (_c = input.sortDirection) !== null && _c !== void 0 ? _c : 1,
204
- searchType,
205
- },
206
- });
207
- };
208
- let payload;
209
- try {
210
- payload = await requestPage(fields);
211
- }
212
- catch (error) {
213
- // `"body.fields[7]" must be one of [...]`: drop what the API rejected and retry once.
214
- const allowed = allowedValuesFromError(error);
215
- if (!allowed)
216
- throw error;
217
- const kept = fields.filter((field) => allowed.has(field));
218
- if (kept.length === fields.length)
219
- throw error;
220
- payload = await requestPage(kept.length ? kept : DEFAULT_FILING_FIELDS);
221
- }
222
- items = asRecordList(payload);
223
- }
224
- const saved = input.saveAs ? await writeWorkspaceFile(workspaceDir, input.saveAs, JSON.stringify(items, null, 2)) : undefined;
225
- const rows = items.map((item) => pick(item, fields));
226
- const last = items[items.length - 1];
227
- return {
228
- count: rows.length,
229
- items: rows,
230
- nextLastItemId: rows.length === limit ? last === null || last === void 0 ? void 0 : last._id : undefined,
231
- nextOffset: searchType === 'INDUSTRY' && rows.length === limit ? ((typeof input.lastItemSortValue === 'number' ? input.lastItemSortValue : 0) + limit) : undefined,
232
- appliedFilters: filters,
233
- saved,
234
- };
235
- },
236
- });
237
- const countFilings = (0, ai_1.tool)({
238
- description: 'One total count of filings matching filters. For counts per state, line or status use summarize_filings.',
239
- inputSchema: zod_1.z.object({
240
- text: zod_1.z.string().max(500).optional(),
241
- filters: zod_1.z.array(filingsFilterSchema).max(30).optional(),
242
- searchType: searchTypeSchema,
243
- }),
244
- execute: async (input) => {
245
- var _b;
246
- const searchType = (0, scope_1.resolveSearchType)(scope, industryData, input.searchType);
247
- const filters = (0, scope_1.scopeFilingsFilters)(scope, (0, filingramp_contract_1.normalizeFilingsFilters)(input.filters, 'count'));
248
- const payload = await client.request('/v2/search/filings/count', {
249
- method: 'POST',
250
- body: { text: input.text, filters, searchType },
251
- });
252
- return { count: (_b = payload === null || payload === void 0 ? void 0 : payload.count) !== null && _b !== void 0 ? _b : 0, appliedFilters: filters };
253
- },
254
- });
255
- const summarizeFilings = (0, ai_1.tool)({
256
- description: 'Counts and totals per group (state, filingType, statusId, typeOfInsurance, subTypeOfInsurance, company, submittedMonth, dispositionMonth, source, businessType). Use this to size a population before reading documents, and for rankings or trends. Never page search_filings to count.',
257
- inputSchema: zod_1.z.object({
258
- text: zod_1.z.string().max(500).optional(),
259
- filters: zod_1.z.array(filingsFilterSchema).max(30).optional(),
260
- groupBy: zod_1.z.array(zod_1.z.string().max(40)).max(4).optional().describe('Singular names: state, typeOfInsurance, subTypeOfInsurance, filingType, statusId, company, businessType, source, submittedMonth, dispositionMonth, createdMonth. Omit for one total row.'),
261
- limit: zod_1.z.number().int().min(1).max(50000).optional(),
262
- sortBy: zod_1.z.enum(['key', 'filings']).optional(),
263
- searchType: searchTypeSchema,
264
- saveAs: zod_1.z.string().max(200).optional().describe('Write the full summary rows as JSON to this workspace path'),
265
- }),
266
- execute: async (input) => {
267
- var _b, _c;
268
- const searchType = (0, scope_1.resolveSearchType)(scope, industryData, input.searchType);
269
- const filters = (0, scope_1.scopeFilingsFilters)(scope, (0, filingramp_contract_1.normalizeFilingsFilters)(input.filters, 'summary'));
270
- const groupBy = (0, filingramp_contract_1.normalizeSummaryGroupBy)(input.groupBy);
271
- const payload = await client.request('/v2/search/filings/summary', {
272
- method: 'POST',
273
- body: { text: input.text, filters, groupBy, limit: input.limit, sortBy: input.sortBy, searchType },
274
- });
275
- const items = (_b = payload === null || payload === void 0 ? void 0 : payload.items) !== null && _b !== void 0 ? _b : [];
276
- const saved = input.saveAs ? await writeWorkspaceFile(workspaceDir, input.saveAs, JSON.stringify(items, null, 2)) : undefined;
277
- // Rows carry per-status day sums the model rarely needs; keep the counts.
278
- const rows = items.slice(0, 200).map((row) => ({
279
- key: row.key,
280
- filings: row.filings,
281
- filingsWithObjections: row.filingsWithObjections,
282
- filingsWithForms: row.filingsWithForms,
283
- objectionLetters: row.objectionLetters,
284
- forms: row.forms,
285
- rates: row.rates,
286
- statusIds: row.statusIds && typeof row.statusIds === 'object'
287
- ? Object.fromEntries(Object.entries(row.statusIds).map(([k, v]) => { var _b; return [k, (_b = v === null || v === void 0 ? void 0 : v.filings) !== null && _b !== void 0 ? _b : 0]; }))
288
- : undefined,
289
- }));
290
- return { rows, totalRows: items.length, truncated: (_c = payload === null || payload === void 0 ? void 0 : payload.truncated) !== null && _c !== void 0 ? _c : false, appliedFilters: filters, saved };
291
- },
292
- });
293
- const getFiling = (0, ai_1.tool)({
294
- description: 'One filing in full: general information, forms, rates, supporting documents, objection letters, dispositions and every attachment (with the `key` download_attachment needs). Large: ask for `include` sections only when you need them.',
295
- inputSchema: zod_1.z.object({
296
- id: zod_1.z.string().min(1).max(100).describe('Filing _id or SERFF tracking number'),
297
- include: zod_1.z.array(zod_1.z.enum(['general', 'forms', 'rates', 'supportings', 'objections', 'dispositions', 'attachments'])).optional(),
298
- saveAs: zod_1.z.string().max(200).optional().describe('Write the full filing JSON to this workspace path'),
299
- }),
300
- execute: async (input) => {
301
- var _b;
302
- const filing = await client.request(`/v1/filings/${encodeURIComponent(input.id)}`);
303
- const saved = input.saveAs ? await writeWorkspaceFile(workspaceDir, input.saveAs, JSON.stringify(filing, null, 2)) : undefined;
304
- const include = new Set((_b = input.include) !== null && _b !== void 0 ? _b : ['general', 'attachments']);
305
- const out = {
306
- _id: filing._id,
307
- trackingNumber: filing.trackingNumber,
308
- state: filing.state,
309
- statusId: filing.statusId,
310
- status: filing.status,
311
- filingType: filing.filingType,
312
- typeOfInsurance: filing.typeOfInsurance,
313
- subTypeOfInsurance: filing.subTypeOfInsurance,
314
- dateSubmitted: filing.dateSubmitted,
315
- companyNames: Array.isArray(filing.companies) ? filing.companies.map((c) => c.name) : undefined,
316
- };
317
- if (include.has('general'))
318
- out.generalInformation = filing.generalInformation;
319
- for (const section of ['forms', 'rates', 'supportings', 'objections', 'dispositions']) {
320
- if (!include.has(section))
321
- continue;
322
- const items = Array.isArray(filing[section]) ? filing[section] : [];
323
- out[section] = items.map((item) => {
324
- const { attachments: _a, ...rest } = item;
325
- return rest;
326
- });
327
- }
328
- if (include.has('attachments'))
329
- out.attachments = collectAttachments(filing);
330
- return { filing: out, saved };
331
- },
332
- });
333
- // Document search matches typeOfInsurance exactly, while the scope holds names or codes
334
- // ("Homeowners", "04.0"); the filings summary says which exact labels those stand for in this
335
- // account. Resolved once per process.
336
- let lineLabels;
337
- const scopeLineLabels = (searchType) => {
338
- var _b;
339
- if (!((_b = scope === null || scope === void 0 ? void 0 : scope.lines) === null || _b === void 0 ? void 0 : _b.length))
340
- return Promise.resolve({ lines: [], subLines: [] });
341
- lineLabels !== null && lineLabels !== void 0 ? lineLabels : (lineLabels = client
342
- .request('/v2/search/filings/summary', {
343
- method: 'POST',
344
- body: { filters: (0, scope_1.scopeFilingsFilters)(scope), groupBy: ['typeOfInsurance', 'subTypeOfInsurance'], limit: 1000, searchType },
345
- })
346
- .then((payload) => {
347
- var _b;
348
- const keys = ((_b = payload === null || payload === void 0 ? void 0 : payload.items) !== null && _b !== void 0 ? _b : []).map((row) => { var _b; return (_b = row.key) !== null && _b !== void 0 ? _b : {}; });
349
- const labels = (field) => [...new Set(keys.map((key) => key[field]).filter((value) => typeof value === 'string' && value.length > 0))];
350
- return { lines: labels('typeOfInsurance'), subLines: labels('subTypeOfInsurance') };
351
- })
352
- .catch((error) => {
353
- lineLabels = undefined;
354
- throw error;
355
- }));
356
- return lineLabels;
357
- };
358
- const requestDocuments = async (body) => {
359
- try {
360
- // ramp-web-api mounts the OpenSearch router at /content-search (POST /global).
361
- const payload = await client.request('/v1/content-search/global', {
362
- method: 'POST',
363
- body,
364
- timeoutMs: 120000,
365
- });
366
- return Array.isArray(payload) ? payload : asRecordList(payload);
367
- }
368
- catch (error) {
369
- if (error instanceof filingramp_client_1.FilingRampHttpError && error.status === 403) {
370
- throw new Error(`Document search is not enabled for this account (FilingRamp "searchV2" feature): ${error.message}. Report it in the findings; filing metadata tools still work.`);
371
- }
372
- if (error instanceof filingramp_client_1.FilingRampHttpError && error.status === 400 && /must be|is not a valid|not allowed|required|invalid/i.test(error.message)) {
373
- throw new Error(`Document search rejected the request: ${error.message}. Fix the filter (the tool description lists the fields and operators) and call again.`);
374
- }
375
- // FilingRamp hides OpenSearch failures (e.g. a missing document index) behind a generic
376
- // "An error occurred": rephrasing the query will not help, falling back will.
377
- if (error instanceof filingramp_client_1.FilingRampHttpError && (error.status === 400 || error.status >= 500)) {
378
- throw new Error(`Document search is unavailable (FilingRamp ${error.status}: ${error.message}). Do not retry it with other wording. ` +
379
- 'Find candidate filings with search_filings / summarize_filings, then read their documents with get_filing and download_attachment (extracted text lands in the workspace for grep). Note the gap in the findings.');
380
- }
381
- throw error;
382
- }
383
- };
384
- const searchDocuments = (0, ai_1.tool)({
385
- description: 'Full-text or semantic search INSIDE documents (extracted PDF text of forms, rate and supporting documents, objection letters, responses, library forms and rates, circulars). This is how you find which filings contain a clause. Returns hits with highlights; set saveText=true to write each hit\'s full extracted text to data/text/<trackingNumber>/<name>.txt for grep and analysis — never read whole documents into the chat. Filters use OpenSearch\'s vocabulary: states, typeOfInsurance, subTypeOfInsurance, filingTypes, statuses, resourceTypes, productIds, projectIds take exact string arrays ("in"); authors, contacts, reviewers match a substring ("cn"); dateSubmitted, createdAt, updatedAt take one date (eq/gt/gte/lt/lte). The session scope is added for you. Library and circular indexes accept only their own fields (resourceTypes, formNumbers, editionDates, circularNumbers…), so neither the scope nor filing filters apply to them; the result reports what was not applied.',
386
- inputSchema: zod_1.z.object({
387
- query: zod_1.z.string().min(1).max(2000),
388
- searchType: zod_1.z.enum(['KEYWORD', 'SEMANTIC', 'HYBRID']).optional().describe('KEYWORD for exact phrases (default), SEMANTIC for meaning, HYBRID for both'),
389
- indexes: zod_1.z
390
- .array(zod_1.z.enum(filingramp_contract_1.DOCUMENT_INDEXES))
391
- .min(1)
392
- .optional()
393
- .describe('Which document collections; default ["filings"]. A collection this deployment has no index for fails on its own (requests[].failed) while the others still answer.'),
394
- matchMode: zod_1.z.enum(['EXACT', 'ANY_WORD', 'PROXIMITY', 'PREFIX', 'FUZZY', 'BOOLEAN']).optional(),
395
- filters: zod_1.z.array(filterInputSchema).max(20).optional().describe('See the tool description for fields and operators'),
396
- scope: zod_1.z.enum(['ACCOUNT', 'INDUSTRY']).optional(),
397
- limit: zod_1.z.number().int().min(1).max(1000).optional(),
398
- saveText: zod_1.z.boolean().optional(),
399
- }),
400
- execute: async (input) => {
401
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
402
- const searchType = (_b = input.searchType) !== null && _b !== void 0 ? _b : 'KEYWORD';
403
- const suffix = searchType === 'KEYWORD' ? 'keyword_index' : 'semantic_index';
404
- const matchMode = (_c = input.matchMode) !== null && _c !== void 0 ? _c : (searchType === 'KEYWORD' ? 'EXACT' : 'ANY_WORD');
405
- const scopeValue = (0, scope_1.resolveSearchType)(scope, industryData, input.scope);
406
- const labels = await scopeLineLabels(scopeValue);
407
- const requests = [];
408
- const hits = [];
409
- const failures = [];
410
- let answered = 0;
411
- // One request per index group: each group has its own filter vocabulary, and one filter
412
- // outside it fails the whole request. A group whose indexes an environment does not have
413
- // (circulars on most deployments) fails alone; the other groups still answer.
414
- for (const group of (0, filingramp_contract_1.documentIndexGroups)((_d = input.indexes) !== null && _d !== void 0 ? _d : ['filings'])) {
415
- const own = (0, filingramp_contract_1.normalizeDocumentFilters)(input.filters, group);
416
- const scoped = (0, scope_1.scopeDocumentFilters)(scope, own.filters, group.fields, labels);
417
- const entry = { indexes: group.indexes, filters: scoped.filters, unscoped: scoped.unscoped, ignoredFilters: own.ignored };
418
- if (scoped.emptyByLines) {
419
- requests.push({ ...entry, skipped: "no filing in scope carries the scope's lines, so no document in these indexes can match" });
420
- continue;
421
- }
422
- try {
423
- const payload = await requestDocuments({
424
- searchType,
425
- searchText: input.query,
426
- matchMode,
427
- indexNames: group.indexes.map((index) => `${index}_${suffix}`),
428
- scope: scopeValue,
429
- limit: (_e = input.limit) !== null && _e !== void 0 ? _e : 50,
430
- filters: scoped.filters,
431
- });
432
- hits.push(...payload);
433
- requests.push(entry);
434
- answered += 1;
435
- }
436
- catch (error) {
437
- const failure = error instanceof Error ? error : new Error(String(error));
438
- failures.push(failure);
439
- requests.push({ ...entry, failed: failure.message });
440
- }
441
- }
442
- // Every group failed: the first failure carries the right instruction (fix the filter,
443
- // or fall back to downloads). A partial failure is reported per group instead.
444
- if (answered === 0 && failures.length > 0)
445
- throw failures[0];
446
- hits.sort((a, b) => { var _b, _c; return Number((_b = b._score) !== null && _b !== void 0 ? _b : 0) - Number((_c = a._score) !== null && _c !== void 0 ? _c : 0); });
447
- const results = [];
448
- for (const hit of hits.slice(0, MAX_DOC_HITS)) {
449
- const source = ((_f = hit._source) !== null && _f !== void 0 ? _f : {});
450
- const highlight = ((_g = hit.highlight) !== null && _g !== void 0 ? _g : {});
451
- const fragments = Object.values(highlight).flat().slice(0, MAX_HIGHLIGHTS);
452
- const text = typeof source.attachmentText === 'string' ? source.attachmentText : undefined;
453
- const trackingNumber = String((_l = (_k = (_j = (_h = source.trackingNumber) !== null && _h !== void 0 ? _h : source.filingTrackingNumber) !== null && _j !== void 0 ? _j : source.resourceId) !== null && _k !== void 0 ? _k : hit._id) !== null && _l !== void 0 ? _l : 'unknown');
454
- const name = String((_r = (_q = (_p = (_o = (_m = source.name) !== null && _m !== void 0 ? _m : source.attachmentName) !== null && _o !== void 0 ? _o : source.formNumber) !== null && _p !== void 0 ? _p : source.title) !== null && _q !== void 0 ? _q : hit._id) !== null && _r !== void 0 ? _r : 'document');
455
- let textPath;
456
- if (input.saveText && text) {
457
- textPath = `data/text/${safeName(trackingNumber)}/${safeName(name)}.txt`;
458
- await writeWorkspaceFile(workspaceDir, textPath, text);
459
- }
460
- results.push({
461
- id: hit._id,
462
- index: hit._index,
463
- score: hit._score,
464
- resourceType: source.resourceType,
465
- trackingNumber,
466
- state: source.state,
467
- filingType: source.filingType,
468
- dateSubmitted: source.dateSubmitted,
469
- name,
470
- formNumber: source.formNumber,
471
- attachmentKey: (_s = source.key) !== null && _s !== void 0 ? _s : source.attachmentKey,
472
- textChars: (_t = text === null || text === void 0 ? void 0 : text.length) !== null && _t !== void 0 ? _t : 0,
473
- textPath,
474
- highlights: fragments.map((fragment) => fragment.replace(/<\/?em>/g, '**').slice(0, 300)),
475
- });
476
- }
477
- return { hits: results, total: hits.length, truncated: hits.length > MAX_DOC_HITS, requests };
478
- },
479
- });
480
- const downloadAttachment = (0, ai_1.tool)({
481
- description: 'Download one attachment by key into data/attachments/<trackingNumber>/<name> and, for PDFs, extract its text to data/text/<trackingNumber>/<name>.txt. Use when search_documents has no text for a document (large or scanned PDFs) or you need the original file. Returns paths and sizes, never the content.',
482
- inputSchema: zod_1.z.object({
483
- key: zod_1.z.string().min(1).max(2000),
484
- trackingNumber: zod_1.z.string().max(100).optional(),
485
- name: zod_1.z.string().max(300).optional(),
486
- extractText: zod_1.z.boolean().optional().describe('default true for PDFs'),
487
- }),
488
- execute: async (input) => {
489
- var _b, _c, _d;
490
- const bytes = await client.downloadAttachment(input.key);
491
- const folder = safeName((_b = input.trackingNumber) !== null && _b !== void 0 ? _b : 'misc');
492
- const fileName = safeName((_d = (_c = input.name) !== null && _c !== void 0 ? _c : input.key.split('/').pop()) !== null && _d !== void 0 ? _d : 'attachment');
493
- const filePath = `data/attachments/${folder}/${fileName}`;
494
- const written = await writeWorkspaceFile(workspaceDir, filePath, bytes);
495
- const isPdf = /\.pdf$/i.test(fileName) || bytes.subarray(0, 4).toString() === '%PDF';
496
- let textPath;
497
- let textChars = 0;
498
- if (isPdf && input.extractText !== false) {
499
- textPath = `data/text/${folder}/${fileName.replace(/\.pdf$/i, '')}.txt`;
500
- const absoluteText = path_1.default.resolve(workspaceDir, textPath);
501
- await fs_1.promises.mkdir(path_1.default.dirname(absoluteText), { recursive: true });
502
- textChars = await extractPdfText(path_1.default.resolve(workspaceDir, filePath), absoluteText);
503
- if (textChars === 0)
504
- textPath = undefined;
505
- }
506
- return {
507
- path: written.path,
508
- bytes: written.bytes,
509
- textPath,
510
- textChars,
511
- note: isPdf && textChars === 0 ? 'No extractable text (scanned or protected PDF) — record it as unreadable in findings.' : undefined,
512
- };
513
- },
514
- });
515
- const searchObjections = (0, ai_1.tool)({
516
- description: 'Objection letters on account filings, open or closed, with their respond-by dates. Account data only.',
517
- inputSchema: zod_1.z.object({
518
- type: zod_1.z.enum(['OPEN', 'CLOSED']),
519
- filters: zod_1.z.array(filingsFilterSchema).max(20).optional(),
520
- limit: zod_1.z.number().int().min(1).max(MAX_PAGE).optional(),
521
- offset: zod_1.z.number().int().min(0).optional(),
522
- sortKey: zod_1.z.enum(['filingType', 'objection.letterDate', 'objection.respondByDate']).optional(),
523
- sortDirection: zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]).optional(),
524
- }),
525
- execute: async (input) => {
526
- var _b, _c, _d, _e, _f;
527
- const filters = (0, scope_1.scopeFilingsFilters)(scope, (0, filingramp_contract_1.normalizeFilingsFilters)(input.filters, 'objections'));
528
- const payload = await client.request('/v2/search/filings/objections', {
529
- method: 'POST',
530
- query: { type: input.type },
531
- body: { filters, limit: (_b = input.limit) !== null && _b !== void 0 ? _b : 50, offset: (_c = input.offset) !== null && _c !== void 0 ? _c : 0, sortKey: input.sortKey, sortDirection: (_d = input.sortDirection) !== null && _d !== void 0 ? _d : -1 },
532
- });
533
- return { count: (_e = payload === null || payload === void 0 ? void 0 : payload.count) !== null && _e !== void 0 ? _e : 0, items: (_f = payload === null || payload === void 0 ? void 0 : payload.items) !== null && _f !== void 0 ? _f : [], appliedFilters: filters };
534
- },
535
- });
536
- const readText = (0, ai_1.tool)({
537
- description: 'Read a slice of an extracted text file in the workspace (data/text/…). Prefer run_command with rg/grep to locate the passage first, then read only the lines around it. Hard cap per call keeps the conversation small.',
538
- inputSchema: zod_1.z.object({
539
- path: zod_1.z.string().min(1).max(500),
540
- startLine: zod_1.z.number().int().min(1).optional(),
541
- endLine: zod_1.z.number().int().min(1).optional(),
542
- }),
543
- execute: async (input) => {
544
- var _b, _c;
545
- const target = path_1.default.resolve(workspaceDir, input.path);
546
- if (!target.startsWith(path_1.default.resolve(workspaceDir) + path_1.default.sep))
547
- throw new Error('path escapes the workspace');
548
- const content = await fs_1.promises.readFile(target, 'utf8');
549
- const lines = content.split('\n');
550
- const start = Math.max(1, (_b = input.startLine) !== null && _b !== void 0 ? _b : 1);
551
- const end = Math.min(lines.length, (_c = input.endLine) !== null && _c !== void 0 ? _c : start + 80);
552
- const slice = lines.slice(start - 1, end).join('\n');
553
- return {
554
- path: input.path,
555
- totalLines: lines.length,
556
- startLine: start,
557
- endLine: end,
558
- text: slice.length > MAX_INLINE_TEXT_CHARS ? `${slice.slice(0, MAX_INLINE_TEXT_CHARS)}…[truncated — narrow the line range]` : slice,
559
- };
560
- },
561
- });
9
+ const filings = (0, filing_search_tools_1.createFilingSearchTools)(options);
10
+ const attachments = (0, attachment_tools_1.createAttachmentTools)(options);
562
11
  return {
563
- search_filings: searchFilings,
564
- count_filings: countFilings,
565
- summarize_filings: summarizeFilings,
566
- get_filing: getFiling,
567
- search_documents: searchDocuments,
568
- download_attachment: downloadAttachment,
569
- search_objections: searchObjections,
570
- read_text: readText,
12
+ search_filings: filings.search_filings,
13
+ count_filings: filings.count_filings,
14
+ summarize_filings: filings.summarize_filings,
15
+ get_filing: (0, filing_detail_tool_1.createFilingDetailTool)(options),
16
+ search_documents: (0, document_search_tool_1.createDocumentSearchTool)(options),
17
+ download_attachment: attachments.download_attachment,
18
+ search_objections: filings.search_objections,
19
+ read_text: attachments.read_text,
571
20
  };
572
21
  }
573
22
  //# sourceMappingURL=filingramp-tools.js.map