@pellux/goodvibes-sdk 0.27.8 → 0.27.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/_internal/contracts/artifacts/operator-contract.json +287 -1
  2. package/dist/_internal/contracts/generated/foundation-metadata.d.ts +1 -1
  3. package/dist/_internal/contracts/generated/foundation-metadata.js +1 -1
  4. package/dist/_internal/contracts/generated/operator-contract.d.ts.map +1 -1
  5. package/dist/_internal/contracts/generated/operator-contract.js +287 -1
  6. package/dist/_internal/platform/control-plane/operator-contract-schemas-knowledge.d.ts +1 -1
  7. package/dist/_internal/platform/control-plane/operator-contract-schemas-knowledge.d.ts.map +1 -1
  8. package/dist/_internal/platform/control-plane/operator-contract-schemas-knowledge.js +23 -0
  9. package/dist/_internal/platform/knowledge/home-graph/ask.js +4 -4
  10. package/dist/_internal/platform/knowledge/home-graph/service.d.ts +1 -0
  11. package/dist/_internal/platform/knowledge/home-graph/service.d.ts.map +1 -1
  12. package/dist/_internal/platform/knowledge/home-graph/service.js +18 -1
  13. package/dist/_internal/platform/knowledge/home-graph/types.d.ts +3 -1
  14. package/dist/_internal/platform/knowledge/home-graph/types.d.ts.map +1 -1
  15. package/dist/_internal/platform/knowledge/home-graph/types.js +1 -0
  16. package/dist/_internal/platform/knowledge/index.d.ts +2 -2
  17. package/dist/_internal/platform/knowledge/index.d.ts.map +1 -1
  18. package/dist/_internal/platform/knowledge/index.js +1 -1
  19. package/dist/_internal/platform/knowledge/scheduling.d.ts +1 -0
  20. package/dist/_internal/platform/knowledge/scheduling.d.ts.map +1 -1
  21. package/dist/_internal/platform/knowledge/scheduling.js +17 -18
  22. package/dist/_internal/platform/knowledge/semantic/answer.d.ts.map +1 -1
  23. package/dist/_internal/platform/knowledge/semantic/answer.js +38 -5
  24. package/dist/_internal/platform/knowledge/semantic/fact-quality.d.ts.map +1 -1
  25. package/dist/_internal/platform/knowledge/semantic/fact-quality.js +16 -3
  26. package/dist/_internal/platform/knowledge/semantic/gap-repair.d.ts +32 -0
  27. package/dist/_internal/platform/knowledge/semantic/gap-repair.d.ts.map +1 -0
  28. package/dist/_internal/platform/knowledge/semantic/gap-repair.js +148 -0
  29. package/dist/_internal/platform/knowledge/semantic/index.d.ts +4 -1
  30. package/dist/_internal/platform/knowledge/semantic/index.d.ts.map +1 -1
  31. package/dist/_internal/platform/knowledge/semantic/index.js +2 -0
  32. package/dist/_internal/platform/knowledge/semantic/self-improvement.d.ts +10 -0
  33. package/dist/_internal/platform/knowledge/semantic/self-improvement.d.ts.map +1 -0
  34. package/dist/_internal/platform/knowledge/semantic/self-improvement.js +486 -0
  35. package/dist/_internal/platform/knowledge/semantic/service.d.ts +9 -2
  36. package/dist/_internal/platform/knowledge/semantic/service.d.ts.map +1 -1
  37. package/dist/_internal/platform/knowledge/semantic/service.js +124 -2
  38. package/dist/_internal/platform/knowledge/semantic/types.d.ts +38 -0
  39. package/dist/_internal/platform/knowledge/semantic/types.d.ts.map +1 -1
  40. package/dist/_internal/platform/knowledge/service.d.ts.map +1 -1
  41. package/dist/_internal/platform/knowledge/service.js +17 -1
  42. package/dist/_internal/platform/knowledge/types.d.ts +1 -1
  43. package/dist/_internal/platform/knowledge/types.d.ts.map +1 -1
  44. package/dist/_internal/platform/runtime/services.d.ts.map +1 -1
  45. package/dist/_internal/platform/runtime/services.js +5 -1
  46. package/dist/_internal/platform/version.js +1 -1
  47. package/package.json +1 -1
@@ -40,6 +40,7 @@ export declare class KnowledgeScheduleService {
40
40
  }): Promise<KnowledgeJobRunRecord>;
