@indexnetwork/protocol 4.14.2-rc.356.1 → 4.16.0-rc.358.1
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/CHANGELOG.md +2 -0
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/opportunity/discriminator/discriminator.env.d.ts +15 -0
- package/dist/opportunity/discriminator/discriminator.env.d.ts.map +1 -1
- package/dist/opportunity/discriminator/discriminator.env.js +15 -0
- package/dist/opportunity/discriminator/discriminator.env.js.map +1 -1
- package/dist/opportunity/discriminator/discriminator.push.d.ts +16 -0
- package/dist/opportunity/discriminator/discriminator.push.d.ts.map +1 -0
- package/dist/opportunity/discriminator/discriminator.push.js +26 -0
- package/dist/opportunity/discriminator/discriminator.push.js.map +1 -0
- package/dist/opportunity/opportunity.graph.d.ts +13 -0
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +5 -1
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.state.d.ts +3 -0
- package/dist/opportunity/opportunity.state.d.ts.map +1 -1
- package/dist/opportunity/opportunity.state.js.map +1 -1
- package/dist/shared/agent/model.config.d.ts +5 -0
- package/dist/shared/agent/model.config.d.ts.map +1 -1
- package/dist/shared/agent/model.config.js +1 -0
- package/dist/shared/agent/model.config.js.map +1 -1
- package/dist/shared/hyde/hyde.documents.d.ts +10 -0
- package/dist/shared/hyde/hyde.documents.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.documents.js +50 -0
- package/dist/shared/hyde/hyde.documents.js.map +1 -0
- package/dist/shared/hyde/hyde.env.d.ts +9 -0
- package/dist/shared/hyde/hyde.env.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.env.js +10 -0
- package/dist/shared/hyde/hyde.env.js.map +1 -0
- package/dist/shared/hyde/hyde.frame.d.ts +151 -0
- package/dist/shared/hyde/hyde.frame.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.frame.js +108 -0
- package/dist/shared/hyde/hyde.frame.js.map +1 -0
- package/dist/shared/hyde/hyde.generator.d.ts +23 -11
- package/dist/shared/hyde/hyde.generator.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.generator.js +50 -21
- package/dist/shared/hyde/hyde.generator.js.map +1 -1
- package/dist/shared/hyde/hyde.graph.d.ts +58 -17
- package/dist/shared/hyde/hyde.graph.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.graph.js +333 -89
- package/dist/shared/hyde/hyde.graph.js.map +1 -1
- package/dist/shared/hyde/hyde.state.d.ts +19 -2
- package/dist/shared/hyde/hyde.state.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.state.js +23 -3
- package/dist/shared/hyde/hyde.state.js.map +1 -1
- package/dist/shared/hyde/hyde.validator.d.ts +79 -0
- package/dist/shared/hyde/hyde.validator.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.validator.js +49 -0
- package/dist/shared/hyde/hyde.validator.js.map +1 -0
- package/dist/shared/hyde/lens.inferrer.d.ts +190 -12
- package/dist/shared/hyde/lens.inferrer.d.ts.map +1 -1
- package/dist/shared/hyde/lens.inferrer.js +93 -38
- package/dist/shared/hyde/lens.inferrer.js.map +1 -1
- package/dist/shared/schemas/question.schema.d.ts +283 -2
- package/dist/shared/schemas/question.schema.d.ts.map +1 -1
- package/dist/shared/schemas/question.schema.js +87 -0
- package/dist/shared/schemas/question.schema.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const HYDE_HARD_CONSTRAINT_TYPES = [
|
|
3
|
+
'location',
|
|
4
|
+
'time',
|
|
5
|
+
'numeric',
|
|
6
|
+
'credential',
|
|
7
|
+
'organization',
|
|
8
|
+
'exclusivity',
|
|
9
|
+
'other',
|
|
10
|
+
];
|
|
11
|
+
export const HYDE_NAMED_ENTITY_TYPES = [
|
|
12
|
+
'person',
|
|
13
|
+
'organization',
|
|
14
|
+
'product',
|
|
15
|
+
'location',
|
|
16
|
+
'event',
|
|
17
|
+
'other',
|
|
18
|
+
];
|
|
19
|
+
const roleSchema = z.object({
|
|
20
|
+
role: z.string().min(1),
|
|
21
|
+
evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),
|
|
22
|
+
});
|
|
23
|
+
const hardConstraintSchema = z.object({
|
|
24
|
+
type: z.enum(HYDE_HARD_CONSTRAINT_TYPES),
|
|
25
|
+
value: z.string().min(1),
|
|
26
|
+
evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),
|
|
27
|
+
});
|
|
28
|
+
const namedEntitySchema = z.object({
|
|
29
|
+
type: z.enum(HYDE_NAMED_ENTITY_TYPES),
|
|
30
|
+
name: z.string().min(1),
|
|
31
|
+
evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),
|
|
32
|
+
});
|
|
33
|
+
const vocabularySchema = z.object({
|
|
34
|
+
term: z.string().min(1),
|
|
35
|
+
evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),
|
|
36
|
+
});
|
|
37
|
+
/** Structured-output schema for source-grounded frames. */
|
|
38
|
+
export const HydeSourceFrameSchema = z.object({
|
|
39
|
+
sourceRoles: z.array(roleSchema),
|
|
40
|
+
counterpartRoles: z.array(roleSchema),
|
|
41
|
+
hardConstraints: z.array(hardConstraintSchema),
|
|
42
|
+
namedEntities: z.array(namedEntitySchema),
|
|
43
|
+
domainVocabulary: z.array(vocabularySchema),
|
|
44
|
+
});
|
|
45
|
+
function escapeRegularExpression(value) {
|
|
46
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
47
|
+
}
|
|
48
|
+
/** Case-insensitive literal matching bounded by Unicode letters and numbers. */
|
|
49
|
+
function containsAlphanumericSpanCaseInsensitive(container, value) {
|
|
50
|
+
const needle = value.trim();
|
|
51
|
+
if (!needle)
|
|
52
|
+
return false;
|
|
53
|
+
return new RegExp(`(?<![\\p{L}\\p{M}\\p{N}])${escapeRegularExpression(needle)}(?![\\p{L}\\p{M}\\p{N}])`, 'iu').test(container);
|
|
54
|
+
}
|
|
55
|
+
function hasExactEvidence(sourceText, evidence) {
|
|
56
|
+
return containsAlphanumericSpanCaseInsensitive(sourceText, evidence);
|
|
57
|
+
}
|
|
58
|
+
const GENERIC_ROLE_TOKENS = new Set([
|
|
59
|
+
'advisor', 'analyst', 'attendee', 'borrower', 'builder', 'buyer', 'candidate',
|
|
60
|
+
'capitalist', 'ceo', 'cfo', 'client', 'cmo', 'cofounder', 'collaborator',
|
|
61
|
+
'consultant', 'coo', 'creator', 'cto', 'customer', 'designer', 'developer',
|
|
62
|
+
'director', 'employer', 'engineer', 'entrepreneur', 'executive', 'expert',
|
|
63
|
+
'founder', 'funder', 'hire', 'hiring', 'investor', 'leader', 'lender',
|
|
64
|
+
'manager', 'mentor', 'operator', 'organizer', 'owner', 'partner', 'practitioner',
|
|
65
|
+
'professional', 'provider', 'recruiter', 'researcher', 'scientist', 'seller',
|
|
66
|
+
'speaker', 'specialist', 'sponsor', 'strategist', 'supplier', 'technologist',
|
|
67
|
+
'vendor', 'vp',
|
|
68
|
+
]);
|
|
69
|
+
const GENERIC_ROLE_MODIFIERS = new Set([
|
|
70
|
+
'business', 'co', 'commercial', 'community', 'creative', 'early', 'experienced',
|
|
71
|
+
'growth', 'independent', 'industry', 'junior', 'lead', 'local', 'nonprofit',
|
|
72
|
+
'operations', 'product', 'professional', 'public', 'senior', 'stage',
|
|
73
|
+
'startup', 'technical', 'venture',
|
|
74
|
+
]);
|
|
75
|
+
function roleTokens(role) {
|
|
76
|
+
return role.toLowerCase().match(/[\p{L}\p{M}\d]+/gu) ?? [];
|
|
77
|
+
}
|
|
78
|
+
function hasUnsupportedSourceRoleMaterial(role, evidence) {
|
|
79
|
+
const substantiveTokens = roleTokens(role).filter((token) => !GENERIC_ROLE_MODIFIERS.has(token));
|
|
80
|
+
return substantiveTokens.length === 0
|
|
81
|
+
|| substantiveTokens.some((token) => !containsAlphanumericSpanCaseInsensitive(evidence, token));
|
|
82
|
+
}
|
|
83
|
+
function hasUnsupportedCounterpartRoleMaterial(role, evidence) {
|
|
84
|
+
return roleTokens(role).some((token) => !GENERIC_ROLE_TOKENS.has(token)
|
|
85
|
+
&& !GENERIC_ROLE_MODIFIERS.has(token)
|
|
86
|
+
&& !containsAlphanumericSpanCaseInsensitive(evidence, token));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Remove frame elements that cross the source-evidence boundary. Structured
|
|
90
|
+
* payloads must occur inside their evidence span. Source roles require grounded
|
|
91
|
+
* substantive tokens; counterpart roles may add generic inferred role language.
|
|
92
|
+
*/
|
|
93
|
+
export function sanitizeHydeSourceFrame(sourceText, frame) {
|
|
94
|
+
const grounded = (items) => items.filter((item) => hasExactEvidence(sourceText, item.evidence));
|
|
95
|
+
return {
|
|
96
|
+
sourceRoles: grounded(frame.sourceRoles)
|
|
97
|
+
.filter((item) => !hasUnsupportedSourceRoleMaterial(item.role, item.evidence)),
|
|
98
|
+
counterpartRoles: grounded(frame.counterpartRoles)
|
|
99
|
+
.filter((item) => !hasUnsupportedCounterpartRoleMaterial(item.role, item.evidence)),
|
|
100
|
+
hardConstraints: grounded(frame.hardConstraints)
|
|
101
|
+
.filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.value)),
|
|
102
|
+
namedEntities: grounded(frame.namedEntities)
|
|
103
|
+
.filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.name)),
|
|
104
|
+
domainVocabulary: grounded(frame.domainVocabulary)
|
|
105
|
+
.filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.term)),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=hyde.frame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyde.frame.js","sourceRoot":"/","sources":["shared/hyde/hyde.frame.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\n\n/** Source-grounded role supported by an exact span from the source text. */\nexport interface HydeFrameRole {\n role: string;\n evidence: string;\n}\n\nexport const HYDE_HARD_CONSTRAINT_TYPES = [\n 'location',\n 'time',\n 'numeric',\n 'credential',\n 'organization',\n 'exclusivity',\n 'other',\n] as const;\n\nexport type HydeHardConstraintType = (typeof HYDE_HARD_CONSTRAINT_TYPES)[number];\n\n/** Explicit hard constraint supported by an exact span from the source text. */\nexport interface HydeFrameHardConstraint {\n type: HydeHardConstraintType;\n value: string;\n evidence: string;\n}\n\nexport const HYDE_NAMED_ENTITY_TYPES = [\n 'person',\n 'organization',\n 'product',\n 'location',\n 'event',\n 'other',\n] as const;\n\nexport type HydeNamedEntityType = (typeof HYDE_NAMED_ENTITY_TYPES)[number];\n\n/** Named entity supported by an exact span from the source text. */\nexport interface HydeFrameNamedEntity {\n type: HydeNamedEntityType;\n name: string;\n evidence: string;\n}\n\n/** Domain term supported by an exact span from the source text. */\nexport interface HydeFrameVocabulary {\n term: string;\n evidence: string;\n}\n\n/**\n * Source-grounded controls for frame-constrained HyDE generation.\n * Counterpart roles may be reciprocal/complementary inferences, but their\n * evidence must still be an exact span from the source text.\n */\nexport interface HydeSourceFrame {\n sourceRoles: HydeFrameRole[];\n counterpartRoles: HydeFrameRole[];\n hardConstraints: HydeFrameHardConstraint[];\n namedEntities: HydeFrameNamedEntity[];\n domainVocabulary: HydeFrameVocabulary[];\n}\n\nconst roleSchema = z.object({\n role: z.string().min(1),\n evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),\n});\n\nconst hardConstraintSchema = z.object({\n type: z.enum(HYDE_HARD_CONSTRAINT_TYPES),\n value: z.string().min(1),\n evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),\n});\n\nconst namedEntitySchema = z.object({\n type: z.enum(HYDE_NAMED_ENTITY_TYPES),\n name: z.string().min(1),\n evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),\n});\n\nconst vocabularySchema = z.object({\n term: z.string().min(1),\n evidence: z.string().min(1).describe('Exact evidence span copied from sourceText'),\n});\n\n/** Structured-output schema for source-grounded frames. */\nexport const HydeSourceFrameSchema = z.object({\n sourceRoles: z.array(roleSchema),\n counterpartRoles: z.array(roleSchema),\n hardConstraints: z.array(hardConstraintSchema),\n namedEntities: z.array(namedEntitySchema),\n domainVocabulary: z.array(vocabularySchema),\n});\n\nfunction escapeRegularExpression(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/** Case-insensitive literal matching bounded by Unicode letters and numbers. */\nfunction containsAlphanumericSpanCaseInsensitive(container: string, value: string): boolean {\n const needle = value.trim();\n if (!needle) return false;\n return new RegExp(\n `(?<![\\\\p{L}\\\\p{M}\\\\p{N}])${escapeRegularExpression(needle)}(?![\\\\p{L}\\\\p{M}\\\\p{N}])`,\n 'iu',\n ).test(container);\n}\n\nfunction hasExactEvidence(sourceText: string, evidence: string): boolean {\n return containsAlphanumericSpanCaseInsensitive(sourceText, evidence);\n}\n\nconst GENERIC_ROLE_TOKENS = new Set([\n 'advisor', 'analyst', 'attendee', 'borrower', 'builder', 'buyer', 'candidate',\n 'capitalist', 'ceo', 'cfo', 'client', 'cmo', 'cofounder', 'collaborator',\n 'consultant', 'coo', 'creator', 'cto', 'customer', 'designer', 'developer',\n 'director', 'employer', 'engineer', 'entrepreneur', 'executive', 'expert',\n 'founder', 'funder', 'hire', 'hiring', 'investor', 'leader', 'lender',\n 'manager', 'mentor', 'operator', 'organizer', 'owner', 'partner', 'practitioner',\n 'professional', 'provider', 'recruiter', 'researcher', 'scientist', 'seller',\n 'speaker', 'specialist', 'sponsor', 'strategist', 'supplier', 'technologist',\n 'vendor', 'vp',\n]);\n\nconst GENERIC_ROLE_MODIFIERS = new Set([\n 'business', 'co', 'commercial', 'community', 'creative', 'early', 'experienced',\n 'growth', 'independent', 'industry', 'junior', 'lead', 'local', 'nonprofit',\n 'operations', 'product', 'professional', 'public', 'senior', 'stage',\n 'startup', 'technical', 'venture',\n]);\n\nfunction roleTokens(role: string): string[] {\n return role.toLowerCase().match(/[\\p{L}\\p{M}\\d]+/gu) ?? [];\n}\n\nfunction hasUnsupportedSourceRoleMaterial(role: string, evidence: string): boolean {\n const substantiveTokens = roleTokens(role).filter((token) => !GENERIC_ROLE_MODIFIERS.has(token));\n return substantiveTokens.length === 0\n || substantiveTokens.some((token) => !containsAlphanumericSpanCaseInsensitive(evidence, token));\n}\n\nfunction hasUnsupportedCounterpartRoleMaterial(role: string, evidence: string): boolean {\n return roleTokens(role).some((token) =>\n !GENERIC_ROLE_TOKENS.has(token)\n && !GENERIC_ROLE_MODIFIERS.has(token)\n && !containsAlphanumericSpanCaseInsensitive(evidence, token));\n}\n\n/**\n * Remove frame elements that cross the source-evidence boundary. Structured\n * payloads must occur inside their evidence span. Source roles require grounded\n * substantive tokens; counterpart roles may add generic inferred role language.\n */\nexport function sanitizeHydeSourceFrame(sourceText: string, frame: HydeSourceFrame): HydeSourceFrame {\n const grounded = <T extends { evidence: string }>(items: T[]): T[] =>\n items.filter((item) => hasExactEvidence(sourceText, item.evidence));\n return {\n sourceRoles: grounded(frame.sourceRoles)\n .filter((item) => !hasUnsupportedSourceRoleMaterial(item.role, item.evidence)),\n counterpartRoles: grounded(frame.counterpartRoles)\n .filter((item) => !hasUnsupportedCounterpartRoleMaterial(item.role, item.evidence)),\n hardConstraints: grounded(frame.hardConstraints)\n .filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.value)),\n namedEntities: grounded(frame.namedEntities)\n .filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.name)),\n domainVocabulary: grounded(frame.domainVocabulary)\n .filter((item) => containsAlphanumericSpanCaseInsensitive(item.evidence, item.term)),\n };\n}\n"]}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HyDE Generator Agent: pure LLM agent for generating hypothetical documents
|
|
3
|
+
* in the target corpus voice. Uses free-text lens labels instead of enum strategies.
|
|
4
|
+
*/
|
|
5
|
+
import type { BaseLanguageModelInput } from '@langchain/core/language_models/base';
|
|
6
|
+
import type { HydeSourceFrame } from './hyde.frame.js';
|
|
1
7
|
import type { HydeTargetCorpus } from './lens.inferrer.js';
|
|
2
8
|
export interface HydeGeneratorOutput {
|
|
3
9
|
text: string;
|
|
@@ -9,19 +15,25 @@ export interface HydeGenerateInput {
|
|
|
9
15
|
lens: string;
|
|
10
16
|
/** Which corpus voice to generate in. */
|
|
11
17
|
corpus: HydeTargetCorpus;
|
|
18
|
+
/** Sanitized source-grounded frame. Absence preserves the exact legacy prompt. */
|
|
19
|
+
sourceFrame?: HydeSourceFrame;
|
|
12
20
|
}
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
/** Minimal structured model contract used for deterministic injection in tests. */
|
|
22
|
+
export interface HydeGeneratorStructuredModel {
|
|
23
|
+
invoke(input: BaseLanguageModelInput, config?: {
|
|
24
|
+
signal?: AbortSignal;
|
|
25
|
+
}): Promise<unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** Build the frame-v1 generation prompt from sanitized source evidence. */
|
|
28
|
+
export declare function buildFrameHydePrompt(input: HydeGenerateInput & {
|
|
29
|
+
sourceFrame: HydeSourceFrame;
|
|
30
|
+
}): string;
|
|
31
|
+
/** Generates hypothetical documents in a target corpus voice for semantic search. */
|
|
17
32
|
export declare class HydeGenerator {
|
|
18
|
-
private model
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @param input - Source text, lens label, and target corpus
|
|
23
|
-
* @returns Generated hypothetical document text
|
|
24
|
-
*/
|
|
33
|
+
private model?;
|
|
34
|
+
constructor(model?: HydeGeneratorStructuredModel);
|
|
35
|
+
private getModel;
|
|
36
|
+
/** Generate a hypothetical document for the given source text and lens. */
|
|
25
37
|
generate(input: HydeGenerateInput): Promise<HydeGeneratorOutput>;
|
|
26
38
|
}
|
|
27
39
|
//# sourceMappingURL=hyde.generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyde.generator.d.ts","sourceRoot":"/","sources":["shared/hyde/hyde.generator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hyde.generator.d.ts","sourceRoot":"/","sources":["shared/hyde/hyde.generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAQnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAoB3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,MAAM,EAAE,gBAAgB,CAAC;IACzB,kFAAkF;IAClF,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,mFAAmF;AACnF,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F;AAMD,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG;IAAE,WAAW,EAAE,eAAe,CAAA;CAAE,GAAG,MAAM,CA0BxG;AAED,qFAAqF;AACrF,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAC,CAA+B;gBAEjC,KAAK,CAAC,EAAE,4BAA4B;IAQhD,OAAO,CAAC,QAAQ;IAOhB,2EAA2E;IAErE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAuBvE"}
|
|
@@ -7,17 +7,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
-
/**
|
|
11
|
-
* HyDE Generator Agent: pure LLM agent for generating hypothetical documents
|
|
12
|
-
* in the target corpus voice. Uses free-text lens labels instead of enum strategies.
|
|
13
|
-
*/
|
|
14
10
|
import { HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
15
11
|
import { z } from 'zod';
|
|
16
|
-
import { HYDE_CORPUS_PROMPTS } from './hyde.strategies.js';
|
|
17
|
-
import { Timed } from "../observability/performance.js";
|
|
18
|
-
import { protocolLogger } from '../observability/protocol.logger.js';
|
|
19
12
|
import { createStructuredModel } from "../agent/model.config.js";
|
|
20
13
|
import { invokeWithAbortSignal } from "../agent/model-signal.js";
|
|
14
|
+
import { protocolLogger } from '../observability/protocol.logger.js';
|
|
15
|
+
import { Timed } from "../observability/performance.js";
|
|
16
|
+
import { HYDE_CORPUS_PROMPTS } from './hyde.strategies.js';
|
|
21
17
|
const logger = protocolLogger("HydeGenerator");
|
|
22
18
|
const SYSTEM_PROMPT = `You are a Hypothetical Document Generator for semantic search.
|
|
23
19
|
|
|
@@ -33,35 +29,68 @@ const responseFormat = z.object({
|
|
|
33
29
|
.string()
|
|
34
30
|
.describe('The hypothetical document text in the target voice, suitable for embedding and retrieval'),
|
|
35
31
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*/
|
|
32
|
+
function renderList(items) {
|
|
33
|
+
return items.length > 0 ? items.join('; ') : '(none)';
|
|
34
|
+
}
|
|
35
|
+
/** Build the frame-v1 generation prompt from sanitized source evidence. */
|
|
36
|
+
export function buildFrameHydePrompt(input) {
|
|
37
|
+
const { sourceText, corpus, sourceFrame } = input;
|
|
38
|
+
const corpusInstruction = {
|
|
39
|
+
profiles: 'Write a first-person professional biography in the target profile voice.',
|
|
40
|
+
intents: 'Write a first-person goal or aspiration in the target intent voice.',
|
|
41
|
+
premises: 'Write a first-person stable identity, values, or worldview statement in the target premise voice.',
|
|
42
|
+
}[corpus];
|
|
43
|
+
return `${corpusInstruction}
|
|
44
|
+
|
|
45
|
+
Source text: "${sourceText}"
|
|
46
|
+
|
|
47
|
+
Sanitized source frame:
|
|
48
|
+
- Source roles: ${renderList(sourceFrame.sourceRoles.map((item) => `${item.role} [evidence: "${item.evidence}"]`))}
|
|
49
|
+
- Counterpart/complementary roles: ${renderList(sourceFrame.counterpartRoles.map((item) => `${item.role} [evidence: "${item.evidence}"]`))}
|
|
50
|
+
- Explicit hard constraints: ${renderList(sourceFrame.hardConstraints.map((item) => `${item.type}: ${item.value} [evidence: "${item.evidence}"]`))}
|
|
51
|
+
- Named entities: ${renderList(sourceFrame.namedEntities.map((item) => `${item.type}: ${item.name} [evidence: "${item.evidence}"]`))}
|
|
52
|
+
- Domain vocabulary: ${renderList(sourceFrame.domainVocabulary.map((item) => `${item.term} [evidence: "${item.evidence}"]`))}
|
|
53
|
+
|
|
54
|
+
Generation constraints:
|
|
55
|
+
- You MAY elaborate generic roles and generic domain language.
|
|
56
|
+
- You MAY use reciprocal/complementary inversion and write in the target voice.
|
|
57
|
+
- You MUST NOT introduce any new proper noun or named entity.
|
|
58
|
+
- You MUST NOT introduce any new hard location, time, numeric, credential, organization, or exclusivity constraint.
|
|
59
|
+
- Preserve explicit source-frame constraints when they apply to the reciprocal target.
|
|
60
|
+
- Output only a few sentences or one short paragraph.`;
|
|
61
|
+
}
|
|
62
|
+
/** Generates hypothetical documents in a target corpus voice for semantic search. */
|
|
40
63
|
export class HydeGenerator {
|
|
41
|
-
constructor() {
|
|
42
|
-
|
|
64
|
+
constructor(model) {
|
|
65
|
+
// Preserve the legacy production model construction path; injected models
|
|
66
|
+
// keep prompt tests provider-free.
|
|
67
|
+
this.model = model ?? createStructuredModel("hydeGenerator", responseFormat, {
|
|
43
68
|
name: "hyde_generator",
|
|
44
69
|
});
|
|
45
70
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
71
|
+
getModel() {
|
|
72
|
+
this.model ?? (this.model = createStructuredModel("hydeGenerator", responseFormat, {
|
|
73
|
+
name: "hyde_generator",
|
|
74
|
+
}));
|
|
75
|
+
return this.model;
|
|
76
|
+
}
|
|
77
|
+
/** Generate a hypothetical document for the given source text and lens. */
|
|
52
78
|
async generate(input) {
|
|
53
|
-
const promptText =
|
|
79
|
+
const promptText = input.sourceFrame
|
|
80
|
+
? buildFrameHydePrompt(input)
|
|
81
|
+
: HYDE_CORPUS_PROMPTS[input.corpus](input.sourceText, input.lens);
|
|
54
82
|
const messages = [
|
|
55
83
|
new SystemMessage(SYSTEM_PROMPT),
|
|
56
84
|
new HumanMessage(promptText),
|
|
57
85
|
];
|
|
58
|
-
const result = await invokeWithAbortSignal(this.
|
|
86
|
+
const result = await invokeWithAbortSignal(this.getModel(), messages);
|
|
59
87
|
const parsed = responseFormat.parse(result);
|
|
60
88
|
const text = parsed.hypotheticalDocument ?? '';
|
|
61
89
|
logger.verbose('Generated HyDE document', {
|
|
62
90
|
lens: input.lens,
|
|
63
91
|
corpus: input.corpus,
|
|
64
92
|
textLength: text.length,
|
|
93
|
+
frameConstrained: !!input.sourceFrame,
|
|
65
94
|
});
|
|
66
95
|
return { text };
|
|
67
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyde.generator.js","sourceRoot":"/","sources":["shared/hyde/hyde.generator.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"hyde.generator.js","sourceRoot":"/","sources":["shared/hyde/hyde.generator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HyDE Generator Agent: pure LLM agent for generating hypothetical documents\n * in the target corpus voice. Uses free-text lens labels instead of enum strategies.\n */\nimport type { BaseLanguageModelInput } from '@langchain/core/language_models/base';\nimport { HumanMessage, SystemMessage } from '@langchain/core/messages';\nimport { z } from 'zod';\n\nimport { createStructuredModel } from \"../agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../agent/model-signal.js\";\nimport { protocolLogger } from '../observability/protocol.logger.js';\nimport { Timed } from \"../observability/performance.js\";\nimport type { HydeSourceFrame } from './hyde.frame.js';\nimport { HYDE_CORPUS_PROMPTS } from './hyde.strategies.js';\nimport type { HydeTargetCorpus } from './lens.inferrer.js';\n\nconst logger = protocolLogger(\"HydeGenerator\");\n\nconst SYSTEM_PROMPT = `You are a Hypothetical Document Generator for semantic search.\n\nYour task: Given a source statement (e.g. an intent or goal), write a short hypothetical document in the voice of the TARGET side—the kind of person or statement that would be an ideal match for that source.\n\nRules:\n- Write in first person as the target.\n- Be concrete and specific so the text is good for vector similarity search.\n- Output only the hypothetical document text, no meta-commentary.\n- Keep length to a few sentences or one short paragraph.`;\n\nconst responseFormat = z.object({\n hypotheticalDocument: z\n .string()\n .describe('The hypothetical document text in the target voice, suitable for embedding and retrieval'),\n});\n\nexport interface HydeGeneratorOutput {\n text: string;\n}\n\nexport interface HydeGenerateInput {\n /** Original intent or query text. */\n sourceText: string;\n /** Free-text lens label from LensInferrer (e.g. \"crypto infra VC\"). */\n lens: string;\n /** Which corpus voice to generate in. */\n corpus: HydeTargetCorpus;\n /** Sanitized source-grounded frame. Absence preserves the exact legacy prompt. */\n sourceFrame?: HydeSourceFrame;\n}\n\n/** Minimal structured model contract used for deterministic injection in tests. */\nexport interface HydeGeneratorStructuredModel {\n invoke(input: BaseLanguageModelInput, config?: { signal?: AbortSignal }): Promise<unknown>;\n}\n\nfunction renderList(items: string[]): string {\n return items.length > 0 ? items.join('; ') : '(none)';\n}\n\n/** Build the frame-v1 generation prompt from sanitized source evidence. */\nexport function buildFrameHydePrompt(input: HydeGenerateInput & { sourceFrame: HydeSourceFrame }): string {\n const { sourceText, corpus, sourceFrame } = input;\n const corpusInstruction = {\n profiles: 'Write a first-person professional biography in the target profile voice.',\n intents: 'Write a first-person goal or aspiration in the target intent voice.',\n premises: 'Write a first-person stable identity, values, or worldview statement in the target premise voice.',\n }[corpus];\n\n return `${corpusInstruction}\n\nSource text: \"${sourceText}\"\n\nSanitized source frame:\n- Source roles: ${renderList(sourceFrame.sourceRoles.map((item) => `${item.role} [evidence: \"${item.evidence}\"]`))}\n- Counterpart/complementary roles: ${renderList(sourceFrame.counterpartRoles.map((item) => `${item.role} [evidence: \"${item.evidence}\"]`))}\n- Explicit hard constraints: ${renderList(sourceFrame.hardConstraints.map((item) => `${item.type}: ${item.value} [evidence: \"${item.evidence}\"]`))}\n- Named entities: ${renderList(sourceFrame.namedEntities.map((item) => `${item.type}: ${item.name} [evidence: \"${item.evidence}\"]`))}\n- Domain vocabulary: ${renderList(sourceFrame.domainVocabulary.map((item) => `${item.term} [evidence: \"${item.evidence}\"]`))}\n\nGeneration constraints:\n- You MAY elaborate generic roles and generic domain language.\n- You MAY use reciprocal/complementary inversion and write in the target voice.\n- You MUST NOT introduce any new proper noun or named entity.\n- You MUST NOT introduce any new hard location, time, numeric, credential, organization, or exclusivity constraint.\n- Preserve explicit source-frame constraints when they apply to the reciprocal target.\n- Output only a few sentences or one short paragraph.`;\n}\n\n/** Generates hypothetical documents in a target corpus voice for semantic search. */\nexport class HydeGenerator {\n private model?: HydeGeneratorStructuredModel;\n\n constructor(model?: HydeGeneratorStructuredModel) {\n // Preserve the legacy production model construction path; injected models\n // keep prompt tests provider-free.\n this.model = model ?? createStructuredModel(\"hydeGenerator\", responseFormat, {\n name: \"hyde_generator\",\n });\n }\n\n private getModel(): HydeGeneratorStructuredModel {\n this.model ??= createStructuredModel(\"hydeGenerator\", responseFormat, {\n name: \"hyde_generator\",\n });\n return this.model;\n }\n\n /** Generate a hypothetical document for the given source text and lens. */\n @Timed()\n async generate(input: HydeGenerateInput): Promise<HydeGeneratorOutput> {\n const promptText = input.sourceFrame\n ? buildFrameHydePrompt(input as HydeGenerateInput & { sourceFrame: HydeSourceFrame })\n : HYDE_CORPUS_PROMPTS[input.corpus](input.sourceText, input.lens);\n\n const messages = [\n new SystemMessage(SYSTEM_PROMPT),\n new HumanMessage(promptText),\n ];\n\n const result = await invokeWithAbortSignal(this.getModel(), messages);\n const parsed = responseFormat.parse(result);\n const text = parsed.hypotheticalDocument ?? '';\n\n logger.verbose('Generated HyDE document', {\n lens: input.lens,\n corpus: input.corpus,\n textLength: text.length,\n frameConstrained: !!input.sourceFrame,\n });\n\n return { text };\n }\n}\n"]}
|
|
@@ -1,27 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* Flow: infer_lenses → check_cache → (generate_missing if needed) → embed → cache_results.
|
|
5
|
-
* Constructor injects Database, Embedder, Cache, LensInferrer, HydeGenerator.
|
|
6
|
-
*/
|
|
7
|
-
import { type HydeDocumentState } from './hyde.state.js';
|
|
8
|
-
import { LensInferrer } from './lens.inferrer.js';
|
|
9
|
-
import { HydeGenerator } from './hyde.generator.js';
|
|
1
|
+
import type { DebugMetaAgent } from '../../chat/chat-streaming.types.js';
|
|
2
|
+
import type { HydeCache } from '../interfaces/cache.interface.js';
|
|
10
3
|
import type { HydeGraphDatabase } from '../interfaces/database.interface.js';
|
|
11
4
|
import type { EmbeddingGenerator } from '../interfaces/embedder.interface.js';
|
|
12
|
-
import type
|
|
13
|
-
import type
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
import { type HydeGenerationMode } from './hyde.env.js';
|
|
6
|
+
import { type HydeSourceFrame } from './hyde.frame.js';
|
|
7
|
+
import type { HydeGenerateInput, HydeGeneratorOutput } from './hyde.generator.js';
|
|
8
|
+
import { type HydeDocumentState } from './hyde.state.js';
|
|
9
|
+
import type { LensInferenceInput, LensInferenceOutput } from './lens.inferrer.js';
|
|
10
|
+
import { type HydeValidationInput, type HydeValidationOutput } from './hyde.validator.js';
|
|
11
|
+
/** Narrow lens inferrer contract accepted by the graph. */
|
|
12
|
+
export interface HydeLensInferrerLike {
|
|
13
|
+
infer(input: LensInferenceInput): Promise<LensInferenceOutput>;
|
|
14
|
+
}
|
|
15
|
+
/** Narrow document generator contract accepted by the graph. */
|
|
16
|
+
export interface HydeGeneratorLike {
|
|
17
|
+
generate(input: HydeGenerateInput): Promise<HydeGeneratorOutput>;
|
|
18
|
+
}
|
|
19
|
+
/** Narrow batch validator contract accepted by the graph. */
|
|
20
|
+
export interface HydeValidatorLike {
|
|
21
|
+
validate(input: HydeValidationInput): Promise<HydeValidationOutput>;
|
|
22
|
+
}
|
|
23
|
+
export interface HydeGraphOptions {
|
|
24
|
+
/** Test override. Production derives the mode from HYDE_FRAME_CONSTRAINTS_ENABLED. */
|
|
25
|
+
mode?: HydeGenerationMode;
|
|
26
|
+
validator?: HydeValidatorLike;
|
|
27
|
+
}
|
|
28
|
+
/** Factory for the HyDE generation graph. Existing five-argument calls remain valid. */
|
|
18
29
|
export declare class HydeGraphFactory {
|
|
19
30
|
private database;
|
|
20
31
|
private embedder;
|
|
21
32
|
private cache;
|
|
22
33
|
private inferrer;
|
|
23
34
|
private generator;
|
|
24
|
-
|
|
35
|
+
private options;
|
|
36
|
+
constructor(database: HydeGraphDatabase, embedder: EmbeddingGenerator, cache: HydeCache, inferrer: HydeLensInferrerLike, generator: HydeGeneratorLike, options?: HydeGraphOptions);
|
|
25
37
|
createGraph(): import("@langchain/langgraph").CompiledStateGraph<{
|
|
26
38
|
sourceType: "intent" | "context" | "query";
|
|
27
39
|
sourceId: import("../interfaces/database.interface.js").Id<"users"> | import("../interfaces/database.interface.js").Id<"intents"> | undefined;
|
|
@@ -30,6 +42,10 @@ export declare class HydeGraphFactory {
|
|
|
30
42
|
maxLenses: number;
|
|
31
43
|
forceRegenerate: boolean;
|
|
32
44
|
lenses: import("./lens.inferrer.js").Lens[];
|
|
45
|
+
sourceFrame: HydeSourceFrame | undefined;
|
|
46
|
+
frameFingerprint: string | undefined;
|
|
47
|
+
sourceTextHash: string | undefined;
|
|
48
|
+
generatedAt: string | undefined;
|
|
33
49
|
hydeDocuments: Record<string, HydeDocumentState>;
|
|
34
50
|
hydeEmbeddings: Record<string, number[]>;
|
|
35
51
|
error: string | undefined;
|
|
@@ -42,6 +58,10 @@ export declare class HydeGraphFactory {
|
|
|
42
58
|
maxLenses?: number | import("@langchain/langgraph").OverwriteValue<number> | undefined;
|
|
43
59
|
forceRegenerate?: boolean | import("@langchain/langgraph").OverwriteValue<boolean> | undefined;
|
|
44
60
|
lenses?: import("./lens.inferrer.js").Lens[] | import("@langchain/langgraph").OverwriteValue<import("./lens.inferrer.js").Lens[]> | undefined;
|
|
61
|
+
sourceFrame?: HydeSourceFrame | import("@langchain/langgraph").OverwriteValue<HydeSourceFrame | undefined> | undefined;
|
|
62
|
+
frameFingerprint?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
|
|
63
|
+
sourceTextHash?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
|
|
64
|
+
generatedAt?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
|
|
45
65
|
hydeDocuments?: Record<string, HydeDocumentState> | import("@langchain/langgraph").OverwriteValue<Record<string, HydeDocumentState>> | undefined;
|
|
46
66
|
hydeEmbeddings?: Record<string, number[]> | import("@langchain/langgraph").OverwriteValue<Record<string, number[]>> | undefined;
|
|
47
67
|
error?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
|
|
@@ -62,6 +82,10 @@ export declare class HydeGraphFactory {
|
|
|
62
82
|
maxLenses: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
|
|
63
83
|
forceRegenerate: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
|
|
64
84
|
lenses: import("@langchain/langgraph").BaseChannel<import("./lens.inferrer.js").Lens[], import("./lens.inferrer.js").Lens[] | import("@langchain/langgraph").OverwriteValue<import("./lens.inferrer.js").Lens[]>, unknown>;
|
|
85
|
+
sourceFrame: import("@langchain/langgraph").BaseChannel<HydeSourceFrame | undefined, HydeSourceFrame | import("@langchain/langgraph").OverwriteValue<HydeSourceFrame | undefined> | undefined, unknown>;
|
|
86
|
+
frameFingerprint: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
87
|
+
sourceTextHash: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
88
|
+
generatedAt: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
65
89
|
hydeDocuments: import("@langchain/langgraph").BaseChannel<Record<string, HydeDocumentState>, Record<string, HydeDocumentState> | import("@langchain/langgraph").OverwriteValue<Record<string, HydeDocumentState>>, unknown>;
|
|
66
90
|
hydeEmbeddings: import("@langchain/langgraph").BaseChannel<Record<string, number[]>, Record<string, number[]> | import("@langchain/langgraph").OverwriteValue<Record<string, number[]>>, unknown>;
|
|
67
91
|
error: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
@@ -82,17 +106,34 @@ export declare class HydeGraphFactory {
|
|
|
82
106
|
maxLenses: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
|
|
83
107
|
forceRegenerate: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
|
|
84
108
|
lenses: import("@langchain/langgraph").BaseChannel<import("./lens.inferrer.js").Lens[], import("./lens.inferrer.js").Lens[] | import("@langchain/langgraph").OverwriteValue<import("./lens.inferrer.js").Lens[]>, unknown>;
|
|
109
|
+
sourceFrame: import("@langchain/langgraph").BaseChannel<HydeSourceFrame | undefined, HydeSourceFrame | import("@langchain/langgraph").OverwriteValue<HydeSourceFrame | undefined> | undefined, unknown>;
|
|
110
|
+
frameFingerprint: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
111
|
+
sourceTextHash: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
112
|
+
generatedAt: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
85
113
|
hydeDocuments: import("@langchain/langgraph").BaseChannel<Record<string, HydeDocumentState>, Record<string, HydeDocumentState> | import("@langchain/langgraph").OverwriteValue<Record<string, HydeDocumentState>>, unknown>;
|
|
86
114
|
hydeEmbeddings: import("@langchain/langgraph").BaseChannel<Record<string, number[]>, Record<string, number[]> | import("@langchain/langgraph").OverwriteValue<Record<string, number[]>>, unknown>;
|
|
87
115
|
error: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
88
116
|
agentTimings: import("@langchain/langgraph").BaseChannel<DebugMetaAgent[], DebugMetaAgent[] | import("@langchain/langgraph").OverwriteValue<DebugMetaAgent[]>, unknown>;
|
|
89
117
|
}, import("@langchain/langgraph").StateDefinition, {
|
|
90
118
|
infer_lenses: {
|
|
119
|
+
lenses: import("./lens.inferrer.js").Lens[];
|
|
120
|
+
sourceFrame: HydeSourceFrame;
|
|
121
|
+
frameFingerprint: string;
|
|
122
|
+
sourceTextHash: string;
|
|
123
|
+
generatedAt: string;
|
|
124
|
+
agentTimings: DebugMetaAgent[];
|
|
125
|
+
} | {
|
|
91
126
|
lenses: import("./lens.inferrer.js").Lens[];
|
|
92
127
|
agentTimings: DebugMetaAgent[];
|
|
128
|
+
sourceFrame?: undefined;
|
|
129
|
+
frameFingerprint?: undefined;
|
|
130
|
+
sourceTextHash?: undefined;
|
|
131
|
+
generatedAt?: undefined;
|
|
93
132
|
};
|
|
94
133
|
check_cache: {
|
|
95
|
-
hydeDocuments:
|
|
134
|
+
hydeDocuments: {
|
|
135
|
+
[k: string]: HydeDocumentState;
|
|
136
|
+
};
|
|
96
137
|
};
|
|
97
138
|
generate_missing: {
|
|
98
139
|
hydeDocuments: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hyde.graph.d.ts","sourceRoot":"/","sources":["shared/hyde/hyde.graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hyde.graph.d.ts","sourceRoot":"/","sources":["shared/hyde/hyde.graph.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAK9E,OAAO,EAAwD,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAiB,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAA8B,MAAM,qBAAqB,CAAC;AAUrI,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAChE;AAED,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAClE;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAsID,wFAAwF;AACxF,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,OAAO;gBALP,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,oBAAoB,EAC9B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,gBAAqB;IAGxC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiZZ"}
|