@moldea.ai/adapter-langchain 1.0.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/LICENSE +21 -0
- package/README.md +41 -0
- package/cover.png +0 -0
- package/dist/adapter/index.d.ts +3 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/constants/index.d.ts +8 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/contracts/index.d.ts +192 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/diagnostics/index.d.ts +23 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2023 -0
- package/dist/inspection/common.d.ts +21 -0
- package/dist/inspection/common.d.ts.map +1 -0
- package/dist/inspection/index.d.ts +2 -0
- package/dist/inspection/index.d.ts.map +1 -0
- package/dist/inspection/inspection.d.ts +18 -0
- package/dist/inspection/inspection.d.ts.map +1 -0
- package/dist/inspection/instruction-inspection.d.ts +6 -0
- package/dist/inspection/instruction-inspection.d.ts.map +1 -0
- package/dist/inspection/middleware-inspection.d.ts +5 -0
- package/dist/inspection/middleware-inspection.d.ts.map +1 -0
- package/dist/inspection/package-inspection.d.ts +7 -0
- package/dist/inspection/package-inspection.d.ts.map +1 -0
- package/dist/inspection/resolution.d.ts +7 -0
- package/dist/inspection/resolution.d.ts.map +1 -0
- package/dist/inspection/schema-inspection.d.ts +6 -0
- package/dist/inspection/schema-inspection.d.ts.map +1 -0
- package/dist/inspection/session.d.ts +5 -0
- package/dist/inspection/session.d.ts.map +1 -0
- package/dist/inspection/tool-inspection.d.ts +6 -0
- package/dist/inspection/tool-inspection.d.ts.map +1 -0
- package/dist/package-discovery/index.d.ts +5 -0
- package/dist/package-discovery/index.d.ts.map +1 -0
- package/dist/source-analysis/agent-definitions.d.ts +4 -0
- package/dist/source-analysis/agent-definitions.d.ts.map +1 -0
- package/dist/source-analysis/bindings.d.ts +20 -0
- package/dist/source-analysis/bindings.d.ts.map +1 -0
- package/dist/source-analysis/function-tools.d.ts +7 -0
- package/dist/source-analysis/function-tools.d.ts.map +1 -0
- package/dist/source-analysis/index.d.ts +7 -0
- package/dist/source-analysis/index.d.ts.map +1 -0
- package/dist/source-analysis/source-analysis.d.ts +5 -0
- package/dist/source-analysis/source-analysis.d.ts.map +1 -0
- package/dist/source-analysis/static-strings.d.ts +5 -0
- package/dist/source-analysis/static-strings.d.ts.map +1 -0
- package/dist/source-analysis/structured-output.d.ts +12 -0
- package/dist/source-analysis/structured-output.d.ts.map +1 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2023 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import { intersects, subset, validRange } from "semver";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
import { parseRepositoryPath } from "@moldea.ai/repository";
|
|
5
|
+
//#region src/constants/index.ts
|
|
6
|
+
var LANGCHAIN_ADAPTER_ID = "langchain";
|
|
7
|
+
var LANGCHAIN_PACKAGE_NAME = "langchain";
|
|
8
|
+
var LANGCHAIN_CORE_PACKAGE_NAME = "@langchain/core";
|
|
9
|
+
var LANGCHAIN_SUPPORTED_PACKAGE_RANGE = ">=1.5.9 <1.6.0";
|
|
10
|
+
var LANGCHAIN_CORE_SUPPORTED_PACKAGE_RANGE = ">=1.2.8 <1.3.0";
|
|
11
|
+
var LANGCHAIN_TARGET_ID = "typescript-create-agent-1-5";
|
|
12
|
+
var LANGCHAIN_SUPPORTED_REPOSITORY_FORMAT_VERSIONS = Object.freeze([1]);
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region ../../packages/adapter-static-analysis/dist/index.js
|
|
15
|
+
/**
|
|
16
|
+
* Creates an operation-local inspection session with deterministic promise caches.
|
|
17
|
+
* @param options Provider callbacks and the optional operation signal.
|
|
18
|
+
* @returns Cached source, package, and entry inspection functions.
|
|
19
|
+
* @throws If the inspection is aborted.
|
|
20
|
+
*/
|
|
21
|
+
var createInspectionSession = (options) => {
|
|
22
|
+
const sourceCache = /* @__PURE__ */ new Map();
|
|
23
|
+
const packageCache = /* @__PURE__ */ new Map();
|
|
24
|
+
const entryCache = /* @__PURE__ */ new Map();
|
|
25
|
+
const analyzeSource = (path) => {
|
|
26
|
+
options.signal?.throwIfAborted();
|
|
27
|
+
const existing = sourceCache.get(path);
|
|
28
|
+
if (existing !== void 0) return existing;
|
|
29
|
+
const analysis = (async () => {
|
|
30
|
+
options.signal?.throwIfAborted();
|
|
31
|
+
const bytes = await options.readFile(path, options.signal);
|
|
32
|
+
options.signal?.throwIfAborted();
|
|
33
|
+
const result = await options.analyzeSource(path, bytes, options.signal);
|
|
34
|
+
options.signal?.throwIfAborted();
|
|
35
|
+
return result;
|
|
36
|
+
})();
|
|
37
|
+
sourceCache.set(path, analysis);
|
|
38
|
+
return analysis;
|
|
39
|
+
};
|
|
40
|
+
const discoverPackage = (path) => {
|
|
41
|
+
options.signal?.throwIfAborted();
|
|
42
|
+
const existing = packageCache.get(path);
|
|
43
|
+
if (existing !== void 0) return existing;
|
|
44
|
+
const discovery = options.discoverPackage(path, options.signal);
|
|
45
|
+
packageCache.set(path, discovery);
|
|
46
|
+
return discovery;
|
|
47
|
+
};
|
|
48
|
+
const getEntry = (path) => {
|
|
49
|
+
options.signal?.throwIfAborted();
|
|
50
|
+
const existing = entryCache.get(path);
|
|
51
|
+
if (existing !== void 0) return existing;
|
|
52
|
+
const entry = options.getEntry(path, options.signal);
|
|
53
|
+
entryCache.set(path, entry);
|
|
54
|
+
return entry;
|
|
55
|
+
};
|
|
56
|
+
return Object.freeze({
|
|
57
|
+
analyzeSource,
|
|
58
|
+
discoverPackage,
|
|
59
|
+
getEntry,
|
|
60
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
var decoder = new TextDecoder("utf-8", {
|
|
64
|
+
fatal: true,
|
|
65
|
+
ignoreBOM: true
|
|
66
|
+
});
|
|
67
|
+
var findLineIndex = (lineStarts, offset) => {
|
|
68
|
+
let lower = 0;
|
|
69
|
+
let upper = lineStarts.length - 1;
|
|
70
|
+
while (lower < upper) {
|
|
71
|
+
const middle = Math.ceil((lower + upper) / 2);
|
|
72
|
+
if ((lineStarts[middle] ?? 0) <= offset) lower = middle;
|
|
73
|
+
else upper = middle - 1;
|
|
74
|
+
}
|
|
75
|
+
return lower;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Creates a TypeScript UTF-16-offset to Unicode-scalar source locator.
|
|
79
|
+
* @param value The normalized valid Unicode-scalar text.
|
|
80
|
+
* @returns The scalar-aware source locator.
|
|
81
|
+
*/
|
|
82
|
+
var createSourceLocator = (value) => {
|
|
83
|
+
const scalarOffsets = new Uint32Array(value.length + 1);
|
|
84
|
+
const lineStarts = [0];
|
|
85
|
+
let scalarOffset = 0;
|
|
86
|
+
for (let codeUnitOffset = 0; codeUnitOffset < value.length;) {
|
|
87
|
+
const codePoint = value.codePointAt(codeUnitOffset);
|
|
88
|
+
const width = codePoint !== void 0 && codePoint > 65535 ? 2 : 1;
|
|
89
|
+
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
90
|
+
for (let interiorOffset = 1; interiorOffset < width; interiorOffset += 1) scalarOffsets[codeUnitOffset + interiorOffset] = scalarOffset;
|
|
91
|
+
codeUnitOffset += width;
|
|
92
|
+
scalarOffset += 1;
|
|
93
|
+
scalarOffsets[codeUnitOffset] = scalarOffset;
|
|
94
|
+
if (codePoint === 10) lineStarts.push(codeUnitOffset);
|
|
95
|
+
}
|
|
96
|
+
const locatePosition = (candidateOffset) => {
|
|
97
|
+
const codeUnitOffset = Math.max(0, Math.min(value.length, candidateOffset));
|
|
98
|
+
const lineIndex = findLineIndex(lineStarts, codeUnitOffset);
|
|
99
|
+
const lineStart = lineStarts[lineIndex] ?? 0;
|
|
100
|
+
const positionScalarOffset = scalarOffsets[codeUnitOffset] ?? 0;
|
|
101
|
+
return {
|
|
102
|
+
column: positionScalarOffset - (scalarOffsets[lineStart] ?? 0) + 1,
|
|
103
|
+
line: lineIndex + 1,
|
|
104
|
+
offset: positionScalarOffset
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
return Object.freeze({ locateRange: (startOffset, endOffset) => ({
|
|
108
|
+
end: locatePosition(endOffset),
|
|
109
|
+
start: locatePosition(startOffset)
|
|
110
|
+
}) });
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Decodes and normalizes source bytes through the runtime-adapter text contract.
|
|
114
|
+
* @param bytes The exact reader-owned source bytes.
|
|
115
|
+
* @returns The normalized text and locator or an invalid-text result.
|
|
116
|
+
*/
|
|
117
|
+
var normalizeText = (bytes) => {
|
|
118
|
+
let decoded;
|
|
119
|
+
try {
|
|
120
|
+
decoded = decoder.decode(bytes);
|
|
121
|
+
} catch {
|
|
122
|
+
return Object.freeze({ valid: false });
|
|
123
|
+
}
|
|
124
|
+
const value = (decoded.startsWith("") ? decoded.slice(1) : decoded).replace(/\r\n?/gu, "\n");
|
|
125
|
+
if (value.includes("\0")) return Object.freeze({ valid: false });
|
|
126
|
+
return Object.freeze({
|
|
127
|
+
locator: createSourceLocator(value),
|
|
128
|
+
valid: true,
|
|
129
|
+
value
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
var PACKAGE_DEPENDENCY_FIELDS = Object.freeze([
|
|
133
|
+
"dependencies",
|
|
134
|
+
"optionalDependencies",
|
|
135
|
+
"peerDependencies",
|
|
136
|
+
"devDependencies"
|
|
137
|
+
]);
|
|
138
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
139
|
+
/**
|
|
140
|
+
* Creates nearest-to-root package-manifest candidates for one source path.
|
|
141
|
+
* @param sourcePath The normalized source path.
|
|
142
|
+
* @returns Deterministically ordered manifest paths.
|
|
143
|
+
*/
|
|
144
|
+
var createPackageManifestCandidatePaths = (sourcePath) => {
|
|
145
|
+
const candidates = [];
|
|
146
|
+
let directory = posix.dirname(sourcePath);
|
|
147
|
+
while (true) {
|
|
148
|
+
candidates.push(posix.join(directory, "package.json"));
|
|
149
|
+
if (directory === "/") break;
|
|
150
|
+
directory = posix.dirname(directory);
|
|
151
|
+
}
|
|
152
|
+
return Object.freeze(candidates);
|
|
153
|
+
};
|
|
154
|
+
var extractPackageDeclarations = (manifest, packageName) => {
|
|
155
|
+
const declarations = [];
|
|
156
|
+
for (const field of PACKAGE_DEPENDENCY_FIELDS) {
|
|
157
|
+
const dependencies = manifest[field];
|
|
158
|
+
if (dependencies === void 0) continue;
|
|
159
|
+
if (!isRecord(dependencies)) return null;
|
|
160
|
+
const declaration = dependencies[packageName];
|
|
161
|
+
if (declaration === void 0) continue;
|
|
162
|
+
if (typeof declaration !== "string" || declaration.trim().length === 0) return null;
|
|
163
|
+
declarations.push(Object.freeze({
|
|
164
|
+
declaredRange: declaration,
|
|
165
|
+
dependencyKind: field
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
return declarations;
|
|
169
|
+
};
|
|
170
|
+
var classifyPackageDeclarations = (declarations, supportedRange) => {
|
|
171
|
+
const classifications = declarations.map(({ declaredRange }) => {
|
|
172
|
+
const normalizedRange = validRange(declaredRange, {
|
|
173
|
+
loose: false,
|
|
174
|
+
includePrerelease: false
|
|
175
|
+
});
|
|
176
|
+
if (normalizedRange === null) return "ambiguous";
|
|
177
|
+
if (subset(normalizedRange, supportedRange, {
|
|
178
|
+
loose: false,
|
|
179
|
+
includePrerelease: false
|
|
180
|
+
})) return "supported";
|
|
181
|
+
if (!intersects(normalizedRange, supportedRange, {
|
|
182
|
+
loose: false,
|
|
183
|
+
includePrerelease: false
|
|
184
|
+
})) return "unsupported";
|
|
185
|
+
return "ambiguous";
|
|
186
|
+
});
|
|
187
|
+
if (classifications.every((classification) => classification === "supported")) return "supported";
|
|
188
|
+
if (classifications.every((classification) => classification === "unsupported")) return "unsupported";
|
|
189
|
+
return "ambiguous";
|
|
190
|
+
};
|
|
191
|
+
var readOwningManifest = async (options) => {
|
|
192
|
+
const { reader, signal, sourcePath } = options;
|
|
193
|
+
for (const manifestPath of createPackageManifestCandidatePaths(sourcePath)) {
|
|
194
|
+
signal?.throwIfAborted();
|
|
195
|
+
const entry = await reader.getEntry(manifestPath);
|
|
196
|
+
signal?.throwIfAborted();
|
|
197
|
+
if (entry === null) continue;
|
|
198
|
+
if (entry.type !== "file") return Object.freeze({
|
|
199
|
+
kind: "invalid",
|
|
200
|
+
path: manifestPath
|
|
201
|
+
});
|
|
202
|
+
const bytes = await reader.readFile(manifestPath);
|
|
203
|
+
signal?.throwIfAborted();
|
|
204
|
+
const text = normalizeText(bytes);
|
|
205
|
+
signal?.throwIfAborted();
|
|
206
|
+
if (!text.valid) return Object.freeze({
|
|
207
|
+
kind: "invalid",
|
|
208
|
+
path: manifestPath
|
|
209
|
+
});
|
|
210
|
+
let parsed;
|
|
211
|
+
try {
|
|
212
|
+
parsed = JSON.parse(text.value);
|
|
213
|
+
} catch {
|
|
214
|
+
return Object.freeze({
|
|
215
|
+
kind: "invalid",
|
|
216
|
+
path: manifestPath
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
signal?.throwIfAborted();
|
|
220
|
+
return isRecord(parsed) ? Object.freeze({
|
|
221
|
+
kind: "present",
|
|
222
|
+
manifest: parsed,
|
|
223
|
+
path: manifestPath
|
|
224
|
+
}) : Object.freeze({
|
|
225
|
+
kind: "invalid",
|
|
226
|
+
path: manifestPath
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return Object.freeze({ kind: "absent" });
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Discovers multiple package declarations from one nearest owning manifest read.
|
|
233
|
+
* @param options The package targets, repository callbacks, source path, and signal.
|
|
234
|
+
* @returns The owning manifest's package observations, invalid state, or absence.
|
|
235
|
+
* @throws If repository reading or the active inspection is aborted.
|
|
236
|
+
*/
|
|
237
|
+
var discoverPackages = async (options) => {
|
|
238
|
+
const owningManifest = await readOwningManifest(options);
|
|
239
|
+
if (owningManifest.kind !== "present") return owningManifest;
|
|
240
|
+
const packages = [];
|
|
241
|
+
for (const target of options.packages) {
|
|
242
|
+
const declarations = extractPackageDeclarations(owningManifest.manifest, target.packageName);
|
|
243
|
+
if (declarations === null) return Object.freeze({
|
|
244
|
+
kind: "invalid",
|
|
245
|
+
path: owningManifest.path
|
|
246
|
+
});
|
|
247
|
+
packages.push(Object.freeze({
|
|
248
|
+
compatibility: declarations.length === 0 ? "absent" : classifyPackageDeclarations(declarations, target.supportedRange),
|
|
249
|
+
declarations: Object.freeze(declarations),
|
|
250
|
+
packageName: target.packageName
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
return Object.freeze({
|
|
254
|
+
kind: "observed",
|
|
255
|
+
observation: Object.freeze({
|
|
256
|
+
packages: Object.freeze(packages),
|
|
257
|
+
path: owningManifest.path
|
|
258
|
+
})
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Removes the transparent expression wrappers supported by runtime adapters.
|
|
263
|
+
* @param expression The expression to normalize.
|
|
264
|
+
* @returns The underlying expression used by static matching.
|
|
265
|
+
*/
|
|
266
|
+
var unwrapExpression = (expression) => {
|
|
267
|
+
let current = expression;
|
|
268
|
+
while (ts.isAsExpression(current) || ts.isParenthesizedExpression(current) || ts.isSatisfiesExpression(current)) current = current.expression;
|
|
269
|
+
return current;
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Resolves one direct call with an optional outer `await` wrapper.
|
|
273
|
+
* @param expression The candidate call expression.
|
|
274
|
+
* @returns The direct call or `null` when the form is unsupported.
|
|
275
|
+
*/
|
|
276
|
+
var getDirectCall = (expression) => {
|
|
277
|
+
const unwrapped = unwrapExpression(expression);
|
|
278
|
+
const candidate = ts.isAwaitExpression(unwrapped) ? unwrapExpression(unwrapped.expression) : unwrapped;
|
|
279
|
+
return ts.isCallExpression(candidate) ? candidate : null;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Reads an exact static string literal from one expression.
|
|
283
|
+
* @param expression The candidate string expression.
|
|
284
|
+
* @returns Its exact value or `null` when dynamic.
|
|
285
|
+
*/
|
|
286
|
+
var getStaticString = (expression) => {
|
|
287
|
+
if (expression === null || expression === void 0) return null;
|
|
288
|
+
const candidate = unwrapExpression(expression);
|
|
289
|
+
return ts.isStringLiteral(candidate) || ts.isNoSubstitutionTemplateLiteral(candidate) ? candidate.text : null;
|
|
290
|
+
};
|
|
291
|
+
var hasModifier = (node, kind) => ts.canHaveModifiers(node) && (ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false);
|
|
292
|
+
var isConstDeclarationList = (declarationList) => (declarationList.flags & ts.NodeFlags.Const) !== 0;
|
|
293
|
+
/**
|
|
294
|
+
* Indexes static value imports and supported SDK constructor imports.
|
|
295
|
+
* @param sourceFile The parsed TypeScript source.
|
|
296
|
+
* @param config The provider package and constructor import forms.
|
|
297
|
+
* @returns Module-owned import bindings needed by static checks.
|
|
298
|
+
*/
|
|
299
|
+
var indexImports = (sourceFile, config) => {
|
|
300
|
+
const constructorNames = /* @__PURE__ */ new Set();
|
|
301
|
+
const namedImports = /* @__PURE__ */ new Map();
|
|
302
|
+
const supportedNamedImports = new Set(config.namedConstructorImports);
|
|
303
|
+
for (const statement of sourceFile.statements) {
|
|
304
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
305
|
+
const importClause = statement.importClause;
|
|
306
|
+
if (importClause?.isTypeOnly === true) continue;
|
|
307
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
308
|
+
if (moduleSpecifier === config.packageName && config.supportsDefaultConstructorImport && importClause?.name !== void 0) constructorNames.add(importClause.name.text);
|
|
309
|
+
if (moduleSpecifier === config.packageName && importClause?.namedBindings !== void 0 && ts.isNamedImports(importClause.namedBindings)) for (const element of importClause.namedBindings.elements) {
|
|
310
|
+
const importedName = element.propertyName?.text ?? element.name.text;
|
|
311
|
+
if (!element.isTypeOnly && supportedNamedImports.has(importedName)) constructorNames.add(element.name.text);
|
|
312
|
+
}
|
|
313
|
+
if (!moduleSpecifier.startsWith(".") || importClause?.namedBindings === void 0 || !ts.isNamedImports(importClause.namedBindings)) continue;
|
|
314
|
+
for (const element of importClause.namedBindings.elements) {
|
|
315
|
+
if (element.isTypeOnly) continue;
|
|
316
|
+
namedImports.set(element.name.text, Object.freeze({
|
|
317
|
+
importedName: element.propertyName?.text ?? element.name.text,
|
|
318
|
+
moduleSpecifier
|
|
319
|
+
}));
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
constructorNames,
|
|
324
|
+
namedImports
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Indexes direct exports, module-level SDK clients, and constant arrays.
|
|
329
|
+
* @param sourceFile The parsed TypeScript source.
|
|
330
|
+
* @param constructorNames The supported constructor bindings.
|
|
331
|
+
* @returns Static module declarations used by adapter inspection.
|
|
332
|
+
*/
|
|
333
|
+
var indexModuleDeclarations = (sourceFile, constructorNames) => {
|
|
334
|
+
const clientNames = /* @__PURE__ */ new Set();
|
|
335
|
+
const exports = /* @__PURE__ */ new Map();
|
|
336
|
+
const moduleArrays = /* @__PURE__ */ new Map();
|
|
337
|
+
const moduleConstDeclarations = /* @__PURE__ */ new Map();
|
|
338
|
+
for (const statement of sourceFile.statements) {
|
|
339
|
+
if (ts.isFunctionDeclaration(statement) && statement.name !== void 0) {
|
|
340
|
+
if (hasModifier(statement, ts.SyntaxKind.ExportKeyword)) exports.set(statement.name.text, Object.freeze({
|
|
341
|
+
declaration: statement,
|
|
342
|
+
kind: statement.body === void 0 || hasModifier(statement, ts.SyntaxKind.DefaultKeyword) ? "present-unsupported" : "present-supported"
|
|
343
|
+
}));
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (ts.isExportDeclaration(statement) && statement.exportClause !== void 0) {
|
|
347
|
+
if (!ts.isNamedExports(statement.exportClause) || statement.isTypeOnly) continue;
|
|
348
|
+
for (const element of statement.exportClause.elements) if (!element.isTypeOnly) exports.set(element.name.text, Object.freeze({
|
|
349
|
+
declaration: element,
|
|
350
|
+
kind: "present-unsupported"
|
|
351
|
+
}));
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if (!ts.isVariableStatement(statement)) {
|
|
355
|
+
if (hasModifier(statement, ts.SyntaxKind.ExportKeyword) && (ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement) || ts.isModuleDeclaration(statement)) && statement.name !== void 0 && ts.isIdentifier(statement.name)) exports.set(statement.name.text, Object.freeze({
|
|
356
|
+
declaration: statement,
|
|
357
|
+
kind: "present-unsupported"
|
|
358
|
+
}));
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const isConst = isConstDeclarationList(statement.declarationList);
|
|
362
|
+
const isExported = hasModifier(statement, ts.SyntaxKind.ExportKeyword);
|
|
363
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
364
|
+
if (!ts.isIdentifier(declaration.name)) continue;
|
|
365
|
+
if (isExported) exports.set(declaration.name.text, Object.freeze({
|
|
366
|
+
declaration,
|
|
367
|
+
kind: isConst && declaration.initializer !== void 0 ? "present-supported" : "present-unsupported"
|
|
368
|
+
}));
|
|
369
|
+
if (!isConst || declaration.initializer === void 0) continue;
|
|
370
|
+
moduleConstDeclarations.set(declaration.name.text, declaration);
|
|
371
|
+
const initializer = unwrapExpression(declaration.initializer);
|
|
372
|
+
if (ts.isNewExpression(initializer)) {
|
|
373
|
+
const constructor = unwrapExpression(initializer.expression);
|
|
374
|
+
if (ts.isIdentifier(constructor) && constructorNames.has(constructor.text)) clientNames.add(declaration.name.text);
|
|
375
|
+
}
|
|
376
|
+
if (ts.isArrayLiteralExpression(initializer)) moduleArrays.set(declaration.name.text, Object.freeze({
|
|
377
|
+
declaration,
|
|
378
|
+
expression: initializer
|
|
379
|
+
}));
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return {
|
|
383
|
+
clientNames,
|
|
384
|
+
exports,
|
|
385
|
+
moduleArrays,
|
|
386
|
+
moduleConstDeclarations
|
|
387
|
+
};
|
|
388
|
+
};
|
|
389
|
+
var addBindingNames = (names, bindingName) => {
|
|
390
|
+
if (ts.isIdentifier(bindingName)) {
|
|
391
|
+
names.add(bindingName.text);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
for (const element of bindingName.elements) if (!ts.isOmittedExpression(element)) addBindingNames(names, element.name);
|
|
395
|
+
};
|
|
396
|
+
var addVariableDeclarationListBindings = (names, declarationList) => {
|
|
397
|
+
for (const declaration of declarationList.declarations) addBindingNames(names, declaration.name);
|
|
398
|
+
};
|
|
399
|
+
var addStatementBindings = (names, statement) => {
|
|
400
|
+
if (ts.isVariableStatement(statement)) {
|
|
401
|
+
addVariableDeclarationListBindings(names, statement.declarationList);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement) || ts.isModuleDeclaration(statement)) {
|
|
405
|
+
if (statement.name !== void 0 && ts.isIdentifier(statement.name)) names.add(statement.name.text);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
var isFunctionScope = (node) => ts.isArrowFunction(node) || ts.isConstructorDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isGetAccessorDeclaration(node) || ts.isMethodDeclaration(node) || ts.isSetAccessorDeclaration(node);
|
|
409
|
+
var getLocalBindingNames = (bindings, scope) => {
|
|
410
|
+
const existingNames = bindings.get(scope);
|
|
411
|
+
if (existingNames !== void 0) return existingNames;
|
|
412
|
+
const names = /* @__PURE__ */ new Set();
|
|
413
|
+
bindings.set(scope, names);
|
|
414
|
+
return names;
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Indexes local runtime bindings that can shadow module-owned identifiers.
|
|
418
|
+
* @param sourceFile The parsed TypeScript source.
|
|
419
|
+
* @returns Local binding names keyed by lexical or function scope.
|
|
420
|
+
*/
|
|
421
|
+
var indexLocalBindingNames = (sourceFile) => {
|
|
422
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
423
|
+
const visit = (node, functionScope) => {
|
|
424
|
+
let childFunctionScope = functionScope;
|
|
425
|
+
if (isFunctionScope(node)) {
|
|
426
|
+
const names = getLocalBindingNames(bindings, node);
|
|
427
|
+
for (const parameter of node.parameters) addBindingNames(names, parameter.name);
|
|
428
|
+
if (node.name !== void 0 && ts.isIdentifier(node.name)) names.add(node.name.text);
|
|
429
|
+
childFunctionScope = node;
|
|
430
|
+
}
|
|
431
|
+
if (ts.isBlock(node) || ts.isModuleBlock(node)) {
|
|
432
|
+
const names = getLocalBindingNames(bindings, node);
|
|
433
|
+
for (const statement of node.statements) addStatementBindings(names, statement);
|
|
434
|
+
} else if (ts.isCaseBlock(node)) {
|
|
435
|
+
const names = getLocalBindingNames(bindings, node);
|
|
436
|
+
for (const clause of node.clauses) for (const statement of clause.statements) addStatementBindings(names, statement);
|
|
437
|
+
} else if (ts.isCatchClause(node) && node.variableDeclaration !== void 0) addBindingNames(getLocalBindingNames(bindings, node), node.variableDeclaration.name);
|
|
438
|
+
else if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer !== void 0 && ts.isVariableDeclarationList(node.initializer)) addVariableDeclarationListBindings(getLocalBindingNames(bindings, node), node.initializer);
|
|
439
|
+
else if (ts.isClassExpression(node) && node.name !== void 0) getLocalBindingNames(bindings, node).add(node.name.text);
|
|
440
|
+
if (childFunctionScope !== null && ts.isVariableDeclarationList(node) && (node.flags & ts.NodeFlags.BlockScoped) === 0) addVariableDeclarationListBindings(getLocalBindingNames(bindings, childFunctionScope), node);
|
|
441
|
+
ts.forEachChild(node, (child) => visit(child, childFunctionScope));
|
|
442
|
+
};
|
|
443
|
+
visit(sourceFile, null);
|
|
444
|
+
return bindings;
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Indexes identifier occurrences once for binding-specific safety analysis.
|
|
448
|
+
* @param sourceFile The parsed TypeScript source.
|
|
449
|
+
* @returns Identifier occurrences grouped by exact source spelling.
|
|
450
|
+
*/
|
|
451
|
+
var indexIdentifierUses = (sourceFile) => {
|
|
452
|
+
const identifierUses = /* @__PURE__ */ new Map();
|
|
453
|
+
const visit = (node) => {
|
|
454
|
+
if (ts.isIdentifier(node)) {
|
|
455
|
+
const uses = identifierUses.get(node.text) ?? [];
|
|
456
|
+
uses.push(node);
|
|
457
|
+
identifierUses.set(node.text, uses);
|
|
458
|
+
}
|
|
459
|
+
ts.forEachChild(node, visit);
|
|
460
|
+
};
|
|
461
|
+
visit(sourceFile);
|
|
462
|
+
return new Map([...identifierUses].map(([name, uses]) => [name, Object.freeze(uses)]));
|
|
463
|
+
};
|
|
464
|
+
/**
|
|
465
|
+
* Determines whether a module-bound name is visible at one identifier use.
|
|
466
|
+
* @param identifier The identifier whose lexical environment is inspected.
|
|
467
|
+
* @param analysis The indexed source containing the identifier.
|
|
468
|
+
* @returns Whether no parameter or local declaration shadows the module binding.
|
|
469
|
+
*/
|
|
470
|
+
var isModuleBindingVisible = (identifier, analysis) => {
|
|
471
|
+
let current = identifier.parent;
|
|
472
|
+
while (current !== void 0 && !ts.isSourceFile(current)) {
|
|
473
|
+
if (analysis.localBindingNames.get(current)?.has(identifier.text) === true) return false;
|
|
474
|
+
current = current.parent;
|
|
475
|
+
}
|
|
476
|
+
return true;
|
|
477
|
+
};
|
|
478
|
+
/**
|
|
479
|
+
* Resolves TypeScript source candidates for a supported relative ESM specifier.
|
|
480
|
+
* @param containingPath The importing source path.
|
|
481
|
+
* @param moduleSpecifier The exact relative ESM specifier.
|
|
482
|
+
* @returns Supported logical source candidates in deterministic order.
|
|
483
|
+
*/
|
|
484
|
+
var resolveImportCandidatePaths = (containingPath, moduleSpecifier) => {
|
|
485
|
+
const resolved = posix.resolve(posix.dirname(containingPath), moduleSpecifier);
|
|
486
|
+
if (resolved.endsWith(".js")) return [`${resolved.slice(0, -3)}.ts`, `${resolved.slice(0, -3)}.tsx`];
|
|
487
|
+
if (resolved.endsWith(".mjs")) return [`${resolved.slice(0, -4)}.mts`];
|
|
488
|
+
return [
|
|
489
|
+
".ts",
|
|
490
|
+
".tsx",
|
|
491
|
+
".mts"
|
|
492
|
+
].some((extension) => resolved.endsWith(extension)) ? [resolved] : [];
|
|
493
|
+
};
|
|
494
|
+
/**
|
|
495
|
+
* Resolves the explicit module references an identifier can denote.
|
|
496
|
+
* @param identifier The local source identifier.
|
|
497
|
+
* @param analysis The source containing that identifier.
|
|
498
|
+
* @returns Same-file or relative-import candidates in deterministic order.
|
|
499
|
+
*/
|
|
500
|
+
var resolveBindingReferences = (identifier, analysis) => {
|
|
501
|
+
if (!isModuleBindingVisible(identifier, analysis)) return [];
|
|
502
|
+
const references = [];
|
|
503
|
+
if (analysis.exports.has(identifier.text)) references.push(Object.freeze({
|
|
504
|
+
path: analysis.path,
|
|
505
|
+
symbol: identifier.text
|
|
506
|
+
}));
|
|
507
|
+
const namedImport = analysis.namedImports.get(identifier.text);
|
|
508
|
+
if (namedImport !== void 0) references.push(...resolveImportCandidatePaths(analysis.path, namedImport.moduleSpecifier).map((path) => Object.freeze({
|
|
509
|
+
path,
|
|
510
|
+
symbol: namedImport.importedName
|
|
511
|
+
})));
|
|
512
|
+
return references;
|
|
513
|
+
};
|
|
514
|
+
/**
|
|
515
|
+
* Checks whether an identifier resolves directly to an explicit bound reference.
|
|
516
|
+
* @param identifier The local source identifier.
|
|
517
|
+
* @param analysis The source containing that identifier.
|
|
518
|
+
* @param reference The explicit source binding to match.
|
|
519
|
+
* @returns Whether local or named-import identity proves the relationship.
|
|
520
|
+
*/
|
|
521
|
+
var isBoundIdentifier = (identifier, analysis, reference) => {
|
|
522
|
+
if (reference.symbol === void 0) return false;
|
|
523
|
+
return resolveBindingReferences(identifier, analysis).some((candidate) => candidate.path === reference.path && candidate.symbol === reference.symbol);
|
|
524
|
+
};
|
|
525
|
+
var READONLY_ARRAY_METHODS = /* @__PURE__ */ new Set([
|
|
526
|
+
"at",
|
|
527
|
+
"concat",
|
|
528
|
+
"entries",
|
|
529
|
+
"flat",
|
|
530
|
+
"includes",
|
|
531
|
+
"indexOf",
|
|
532
|
+
"join",
|
|
533
|
+
"keys",
|
|
534
|
+
"lastIndexOf",
|
|
535
|
+
"slice",
|
|
536
|
+
"toLocaleString",
|
|
537
|
+
"toReversed",
|
|
538
|
+
"toSpliced",
|
|
539
|
+
"toString",
|
|
540
|
+
"values",
|
|
541
|
+
"with"
|
|
542
|
+
]);
|
|
543
|
+
var skipTransparentParents$1 = (node) => {
|
|
544
|
+
let current = node;
|
|
545
|
+
while (ts.isAsExpression(current.parent) || ts.isParenthesizedExpression(current.parent) || ts.isSatisfiesExpression(current.parent)) current = current.parent;
|
|
546
|
+
return current;
|
|
547
|
+
};
|
|
548
|
+
var isAssignmentOperator$1 = (kind) => kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
|
|
549
|
+
var isAssignmentTarget = (expression) => {
|
|
550
|
+
let current = skipTransparentParents$1(expression);
|
|
551
|
+
while (true) {
|
|
552
|
+
const parent = current.parent;
|
|
553
|
+
if (ts.isBinaryExpression(parent) && isAssignmentOperator$1(parent.operatorToken.kind)) return parent.left === current;
|
|
554
|
+
if ((ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent)) && parent.operand === current && (parent.operator === ts.SyntaxKind.PlusPlusToken || parent.operator === ts.SyntaxKind.MinusMinusToken)) return true;
|
|
555
|
+
if (ts.isDeleteExpression(parent) && parent.expression === current) return true;
|
|
556
|
+
if ((ts.isForInStatement(parent) || ts.isForOfStatement(parent)) && parent.initializer === current) return true;
|
|
557
|
+
if (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent) || ts.isPropertyAssignment(parent) || ts.isSpreadAssignment(parent) || ts.isSpreadElement(parent) || ts.isArrayLiteralExpression(parent) || ts.isObjectLiteralExpression(parent)) {
|
|
558
|
+
current = skipTransparentParents$1(parent);
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
return false;
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
var getStaticMemberName$1 = (member) => {
|
|
565
|
+
if (ts.isPropertyAccessExpression(member)) return member.name.text;
|
|
566
|
+
const argument = member.argumentExpression;
|
|
567
|
+
return argument !== void 0 && (ts.isStringLiteral(argument) || ts.isNoSubstitutionTemplateLiteral(argument)) ? argument.text : null;
|
|
568
|
+
};
|
|
569
|
+
var isSafeArrayMemberUse = (member) => {
|
|
570
|
+
if (isAssignmentTarget(member)) return false;
|
|
571
|
+
const candidate = skipTransparentParents$1(member);
|
|
572
|
+
const parent = candidate.parent;
|
|
573
|
+
if (!ts.isCallExpression(parent) || parent.expression !== candidate) return ts.isPropertyAccessExpression(member) && member.name.text === "length";
|
|
574
|
+
const memberName = getStaticMemberName$1(member);
|
|
575
|
+
const call = skipTransparentParents$1(parent);
|
|
576
|
+
return memberName !== null && READONLY_ARRAY_METHODS.has(memberName) && ts.isExpressionStatement(call.parent);
|
|
577
|
+
};
|
|
578
|
+
var isIgnoredIdentifierPosition = (identifier, declarationName) => identifier === declarationName || ts.isImportSpecifier(identifier.parent) || ts.isPropertyAssignment(identifier.parent) && identifier.parent.name === identifier || ts.isPropertyAccessExpression(identifier.parent) && identifier.parent.name === identifier;
|
|
579
|
+
/**
|
|
580
|
+
* Determines whether a module value binding has only explicitly allowed value uses.
|
|
581
|
+
* @param analysis The indexed source containing the binding references.
|
|
582
|
+
* @param bindingName The exact lexically visible module binding name.
|
|
583
|
+
* @param declarationName The optional local declaration identifier to exclude.
|
|
584
|
+
* @param allowedReferences Exact bare identifier occurrences owned by supported relationships.
|
|
585
|
+
* @param kind Whether array read-only member access is permitted for the value.
|
|
586
|
+
* @returns Whether the binding cannot be aliased, escaped, reassigned, or mutated.
|
|
587
|
+
*/
|
|
588
|
+
var isModuleValueBindingSafe = (analysis, bindingName, declarationName, allowedReferences, kind) => {
|
|
589
|
+
const identifierUses = analysis.identifierUses.get(bindingName) ?? [];
|
|
590
|
+
for (const identifier of identifierUses) {
|
|
591
|
+
if (isIgnoredIdentifierPosition(identifier, declarationName) || !isModuleBindingVisible(identifier, analysis)) continue;
|
|
592
|
+
if (allowedReferences.has(identifier)) continue;
|
|
593
|
+
const expression = skipTransparentParents$1(identifier);
|
|
594
|
+
const parent = expression.parent;
|
|
595
|
+
const member = (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) && parent.expression === expression ? parent : null;
|
|
596
|
+
if (kind !== "array" || member === null || !isSafeArrayMemberUse(member)) return false;
|
|
597
|
+
}
|
|
598
|
+
return true;
|
|
599
|
+
};
|
|
600
|
+
/**
|
|
601
|
+
* Determines whether a module-local constant literal has only explicitly allowed value uses.
|
|
602
|
+
* @param analysis The indexed source containing the declaration and its references.
|
|
603
|
+
* @param declaration The module-local constant declaration to inspect.
|
|
604
|
+
* @param allowedReferences Exact bare identifier occurrences owned by supported relationships.
|
|
605
|
+
* @param kind Whether array read-only member access is permitted for the value.
|
|
606
|
+
* @returns Whether the binding cannot be aliased, escaped, reassigned, or mutated.
|
|
607
|
+
*/
|
|
608
|
+
var isModuleConstValueSafe = (analysis, declaration, allowedReferences, kind) => {
|
|
609
|
+
if (!ts.isIdentifier(declaration.name)) return false;
|
|
610
|
+
return isModuleValueBindingSafe(analysis, declaration.name.text, declaration.name, allowedReferences, kind);
|
|
611
|
+
};
|
|
612
|
+
var skipTransparentParents = (node) => {
|
|
613
|
+
let current = node;
|
|
614
|
+
while (ts.isAsExpression(current.parent) || ts.isParenthesizedExpression(current.parent) || ts.isSatisfiesExpression(current.parent)) current = current.parent;
|
|
615
|
+
return current;
|
|
616
|
+
};
|
|
617
|
+
var isAssignmentOperator = (kind) => kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
|
|
618
|
+
var isMutatingTarget = (expression) => {
|
|
619
|
+
const candidate = skipTransparentParents(expression);
|
|
620
|
+
const parent = candidate.parent;
|
|
621
|
+
return ts.isBinaryExpression(parent) && parent.left === candidate && isAssignmentOperator(parent.operatorToken.kind) || (ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent)) && parent.operand === candidate && (parent.operator === ts.SyntaxKind.PlusPlusToken || parent.operator === ts.SyntaxKind.MinusMinusToken) || ts.isDeleteExpression(parent) && parent.expression === candidate || (ts.isForInStatement(parent) || ts.isForOfStatement(parent)) && parent.initializer === candidate;
|
|
622
|
+
};
|
|
623
|
+
var getStaticMemberName = (member) => {
|
|
624
|
+
if (ts.isPropertyAccessExpression(member)) return member.name.text;
|
|
625
|
+
const argument = member.argumentExpression;
|
|
626
|
+
return argument !== void 0 && (ts.isStringLiteral(argument) || ts.isNoSubstitutionTemplateLiteral(argument)) ? argument.text : null;
|
|
627
|
+
};
|
|
628
|
+
var isIgnoredIdentifier = (identifier, declarationName) => identifier === declarationName || ts.isImportSpecifier(identifier.parent) || ts.isPropertyAccessExpression(identifier.parent) && identifier.parent.name === identifier || ts.isPropertyAssignment(identifier.parent) && identifier.parent.name === identifier;
|
|
629
|
+
var addObjectAssignmentMembers = (object, mutatedMembers) => {
|
|
630
|
+
let hasUnknownMutation = false;
|
|
631
|
+
for (const property of object.properties) {
|
|
632
|
+
if (!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property) || ts.isComputedPropertyName(property.name)) {
|
|
633
|
+
hasUnknownMutation = true;
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
const propertyName = ts.isIdentifier(property.name) || ts.isStringLiteral(property.name) ? property.name.text : null;
|
|
637
|
+
if (propertyName === null) hasUnknownMutation = true;
|
|
638
|
+
else mutatedMembers.add(propertyName);
|
|
639
|
+
}
|
|
640
|
+
return hasUnknownMutation;
|
|
641
|
+
};
|
|
642
|
+
var analyzeMutationCall = (identifier, mutatedMembers) => {
|
|
643
|
+
const candidate = skipTransparentParents(identifier);
|
|
644
|
+
const parent = candidate.parent;
|
|
645
|
+
if (!ts.isCallExpression(parent)) return null;
|
|
646
|
+
const callee = unwrapExpression(parent.expression);
|
|
647
|
+
if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.expression) && callee.expression.text === "Object" && callee.name.text === "assign" && parent.arguments[0] === candidate) {
|
|
648
|
+
let hasUnknownMutation = parent.arguments.length < 2;
|
|
649
|
+
for (const source of parent.arguments.slice(1)) {
|
|
650
|
+
const assignmentSource = unwrapExpression(source);
|
|
651
|
+
if (!ts.isObjectLiteralExpression(assignmentSource)) hasUnknownMutation = true;
|
|
652
|
+
else if (addObjectAssignmentMembers(assignmentSource, mutatedMembers)) hasUnknownMutation = true;
|
|
653
|
+
}
|
|
654
|
+
return hasUnknownMutation;
|
|
655
|
+
}
|
|
656
|
+
if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.expression) && callee.expression.text === "Reflect" && callee.name.text === "set" && parent.arguments[0] === candidate) {
|
|
657
|
+
const member = parent.arguments[1];
|
|
658
|
+
if (member !== void 0 && (ts.isStringLiteral(member) || ts.isNoSubstitutionTemplateLiteral(member))) {
|
|
659
|
+
mutatedMembers.add(member.text);
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
return true;
|
|
665
|
+
};
|
|
666
|
+
/**
|
|
667
|
+
* Classifies module-local mutations and escapes for one returned object value.
|
|
668
|
+
* @param analysis The indexed source containing the binding.
|
|
669
|
+
* @param declaration The module-local constant declaration.
|
|
670
|
+
* @param allowedReferences Bare identifier uses proven to be supported registrations or targets.
|
|
671
|
+
* @param safeMethodCalls Read-only method calls that preserve the value's runtime configuration.
|
|
672
|
+
* @returns Member-specific mutations and whether an unknown use can affect every relationship.
|
|
673
|
+
*/
|
|
674
|
+
var analyzeModuleValueMutations = (analysis, declaration, allowedReferences, safeMethodCalls = /* @__PURE__ */ new Set()) => {
|
|
675
|
+
if (!ts.isIdentifier(declaration.name)) return Object.freeze({
|
|
676
|
+
hasUnknownMutation: true,
|
|
677
|
+
mutatedMembers: /* @__PURE__ */ new Set()
|
|
678
|
+
});
|
|
679
|
+
const mutatedMembers = /* @__PURE__ */ new Set();
|
|
680
|
+
let hasUnknownMutation = false;
|
|
681
|
+
for (const identifier of analysis.identifierUses.get(declaration.name.text) ?? []) {
|
|
682
|
+
if (isIgnoredIdentifier(identifier, declaration.name) || !isModuleBindingVisible(identifier, analysis) || allowedReferences.has(identifier)) continue;
|
|
683
|
+
const expression = skipTransparentParents(identifier);
|
|
684
|
+
const parent = expression.parent;
|
|
685
|
+
const member = (ts.isPropertyAccessExpression(parent) || ts.isElementAccessExpression(parent)) && parent.expression === expression ? parent : null;
|
|
686
|
+
if (member !== null) {
|
|
687
|
+
const memberName = getStaticMemberName(member);
|
|
688
|
+
if (memberName === null) hasUnknownMutation = true;
|
|
689
|
+
else if (isMutatingTarget(member)) mutatedMembers.add(memberName);
|
|
690
|
+
else {
|
|
691
|
+
const memberExpression = skipTransparentParents(member);
|
|
692
|
+
const memberParent = memberExpression.parent;
|
|
693
|
+
if ((ts.isPropertyAccessExpression(memberParent) || ts.isElementAccessExpression(memberParent)) && memberParent.expression === memberExpression && ts.isCallExpression(skipTransparentParents(memberParent).parent)) mutatedMembers.add(memberName);
|
|
694
|
+
else if (ts.isCallExpression(memberParent) && memberParent.expression === memberExpression) {
|
|
695
|
+
if (!safeMethodCalls.has(memberName)) mutatedMembers.add(memberName);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
if (isMutatingTarget(identifier)) {
|
|
701
|
+
hasUnknownMutation = true;
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const mutationCall = analyzeMutationCall(identifier, mutatedMembers);
|
|
705
|
+
hasUnknownMutation ||= mutationCall ?? true;
|
|
706
|
+
}
|
|
707
|
+
return Object.freeze({
|
|
708
|
+
hasUnknownMutation,
|
|
709
|
+
mutatedMembers: new Set(mutatedMembers)
|
|
710
|
+
});
|
|
711
|
+
};
|
|
712
|
+
var TYPESCRIPT_DECLARATION_EXTENSIONS = [
|
|
713
|
+
".d.ts",
|
|
714
|
+
".d.tsx",
|
|
715
|
+
".d.mts",
|
|
716
|
+
".d.cts"
|
|
717
|
+
];
|
|
718
|
+
var TYPESCRIPT_SOURCE_EXTENSIONS = [
|
|
719
|
+
".ts",
|
|
720
|
+
".tsx",
|
|
721
|
+
".mts"
|
|
722
|
+
];
|
|
723
|
+
var getScriptKind = (path) => path.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
|
|
724
|
+
var createSyntaxProgram = (sourceFile, text) => {
|
|
725
|
+
return ts.createProgram({
|
|
726
|
+
host: {
|
|
727
|
+
fileExists: (fileName) => fileName === sourceFile.fileName,
|
|
728
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
729
|
+
getCurrentDirectory: () => "/",
|
|
730
|
+
getDefaultLibFileName: () => "/lib.d.ts",
|
|
731
|
+
getDirectories: () => [],
|
|
732
|
+
getNewLine: () => "\n",
|
|
733
|
+
getSourceFile: (fileName) => fileName === sourceFile.fileName ? sourceFile : void 0,
|
|
734
|
+
readFile: (fileName) => fileName === sourceFile.fileName ? text : void 0,
|
|
735
|
+
useCaseSensitiveFileNames: () => true,
|
|
736
|
+
writeFile: () => void 0
|
|
737
|
+
},
|
|
738
|
+
options: {
|
|
739
|
+
jsx: ts.JsxEmit.Preserve,
|
|
740
|
+
module: ts.ModuleKind.ESNext,
|
|
741
|
+
noLib: true,
|
|
742
|
+
noResolve: true,
|
|
743
|
+
target: ts.ScriptTarget.ES2023
|
|
744
|
+
},
|
|
745
|
+
rootNames: [sourceFile.fileName]
|
|
746
|
+
});
|
|
747
|
+
};
|
|
748
|
+
/**
|
|
749
|
+
* Parses and indexes one TypeScript module without provider request assumptions.
|
|
750
|
+
* @param path The normalized logical source path.
|
|
751
|
+
* @param bytes The exact source bytes returned by the adapter reader.
|
|
752
|
+
* @param importConfig The provider constructor-import contract.
|
|
753
|
+
* @param signal The active inspection signal.
|
|
754
|
+
* @returns A source analysis or stable invalid-text or invalid-syntax result.
|
|
755
|
+
* @throws If source analysis is aborted.
|
|
756
|
+
*/
|
|
757
|
+
var analyzeTypeScriptModule = (path, bytes, importConfig, signal) => {
|
|
758
|
+
signal?.throwIfAborted();
|
|
759
|
+
const text = normalizeText(bytes);
|
|
760
|
+
if (!text.valid) return Object.freeze({ kind: "invalid-text" });
|
|
761
|
+
signal?.throwIfAborted();
|
|
762
|
+
const sourceFile = ts.createSourceFile(path, text.value, ts.ScriptTarget.ES2023, true, getScriptKind(path));
|
|
763
|
+
const syntaxDiagnostic = createSyntaxProgram(sourceFile, text.value).getSyntacticDiagnostics(sourceFile).filter(({ category }) => category === ts.DiagnosticCategory.Error).sort((left, right) => (left.start ?? 0) - (right.start ?? 0))[0];
|
|
764
|
+
signal?.throwIfAborted();
|
|
765
|
+
if (syntaxDiagnostic !== void 0) {
|
|
766
|
+
const start = syntaxDiagnostic.start;
|
|
767
|
+
return Object.freeze({
|
|
768
|
+
kind: "invalid-syntax",
|
|
769
|
+
range: start === void 0 ? null : text.locator.locateRange(start, start + (syntaxDiagnostic.length ?? 0))
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
const { constructorNames, namedImports } = indexImports(sourceFile, importConfig);
|
|
773
|
+
signal?.throwIfAborted();
|
|
774
|
+
const { clientNames, exports, moduleArrays, moduleConstDeclarations } = indexModuleDeclarations(sourceFile, constructorNames);
|
|
775
|
+
signal?.throwIfAborted();
|
|
776
|
+
const identifierUses = indexIdentifierUses(sourceFile);
|
|
777
|
+
signal?.throwIfAborted();
|
|
778
|
+
const localBindingNames = indexLocalBindingNames(sourceFile);
|
|
779
|
+
signal?.throwIfAborted();
|
|
780
|
+
const analysis = Object.freeze({
|
|
781
|
+
clientNames,
|
|
782
|
+
constructorNames,
|
|
783
|
+
exports,
|
|
784
|
+
identifierUses,
|
|
785
|
+
localBindingNames,
|
|
786
|
+
moduleArrays,
|
|
787
|
+
moduleConstDeclarations,
|
|
788
|
+
namedImports,
|
|
789
|
+
path,
|
|
790
|
+
safeModuleArrayNames: /* @__PURE__ */ new Set(),
|
|
791
|
+
sourceFile,
|
|
792
|
+
text
|
|
793
|
+
});
|
|
794
|
+
signal?.throwIfAborted();
|
|
795
|
+
return Object.freeze({
|
|
796
|
+
analysis,
|
|
797
|
+
kind: "valid"
|
|
798
|
+
});
|
|
799
|
+
};
|
|
800
|
+
/**
|
|
801
|
+
* Determines whether a path uses a supported TypeScript source extension.
|
|
802
|
+
* @param path The bound source path.
|
|
803
|
+
* @returns Whether its extension is supported.
|
|
804
|
+
*/
|
|
805
|
+
var isSupportedTypeScriptSourcePath = (path) => !TYPESCRIPT_DECLARATION_EXTENSIONS.some((extension) => path.endsWith(extension)) && TYPESCRIPT_SOURCE_EXTENSIONS.some((extension) => path.endsWith(extension));
|
|
806
|
+
/**
|
|
807
|
+
* Classifies a direct exported runtime-agent function and exposes its body.
|
|
808
|
+
* @param analysis The indexed runtime source.
|
|
809
|
+
* @param symbol The bound runtime-agent symbol.
|
|
810
|
+
* @returns The symbol state and supported body when available.
|
|
811
|
+
*/
|
|
812
|
+
var getRuntimeExport = (analysis, symbol) => {
|
|
813
|
+
const exported = analysis.exports.get(symbol);
|
|
814
|
+
if (exported === void 0) return Object.freeze({ kind: "absent" });
|
|
815
|
+
if (exported.kind === "present-unsupported") return exported;
|
|
816
|
+
const { declaration } = exported;
|
|
817
|
+
if (ts.isFunctionDeclaration(declaration) && declaration.body !== void 0) return Object.freeze({
|
|
818
|
+
body: declaration.body,
|
|
819
|
+
declaration,
|
|
820
|
+
kind: "present-supported"
|
|
821
|
+
});
|
|
822
|
+
if (ts.isVariableDeclaration(declaration) && declaration.initializer !== void 0) {
|
|
823
|
+
const initializer = unwrapExpression(declaration.initializer);
|
|
824
|
+
if (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer)) return Object.freeze({
|
|
825
|
+
body: initializer.body,
|
|
826
|
+
declaration,
|
|
827
|
+
kind: "present-supported"
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
return Object.freeze({
|
|
831
|
+
declaration,
|
|
832
|
+
kind: "present-unsupported"
|
|
833
|
+
});
|
|
834
|
+
};
|
|
835
|
+
/**
|
|
836
|
+
* Classifies a directly exported callable value such as an instruction loader.
|
|
837
|
+
* @param analysis The indexed source.
|
|
838
|
+
* @param symbol The exact bound symbol.
|
|
839
|
+
* @returns The symbol state for conservative call matching.
|
|
840
|
+
*/
|
|
841
|
+
var getCallableExportState = (analysis, symbol) => {
|
|
842
|
+
const runtimeExport = getRuntimeExport(analysis, symbol);
|
|
843
|
+
return runtimeExport.kind === "present-supported" ? Object.freeze({
|
|
844
|
+
declaration: runtimeExport.declaration,
|
|
845
|
+
kind: "present-supported"
|
|
846
|
+
}) : runtimeExport;
|
|
847
|
+
};
|
|
848
|
+
/**
|
|
849
|
+
* Classifies a directly exported constant and returns its static initializer.
|
|
850
|
+
* @param analysis The indexed source.
|
|
851
|
+
* @param symbol The exact bound symbol.
|
|
852
|
+
* @returns The symbol state and initializer when supported.
|
|
853
|
+
*/
|
|
854
|
+
var getConstExport = (analysis, symbol) => {
|
|
855
|
+
const exported = analysis.exports.get(symbol);
|
|
856
|
+
if (exported === void 0) return Object.freeze({ kind: "absent" });
|
|
857
|
+
if (exported.kind === "present-supported" && ts.isVariableDeclaration(exported.declaration) && exported.declaration.initializer !== void 0) return Object.freeze({
|
|
858
|
+
declaration: exported.declaration,
|
|
859
|
+
expression: unwrapExpression(exported.declaration.initializer),
|
|
860
|
+
kind: "present-supported"
|
|
861
|
+
});
|
|
862
|
+
return Object.freeze({
|
|
863
|
+
declaration: exported.declaration,
|
|
864
|
+
kind: "present-unsupported"
|
|
865
|
+
});
|
|
866
|
+
};
|
|
867
|
+
var resolveCandidatePath = async (options, containingPath, moduleSpecifier) => {
|
|
868
|
+
const matchingPaths = [];
|
|
869
|
+
for (const candidate of resolveImportCandidatePaths(containingPath, moduleSpecifier)) {
|
|
870
|
+
const path = options.parsePath(candidate);
|
|
871
|
+
if ((await options.getEntry(path))?.type === "file") matchingPaths.push(path);
|
|
872
|
+
}
|
|
873
|
+
return matchingPaths.length === 1 ? matchingPaths[0] : null;
|
|
874
|
+
};
|
|
875
|
+
var resolveStaticStringExpression = async (options, analysis, expression, visited) => {
|
|
876
|
+
options.signal?.throwIfAborted();
|
|
877
|
+
const candidate = unwrapExpression(expression);
|
|
878
|
+
const literal = getStaticString(candidate);
|
|
879
|
+
if (literal !== null) return Object.freeze({
|
|
880
|
+
expression: candidate,
|
|
881
|
+
kind: "supported",
|
|
882
|
+
value: literal
|
|
883
|
+
});
|
|
884
|
+
if (!ts.isIdentifier(candidate) || !isModuleBindingVisible(candidate, analysis)) return Object.freeze({ kind: "unsupported" });
|
|
885
|
+
const localDeclaration = analysis.moduleConstDeclarations.get(candidate.text);
|
|
886
|
+
if (localDeclaration?.initializer !== void 0) {
|
|
887
|
+
const key = `${analysis.path}\0local\0${candidate.text}`;
|
|
888
|
+
if (visited.has(key)) return Object.freeze({ kind: "unsupported" });
|
|
889
|
+
visited.add(key);
|
|
890
|
+
const result = await resolveStaticStringExpression(options, analysis, localDeclaration.initializer, visited);
|
|
891
|
+
visited.delete(key);
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
const namedImport = analysis.namedImports.get(candidate.text);
|
|
895
|
+
if (namedImport === void 0) return Object.freeze({ kind: "unsupported" });
|
|
896
|
+
const importedPath = await resolveCandidatePath(options, analysis.path, namedImport.moduleSpecifier);
|
|
897
|
+
if (importedPath === null) return Object.freeze({ kind: "unsupported" });
|
|
898
|
+
const key = `${importedPath}\0export\0${namedImport.importedName}`;
|
|
899
|
+
if (visited.has(key)) return Object.freeze({ kind: "unsupported" });
|
|
900
|
+
visited.add(key);
|
|
901
|
+
const importedResult = await options.analyzeSource(importedPath);
|
|
902
|
+
if (importedResult.kind !== "valid") {
|
|
903
|
+
options.onSourceFailure?.(importedPath, importedResult);
|
|
904
|
+
visited.delete(key);
|
|
905
|
+
return Object.freeze({ kind: "unsupported" });
|
|
906
|
+
}
|
|
907
|
+
const exported = getConstExport(importedResult.analysis, namedImport.importedName);
|
|
908
|
+
if (exported.kind !== "present-supported" || exported.expression === void 0) {
|
|
909
|
+
visited.delete(key);
|
|
910
|
+
return Object.freeze({ kind: "unsupported" });
|
|
911
|
+
}
|
|
912
|
+
const result = await resolveStaticStringExpression(options, importedResult.analysis, exported.expression, visited);
|
|
913
|
+
visited.delete(key);
|
|
914
|
+
return result;
|
|
915
|
+
};
|
|
916
|
+
/**
|
|
917
|
+
* Resolves one exact supported static string without normalization or execution.
|
|
918
|
+
* @param options The source, expression, repository callbacks, and parser for the relationship.
|
|
919
|
+
* @returns The exact compiler-parsed string or an unsupported state.
|
|
920
|
+
*/
|
|
921
|
+
var resolveStaticString = (options) => resolveStaticStringExpression(options, options.analysis, options.expression, /* @__PURE__ */ new Set());
|
|
922
|
+
//#endregion
|
|
923
|
+
//#region src/source-analysis/bindings.ts
|
|
924
|
+
/** Returns an exact supported object-property name. */
|
|
925
|
+
var getLangChainPropertyName = (name) => ts.isIdentifier(name) || ts.isStringLiteral(name) ? name.text : null;
|
|
926
|
+
/** Determines whether an object uses JavaScript's non-own `__proto__` setter form. */
|
|
927
|
+
var hasLangChainPrototypeSetter = (object) => object.properties.some((property) => ts.isPropertyAssignment(property) && !ts.isComputedPropertyName(property.name) && getLangChainPropertyName(property.name) === "__proto__");
|
|
928
|
+
/** Classifies one direct expression against an exact manifest binding. */
|
|
929
|
+
var classifyLangChainDirectBinding = (expression, analysis, reference) => {
|
|
930
|
+
const candidate = unwrapExpression(expression);
|
|
931
|
+
if (!ts.isIdentifier(candidate) || !isModuleBindingVisible(candidate, analysis)) return ts.isStringLiteral(candidate) || ts.isNoSubstitutionTemplateLiteral(candidate) || ts.isNumericLiteral(candidate) || ts.isObjectLiteralExpression(candidate) || ts.isArrayLiteralExpression(candidate) || ts.isArrowFunction(candidate) || ts.isFunctionExpression(candidate) || ts.isClassExpression(candidate) || candidate.kind === ts.SyntaxKind.NullKeyword || candidate.kind === ts.SyntaxKind.TrueKeyword || candidate.kind === ts.SyntaxKind.FalseKeyword ? Object.freeze({
|
|
932
|
+
expression: candidate,
|
|
933
|
+
kind: "different"
|
|
934
|
+
}) : Object.freeze({ kind: "unresolved" });
|
|
935
|
+
if (isBoundIdentifier(candidate, analysis, reference)) return Object.freeze({
|
|
936
|
+
expression: candidate,
|
|
937
|
+
kind: "wired"
|
|
938
|
+
});
|
|
939
|
+
return resolveBindingReferences(candidate, analysis).length > 0 ? Object.freeze({
|
|
940
|
+
expression: candidate,
|
|
941
|
+
kind: "different"
|
|
942
|
+
}) : Object.freeze({ kind: "unresolved" });
|
|
943
|
+
};
|
|
944
|
+
/** Classifies a direct or awaited call to an exact bound loader. */
|
|
945
|
+
var classifyLangChainLoaderCall = (expression, analysis, reference) => {
|
|
946
|
+
const call = getDirectCall(expression);
|
|
947
|
+
if (call === null) {
|
|
948
|
+
const candidate = unwrapExpression(expression);
|
|
949
|
+
return ts.isStringLiteral(candidate) || ts.isNoSubstitutionTemplateLiteral(candidate) ? Object.freeze({
|
|
950
|
+
expression: candidate,
|
|
951
|
+
kind: "different"
|
|
952
|
+
}) : Object.freeze({ kind: "unresolved" });
|
|
953
|
+
}
|
|
954
|
+
const callee = unwrapExpression(call.expression);
|
|
955
|
+
if (!ts.isIdentifier(callee) || !isModuleBindingVisible(callee, analysis)) return Object.freeze({ kind: "unresolved" });
|
|
956
|
+
if (isBoundIdentifier(callee, analysis, reference)) return Object.freeze({
|
|
957
|
+
expression: call,
|
|
958
|
+
kind: "wired"
|
|
959
|
+
});
|
|
960
|
+
return resolveBindingReferences(callee, analysis).length > 0 ? Object.freeze({
|
|
961
|
+
expression: call,
|
|
962
|
+
kind: "different"
|
|
963
|
+
}) : Object.freeze({ kind: "unresolved" });
|
|
964
|
+
};
|
|
965
|
+
//#endregion
|
|
966
|
+
//#region src/source-analysis/agent-definitions.ts
|
|
967
|
+
var CONFIGURATION_PROPERTY_NAMES = /* @__PURE__ */ new Set([
|
|
968
|
+
"model",
|
|
969
|
+
"tools",
|
|
970
|
+
"systemPrompt",
|
|
971
|
+
"stateSchema",
|
|
972
|
+
"contextSchema",
|
|
973
|
+
"checkpointer",
|
|
974
|
+
"store",
|
|
975
|
+
"responseFormat",
|
|
976
|
+
"middleware",
|
|
977
|
+
"name",
|
|
978
|
+
"description",
|
|
979
|
+
"includeAgentName",
|
|
980
|
+
"signal",
|
|
981
|
+
"version",
|
|
982
|
+
"streamTransformers"
|
|
983
|
+
]);
|
|
984
|
+
var RELATIONSHIP_NAMES = [
|
|
985
|
+
"middleware",
|
|
986
|
+
"name",
|
|
987
|
+
"responseFormat",
|
|
988
|
+
"systemPrompt",
|
|
989
|
+
"tools"
|
|
990
|
+
];
|
|
991
|
+
var SAFE_AGENT_METHOD_CALLS = /* @__PURE__ */ new Set([
|
|
992
|
+
"invoke",
|
|
993
|
+
"stream",
|
|
994
|
+
"streamEvents"
|
|
995
|
+
]);
|
|
996
|
+
var AGENT_INVOCATION_MEMBER_NAMES = /* @__PURE__ */ new Set([
|
|
997
|
+
"invoke",
|
|
998
|
+
"stream",
|
|
999
|
+
"streamEvents"
|
|
1000
|
+
]);
|
|
1001
|
+
var createRelationships = () => Object.fromEntries(RELATIONSHIP_NAMES.map((name) => [name, {
|
|
1002
|
+
expression: null,
|
|
1003
|
+
kind: "absent"
|
|
1004
|
+
}]));
|
|
1005
|
+
var getAgentObject = (initializer, analysis) => {
|
|
1006
|
+
const candidate = unwrapExpression(initializer);
|
|
1007
|
+
if (!ts.isCallExpression(candidate) || candidate.arguments.length !== 1) return null;
|
|
1008
|
+
const callee = unwrapExpression(candidate.expression);
|
|
1009
|
+
if (!ts.isIdentifier(callee) || !analysis.imports.createAgentNames.has(callee.text) || !isModuleBindingVisible(callee, analysis)) return null;
|
|
1010
|
+
const object = unwrapExpression(candidate.arguments[0]);
|
|
1011
|
+
return ts.isObjectLiteralExpression(object) ? object : null;
|
|
1012
|
+
};
|
|
1013
|
+
var analyzeConfiguration = (object) => {
|
|
1014
|
+
const hasPrototypeSetter = hasLangChainPrototypeSetter(object);
|
|
1015
|
+
const relationships = createRelationships();
|
|
1016
|
+
const seenRelationships = /* @__PURE__ */ new Set();
|
|
1017
|
+
let hasModel = false;
|
|
1018
|
+
let isModelClosed = false;
|
|
1019
|
+
for (const property of object.properties) {
|
|
1020
|
+
if (ts.isSpreadAssignment(property) || ts.isComputedPropertyName(property.name)) {
|
|
1021
|
+
isModelClosed = false;
|
|
1022
|
+
for (const name of RELATIONSHIP_NAMES) relationships[name] = { kind: "unresolved" };
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
const name = getLangChainPropertyName(property.name);
|
|
1026
|
+
if (hasPrototypeSetter && name === "__proto__" && ts.isPropertyAssignment(property)) continue;
|
|
1027
|
+
if (name === null || !CONFIGURATION_PROPERTY_NAMES.has(name)) return null;
|
|
1028
|
+
if (name === "model") {
|
|
1029
|
+
if (hasModel || !ts.isPropertyAssignment(property)) return null;
|
|
1030
|
+
hasModel = true;
|
|
1031
|
+
isModelClosed = true;
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
if (!RELATIONSHIP_NAMES.includes(name)) continue;
|
|
1035
|
+
const relationshipName = name;
|
|
1036
|
+
if (seenRelationships.has(name)) {
|
|
1037
|
+
relationships[relationshipName] = { kind: "unresolved" };
|
|
1038
|
+
continue;
|
|
1039
|
+
}
|
|
1040
|
+
seenRelationships.add(name);
|
|
1041
|
+
relationships[relationshipName] = ts.isPropertyAssignment(property) ? {
|
|
1042
|
+
expression: unwrapExpression(property.initializer),
|
|
1043
|
+
kind: "present"
|
|
1044
|
+
} : { kind: "unresolved" };
|
|
1045
|
+
}
|
|
1046
|
+
if (!hasModel || !isModelClosed) return null;
|
|
1047
|
+
if (hasPrototypeSetter) for (const name of RELATIONSHIP_NAMES) relationships[name] = { kind: "unresolved" };
|
|
1048
|
+
return relationships;
|
|
1049
|
+
};
|
|
1050
|
+
/** Classifies one directly exported package-root `createAgent(...)` definition. */
|
|
1051
|
+
var getLangChainAgentDefinition = (analysis, symbol) => {
|
|
1052
|
+
const exported = analysis.exports.get(symbol);
|
|
1053
|
+
if (exported === void 0) return Object.freeze({ kind: "absent" });
|
|
1054
|
+
if (exported.kind !== "present-supported" || !ts.isVariableDeclaration(exported.declaration) || exported.declaration.initializer === void 0) return Object.freeze({
|
|
1055
|
+
declaration: exported.declaration,
|
|
1056
|
+
kind: "present-unsupported"
|
|
1057
|
+
});
|
|
1058
|
+
const object = getAgentObject(exported.declaration.initializer, analysis);
|
|
1059
|
+
const relationships = object === null ? null : analyzeConfiguration(object);
|
|
1060
|
+
if (object === null || relationships === null) return Object.freeze({
|
|
1061
|
+
declaration: exported.declaration,
|
|
1062
|
+
kind: "present-unsupported"
|
|
1063
|
+
});
|
|
1064
|
+
const mutations = analyzeModuleValueMutations(analysis, exported.declaration, /* @__PURE__ */ new Set(), SAFE_AGENT_METHOD_CALLS);
|
|
1065
|
+
const hasInvocationMutation = [...AGENT_INVOCATION_MEMBER_NAMES].some((name) => mutations.mutatedMembers.has(name));
|
|
1066
|
+
const hasBroadRelationshipMutation = mutations.hasUnknownMutation || [...mutations.mutatedMembers].some((name) => name !== "name" && !RELATIONSHIP_NAMES.includes(name) && !AGENT_INVOCATION_MEMBER_NAMES.has(name));
|
|
1067
|
+
const relationship = (name) => {
|
|
1068
|
+
const isInvocationRelationship = [
|
|
1069
|
+
"middleware",
|
|
1070
|
+
"responseFormat",
|
|
1071
|
+
"systemPrompt",
|
|
1072
|
+
"tools"
|
|
1073
|
+
].includes(name);
|
|
1074
|
+
return hasBroadRelationshipMutation || hasInvocationMutation && isInvocationRelationship || mutations.mutatedMembers.has(name) ? { kind: "unresolved" } : relationships[name];
|
|
1075
|
+
};
|
|
1076
|
+
const definition = Object.freeze({
|
|
1077
|
+
configuredTools: relationships.tools,
|
|
1078
|
+
declaration: exported.declaration,
|
|
1079
|
+
middleware: relationship("middleware"),
|
|
1080
|
+
name: mutations.hasUnknownMutation || mutations.mutatedMembers.has("name") ? { kind: "unresolved" } : relationships.name,
|
|
1081
|
+
object,
|
|
1082
|
+
responseFormat: relationship("responseFormat"),
|
|
1083
|
+
systemPrompt: relationship("systemPrompt"),
|
|
1084
|
+
tools: relationship("tools")
|
|
1085
|
+
});
|
|
1086
|
+
return Object.freeze({
|
|
1087
|
+
definition,
|
|
1088
|
+
kind: "present-supported"
|
|
1089
|
+
});
|
|
1090
|
+
};
|
|
1091
|
+
//#endregion
|
|
1092
|
+
//#region src/source-analysis/function-tools.ts
|
|
1093
|
+
var FUNCTION_TOOL_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
1094
|
+
"name",
|
|
1095
|
+
"description",
|
|
1096
|
+
"schema",
|
|
1097
|
+
"responseFormat",
|
|
1098
|
+
"returnDirect",
|
|
1099
|
+
"defaultConfig",
|
|
1100
|
+
"verboseParsingErrors",
|
|
1101
|
+
"verbose",
|
|
1102
|
+
"callbacks",
|
|
1103
|
+
"tags",
|
|
1104
|
+
"metadata",
|
|
1105
|
+
"extras"
|
|
1106
|
+
]);
|
|
1107
|
+
var getFunctionToolCall = (initializer, analysis) => {
|
|
1108
|
+
const candidate = unwrapExpression(initializer);
|
|
1109
|
+
if (!ts.isCallExpression(candidate) || candidate.arguments.length !== 2) return null;
|
|
1110
|
+
const callee = unwrapExpression(candidate.expression);
|
|
1111
|
+
if (!ts.isIdentifier(callee) || !isModuleBindingVisible(callee, analysis)) return null;
|
|
1112
|
+
const helperSource = analysis.imports.toolNames.get(callee.text);
|
|
1113
|
+
return helperSource === void 0 ? null : Object.freeze({
|
|
1114
|
+
call: candidate,
|
|
1115
|
+
helperSource
|
|
1116
|
+
});
|
|
1117
|
+
};
|
|
1118
|
+
var getFunctionToolFields = (call) => {
|
|
1119
|
+
const fields = unwrapExpression(call.arguments[1]);
|
|
1120
|
+
if (!ts.isObjectLiteralExpression(fields) || hasLangChainPrototypeSetter(fields)) return null;
|
|
1121
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1122
|
+
let description = {
|
|
1123
|
+
expression: null,
|
|
1124
|
+
kind: "absent"
|
|
1125
|
+
};
|
|
1126
|
+
let name = null;
|
|
1127
|
+
let schema = {
|
|
1128
|
+
expression: null,
|
|
1129
|
+
kind: "absent"
|
|
1130
|
+
};
|
|
1131
|
+
for (const property of fields.properties) {
|
|
1132
|
+
if (!ts.isPropertyAssignment(property) || ts.isComputedPropertyName(property.name)) return null;
|
|
1133
|
+
const propertyName = getLangChainPropertyName(property.name);
|
|
1134
|
+
if (propertyName === null || !FUNCTION_TOOL_FIELD_NAMES.has(propertyName) || seen.has(propertyName)) return null;
|
|
1135
|
+
seen.add(propertyName);
|
|
1136
|
+
if (propertyName === "name") name = unwrapExpression(property.initializer);
|
|
1137
|
+
else if (propertyName === "description") description = {
|
|
1138
|
+
expression: unwrapExpression(property.initializer),
|
|
1139
|
+
kind: "present"
|
|
1140
|
+
};
|
|
1141
|
+
else if (propertyName === "schema") schema = {
|
|
1142
|
+
expression: unwrapExpression(property.initializer),
|
|
1143
|
+
kind: "present"
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
return name === null ? null : Object.freeze({
|
|
1147
|
+
description,
|
|
1148
|
+
fields,
|
|
1149
|
+
name,
|
|
1150
|
+
schema
|
|
1151
|
+
});
|
|
1152
|
+
};
|
|
1153
|
+
var createFunctionToolShape = (functionToolCall, functionToolFields, mutations) => {
|
|
1154
|
+
const hasUnknownMutation = mutations?.hasUnknownMutation === true;
|
|
1155
|
+
const isImplementationUnresolved = hasUnknownMutation || mutations?.mutatedMembers.has("func") === true || mutations?.mutatedMembers.has("invoke") === true;
|
|
1156
|
+
const isNameUnresolved = hasUnknownMutation || mutations?.mutatedMembers.has("name") === true;
|
|
1157
|
+
const implementationKind = isImplementationUnresolved ? "unresolved" : "present";
|
|
1158
|
+
const nameKind = isNameUnresolved ? "unresolved" : "present";
|
|
1159
|
+
const schema = hasUnknownMutation || mutations?.mutatedMembers.has("schema") === true ? { kind: "unresolved" } : functionToolFields.schema;
|
|
1160
|
+
return Object.freeze({
|
|
1161
|
+
description: functionToolFields.description,
|
|
1162
|
+
fields: functionToolFields.fields,
|
|
1163
|
+
helperSource: functionToolCall.helperSource,
|
|
1164
|
+
implementation: {
|
|
1165
|
+
expression: unwrapExpression(functionToolCall.call.arguments[0]),
|
|
1166
|
+
kind: implementationKind
|
|
1167
|
+
},
|
|
1168
|
+
name: {
|
|
1169
|
+
expression: functionToolFields.name,
|
|
1170
|
+
kind: nameKind
|
|
1171
|
+
},
|
|
1172
|
+
schema
|
|
1173
|
+
});
|
|
1174
|
+
};
|
|
1175
|
+
/** Classifies one directly exported normal two-argument LangChain function tool. */
|
|
1176
|
+
var getLangChainFunctionTool = (analysis, symbol, allowedReferences = /* @__PURE__ */ new Set()) => {
|
|
1177
|
+
const exported = analysis.exports.get(symbol);
|
|
1178
|
+
if (exported === void 0) return Object.freeze({ kind: "absent" });
|
|
1179
|
+
if (exported.kind !== "present-supported" || !ts.isVariableDeclaration(exported.declaration) || exported.declaration.initializer === void 0) return Object.freeze({
|
|
1180
|
+
declaration: exported.declaration,
|
|
1181
|
+
kind: "present-unsupported"
|
|
1182
|
+
});
|
|
1183
|
+
const functionToolCall = getFunctionToolCall(exported.declaration.initializer, analysis);
|
|
1184
|
+
const functionToolFields = functionToolCall === null ? null : getFunctionToolFields(functionToolCall.call);
|
|
1185
|
+
if (functionToolCall === null || functionToolFields === null) return Object.freeze({
|
|
1186
|
+
declaration: exported.declaration,
|
|
1187
|
+
kind: "present-unsupported"
|
|
1188
|
+
});
|
|
1189
|
+
const mutations = analyzeModuleValueMutations(analysis, exported.declaration, allowedReferences);
|
|
1190
|
+
const tool = Object.freeze({
|
|
1191
|
+
declaration: exported.declaration,
|
|
1192
|
+
...createFunctionToolShape(functionToolCall, functionToolFields, mutations)
|
|
1193
|
+
});
|
|
1194
|
+
return Object.freeze({
|
|
1195
|
+
kind: "present-supported",
|
|
1196
|
+
tool
|
|
1197
|
+
});
|
|
1198
|
+
};
|
|
1199
|
+
/** Classifies one inline normal function-tool declaration. */
|
|
1200
|
+
var getInlineLangChainFunctionTool = (expression, analysis) => {
|
|
1201
|
+
const functionToolCall = getFunctionToolCall(expression, analysis);
|
|
1202
|
+
const functionToolFields = functionToolCall === null ? null : getFunctionToolFields(functionToolCall.call);
|
|
1203
|
+
return functionToolCall === null || functionToolFields === null ? null : createFunctionToolShape(functionToolCall, functionToolFields);
|
|
1204
|
+
};
|
|
1205
|
+
//#endregion
|
|
1206
|
+
//#region src/source-analysis/source-analysis.ts
|
|
1207
|
+
var SUPPORTED_IMPORTS = Object.freeze({
|
|
1208
|
+
"@langchain/core/messages": /* @__PURE__ */ new Set(["SystemMessage"]),
|
|
1209
|
+
"@langchain/core/tools": /* @__PURE__ */ new Set(["tool"]),
|
|
1210
|
+
langchain: /* @__PURE__ */ new Set([
|
|
1211
|
+
"createAgent",
|
|
1212
|
+
"providerStrategy",
|
|
1213
|
+
"SystemMessage",
|
|
1214
|
+
"tool",
|
|
1215
|
+
"toolStrategy"
|
|
1216
|
+
]),
|
|
1217
|
+
"langchain/tools": /* @__PURE__ */ new Set(["tool"])
|
|
1218
|
+
});
|
|
1219
|
+
var indexLangChainImports = (sourceFile) => {
|
|
1220
|
+
const createAgentNames = /* @__PURE__ */ new Set();
|
|
1221
|
+
const providerStrategyNames = /* @__PURE__ */ new Set();
|
|
1222
|
+
const systemMessageNames = /* @__PURE__ */ new Set();
|
|
1223
|
+
const toolNames = /* @__PURE__ */ new Map();
|
|
1224
|
+
const toolStrategyNames = /* @__PURE__ */ new Set();
|
|
1225
|
+
for (const statement of sourceFile.statements) {
|
|
1226
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier) || statement.importClause?.isTypeOnly === true || statement.importClause?.namedBindings === void 0 || !ts.isNamedImports(statement.importClause.namedBindings)) continue;
|
|
1227
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
1228
|
+
const supportedNames = SUPPORTED_IMPORTS[moduleSpecifier];
|
|
1229
|
+
if (supportedNames === void 0) continue;
|
|
1230
|
+
for (const element of statement.importClause.namedBindings.elements) {
|
|
1231
|
+
const importedName = element.propertyName?.text ?? element.name.text;
|
|
1232
|
+
if (element.isTypeOnly || !supportedNames.has(importedName)) continue;
|
|
1233
|
+
if (moduleSpecifier === "langchain" && importedName === "createAgent") createAgentNames.add(element.name.text);
|
|
1234
|
+
else if (moduleSpecifier === "langchain" && importedName === "providerStrategy") providerStrategyNames.add(element.name.text);
|
|
1235
|
+
else if (importedName === "SystemMessage") systemMessageNames.add(element.name.text);
|
|
1236
|
+
else if (importedName === "tool") toolNames.set(element.name.text, moduleSpecifier);
|
|
1237
|
+
else if (moduleSpecifier === "langchain" && importedName === "toolStrategy") toolStrategyNames.add(element.name.text);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return Object.freeze({
|
|
1241
|
+
createAgentNames,
|
|
1242
|
+
providerStrategyNames,
|
|
1243
|
+
systemMessageNames,
|
|
1244
|
+
toolNames,
|
|
1245
|
+
toolStrategyNames
|
|
1246
|
+
});
|
|
1247
|
+
};
|
|
1248
|
+
/** Parses and indexes one supported LangChain TypeScript module without executing it. */
|
|
1249
|
+
var analyzeLangChainSource = (path, bytes, signal) => {
|
|
1250
|
+
const result = analyzeTypeScriptModule(path, bytes, {
|
|
1251
|
+
namedConstructorImports: [],
|
|
1252
|
+
packageName: LANGCHAIN_PACKAGE_NAME,
|
|
1253
|
+
supportsDefaultConstructorImport: false
|
|
1254
|
+
}, signal);
|
|
1255
|
+
if (result.kind !== "valid") return result;
|
|
1256
|
+
const analysis = Object.freeze({
|
|
1257
|
+
...result.analysis,
|
|
1258
|
+
imports: indexLangChainImports(result.analysis.sourceFile),
|
|
1259
|
+
path
|
|
1260
|
+
});
|
|
1261
|
+
return Object.freeze({
|
|
1262
|
+
analysis,
|
|
1263
|
+
kind: "valid"
|
|
1264
|
+
});
|
|
1265
|
+
};
|
|
1266
|
+
//#endregion
|
|
1267
|
+
//#region src/source-analysis/static-strings.ts
|
|
1268
|
+
/** Resolves one supported immutable source string across relative import edges. */
|
|
1269
|
+
var resolveLangChainStaticString = (session, analysis, expression, onSourceFailure) => resolveStaticString({
|
|
1270
|
+
analysis,
|
|
1271
|
+
analyzeSource: (path) => session.analyzeSource(path),
|
|
1272
|
+
expression,
|
|
1273
|
+
getEntry: (path) => session.getEntry(path),
|
|
1274
|
+
...onSourceFailure === void 0 ? {} : { onSourceFailure: (path, result) => onSourceFailure(Object.freeze({
|
|
1275
|
+
...result,
|
|
1276
|
+
path
|
|
1277
|
+
})) },
|
|
1278
|
+
parsePath: (path) => parseRepositoryPath(path),
|
|
1279
|
+
...session.signal === void 0 ? {} : { signal: session.signal }
|
|
1280
|
+
});
|
|
1281
|
+
//#endregion
|
|
1282
|
+
//#region src/source-analysis/structured-output.ts
|
|
1283
|
+
var isExactImportedHelper = (expression, names, analysis) => ts.isIdentifier(expression) && names.has(expression.text) && isModuleBindingVisible(expression, analysis);
|
|
1284
|
+
var classifyProviderStrategyObject = (object, analysis, reference) => {
|
|
1285
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1286
|
+
let schema = null;
|
|
1287
|
+
for (const property of object.properties) {
|
|
1288
|
+
if (!ts.isPropertyAssignment(property) || ts.isComputedPropertyName(property.name)) return Object.freeze({ kind: "unresolved" });
|
|
1289
|
+
const name = getLangChainPropertyName(property.name);
|
|
1290
|
+
if (name === null || !["schema", "strict"].includes(name) || seen.has(name)) return Object.freeze({ kind: "unresolved" });
|
|
1291
|
+
seen.add(name);
|
|
1292
|
+
if (name === "schema") schema = unwrapExpression(property.initializer);
|
|
1293
|
+
else {
|
|
1294
|
+
const strict = unwrapExpression(property.initializer);
|
|
1295
|
+
if (strict.kind !== ts.SyntaxKind.TrueKeyword && strict.kind !== ts.SyntaxKind.FalseKeyword) return Object.freeze({ kind: "unresolved" });
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
return schema === null ? Object.freeze({ kind: "unresolved" }) : classifyLangChainDirectBinding(schema, analysis, reference);
|
|
1299
|
+
};
|
|
1300
|
+
/** Classifies a direct schema or supported one-schema response strategy. */
|
|
1301
|
+
var classifyLangChainResponseFormat = (expression, analysis, reference) => {
|
|
1302
|
+
const candidate = unwrapExpression(expression);
|
|
1303
|
+
if (ts.isArrayLiteralExpression(candidate)) return Object.freeze({ kind: "unresolved" });
|
|
1304
|
+
if (!ts.isCallExpression(candidate)) return classifyLangChainDirectBinding(candidate, analysis, reference);
|
|
1305
|
+
const callee = unwrapExpression(candidate.expression);
|
|
1306
|
+
if (isExactImportedHelper(callee, analysis.imports.toolStrategyNames, analysis) && (candidate.arguments.length === 1 || candidate.arguments.length === 2)) {
|
|
1307
|
+
const firstArgument = unwrapExpression(candidate.arguments[0]);
|
|
1308
|
+
const result = ts.isArrayLiteralExpression(firstArgument) ? Object.freeze({ kind: "unresolved" }) : classifyLangChainDirectBinding(firstArgument, analysis, reference);
|
|
1309
|
+
return Object.freeze({
|
|
1310
|
+
...result,
|
|
1311
|
+
strategy: "tool-strategy"
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
if (!isExactImportedHelper(callee, analysis.imports.providerStrategyNames, analysis) || candidate.arguments.length !== 1) return Object.freeze({ kind: "unresolved" });
|
|
1315
|
+
const argument = unwrapExpression(candidate.arguments[0]);
|
|
1316
|
+
const result = ts.isObjectLiteralExpression(argument) ? classifyProviderStrategyObject(argument, analysis, reference) : classifyLangChainDirectBinding(argument, analysis, reference);
|
|
1317
|
+
return Object.freeze({
|
|
1318
|
+
...result,
|
|
1319
|
+
strategy: "provider-strategy"
|
|
1320
|
+
});
|
|
1321
|
+
};
|
|
1322
|
+
/** Determines whether a schema binding is obviously an array or prebuilt strategy value. */
|
|
1323
|
+
var isLangChainSingleSchemaInitializer = (expression, analysis) => {
|
|
1324
|
+
const candidate = unwrapExpression(expression);
|
|
1325
|
+
if (ts.isArrayLiteralExpression(candidate)) return false;
|
|
1326
|
+
if (!ts.isCallExpression(candidate)) return true;
|
|
1327
|
+
const callee = unwrapExpression(candidate.expression);
|
|
1328
|
+
return !(isExactImportedHelper(callee, analysis.imports.toolStrategyNames, analysis) || isExactImportedHelper(callee, analysis.imports.providerStrategyNames, analysis));
|
|
1329
|
+
};
|
|
1330
|
+
//#endregion
|
|
1331
|
+
//#region src/diagnostics/index.ts
|
|
1332
|
+
var LANGCHAIN_ADAPTER_DIAGNOSTICS = Object.freeze({
|
|
1333
|
+
LANGCHAIN_PACKAGE_MANIFEST_INVALID: "The owning package manifest is invalid for LangChain dependency detection.",
|
|
1334
|
+
LANGCHAIN_VERSION_UNSUPPORTED: "The observed LangChain package ranges are disjoint from the supported target.",
|
|
1335
|
+
LANGCHAIN_SOURCE_TEXT_INVALID: "The referenced LangChain source file is not valid normalized text.",
|
|
1336
|
+
LANGCHAIN_SOURCE_SYNTAX_INVALID: "The referenced LangChain source file contains invalid TypeScript syntax.",
|
|
1337
|
+
LANGCHAIN_RUNTIME_AGENT_SYMBOL_NOT_FOUND: "The declared runtime-agent symbol was not found.",
|
|
1338
|
+
LANGCHAIN_INSTRUCTION_LOADER_SYMBOL_NOT_FOUND: "The declared instruction-loader symbol was not found.",
|
|
1339
|
+
LANGCHAIN_AGENT_OUTPUT_SCHEMA_SYMBOL_NOT_FOUND: "The declared agent output-schema symbol was not found.",
|
|
1340
|
+
LANGCHAIN_TOOL_IMPLEMENTATION_SYMBOL_NOT_FOUND: "The declared tool-implementation symbol was not found.",
|
|
1341
|
+
LANGCHAIN_TOOL_REGISTRATION_SYMBOL_NOT_FOUND: "The declared tool-registration symbol was not found.",
|
|
1342
|
+
LANGCHAIN_TOOL_INPUT_SCHEMA_SYMBOL_NOT_FOUND: "The declared tool input-schema symbol was not found.",
|
|
1343
|
+
LANGCHAIN_INSTRUCTION_LOADER_NOT_WIRED: "The declared instruction loader is not wired to the detected LangChain agent.",
|
|
1344
|
+
LANGCHAIN_AGENT_OUTPUT_SCHEMA_NOT_WIRED: "The declared agent output schema is not wired to the detected LangChain structured-output configuration.",
|
|
1345
|
+
LANGCHAIN_TOOL_IMPLEMENTATION_NOT_WIRED: "The declared tool implementation is not wired to the detected LangChain function tool.",
|
|
1346
|
+
LANGCHAIN_TOOL_REGISTRATION_NOT_WIRED: "The declared tool registration is not available to the detected LangChain agent.",
|
|
1347
|
+
LANGCHAIN_TOOL_NAME_MISMATCH: "The declared tool name does not match the detected LangChain tool name.",
|
|
1348
|
+
LANGCHAIN_TOOL_INPUT_SCHEMA_NOT_WIRED: "The declared tool input schema is not wired to the detected LangChain function tool."
|
|
1349
|
+
});
|
|
1350
|
+
/** Creates one frozen, safely namespaced LangChain adapter diagnostic. */
|
|
1351
|
+
var createLangChainDiagnostic = (input) => Object.freeze({
|
|
1352
|
+
...input,
|
|
1353
|
+
details: Object.freeze({ ...input.details }),
|
|
1354
|
+
entity: input.entity === null ? null : Object.freeze({ ...input.entity }),
|
|
1355
|
+
message: LANGCHAIN_ADAPTER_DIAGNOSTICS[input.code],
|
|
1356
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1357
|
+
});
|
|
1358
|
+
//#endregion
|
|
1359
|
+
//#region src/inspection/common.ts
|
|
1360
|
+
var LINE_BREAK_CODE_POINTS = /* @__PURE__ */ new Set([
|
|
1361
|
+
10,
|
|
1362
|
+
13,
|
|
1363
|
+
133,
|
|
1364
|
+
8232,
|
|
1365
|
+
8233
|
|
1366
|
+
]);
|
|
1367
|
+
var isUnicodeWhiteSpace = (codePoint) => codePoint >= 9 && codePoint <= 13 || codePoint === 32 || codePoint === 133 || codePoint === 160 || codePoint === 5760 || codePoint >= 8192 && codePoint <= 8202 || codePoint >= 8232 && codePoint <= 8233 || codePoint === 8239 || codePoint === 8287 || codePoint === 12288;
|
|
1368
|
+
/** Compares exact strings without locale-dependent behavior. */
|
|
1369
|
+
var compareLangChainStrings = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
1370
|
+
/** Determines whether a runtime-visible value satisfies Core's machine-string contract. */
|
|
1371
|
+
var isLangChainMachineString = (value) => {
|
|
1372
|
+
const codePoints = [...value].map((character) => character.codePointAt(0));
|
|
1373
|
+
return codePoints.length > 0 && codePoints.every((codePoint) => codePoint < 55296 || codePoint > 57343) && !codePoints.includes(0) && !codePoints.some((codePoint) => LINE_BREAK_CODE_POINTS.has(codePoint)) && !isUnicodeWhiteSpace(codePoints[0]) && !isUnicodeWhiteSpace(codePoints.at(-1));
|
|
1374
|
+
};
|
|
1375
|
+
var freezeReference = (reference) => Object.freeze({
|
|
1376
|
+
path: reference.path,
|
|
1377
|
+
...reference.symbol === void 0 ? {} : { symbol: reference.symbol }
|
|
1378
|
+
});
|
|
1379
|
+
/** Creates one deeply immutable LangChain evidence record. */
|
|
1380
|
+
var createLangChainEvidence = (evidence) => Object.freeze({
|
|
1381
|
+
...evidence,
|
|
1382
|
+
details: Object.freeze({ ...evidence.details }),
|
|
1383
|
+
references: Object.freeze(evidence.references.map(freezeReference))
|
|
1384
|
+
});
|
|
1385
|
+
var createEntity = (agentId, capabilityId) => Object.freeze({
|
|
1386
|
+
adapterId: LANGCHAIN_ADAPTER_ID,
|
|
1387
|
+
agentId,
|
|
1388
|
+
...capabilityId === void 0 ? {} : {
|
|
1389
|
+
capabilityId,
|
|
1390
|
+
capabilityKind: "tool"
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
/** Appends one stable package-owned diagnostic. */
|
|
1394
|
+
var addLangChainDiagnostic = (diagnostics, code, path, agentId, range = null, capabilityId, details = {}) => {
|
|
1395
|
+
diagnostics.push(createLangChainDiagnostic({
|
|
1396
|
+
code,
|
|
1397
|
+
details,
|
|
1398
|
+
entity: createEntity(agentId, capabilityId),
|
|
1399
|
+
path,
|
|
1400
|
+
pointer: null,
|
|
1401
|
+
range
|
|
1402
|
+
}));
|
|
1403
|
+
};
|
|
1404
|
+
/** Appends the stable diagnostic for one invalid imported relationship source. */
|
|
1405
|
+
var addLangChainSourceFailureDiagnostic = (diagnostics, failure, agentId, capabilityId) => {
|
|
1406
|
+
if (failure.kind === "invalid-text") {
|
|
1407
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_SOURCE_TEXT_INVALID", failure.path, agentId, null, capabilityId);
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_SOURCE_SYNTAX_INVALID", failure.path, agentId, failure.range, capabilityId);
|
|
1411
|
+
};
|
|
1412
|
+
/** Returns the Core scalar range for one node in its analyzed source. */
|
|
1413
|
+
var locateLangChainNode = (analysis, node) => analysis.text.locator.locateRange(node.getStart(analysis.sourceFile), node.getEnd());
|
|
1414
|
+
/** Loads and validates one supported manifest-bound TypeScript source. */
|
|
1415
|
+
var analyzeLangChainBoundReference = async (session, reference, diagnostics, agentId, capabilityId) => {
|
|
1416
|
+
if (!isSupportedTypeScriptSourcePath(reference.path)) return null;
|
|
1417
|
+
const result = await session.analyzeSource(reference.path);
|
|
1418
|
+
if (result.kind === "invalid-text") {
|
|
1419
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_SOURCE_TEXT_INVALID", reference.path, agentId, null, capabilityId);
|
|
1420
|
+
return null;
|
|
1421
|
+
}
|
|
1422
|
+
if (result.kind === "invalid-syntax") {
|
|
1423
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_SOURCE_SYNTAX_INVALID", reference.path, agentId, result.range, capabilityId);
|
|
1424
|
+
return null;
|
|
1425
|
+
}
|
|
1426
|
+
return result.analysis;
|
|
1427
|
+
};
|
|
1428
|
+
//#endregion
|
|
1429
|
+
//#region src/inspection/instruction-inspection.ts
|
|
1430
|
+
var classifyInstruction = (inspected, reference) => {
|
|
1431
|
+
const relationship = inspected.definition.systemPrompt;
|
|
1432
|
+
if (relationship.kind === "absent") return Object.freeze({
|
|
1433
|
+
expression: null,
|
|
1434
|
+
kind: "different"
|
|
1435
|
+
});
|
|
1436
|
+
if (relationship.kind === "unresolved") return Object.freeze({ kind: "unresolved" });
|
|
1437
|
+
const candidate = unwrapExpression(relationship.expression);
|
|
1438
|
+
if (ts.isNewExpression(candidate) && candidate.arguments?.length === 1) {
|
|
1439
|
+
const constructor = unwrapExpression(candidate.expression);
|
|
1440
|
+
if (ts.isIdentifier(constructor) && inspected.analysis.imports.systemMessageNames.has(constructor.text) && isModuleBindingVisible(constructor, inspected.analysis)) {
|
|
1441
|
+
const result = classifyLangChainLoaderCall(candidate.arguments[0], inspected.analysis, reference);
|
|
1442
|
+
return Object.freeze({
|
|
1443
|
+
...result,
|
|
1444
|
+
instructionForm: "system-message"
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
return Object.freeze({ kind: "unresolved" });
|
|
1448
|
+
}
|
|
1449
|
+
const result = classifyLangChainLoaderCall(candidate, inspected.analysis, reference);
|
|
1450
|
+
return Object.freeze({
|
|
1451
|
+
...result,
|
|
1452
|
+
instructionForm: "direct-loader-call"
|
|
1453
|
+
});
|
|
1454
|
+
};
|
|
1455
|
+
/** Inspects one declared instruction loader against the supported system prompt surface. */
|
|
1456
|
+
var inspectLangChainInstruction = async (session, inspected, evidence, diagnostics) => {
|
|
1457
|
+
const reference = inspected.agent.declaration.bindings?.instructionLoader;
|
|
1458
|
+
if (reference?.symbol === void 0) return;
|
|
1459
|
+
const boundReference = Object.freeze({
|
|
1460
|
+
path: reference.path,
|
|
1461
|
+
symbol: reference.symbol
|
|
1462
|
+
});
|
|
1463
|
+
const loaderAnalysis = await analyzeLangChainBoundReference(session, reference, diagnostics, inspected.agent.id);
|
|
1464
|
+
if (loaderAnalysis === null) return;
|
|
1465
|
+
const loader = getCallableExportState(loaderAnalysis, reference.symbol);
|
|
1466
|
+
if (loader.kind === "absent") {
|
|
1467
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_INSTRUCTION_LOADER_SYMBOL_NOT_FOUND", reference.path, inspected.agent.id);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
if (loader.kind !== "present-supported" || inspected.middlewareState !== "inactive") return;
|
|
1471
|
+
const result = classifyInstruction(inspected, boundReference);
|
|
1472
|
+
if (result.kind === "wired") evidence.push(createLangChainEvidence({
|
|
1473
|
+
agentId: inspected.agent.id,
|
|
1474
|
+
capabilityId: null,
|
|
1475
|
+
capabilityKind: null,
|
|
1476
|
+
details: {
|
|
1477
|
+
instructionForm: result.instructionForm ?? "direct-loader-call",
|
|
1478
|
+
property: "systemPrompt",
|
|
1479
|
+
targetId: LANGCHAIN_TARGET_ID
|
|
1480
|
+
},
|
|
1481
|
+
kind: "instruction-loader",
|
|
1482
|
+
references: [inspected.agent.declaration.bindings?.runtimeAgent, boundReference],
|
|
1483
|
+
runtimeName: boundReference.symbol,
|
|
1484
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1485
|
+
}));
|
|
1486
|
+
else if (result.kind === "different") addLangChainDiagnostic(diagnostics, "LANGCHAIN_INSTRUCTION_LOADER_NOT_WIRED", inspected.analysis.path, inspected.agent.id, result.expression === null ? locateLangChainNode(inspected.analysis, inspected.definition.object) : locateLangChainNode(inspected.analysis, result.expression));
|
|
1487
|
+
};
|
|
1488
|
+
//#endregion
|
|
1489
|
+
//#region src/inspection/resolution.ts
|
|
1490
|
+
var collectRelationshipReferences = (relationships) => {
|
|
1491
|
+
const references = /* @__PURE__ */ new Set();
|
|
1492
|
+
for (const relationship of relationships) {
|
|
1493
|
+
if (relationship.kind !== "present") continue;
|
|
1494
|
+
const expression = unwrapExpression(relationship.expression);
|
|
1495
|
+
if (ts.isIdentifier(expression)) references.add(expression);
|
|
1496
|
+
}
|
|
1497
|
+
return references;
|
|
1498
|
+
};
|
|
1499
|
+
/** Resolves one closed inline, module-local, or relative-imported array literal. */
|
|
1500
|
+
var resolveLangChainArray = async (session, analysis, relationship, relatedRelationships = [relationship]) => {
|
|
1501
|
+
if (relationship.kind !== "present") return Object.freeze({ kind: "unresolved" });
|
|
1502
|
+
const candidate = unwrapExpression(relationship.expression);
|
|
1503
|
+
if (ts.isArrayLiteralExpression(candidate)) return Object.freeze({
|
|
1504
|
+
kind: "resolved",
|
|
1505
|
+
value: Object.freeze({
|
|
1506
|
+
analysis,
|
|
1507
|
+
expression: candidate,
|
|
1508
|
+
reference: null
|
|
1509
|
+
})
|
|
1510
|
+
});
|
|
1511
|
+
if (!ts.isIdentifier(candidate) || !isModuleBindingVisible(candidate, analysis)) return Object.freeze({ kind: "unresolved" });
|
|
1512
|
+
const localDeclaration = analysis.moduleConstDeclarations.get(candidate.text);
|
|
1513
|
+
const localInitializer = localDeclaration?.initializer === void 0 ? null : unwrapExpression(localDeclaration.initializer);
|
|
1514
|
+
if (localDeclaration !== void 0 && localInitializer !== null && ts.isArrayLiteralExpression(localInitializer) && isModuleConstValueSafe(analysis, localDeclaration, collectRelationshipReferences(relatedRelationships), "array")) return Object.freeze({
|
|
1515
|
+
kind: "resolved",
|
|
1516
|
+
value: Object.freeze({
|
|
1517
|
+
analysis,
|
|
1518
|
+
expression: localInitializer,
|
|
1519
|
+
reference: Object.freeze({
|
|
1520
|
+
path: analysis.path,
|
|
1521
|
+
symbol: candidate.text
|
|
1522
|
+
})
|
|
1523
|
+
})
|
|
1524
|
+
});
|
|
1525
|
+
const importedCandidates = [];
|
|
1526
|
+
for (const reference of resolveBindingReferences(candidate, analysis).filter(({ path }) => path !== analysis.path)) {
|
|
1527
|
+
session.signal?.throwIfAborted();
|
|
1528
|
+
const path = parseRepositoryPath(reference.path);
|
|
1529
|
+
if ((await session.getEntry(path))?.type === "file") importedCandidates.push({
|
|
1530
|
+
path,
|
|
1531
|
+
symbol: reference.symbol
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
if (importedCandidates.length !== 1) return Object.freeze({ kind: "unresolved" });
|
|
1535
|
+
const importedReference = importedCandidates[0];
|
|
1536
|
+
const source = await session.analyzeSource(importedReference.path);
|
|
1537
|
+
if (source.kind !== "valid") return Object.freeze({
|
|
1538
|
+
failure: Object.freeze({
|
|
1539
|
+
...source,
|
|
1540
|
+
path: importedReference.path
|
|
1541
|
+
}),
|
|
1542
|
+
kind: "source-failure"
|
|
1543
|
+
});
|
|
1544
|
+
const exported = getConstExport(source.analysis, importedReference.symbol);
|
|
1545
|
+
const declaration = source.analysis.moduleConstDeclarations.get(importedReference.symbol);
|
|
1546
|
+
if (exported.kind !== "present-supported" || exported.expression === void 0 || !ts.isArrayLiteralExpression(exported.expression) || declaration === void 0 || !isModuleConstValueSafe(source.analysis, declaration, /* @__PURE__ */ new Set(), "array")) return Object.freeze({ kind: "unresolved" });
|
|
1547
|
+
return Object.freeze({
|
|
1548
|
+
kind: "resolved",
|
|
1549
|
+
value: Object.freeze({
|
|
1550
|
+
analysis: source.analysis,
|
|
1551
|
+
expression: exported.expression,
|
|
1552
|
+
reference: Object.freeze(importedReference)
|
|
1553
|
+
})
|
|
1554
|
+
});
|
|
1555
|
+
};
|
|
1556
|
+
/** Determines whether an array has no holes or spread elements. */
|
|
1557
|
+
var isClosedLangChainArray = (array) => array.elements.every((element) => !ts.isOmittedExpression(element) && !ts.isSpreadElement(element));
|
|
1558
|
+
//#endregion
|
|
1559
|
+
//#region src/inspection/middleware-inspection.ts
|
|
1560
|
+
/** Classifies middleware as inactive, active, or unresolved without interpreting it. */
|
|
1561
|
+
var classifyLangChainMiddleware = async (session, analysis, relationship, relatedRelationships, diagnostics, agentId) => {
|
|
1562
|
+
if (relationship.kind === "absent") return "inactive";
|
|
1563
|
+
if (relationship.kind === "unresolved") return "unresolved";
|
|
1564
|
+
const resolved = await resolveLangChainArray(session, analysis, relationship, relatedRelationships);
|
|
1565
|
+
if (resolved.kind === "source-failure") {
|
|
1566
|
+
addLangChainSourceFailureDiagnostic(diagnostics, resolved.failure, agentId);
|
|
1567
|
+
return "unresolved";
|
|
1568
|
+
}
|
|
1569
|
+
if (resolved.kind === "unresolved" || !isClosedLangChainArray(resolved.value.expression)) return "unresolved";
|
|
1570
|
+
return resolved.value.expression.elements.length === 0 ? "inactive" : "active";
|
|
1571
|
+
};
|
|
1572
|
+
//#endregion
|
|
1573
|
+
//#region src/inspection/package-inspection.ts
|
|
1574
|
+
var getPackageRole = (packageName) => packageName === "@langchain/core" ? "companion" : "primary";
|
|
1575
|
+
/** Inspects the nearest owning manifest and returns the conjunctive target state. */
|
|
1576
|
+
var inspectLangChainPackage = async (session, sourcePath, evidence, diagnostics, agentId) => {
|
|
1577
|
+
const discovery = await session.discoverPackage(sourcePath);
|
|
1578
|
+
if (discovery.kind === "absent") return "absent";
|
|
1579
|
+
if (discovery.kind === "invalid") {
|
|
1580
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_PACKAGE_MANIFEST_INVALID", discovery.path, agentId);
|
|
1581
|
+
return "absent";
|
|
1582
|
+
}
|
|
1583
|
+
const { observation } = discovery;
|
|
1584
|
+
if (observation.targetClassification === "absent") return observation.targetClassification;
|
|
1585
|
+
if (observation.targetClassification === "unsupported") {
|
|
1586
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_VERSION_UNSUPPORTED", observation.path, agentId);
|
|
1587
|
+
return observation.targetClassification;
|
|
1588
|
+
}
|
|
1589
|
+
for (const packageObservation of observation.packages) for (const declaration of packageObservation.declarations) {
|
|
1590
|
+
const isSemverRange = validRange(declaration.declaredRange, {
|
|
1591
|
+
includePrerelease: false,
|
|
1592
|
+
loose: false
|
|
1593
|
+
}) !== null;
|
|
1594
|
+
evidence.push(createLangChainEvidence({
|
|
1595
|
+
agentId,
|
|
1596
|
+
capabilityId: null,
|
|
1597
|
+
capabilityKind: null,
|
|
1598
|
+
details: {
|
|
1599
|
+
classification: packageObservation.compatibility,
|
|
1600
|
+
dependencyKind: declaration.dependencyKind,
|
|
1601
|
+
...isSemverRange ? { declaredRange: declaration.declaredRange } : {},
|
|
1602
|
+
packageName: packageObservation.packageName,
|
|
1603
|
+
packageRole: getPackageRole(packageObservation.packageName),
|
|
1604
|
+
targetClassification: observation.targetClassification,
|
|
1605
|
+
targetId: LANGCHAIN_TARGET_ID
|
|
1606
|
+
},
|
|
1607
|
+
kind: "runtime-package",
|
|
1608
|
+
references: [{ path: observation.path }],
|
|
1609
|
+
runtimeName: packageObservation.packageName === "langchain" ? LANGCHAIN_PACKAGE_NAME : LANGCHAIN_CORE_PACKAGE_NAME,
|
|
1610
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1611
|
+
}));
|
|
1612
|
+
}
|
|
1613
|
+
return observation.targetClassification;
|
|
1614
|
+
};
|
|
1615
|
+
//#endregion
|
|
1616
|
+
//#region src/inspection/schema-inspection.ts
|
|
1617
|
+
/** Inspects one declared agent output schema against supported response formats. */
|
|
1618
|
+
var inspectLangChainOutputSchema = async (session, inspected, evidence, diagnostics) => {
|
|
1619
|
+
const reference = inspected.agent.declaration.bindings?.outputSchema;
|
|
1620
|
+
if (reference?.symbol === void 0) return;
|
|
1621
|
+
const boundReference = Object.freeze({
|
|
1622
|
+
path: reference.path,
|
|
1623
|
+
symbol: reference.symbol
|
|
1624
|
+
});
|
|
1625
|
+
const schemaAnalysis = await analyzeLangChainBoundReference(session, reference, diagnostics, inspected.agent.id);
|
|
1626
|
+
if (schemaAnalysis === null) return;
|
|
1627
|
+
const schema = getConstExport(schemaAnalysis, reference.symbol);
|
|
1628
|
+
if (schema.kind === "absent") {
|
|
1629
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_AGENT_OUTPUT_SCHEMA_SYMBOL_NOT_FOUND", reference.path, inspected.agent.id);
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1632
|
+
if (schema.kind !== "present-supported" || schema.expression === void 0 || !isLangChainSingleSchemaInitializer(schema.expression, schemaAnalysis) || inspected.middlewareState !== "inactive") return;
|
|
1633
|
+
const relationship = inspected.definition.responseFormat;
|
|
1634
|
+
if (relationship.kind === "unresolved") return;
|
|
1635
|
+
const result = relationship.kind === "absent" ? {
|
|
1636
|
+
expression: null,
|
|
1637
|
+
kind: "different"
|
|
1638
|
+
} : classifyLangChainResponseFormat(relationship.expression, inspected.analysis, boundReference);
|
|
1639
|
+
if (result.kind === "wired") evidence.push(createLangChainEvidence({
|
|
1640
|
+
agentId: inspected.agent.id,
|
|
1641
|
+
capabilityId: null,
|
|
1642
|
+
capabilityKind: null,
|
|
1643
|
+
details: {
|
|
1644
|
+
property: "responseFormat",
|
|
1645
|
+
schemaRole: "agent-output",
|
|
1646
|
+
schemaStrategy: result.strategy ?? "direct",
|
|
1647
|
+
targetId: LANGCHAIN_TARGET_ID
|
|
1648
|
+
},
|
|
1649
|
+
kind: "schema",
|
|
1650
|
+
references: [inspected.agent.declaration.bindings?.runtimeAgent, boundReference],
|
|
1651
|
+
runtimeName: boundReference.symbol,
|
|
1652
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1653
|
+
}));
|
|
1654
|
+
else if (result.kind === "different") addLangChainDiagnostic(diagnostics, "LANGCHAIN_AGENT_OUTPUT_SCHEMA_NOT_WIRED", inspected.analysis.path, inspected.agent.id, result.expression === null ? locateLangChainNode(inspected.analysis, inspected.definition.object) : locateLangChainNode(inspected.analysis, result.expression));
|
|
1655
|
+
};
|
|
1656
|
+
//#endregion
|
|
1657
|
+
//#region src/package-discovery/index.ts
|
|
1658
|
+
var classifyTarget = (primary, companion) => {
|
|
1659
|
+
if (primary === "absent") return "absent";
|
|
1660
|
+
if (primary === "unsupported" || (primary === "supported" || primary === "ambiguous") && companion === "unsupported") return "unsupported";
|
|
1661
|
+
if (primary === "supported" && companion === "supported") return "supported";
|
|
1662
|
+
if (primary === "supported" && companion === "absent") return "incomplete";
|
|
1663
|
+
return "ambiguous";
|
|
1664
|
+
};
|
|
1665
|
+
/** Discovers the exact primary and companion declarations in one owning manifest read. */
|
|
1666
|
+
var discoverLangChainPackages = async (reader, sourcePath, signal) => {
|
|
1667
|
+
const result = await discoverPackages({
|
|
1668
|
+
packages: [{
|
|
1669
|
+
packageName: LANGCHAIN_PACKAGE_NAME,
|
|
1670
|
+
supportedRange: LANGCHAIN_SUPPORTED_PACKAGE_RANGE
|
|
1671
|
+
}, {
|
|
1672
|
+
packageName: LANGCHAIN_CORE_PACKAGE_NAME,
|
|
1673
|
+
supportedRange: LANGCHAIN_CORE_SUPPORTED_PACKAGE_RANGE
|
|
1674
|
+
}],
|
|
1675
|
+
reader: {
|
|
1676
|
+
getEntry: (path) => reader.getEntry(path, signal === void 0 ? void 0 : { signal }),
|
|
1677
|
+
readFile: (path) => reader.readFile(path, signal === void 0 ? void 0 : { signal })
|
|
1678
|
+
},
|
|
1679
|
+
...signal === void 0 ? {} : { signal },
|
|
1680
|
+
sourcePath
|
|
1681
|
+
});
|
|
1682
|
+
if (result.kind !== "observed") return result.kind === "invalid" ? Object.freeze({
|
|
1683
|
+
kind: "invalid",
|
|
1684
|
+
path: result.path
|
|
1685
|
+
}) : result;
|
|
1686
|
+
const [primary, companion] = result.observation.packages;
|
|
1687
|
+
if (primary === void 0 || companion === void 0) return Object.freeze({
|
|
1688
|
+
kind: "invalid",
|
|
1689
|
+
path: result.observation.path
|
|
1690
|
+
});
|
|
1691
|
+
return Object.freeze({
|
|
1692
|
+
kind: "observed",
|
|
1693
|
+
observation: Object.freeze({
|
|
1694
|
+
packages: result.observation.packages,
|
|
1695
|
+
path: result.observation.path,
|
|
1696
|
+
targetClassification: classifyTarget(primary.compatibility, companion.compatibility)
|
|
1697
|
+
})
|
|
1698
|
+
});
|
|
1699
|
+
};
|
|
1700
|
+
//#endregion
|
|
1701
|
+
//#region src/inspection/session.ts
|
|
1702
|
+
/** Creates one operation-local LangChain inspection session. */
|
|
1703
|
+
var createLangChainInspectionSession = (context) => createInspectionSession({
|
|
1704
|
+
analyzeSource: analyzeLangChainSource,
|
|
1705
|
+
discoverPackage: (path, signal) => discoverLangChainPackages(context.repository, path, signal),
|
|
1706
|
+
getEntry: (path, signal) => context.repository.getEntry(path, signal === void 0 ? void 0 : { signal }),
|
|
1707
|
+
readFile: (path, signal) => context.repository.readFile(path, signal === void 0 ? void 0 : { signal }),
|
|
1708
|
+
...context.signal === void 0 ? {} : { signal: context.signal }
|
|
1709
|
+
});
|
|
1710
|
+
//#endregion
|
|
1711
|
+
//#region src/inspection/tool-inspection.ts
|
|
1712
|
+
/** Resolves the static metadata required for one supported normal function-tool shape. */
|
|
1713
|
+
var resolveFunctionToolMetadata = async (session, analysis, functionTool, diagnostics, agentId, capabilityId) => {
|
|
1714
|
+
const onSourceFailure = (failure) => addLangChainSourceFailureDiagnostic(diagnostics, failure, agentId, capabilityId);
|
|
1715
|
+
const name = await resolveLangChainStaticString(session, analysis, functionTool.name.expression, onSourceFailure);
|
|
1716
|
+
if (name.kind !== "supported" || functionTool.description.kind === "unresolved") return null;
|
|
1717
|
+
if (functionTool.description.kind === "present") {
|
|
1718
|
+
if ((await resolveLangChainStaticString(session, analysis, functionTool.description.expression, onSourceFailure)).kind !== "supported") return null;
|
|
1719
|
+
}
|
|
1720
|
+
return Object.freeze({ runtimeName: functionTool.name.kind === "present" ? name.value : null });
|
|
1721
|
+
};
|
|
1722
|
+
/** Finds the direct array containing one registration use through transparent wrappers. */
|
|
1723
|
+
var getContainingArrayLiteral = (identifier) => {
|
|
1724
|
+
let expression = identifier;
|
|
1725
|
+
while (ts.isAsExpression(expression.parent) || ts.isParenthesizedExpression(expression.parent) || ts.isSatisfiesExpression(expression.parent)) expression = expression.parent;
|
|
1726
|
+
return ts.isArrayLiteralExpression(expression.parent) ? expression.parent : null;
|
|
1727
|
+
};
|
|
1728
|
+
/** Groups direct array-element uses of one bound registration by their containing arrays. */
|
|
1729
|
+
var collectRegistrationArrayReferences = (analysis, reference) => {
|
|
1730
|
+
const references = /* @__PURE__ */ new Map();
|
|
1731
|
+
for (const identifier of analysis.identifierUses.get(reference.symbol) ?? []) {
|
|
1732
|
+
if (!isModuleBindingVisible(identifier, analysis) || !isBoundIdentifier(identifier, analysis, reference)) continue;
|
|
1733
|
+
const array = getContainingArrayLiteral(identifier);
|
|
1734
|
+
if (array !== null) {
|
|
1735
|
+
const arrayReferences = references.get(array) ?? [];
|
|
1736
|
+
arrayReferences.push(identifier);
|
|
1737
|
+
references.set(array, arrayReferences);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
return references;
|
|
1741
|
+
};
|
|
1742
|
+
/** Checks whether one agent relationship can resolve to a candidate registration array. */
|
|
1743
|
+
var canResolveToRegistrationArray = (inspected, registrationAnalysis, arrays) => {
|
|
1744
|
+
if (inspected.definition.configuredTools.kind !== "present") return false;
|
|
1745
|
+
const relationship = unwrapExpression(inspected.definition.configuredTools.expression);
|
|
1746
|
+
if (ts.isArrayLiteralExpression(relationship)) return inspected.analysis === registrationAnalysis && arrays.has(relationship);
|
|
1747
|
+
if (!ts.isIdentifier(relationship) || !isModuleBindingVisible(relationship, inspected.analysis)) return false;
|
|
1748
|
+
const localDeclaration = inspected.analysis.moduleConstDeclarations.get(relationship.text);
|
|
1749
|
+
const localInitializer = localDeclaration?.initializer === void 0 ? null : unwrapExpression(localDeclaration.initializer);
|
|
1750
|
+
if (inspected.analysis === registrationAnalysis && localInitializer !== null && ts.isArrayLiteralExpression(localInitializer) && arrays.has(localInitializer)) return true;
|
|
1751
|
+
return resolveBindingReferences(relationship, inspected.analysis).some((reference) => {
|
|
1752
|
+
if (reference.path !== registrationAnalysis.path) return false;
|
|
1753
|
+
const declaration = registrationAnalysis.moduleConstDeclarations.get(reference.symbol);
|
|
1754
|
+
const initializer = declaration?.initializer === void 0 ? null : unwrapExpression(declaration.initializer);
|
|
1755
|
+
return initializer !== null && ts.isArrayLiteralExpression(initializer) && arrays.has(initializer);
|
|
1756
|
+
});
|
|
1757
|
+
};
|
|
1758
|
+
/** Collects exact registration uses from closed tool collections owned by supported agents. */
|
|
1759
|
+
var collectAllowedRegistrationReferences = async (session, inspectedAgents, analysis, reference) => {
|
|
1760
|
+
const registrationArrays = collectRegistrationArrayReferences(analysis, reference);
|
|
1761
|
+
const references = /* @__PURE__ */ new Set();
|
|
1762
|
+
if (registrationArrays.size === 0) return references;
|
|
1763
|
+
for (const inspected of inspectedAgents) {
|
|
1764
|
+
session.signal?.throwIfAborted();
|
|
1765
|
+
if (!canResolveToRegistrationArray(inspected, analysis, registrationArrays)) continue;
|
|
1766
|
+
const relatedRelationships = inspectedAgents.filter(({ analysis: candidateAnalysis }) => candidateAnalysis === inspected.analysis).map(({ definition }) => definition.configuredTools);
|
|
1767
|
+
const resolved = await resolveLangChainArray(session, inspected.analysis, inspected.definition.configuredTools, relatedRelationships);
|
|
1768
|
+
if (resolved.kind !== "resolved" || resolved.value.analysis !== analysis || !isClosedLangChainArray(resolved.value.expression)) continue;
|
|
1769
|
+
for (const candidate of registrationArrays.get(resolved.value.expression) ?? []) references.add(candidate);
|
|
1770
|
+
}
|
|
1771
|
+
return references;
|
|
1772
|
+
};
|
|
1773
|
+
var inspectImplementation = async (session, inspected, capabilityId, manifestTool, registrationAnalysis, functionTool, diagnostics) => {
|
|
1774
|
+
const reference = manifestTool.implementation;
|
|
1775
|
+
if (reference.symbol === void 0) return null;
|
|
1776
|
+
const boundReference = Object.freeze({
|
|
1777
|
+
path: reference.path,
|
|
1778
|
+
symbol: reference.symbol
|
|
1779
|
+
});
|
|
1780
|
+
const implementationAnalysis = await analyzeLangChainBoundReference(session, reference, diagnostics, inspected.agent.id, capabilityId);
|
|
1781
|
+
if (implementationAnalysis === null) return null;
|
|
1782
|
+
const implementation = getCallableExportState(implementationAnalysis, reference.symbol);
|
|
1783
|
+
if (implementation.kind === "absent") {
|
|
1784
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_IMPLEMENTATION_SYMBOL_NOT_FOUND", reference.path, inspected.agent.id, null, capabilityId);
|
|
1785
|
+
return null;
|
|
1786
|
+
}
|
|
1787
|
+
if (implementation.kind !== "present-supported") return null;
|
|
1788
|
+
if (functionTool.implementation.kind === "unresolved") return { kind: "unresolved" };
|
|
1789
|
+
const result = classifyLangChainDirectBinding(functionTool.implementation.expression, registrationAnalysis, boundReference);
|
|
1790
|
+
if (result.kind === "different") addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_IMPLEMENTATION_NOT_WIRED", registrationAnalysis.path, inspected.agent.id, result.expression === null ? locateLangChainNode(registrationAnalysis, functionTool.fields) : locateLangChainNode(registrationAnalysis, result.expression), capabilityId);
|
|
1791
|
+
return result;
|
|
1792
|
+
};
|
|
1793
|
+
var inspectInputSchema = async (session, inspected, capabilityId, manifestTool, registrationAnalysis, functionTool, evidence, diagnostics) => {
|
|
1794
|
+
const reference = manifestTool.inputSchema;
|
|
1795
|
+
if (reference?.symbol === void 0) return null;
|
|
1796
|
+
const boundReference = Object.freeze({
|
|
1797
|
+
path: reference.path,
|
|
1798
|
+
symbol: reference.symbol
|
|
1799
|
+
});
|
|
1800
|
+
const schemaAnalysis = await analyzeLangChainBoundReference(session, reference, diagnostics, inspected.agent.id, capabilityId);
|
|
1801
|
+
if (schemaAnalysis === null) return null;
|
|
1802
|
+
const schema = getConstExport(schemaAnalysis, reference.symbol);
|
|
1803
|
+
if (schema.kind === "absent") {
|
|
1804
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_INPUT_SCHEMA_SYMBOL_NOT_FOUND", reference.path, inspected.agent.id, null, capabilityId);
|
|
1805
|
+
return null;
|
|
1806
|
+
}
|
|
1807
|
+
if (schema.kind !== "present-supported") return null;
|
|
1808
|
+
const result = functionTool.schema.kind === "absent" ? {
|
|
1809
|
+
expression: null,
|
|
1810
|
+
kind: "different"
|
|
1811
|
+
} : functionTool.schema.kind === "unresolved" ? { kind: "unresolved" } : classifyLangChainDirectBinding(functionTool.schema.expression, registrationAnalysis, boundReference);
|
|
1812
|
+
if (result.kind === "wired") evidence.push(createLangChainEvidence({
|
|
1813
|
+
agentId: inspected.agent.id,
|
|
1814
|
+
capabilityId,
|
|
1815
|
+
capabilityKind: "tool",
|
|
1816
|
+
details: {
|
|
1817
|
+
property: "schema",
|
|
1818
|
+
schemaRole: "tool-input",
|
|
1819
|
+
targetId: LANGCHAIN_TARGET_ID
|
|
1820
|
+
},
|
|
1821
|
+
kind: "schema",
|
|
1822
|
+
references: [manifestTool.registration, boundReference],
|
|
1823
|
+
runtimeName: boundReference.symbol,
|
|
1824
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1825
|
+
}));
|
|
1826
|
+
else if (result.kind === "different") addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_INPUT_SCHEMA_NOT_WIRED", registrationAnalysis.path, inspected.agent.id, result.expression === null ? locateLangChainNode(registrationAnalysis, functionTool.fields) : locateLangChainNode(registrationAnalysis, result.expression), capabilityId);
|
|
1827
|
+
return result;
|
|
1828
|
+
};
|
|
1829
|
+
var classifyRegistration = async (session, inspectedAgents, inspected, registrationReference, diagnostics, capabilityId) => {
|
|
1830
|
+
const relationship = inspected.definition.tools;
|
|
1831
|
+
if (relationship.kind === "absent") return false;
|
|
1832
|
+
if (relationship.kind === "unresolved") return null;
|
|
1833
|
+
const relatedRelationships = inspectedAgents.filter(({ analysis }) => analysis === inspected.analysis).map(({ definition }) => definition.tools);
|
|
1834
|
+
const resolved = await resolveLangChainArray(session, inspected.analysis, relationship, relatedRelationships);
|
|
1835
|
+
if (resolved.kind === "source-failure") {
|
|
1836
|
+
addLangChainSourceFailureDiagnostic(diagnostics, resolved.failure, inspected.agent.id, capabilityId);
|
|
1837
|
+
return null;
|
|
1838
|
+
}
|
|
1839
|
+
if (resolved.kind === "unresolved" || !isClosedLangChainArray(resolved.value.expression)) return null;
|
|
1840
|
+
const resolvedArray = resolved.value;
|
|
1841
|
+
const knownRegistrationReferences = Object.values(inspected.agent.declaration.tools ?? {}).map(({ registration }) => registration).filter((reference) => reference?.symbol !== void 0);
|
|
1842
|
+
let hasUnresolvedElement = false;
|
|
1843
|
+
for (const element of resolvedArray.expression.elements) {
|
|
1844
|
+
const candidate = unwrapExpression(element);
|
|
1845
|
+
if (ts.isIdentifier(candidate) && isModuleBindingVisible(candidate, resolvedArray.analysis)) {
|
|
1846
|
+
if (isBoundIdentifier(candidate, resolvedArray.analysis, registrationReference)) return true;
|
|
1847
|
+
if (resolveBindingReferences(candidate, resolvedArray.analysis).some((reference) => knownRegistrationReferences.some((known) => known.path === reference.path && known.symbol === reference.symbol))) continue;
|
|
1848
|
+
const localTool = getLangChainFunctionTool(resolvedArray.analysis, candidate.text, /* @__PURE__ */ new Set([candidate]));
|
|
1849
|
+
if (localTool.kind === "present-supported") {
|
|
1850
|
+
const metadata = await resolveFunctionToolMetadata(session, resolvedArray.analysis, localTool.tool, diagnostics, inspected.agent.id, capabilityId);
|
|
1851
|
+
if (metadata !== null && metadata.runtimeName !== null) continue;
|
|
1852
|
+
}
|
|
1853
|
+
hasUnresolvedElement = true;
|
|
1854
|
+
continue;
|
|
1855
|
+
}
|
|
1856
|
+
const inlineTool = getInlineLangChainFunctionTool(candidate, resolvedArray.analysis);
|
|
1857
|
+
if (inlineTool !== null) {
|
|
1858
|
+
const metadata = await resolveFunctionToolMetadata(session, resolvedArray.analysis, inlineTool, diagnostics, inspected.agent.id, capabilityId);
|
|
1859
|
+
if (metadata !== null && metadata.runtimeName !== null) continue;
|
|
1860
|
+
}
|
|
1861
|
+
hasUnresolvedElement = true;
|
|
1862
|
+
}
|
|
1863
|
+
return hasUnresolvedElement ? null : false;
|
|
1864
|
+
};
|
|
1865
|
+
var createRegistrationReferences = (inspected, registrationReference, manifestTool, relationships) => [
|
|
1866
|
+
inspected.agent.declaration.bindings?.runtimeAgent,
|
|
1867
|
+
registrationReference,
|
|
1868
|
+
...relationships.implementation?.kind === "wired" ? [manifestTool.implementation] : [],
|
|
1869
|
+
...relationships.inputSchema?.kind === "wired" && manifestTool.inputSchema !== void 0 ? [manifestTool.inputSchema] : []
|
|
1870
|
+
];
|
|
1871
|
+
/** Inspects all declared normal function tools and their agent registrations. */
|
|
1872
|
+
var inspectLangChainTools = async (session, inspectedAgents, evidence, diagnostics) => {
|
|
1873
|
+
for (const inspected of inspectedAgents) {
|
|
1874
|
+
const tools = Object.entries(inspected.agent.declaration.tools ?? {}).sort(([left], [right]) => compareLangChainStrings(left, right));
|
|
1875
|
+
for (const [capabilityId, manifestTool] of tools) {
|
|
1876
|
+
session.signal?.throwIfAborted();
|
|
1877
|
+
const registrationReference = manifestTool.registration;
|
|
1878
|
+
if (registrationReference?.symbol === void 0) continue;
|
|
1879
|
+
const boundRegistrationReference = Object.freeze({
|
|
1880
|
+
path: registrationReference.path,
|
|
1881
|
+
symbol: registrationReference.symbol
|
|
1882
|
+
});
|
|
1883
|
+
const registrationAnalysis = await analyzeLangChainBoundReference(session, registrationReference, diagnostics, inspected.agent.id, capabilityId);
|
|
1884
|
+
if (registrationAnalysis === null) continue;
|
|
1885
|
+
const functionTool = getLangChainFunctionTool(registrationAnalysis, registrationReference.symbol, await collectAllowedRegistrationReferences(session, inspectedAgents, registrationAnalysis, boundRegistrationReference));
|
|
1886
|
+
if (functionTool.kind === "absent") {
|
|
1887
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_REGISTRATION_SYMBOL_NOT_FOUND", registrationReference.path, inspected.agent.id, null, capabilityId);
|
|
1888
|
+
continue;
|
|
1889
|
+
}
|
|
1890
|
+
if (functionTool.kind !== "present-supported") continue;
|
|
1891
|
+
const metadata = await resolveFunctionToolMetadata(session, registrationAnalysis, functionTool.tool, diagnostics, inspected.agent.id, capabilityId);
|
|
1892
|
+
if (metadata === null) continue;
|
|
1893
|
+
const implementation = await inspectImplementation(session, inspected, capabilityId, manifestTool, registrationAnalysis, functionTool.tool, diagnostics);
|
|
1894
|
+
const inputSchema = await inspectInputSchema(session, inspected, capabilityId, manifestTool, registrationAnalysis, functionTool.tool, evidence, diagnostics);
|
|
1895
|
+
const runtimeName = metadata.runtimeName !== null && isLangChainMachineString(metadata.runtimeName) ? metadata.runtimeName : null;
|
|
1896
|
+
if (inspected.middlewareState !== "inactive" || runtimeName === null) continue;
|
|
1897
|
+
const registration = await classifyRegistration(session, inspectedAgents, inspected, boundRegistrationReference, diagnostics, capabilityId);
|
|
1898
|
+
if (registration === true && runtimeName !== manifestTool.name) addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_NAME_MISMATCH", registrationAnalysis.path, inspected.agent.id, locateLangChainNode(registrationAnalysis, functionTool.tool.name.expression), capabilityId);
|
|
1899
|
+
else if (registration === false) addLangChainDiagnostic(diagnostics, "LANGCHAIN_TOOL_REGISTRATION_NOT_WIRED", inspected.analysis.path, inspected.agent.id, inspected.definition.tools.kind === "present" ? locateLangChainNode(inspected.analysis, inspected.definition.tools.expression) : locateLangChainNode(inspected.analysis, inspected.definition.object), capabilityId);
|
|
1900
|
+
else if (registration === true) evidence.push(createLangChainEvidence({
|
|
1901
|
+
agentId: inspected.agent.id,
|
|
1902
|
+
capabilityId,
|
|
1903
|
+
capabilityKind: "tool",
|
|
1904
|
+
details: {
|
|
1905
|
+
helperSource: functionTool.tool.helperSource,
|
|
1906
|
+
registrationForm: "normal-function-tool",
|
|
1907
|
+
targetId: LANGCHAIN_TARGET_ID
|
|
1908
|
+
},
|
|
1909
|
+
kind: "tool-registration",
|
|
1910
|
+
references: createRegistrationReferences(inspected, boundRegistrationReference, manifestTool, {
|
|
1911
|
+
implementation,
|
|
1912
|
+
inputSchema
|
|
1913
|
+
}),
|
|
1914
|
+
runtimeName,
|
|
1915
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1916
|
+
}));
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
//#endregion
|
|
1921
|
+
//#region src/inspection/inspection.ts
|
|
1922
|
+
var inspectAgent = async (session, agent, evidence, diagnostics) => {
|
|
1923
|
+
const runtimeAgent = agent.declaration.bindings?.runtimeAgent;
|
|
1924
|
+
if (runtimeAgent === void 0) return null;
|
|
1925
|
+
const targetClassification = await inspectLangChainPackage(session, runtimeAgent.path, evidence, diagnostics, agent.id);
|
|
1926
|
+
if (!isSupportedTypeScriptSourcePath(runtimeAgent.path)) return null;
|
|
1927
|
+
const analysis = await analyzeLangChainBoundReference(session, runtimeAgent, diagnostics, agent.id);
|
|
1928
|
+
if (analysis === null) return null;
|
|
1929
|
+
evidence.push(createLangChainEvidence({
|
|
1930
|
+
agentId: agent.id,
|
|
1931
|
+
capabilityId: null,
|
|
1932
|
+
capabilityKind: null,
|
|
1933
|
+
details: { language: "typescript" },
|
|
1934
|
+
kind: "language",
|
|
1935
|
+
references: [runtimeAgent],
|
|
1936
|
+
runtimeName: null,
|
|
1937
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1938
|
+
}));
|
|
1939
|
+
if (targetClassification !== "supported" || runtimeAgent.symbol === void 0) return null;
|
|
1940
|
+
const definition = getLangChainAgentDefinition(analysis, runtimeAgent.symbol);
|
|
1941
|
+
if (definition.kind === "absent") {
|
|
1942
|
+
addLangChainDiagnostic(diagnostics, "LANGCHAIN_RUNTIME_AGENT_SYMBOL_NOT_FOUND", runtimeAgent.path, agent.id);
|
|
1943
|
+
return null;
|
|
1944
|
+
}
|
|
1945
|
+
if (definition.kind !== "present-supported") return null;
|
|
1946
|
+
const staticName = definition.definition.name.kind === "present" ? await resolveLangChainStaticString(session, analysis, definition.definition.name.expression, (failure) => addLangChainSourceFailureDiagnostic(diagnostics, failure, agent.id)) : null;
|
|
1947
|
+
const runtimeName = staticName?.kind === "supported" && isLangChainMachineString(staticName.value) ? staticName.value : null;
|
|
1948
|
+
evidence.push(createLangChainEvidence({
|
|
1949
|
+
agentId: agent.id,
|
|
1950
|
+
capabilityId: null,
|
|
1951
|
+
capabilityKind: null,
|
|
1952
|
+
details: { targetId: LANGCHAIN_TARGET_ID },
|
|
1953
|
+
kind: "agent-definition",
|
|
1954
|
+
references: [runtimeAgent],
|
|
1955
|
+
runtimeName,
|
|
1956
|
+
source: LANGCHAIN_ADAPTER_ID
|
|
1957
|
+
}));
|
|
1958
|
+
return Object.freeze({
|
|
1959
|
+
agent,
|
|
1960
|
+
analysis,
|
|
1961
|
+
definition: definition.definition
|
|
1962
|
+
});
|
|
1963
|
+
};
|
|
1964
|
+
/**
|
|
1965
|
+
* Inspects all scoped LangChain agents through one deterministic operation-local session.
|
|
1966
|
+
* @param context The Core-provided immutable adapter context.
|
|
1967
|
+
* @returns A promise resolving to source-grounded evidence and diagnostics.
|
|
1968
|
+
* @throws
|
|
1969
|
+
* - INVALID_REPOSITORY_PATH: The repository path is invalid.
|
|
1970
|
+
* - ENTRY_NOT_FOUND: The requested repository entry was not found.
|
|
1971
|
+
* - ENTRY_NOT_FILE: The requested repository entry is not a file.
|
|
1972
|
+
* - ACCESS_DENIED: Access to the repository source was denied.
|
|
1973
|
+
* - SOURCE_UNAVAILABLE: The repository source is unavailable.
|
|
1974
|
+
* - SNAPSHOT_CHANGED: The repository snapshot changed during the operation.
|
|
1975
|
+
* - INVALID_SOURCE_DATA: The repository source returned invalid data.
|
|
1976
|
+
* - RESOURCE_LIMIT_EXCEEDED: A repository reading resource limit was exceeded.
|
|
1977
|
+
* - ABORTED: The repository operation or inspection signal was aborted.
|
|
1978
|
+
*/
|
|
1979
|
+
var inspectLangChain = async (context) => {
|
|
1980
|
+
context.signal?.throwIfAborted();
|
|
1981
|
+
const session = createLangChainInspectionSession(context);
|
|
1982
|
+
const evidence = [];
|
|
1983
|
+
const diagnostics = [];
|
|
1984
|
+
const agents = [...context.agents].sort((left, right) => compareLangChainStrings(left.id, right.id));
|
|
1985
|
+
const candidates = [];
|
|
1986
|
+
for (const agent of agents) {
|
|
1987
|
+
context.signal?.throwIfAborted();
|
|
1988
|
+
const candidate = await inspectAgent(session, agent, evidence, diagnostics);
|
|
1989
|
+
if (candidate !== null) candidates.push(candidate);
|
|
1990
|
+
}
|
|
1991
|
+
const inspectedAgents = [];
|
|
1992
|
+
for (const candidate of candidates) {
|
|
1993
|
+
context.signal?.throwIfAborted();
|
|
1994
|
+
const relatedMiddleware = candidates.filter(({ analysis }) => analysis === candidate.analysis).map(({ definition }) => definition.middleware);
|
|
1995
|
+
const middlewareState = await classifyLangChainMiddleware(session, candidate.analysis, candidate.definition.middleware, relatedMiddleware, diagnostics, candidate.agent.id);
|
|
1996
|
+
inspectedAgents.push(Object.freeze({
|
|
1997
|
+
...candidate,
|
|
1998
|
+
middlewareState
|
|
1999
|
+
}));
|
|
2000
|
+
}
|
|
2001
|
+
for (const inspected of inspectedAgents) {
|
|
2002
|
+
context.signal?.throwIfAborted();
|
|
2003
|
+
await inspectLangChainInstruction(session, inspected, evidence, diagnostics);
|
|
2004
|
+
context.signal?.throwIfAborted();
|
|
2005
|
+
await inspectLangChainOutputSchema(session, inspected, evidence, diagnostics);
|
|
2006
|
+
}
|
|
2007
|
+
context.signal?.throwIfAborted();
|
|
2008
|
+
await inspectLangChainTools(session, inspectedAgents, evidence, diagnostics);
|
|
2009
|
+
context.signal?.throwIfAborted();
|
|
2010
|
+
return Object.freeze({
|
|
2011
|
+
diagnostics: Object.freeze(diagnostics),
|
|
2012
|
+
evidence: Object.freeze(evidence)
|
|
2013
|
+
});
|
|
2014
|
+
};
|
|
2015
|
+
//#endregion
|
|
2016
|
+
//#region src/adapter/index.ts
|
|
2017
|
+
var langChainAdapter = Object.freeze({
|
|
2018
|
+
id: LANGCHAIN_ADAPTER_ID,
|
|
2019
|
+
inspect: inspectLangChain,
|
|
2020
|
+
supportedRepositoryFormatVersions: LANGCHAIN_SUPPORTED_REPOSITORY_FORMAT_VERSIONS
|
|
2021
|
+
});
|
|
2022
|
+
//#endregion
|
|
2023
|
+
export { langChainAdapter };
|