41
41
  dispose(): void;
42
42
  private initializeSchedules;
43
+ private ensureBootstrapSchedule;
43
44
  private clearScheduleTimer;
44
45
  private reconcileSchedules;
45
46
  private runScheduledJob;
@@ -1 +1 @@
1
- {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/knowledge/scheduling.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8E,KAAK,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC3J,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEvH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGlE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,CACpB,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,EAC1H,SAAS,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;IACV,QAAQ,CAAC,YAAY,EAAE,CACrB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KACvE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvC;AAED,qBAAa,wBAAwB;IAKvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoD;IACnF,OAAO,CAAC,oBAAoB,CAAS;gBAER,OAAO,EAAE,0BAA0B;IAehE,QAAQ,IAAI,SAAS,kBAAkB,EAAE;IAIzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAIvC,YAAY,CAAC,KAAK,EAAE;QACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,4BAA4B,CAAC;QAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC7C,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAqB9B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAiB/F,WAAW,CAAC,KAAK,SAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,qBAAqB,EAAE;IAIpE,MAAM,CACV,EAAE,EAAE,MAAM,EACV,KAAK,GAAE;QACL,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACpB,GACL,OAAO,CAAC,qBAAqB,CAAC;IA6BjC,OAAO,IAAI,IAAI;YAOD,mBAAmB;IAyBjC,OAAO,CAAC,kBAAkB;YAQZ,kBAAkB;YA6BlB,eAAe;YAmBf,aAAa;CA0D5B"}
1
+ {"version":3,"file":"scheduling.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/knowledge/scheduling.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8E,KAAK,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC3J,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEvH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGlE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,CACpB,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,EAC1H,SAAS,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;IACV,QAAQ,CAAC,YAAY,EAAE,CACrB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KACvE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACvC;AAED,qBAAa,wBAAwB;IAKvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoD;IACnF,OAAO,CAAC,oBAAoB,CAAS;gBAER,OAAO,EAAE,0BAA0B;IAgBhE,QAAQ,IAAI,SAAS,kBAAkB,EAAE;IAIzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI;IAIvC,YAAY,CAAC,KAAK,EAAE;QACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,4BAA4B,CAAC;QAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC7C,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAqB9B,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAM5C,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAiB/F,WAAW,CAAC,KAAK,SAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,qBAAqB,EAAE;IAIpE,MAAM,CACV,EAAE,EAAE,MAAM,EACV,KAAK,GAAE;QACL,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACpB,GACL,OAAO,CAAC,qBAAqB,CAAC;IA6BjC,OAAO,IAAI,IAAI;YAOD,mBAAmB;YAUnB,uBAAuB;IAiBrC,OAAO,CAAC,kBAAkB;YAQZ,kBAAkB;YA6BlB,eAAe;YAmBf,aAAa;CA0D5B"}
@@ -16,6 +16,7 @@ export class KnowledgeScheduleService {
16
16
  { id: 'knowledge-sync-browser-history', kind: 'sync-browser-history', title: 'Sync Browser History', description: 'Index local browser history and bookmarks as metadata-first structured knowledge.', defaultMode: 'background', metadata: { category: 'ingest', localOnly: true } },
17
17
  { id: 'knowledge-rebuild-projections', kind: 'rebuild-projections', title: 'Rebuild Projections', description: 'Render and materialize the major derived markdown/wiki projections.', defaultMode: 'background', metadata: { category: 'projection' } },
18
18
  { id: 'knowledge-semantic-enrichment', kind: 'semantic-enrichment', title: 'Semantic Enrichment', description: 'Extract durable facts, entities, wiki pages, and gaps from indexed sources.', defaultMode: 'background', metadata: { category: 'semantic' } },
19
+ { id: 'knowledge-semantic-self-improvement', kind: 'semantic-self-improvement', title: 'Semantic Self-Improvement', description: 'Classify semantic gaps and repair eligible concrete subjects with corroborated source-backed ingest.', defaultMode: 'background', metadata: { category: 'semantic' } },
19
20
  { id: 'knowledge-light-consolidation', kind: 'light-consolidation', title: 'Light Consolidation', description: 'Score recent usage, refresh candidate promotions, and write a deterministic consolidation report.', defaultMode: 'background', metadata: { category: 'consolidation' } },
20
21
  { id: 'knowledge-deep-consolidation', kind: 'deep-consolidation', title: 'Deep Consolidation', description: 'Run the full consolidation loop, including high-confidence memory promotion and deterministic reporting.', defaultMode: 'background', metadata: { category: 'consolidation' } },
21
22
  ];
@@ -113,26 +114,24 @@ export class KnowledgeScheduleService {
113
114
  return;
114
115
  this.schedulesInitialized = true;
115
116
  await this.context.store.init();
116
- if (this.context.store.listSchedules(10_000).length === 0) {
117
- await this.context.store.upsertSchedule({
118
- jobId: 'knowledge-light-consolidation',
119
- label: 'Daily Light Consolidation',
120
- enabled: true,
121
- schedule: normalizeEverySchedule('24h'),
122
- nextRunAt: getNextAutomationOccurrence(normalizeEverySchedule('24h'), Date.now(), 'knowledge-light-consolidation'),
123
- metadata: { bootstrap: true },
124
- });
125
- await this.context.store.upsertSchedule({
126
- jobId: 'knowledge-deep-consolidation',
127
- label: 'Weekly Deep Consolidation',
128
- enabled: true,
129
- schedule: normalizeCronSchedule('15 4 * * 0'),
130
- nextRunAt: getNextAutomationOccurrence(normalizeCronSchedule('15 4 * * 0'), Date.now(), 'knowledge-deep-consolidation'),
131
- metadata: { bootstrap: true },
132
- });
133
- }
117
+ await this.ensureBootstrapSchedule('knowledge-light-consolidation', 'Daily Light Consolidation', normalizeEverySchedule('24h'));
118
+ await this.ensureBootstrapSchedule('knowledge-deep-consolidation', 'Weekly Deep Consolidation', normalizeCronSchedule('15 4 * * 0'));
119
+ await this.ensureBootstrapSchedule('knowledge-semantic-self-improvement', 'Continuous Semantic Self-Improvement', normalizeEverySchedule('6h'));
134
120
  await this.reconcileSchedules();
135
121
  }
122
+ async ensureBootstrapSchedule(jobId, label, schedule) {
123
+ const existing = this.context.store.listSchedules(10_000).find((entry) => entry.jobId === jobId && entry.metadata.bootstrap === true);
124
+ if (existing)
125
+ return;
126
+ await this.context.store.upsertSchedule({
127
+ jobId,
128
+ label,
129
+ enabled: true,
130
+ schedule,
131
+ nextRunAt: getNextAutomationOccurrence(schedule, Date.now(), jobId),
132
+ metadata: { bootstrap: true },
133
+ });
134
+ }
136
135
  clearScheduleTimer(id) {
137
136
  const timer = this.scheduleTimers.get(id);
138
137
  if (timer) {
@@ -1 +1 @@
1
- {"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/answer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAE7B,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAqBpB,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC5C;AAsCD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,sBAAsB,EAC/B,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,6BAA6B,CAAC,CAmDxC"}
1
+ {"version":3,"file":"answer.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/answer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD,OAAO,KAAK,EACV,4BAA4B,EAC5B,6BAA6B,EAE7B,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAsBpB,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC5C;AAsCD,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,sBAAsB,EAC/B,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,6BAA6B,CAAC,CAuDxC"}
@@ -1,5 +1,5 @@
1
1
  import { getKnowledgeSpaceId, isInKnowledgeSpace, normalizeKnowledgeSpaceId } from '../spaces.js';
2
- import { MAX_ANSWER_EVIDENCE_CHARS, clampText, normalizeWhitespace, readRecord, readString, scoreSemanticText, semanticHash, semanticMetadata, sourceSemanticText, tokenizeSemanticQuery, uniqueStrings, } from './utils.js';
2
+ import { MAX_ANSWER_EVIDENCE_CHARS, clampText, normalizeWhitespace, readRecord, readString, scoreSemanticText, semanticHash, semanticMetadata, sourceSemanticText, splitSentences, tokenizeSemanticQuery, uniqueStrings, } from './utils.js';
3
3
  import { hasConcreteFeatureSignal, isLowValueFeatureOrSpecText, isSemanticAnswerLinkedObject, semanticFactText, } from './fact-quality.js';
4
4
  const GENERIC_ANSWER_INTENT_TOKENS = new Set([
5
5
  'capabilities',
@@ -58,7 +58,8 @@ export async function answerKnowledgeQuery(context, input) {
58
58
  .filter(isSemanticAnswerLinkedObject)
59
59
  .slice(0, 24);
60
60
  const gaps = await persistAnswerGaps(context.store, spaceId, input.query, llmAnswer?.gaps ?? []);
61
- const text = llmAnswer?.answer?.trim() || renderFallbackAnswer(input.query, mode, evidence);
61
+ const featureIntent = hasFeatureIntentForQuery(input.query);
62
+ const text = cleanSynthesizedAnswer(llmAnswer?.answer?.trim() || renderFallbackAnswer(input.query, mode, evidence), featureIntent);
62
63
  return {
63
64
  ok: true,
64
65
  spaceId,
@@ -172,6 +173,8 @@ async function synthesizeAnswer(llm, query, mode, evidence) {
172
173
  'You answer questions from a GoodVibes self-improving knowledge wiki.',
173
174
  'Use only the supplied evidence. Synthesize the answer for the user intent rather than dumping snippets.',
174
175
  'If evidence is insufficient, say what is missing. Prefer concrete features, specs, procedures, and relationships.',
176
+ 'For feature or specification questions, ignore manual boilerplate about accessories, cable recommendations, USB/HDMI physical-fit guidance, button maps, remote aiming instructions, batteries, cleaning, servicing, safety, furniture, wall mounting, and future product changes unless the user asks about those topics.',
177
+ 'Do not mention future features, specifications changing without notice, cable fit, USB extension cables, remote sensor aiming, service personnel, or child-safety/furniture/platform guidance in a feature/spec answer.',
175
178
  'Return only JSON with answer, confidence, usedSourceIds, usedNodeIds, and optional gaps.',
176
179
  ].join(' '),
177
180
  prompt: JSON.stringify({
@@ -276,6 +279,10 @@ function isLowValueFactForQuery(tokens, intent, fact) {
276
279
  function hasFeatureIntent(intent) {
277
280
  return intent.has('feature') || intent.has('capability') || intent.has('specification') || intent.has('compatibility');
278
281
  }
282
+ function hasFeatureIntentForQuery(query) {
283
+ const intent = factIntent(tokenizeSemanticQuery(query));
284
+ return Boolean(intent && hasFeatureIntent(intent));
285
+ }
279
286
  function compareFactQuality(left, right) {
280
287
  return factQuality(right) - factQuality(left) || left.title.localeCompare(right.title);
281
288
  }
@@ -367,6 +374,10 @@ function selectEvidenceExcerpt(query, text, facts) {
367
374
  }
368
375
  function evidenceWindows(text, tokens) {
369
376
  const normalized = normalizeWhitespace(text);
377
+ const sentences = splitSentences(normalized, 420);
378
+ const sentenceMatches = sentences.filter((sentence) => scoreSemanticText(sentence, tokens) > 0);
379
+ if (sentenceMatches.length > 0)
380
+ return uniqueStrings(sentenceMatches).slice(0, 12);
370
381
  const lower = normalized.toLowerCase();
371
382
  const windows = [];
372
383
  for (const token of tokens) {
@@ -375,12 +386,34 @@ function evidenceWindows(text, tokens) {
375
386
  const index = lower.indexOf(token);
376
387
  if (index < 0)
377
388
  continue;
378
- const start = Math.max(0, index - 220);
379
- const end = Math.min(normalized.length, index + 620);
380
- windows.push(`${start > 0 ? '...' : ''}${normalized.slice(start, end)}${end < normalized.length ? '...' : ''}`);
389
+ const start = Math.max(0, normalized.lastIndexOf('.', index - 1) + 1, index - 160);
390
+ const nextPeriod = normalized.indexOf('.', index + token.length);
391
+ const end = nextPeriod >= 0 ? Math.min(normalized.length, nextPeriod + 1) : Math.min(normalized.length, index + 360);
392
+ windows.push(`${start > 0 ? '...' : ''}${normalized.slice(start, end).trim()}${end < normalized.length ? '...' : ''}`);
381
393
  }
382
394
  return uniqueStrings(windows);
383
395
  }
396
+ function cleanSynthesizedAnswer(text, featureIntent) {
397
+ if (!featureIntent)
398
+ return text;
399
+ const blocks = text.split(/\n{2,}/).map((block) => block.trim()).filter(Boolean);
400
+ const cleanedBlocks = blocks.map((block) => {
401
+ const lines = block.split(/\n/).map((line) => line.trim()).filter(Boolean);
402
+ const kept = lines.filter((line) => !isLowValueFeatureOrSpecText(line));
403
+ if (kept.length > 0 && kept.length < lines.length)
404
+ return kept.join('\n');
405
+ if (lines.length > 1)
406
+ return kept.join('\n');
407
+ const sentences = splitSentences(block, 600);
408
+ const keptSentences = sentences.filter((sentence) => !isLowValueFeatureOrSpecText(sentence));
409
+ return keptSentences.length > 0 && keptSentences.length < sentences.length
410
+ ? keptSentences.join(' ')
411
+ : block;
412
+ }).filter(Boolean);
413
+ return cleanedBlocks.length > 0
414
+ ? cleanedBlocks.join('\n\n')
415
+ : 'The available evidence did not contain source-backed feature or specification details after filtering manual boilerplate.';
416
+ }
384
417
  function expandQueryTokens(tokens) {
385
418
  const expansions = {
386
419
  capabilities: ['capability', 'feature', 'features', 'function', 'functions', 'supports', 'specifications'],
@@ -1 +1 @@
1
- {"version":3,"file":"fact-quality.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/fact-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAcvD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAK/E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQlE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgCjE;AAWD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAa5E"}
1
+ {"version":3,"file":"fact-quality.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/fact-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAcvD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAK/E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQlE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA6CjE;AAWD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAa5E"}
@@ -46,13 +46,26 @@ export function isLowValueFeatureOrSpecText(text) {
46
46
  if (!magicRemoteDetail && /\b(may vary|depending (upon|on) (the )?model|depending on country|depending on region)\b/.test(lower)) {
47
47
  return true;
48
48
  }
49
- if (/\b(fasten|screws?|stand|tip over|overturn|fall over|transporting|move the tv|moving the tv|oils?|lubricants?|cleaning cloth|dry cloth|power cord|electric shock|fire hazard|near water|ventilation|antenna grounding|qualified personnel|customer service|servicing|repair is required|refer all servicing)\b/.test(lower)) {
49
+ if (/\b(fasten|screws?|stand|tip over|overturn|fall over|transporting|move the tv|moving the tv|oils?|lubricants?|cleaning cloth|dry cloth|power cord|electric shock|fire hazard|near water|ventilation|antenna grounding|qualified personnel|qualified service personnel|service personnel|customer service|servicing|repair is required|refer all servicing)\b/.test(lower)) {
50
+ return true;
51
+ }
52
+ if (/\b(platform|cabinet|furniture|supporting furniture|television placement|child safety|proper television placement|wall mount|mounting bracket|stand hole)\b/.test(lower)
53
+ && /\b(support|supports|safe|safely|recommended|install|installation|place|placement|mount|mounting)\b/.test(lower)) {
54
+ return true;
55
+ }
56
+ if (/\b(infrared light|remote control sensor|point (the )?(magic )?remote|aim (the )?(magic )?remote)\b/.test(lower)) {
57
+ return true;
58
+ }
59
+ if (/\bif (the )?device (doesn'?t|does not) support\b/.test(lower) && /\bmay not work properly\b/.test(lower)) {
60
+ return true;
61
+ }
62
+ if (/\bchange\b/.test(lower) && /\bsetting to off\b/.test(lower)) {
50
63
  return true;
51
64
  }
52
65
  if (/\bbatter(y|ies)\b/.test(lower) && /\b(remote|magic remote|button)\b/.test(lower)) {
53
66
  return true;
54
67
  }
55
- if (/\b(bezel|less than \d+(?:\.\d+)?\s*(mm|cm|inches?)|does not fit|will not fit|fit your tv'?s usb port|usb port may not fit)\b/.test(lower)) {
68
+ if (/\b(bezel|less than \d+(?:\.\d+)?\s*(mm|cm|inches?)|does not fit|will not fit|fit your tv'?s usb port|usb port may not fit|usb flash drive does not fit|usb cable does not fit)\b/.test(lower)) {
56
69
  return true;
57
70
  }
58
71
  if (/\b(warning|caution|risk|hazard|do not|never)\b/.test(lower) && !/\b(feature|supports?|hdmi|usb|hdr|remote|bluetooth)\b/.test(lower)) {
@@ -71,7 +84,7 @@ function isTruncatedManualFragment(value) {
71
84
  return false;
72
85
  }
73
86
  export function hasConcreteFeatureSignal(text) {
74
- return /\b(hdmi|usb|hdr|hdr10|dolby|vision|earc|arc|bluetooth|wi-?fi|ethernet|voice|remote|game|filmmaker|airplay|chromecast|resolution|4k|8k|refresh|ports?|speakers?|audio|display|screen|apps?|streaming|matter|energy monitoring|scheduling|sensor|battery|z-?wave|zigbee|thread|motion|temperature|humidity|camera|recording|lock|garage|local control|api|automation)\b/.test(text.toLowerCase());
87
+ return /\b(hdmi|usb|hdr|hdr10|dolby|vision|earc|arc|bluetooth|wi-?fi|wireless lan|ethernet|voice|remote|game|filmmaker|airplay|chromecast|resolution|4k|8k|refresh|ports?|speakers?|audio|display|screen|apps?|streaming|matter|energy monitoring|scheduling|sensor|battery|z-?wave|zigbee|thread|motion|temperature|humidity|camera|recording|lock|garage|local control|api|automation|atsc|ntsc|qam|tuner|broadcast|rs-?232c|external control)\b/.test(text.toLowerCase());
75
88
  }
76
89
  export function isUsefulHomeGraphPageFact(fact) {
77
90
  if (fact.status === 'stale')
@@ -0,0 +1,32 @@
1
+ import type { WebSearchRequest, WebSearchResponse } from '../../web-search/types.js';
2
+ import type { KnowledgeSourceType } from '../types.js';
3
+ import type { KnowledgeSemanticGapRepairer } from './types.js';
4
+ interface GapRepairSearch {
5
+ search(request: WebSearchRequest): Promise<WebSearchResponse>;
6
+ }
7
+ interface GapRepairIngest {
8
+ ingestUrl(input: {
9
+ readonly url: string;
10
+ readonly title?: string;
11
+ readonly tags?: readonly string[];
12
+ readonly sourceType?: KnowledgeSourceType;
13
+ readonly connectorId?: string;
14
+ readonly allowPrivateHosts?: boolean;
15
+ readonly metadata?: Record<string, unknown>;
16
+ }): Promise<{
17
+ readonly source: {
18
+ readonly id: string;
19
+ readonly status: string;
20
+ };
21
+ }>;
22
+ }
23
+ export interface WebGapRepairOptions {
24
+ readonly searchService: GapRepairSearch;
25
+ readonly ingestService: GapRepairIngest;
26
+ readonly maxResults?: number;
27
+ readonly minDistinctDomains?: number;
28
+ readonly maxIngest?: number;
29
+ }
30
+ export declare function createWebKnowledgeGapRepairer(options: WebGapRepairOptions): KnowledgeSemanticGapRepairer;
31
+ export {};
32
+ //# sourceMappingURL=gap-repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gap-repair.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/gap-repair.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EACV,4BAA4B,EAG7B,MAAM,YAAY,CAAC;AAGpB,UAAU,eAAe;IACvB,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/D;AAED,UAAU,eAAe;IACvB,SAAS,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC;QAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;QACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC7C,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,mBAAmB,GAAG,4BAA4B,CAExG"}
@@ -0,0 +1,148 @@
1
+ import { canonicalizeUri } from '../internal.js';
2
+ import { readString, scoreSemanticText, tokenizeSemanticQuery, uniqueStrings } from './utils.js';
3
+ export function createWebKnowledgeGapRepairer(options) {
4
+ return async (request) => repairKnowledgeGapsWithWeb(request, options);
5
+ }
6
+ async function repairKnowledgeGapsWithWeb(request, options) {
7
+ const query = buildGapRepairQuery(request);
8
+ if (!query) {
9
+ return {
10
+ searched: false,
11
+ ingestedSourceIds: [],
12
+ skippedUrls: [],
13
+ reason: 'No concrete subject was available for gap repair.',
14
+ };
15
+ }
16
+ let response;
17
+ try {
18
+ response = await options.searchService.search({
19
+ query,
20
+ maxResults: Math.max(2, Math.min(12, options.maxResults ?? 6)),
21
+ verbosity: 'snippets',
22
+ safeSearch: 'moderate',
23
+ metadata: {
24
+ purpose: 'knowledge-gap-repair',
25
+ knowledgeSpaceId: request.spaceId,
26
+ },
27
+ });
28
+ }
29
+ catch (error) {
30
+ return {
31
+ searched: true,
32
+ query,
33
+ ingestedSourceIds: [],
34
+ skippedUrls: [],
35
+ reason: error instanceof Error ? error.message : String(error),
36
+ };
37
+ }
38
+ const existing = new Set(request.sources.flatMap((source) => [
39
+ canonicalizeUri(source.canonicalUri ?? ''),
40
+ canonicalizeUri(source.sourceUri ?? ''),
41
+ ].filter((value) => Boolean(value))));
42
+ const candidates = selectGapRepairCandidates(response.results, existing, options, query);
43
+ if (candidates.length < Math.max(2, options.minDistinctDomains ?? 2)) {
44
+ return {
45
+ searched: true,
46
+ query,
47
+ ingestedSourceIds: [],
48
+ skippedUrls: response.results.map((result) => result.url),
49
+ reason: 'Fewer than two distinct external sources were found for source-backed gap repair.',
50
+ };
51
+ }
52
+ const ingestedSourceIds = [];
53
+ const skippedUrls = [];
54
+ for (const result of candidates.slice(0, Math.max(2, Math.min(4, options.maxIngest ?? 3)))) {
55
+ try {
56
+ const ingested = await options.ingestService.ingestUrl({
57
+ url: result.url,
58
+ ...(result.title ? { title: result.title } : {}),
59
+ sourceType: 'url',
60
+ connectorId: 'semantic-gap-repair',
61
+ tags: ['semantic-gap-repair', 'gap-repair', ...gapRepairTags(request)],
62
+ metadata: {
63
+ knowledgeSpaceId: request.spaceId,
64
+ sourceDiscovery: {
65
+ purpose: 'semantic-gap-repair',
66
+ query,
67
+ providerId: response.providerId,
68
+ gapIds: request.gaps.map((gap) => gap.id),
69
+ gapQuestions: request.gaps.map((gap) => gap.title),
70
+ originalSourceIds: request.sources.map((source) => source.id),
71
+ linkedObjectIds: request.linkedObjects.map((node) => node.id),
72
+ searchedAt: Date.now(),
73
+ },
74
+ },
75
+ });
76
+ if (ingested.source.status === 'indexed' || ingested.source.status === 'pending') {
77
+ ingestedSourceIds.push(ingested.source.id);
78
+ }
79
+ }
80
+ catch {
81
+ skippedUrls.push(result.url);
82
+ }
83
+ }
84
+ return {
85
+ searched: true,
86
+ query,
87
+ ingestedSourceIds,
88
+ skippedUrls,
89
+ ...(ingestedSourceIds.length < 2 ? { reason: 'Gap repair searched but fewer than two sources were ingested.' } : {}),
90
+ };
91
+ }
92
+ function buildGapRepairQuery(request) {
93
+ const subject = bestSubject(request);
94
+ if (!subject)
95
+ return null;
96
+ const gapTerms = uniqueStrings(request.gaps.flatMap((gap) => [
97
+ gap.title,
98
+ gap.summary,
99
+ readString(gap.metadata.reason),
100
+ ])).join(' ');
101
+ return uniqueStrings([
102
+ subject,
103
+ gapTerms,
104
+ 'official specifications features',
105
+ ]).join(' ');
106
+ }
107
+ function bestSubject(request) {
108
+ const linked = request.linkedObjects[0];
109
+ const source = request.sources[0];
110
+ const metadata = linked?.metadata ?? {};
111
+ return uniqueStrings([
112
+ readString(metadata.manufacturer),
113
+ readString(metadata.model),
114
+ linked?.title,
115
+ source?.title,
116
+ ]).join(' ') || null;
117
+ }
118
+ function selectGapRepairCandidates(results, existingCanonicalUris, options, query) {
119
+ const tokens = tokenizeSemanticQuery(query);
120
+ const byDomain = new Map();
121
+ for (const result of results) {
122
+ const canonical = canonicalizeUri(result.url);
123
+ if (!canonical || existingCanonicalUris.has(canonical))
124
+ continue;
125
+ const searchable = [result.title, result.snippet, result.url, result.domain].filter(Boolean).join(' ');
126
+ if (tokens.length > 0 && scoreSemanticText(searchable, tokens) === 0)
127
+ continue;
128
+ const domain = result.domain ?? safeDomain(result.url);
129
+ if (!domain || byDomain.has(domain))
130
+ continue;
131
+ byDomain.set(domain, result);
132
+ }
133
+ return [...byDomain.values()].slice(0, Math.max(2, Math.min(8, options.maxResults ?? 6)));
134
+ }
135
+ function safeDomain(url) {
136
+ try {
137
+ return new URL(url).hostname;
138
+ }
139
+ catch {
140
+ return undefined;
141
+ }
142
+ }
143
+ function gapRepairTags(request) {
144
+ return uniqueStrings([
145
+ ...request.linkedObjects.flatMap((node) => [node.kind, node.title]),
146
+ ...request.sources.flatMap((source) => source.tags),
147
+ ]).slice(0, 12);
148
+ }
@@ -1,5 +1,8 @@
1
1
  export { createProviderBackedKnowledgeSemanticLlm } from './llm.js';
2
+ export { createWebKnowledgeGapRepairer } from './gap-repair.js';
2
3
  export { KnowledgeSemanticService } from './service.js';
4
+ export { runKnowledgeSemanticSelfImprovement } from './self-improvement.js';
5
+ export type { WebGapRepairOptions } from './gap-repair.js';
3
6
  export type { KnowledgeSemanticServiceOptions } from './service.js';
4
- export type { KnowledgeSemanticAnswer, KnowledgeSemanticAnswerInput, KnowledgeSemanticAnswerResult, KnowledgeSemanticEnrichmentResult, KnowledgeSemanticExtraction, KnowledgeSemanticFactInput, KnowledgeSemanticFactKind, KnowledgeSemanticGapInput, KnowledgeSemanticLlm, KnowledgeSemanticLlmAnswer, } from './types.js';
7
+ export type { KnowledgeSemanticAnswer, KnowledgeSemanticAnswerInput, KnowledgeSemanticAnswerResult, KnowledgeSemanticEnrichmentResult, KnowledgeSemanticExtraction, KnowledgeSemanticFactInput, KnowledgeSemanticFactKind, KnowledgeSemanticGapRepairer, KnowledgeSemanticGapRepairRequest, KnowledgeSemanticGapRepairResult, KnowledgeSemanticGapInput, KnowledgeSemanticLlm, KnowledgeSemanticLlmAnswer, KnowledgeSemanticSelfImproveInput, KnowledgeSemanticSelfImproveResult, } from './types.js';
5
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wCAAwC,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AACpE,YAAY,EACV,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wCAAwC,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,mCAAmC,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,YAAY,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AACpE,YAAY,EACV,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,iCAAiC,EACjC,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,0BAA0B,EAC1B,iCAAiC,EACjC,kCAAkC,GACnC,MAAM,YAAY,CAAC"}
@@ -1,2 +1,4 @@
1
1
  export { createProviderBackedKnowledgeSemanticLlm } from './llm.js';
2
+ export { createWebKnowledgeGapRepairer } from './gap-repair.js';
2
3
  export { KnowledgeSemanticService } from './service.js';
4
+ export { runKnowledgeSemanticSelfImprovement } from './self-improvement.js';
@@ -0,0 +1,10 @@
1
+ import type { KnowledgeStore } from '../store.js';
2
+ import type { KnowledgeSemanticGapRepairer, KnowledgeSemanticSelfImproveInput, KnowledgeSemanticSelfImproveResult } from './types.js';
3
+ interface SelfImproveContext {
4
+ readonly store: KnowledgeStore;
5
+ readonly gapRepairer?: KnowledgeSemanticGapRepairer | null;
6
+ readonly activeGapRepairs: Set<string>;
7
+ }
8
+ export declare function runKnowledgeSemanticSelfImprovement(context: SelfImproveContext, input?: KnowledgeSemanticSelfImproveInput): Promise<KnowledgeSemanticSelfImproveResult>;
9
+ export {};
10
+ //# sourceMappingURL=self-improvement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-improvement.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/knowledge/semantic/self-improvement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD,OAAO,KAAK,EACV,4BAA4B,EAC5B,iCAAiC,EACjC,kCAAkC,EACnC,MAAM,YAAY,CAAC;AAapB,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAC3D,QAAQ,CAAC,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxC;AASD,wBAAsB,mCAAmC,CACvD,OAAO,EAAE,kBAAkB,EAC3B,KAAK,GAAE,iCAAsC,GAC5C,OAAO,CAAC,kCAAkC,CAAC,CAwF7C"}