@pellux/goodvibes-sdk 0.27.9 → 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 (46) 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/service.d.ts +1 -0
  10. package/dist/_internal/platform/knowledge/home-graph/service.d.ts.map +1 -1
  11. package/dist/_internal/platform/knowledge/home-graph/service.js +18 -1
  12. package/dist/_internal/platform/knowledge/home-graph/types.d.ts +3 -1
  13. package/dist/_internal/platform/knowledge/home-graph/types.d.ts.map +1 -1
  14. package/dist/_internal/platform/knowledge/home-graph/types.js +1 -0
  15. package/dist/_internal/platform/knowledge/index.d.ts +2 -2
  16. package/dist/_internal/platform/knowledge/index.d.ts.map +1 -1
  17. package/dist/_internal/platform/knowledge/index.js +1 -1
  18. package/dist/_internal/platform/knowledge/scheduling.d.ts +1 -0
  19. package/dist/_internal/platform/knowledge/scheduling.d.ts.map +1 -1
  20. package/dist/_internal/platform/knowledge/scheduling.js +17 -18
  21. package/dist/_internal/platform/knowledge/semantic/answer.d.ts.map +1 -1
  22. package/dist/_internal/platform/knowledge/semantic/answer.js +38 -6
  23. package/dist/_internal/platform/knowledge/semantic/fact-quality.d.ts.map +1 -1
  24. package/dist/_internal/platform/knowledge/semantic/fact-quality.js +6 -2
  25. package/dist/_internal/platform/knowledge/semantic/gap-repair.d.ts +32 -0
  26. package/dist/_internal/platform/knowledge/semantic/gap-repair.d.ts.map +1 -0
  27. package/dist/_internal/platform/knowledge/semantic/gap-repair.js +148 -0
  28. package/dist/_internal/platform/knowledge/semantic/index.d.ts +4 -1
  29. package/dist/_internal/platform/knowledge/semantic/index.d.ts.map +1 -1
  30. package/dist/_internal/platform/knowledge/semantic/index.js +2 -0
  31. package/dist/_internal/platform/knowledge/semantic/self-improvement.d.ts +10 -0
  32. package/dist/_internal/platform/knowledge/semantic/self-improvement.d.ts.map +1 -0
  33. package/dist/_internal/platform/knowledge/semantic/self-improvement.js +486 -0
  34. package/dist/_internal/platform/knowledge/semantic/service.d.ts +9 -2
  35. package/dist/_internal/platform/knowledge/semantic/service.d.ts.map +1 -1
  36. package/dist/_internal/platform/knowledge/semantic/service.js +124 -2
  37. package/dist/_internal/platform/knowledge/semantic/types.d.ts +38 -0
  38. package/dist/_internal/platform/knowledge/semantic/types.d.ts.map +1 -1
  39. package/dist/_internal/platform/knowledge/service.d.ts.map +1 -1
  40. package/dist/_internal/platform/knowledge/service.js +17 -1
  41. package/dist/_internal/platform/knowledge/types.d.ts +1 -1
  42. package/dist/_internal/platform/knowledge/types.d.ts.map +1 -1
  43. package/dist/_internal/platform/runtime/services.d.ts.map +1 -1
  44. package/dist/_internal/platform/runtime/services.js +5 -1
  45. package/dist/_internal/platform/version.js +1 -1
  46. package/package.json +1 -1
@@ -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,7 +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.',
175
- 'For feature or specification questions, ignore manual boilerplate about accessories, cable recommendations, button maps, batteries, cleaning, servicing, safety, and future product changes unless the user asks about those topics.',
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.',
176
178
  'Return only JSON with answer, confidence, usedSourceIds, usedNodeIds, and optional gaps.',
177
179
  ].join(' '),
178
180
  prompt: JSON.stringify({
@@ -277,6 +279,10 @@ function isLowValueFactForQuery(tokens, intent, fact) {
277
279
  function hasFeatureIntent(intent) {
278
280
  return intent.has('feature') || intent.has('capability') || intent.has('specification') || intent.has('compatibility');
279
281
  }
282
+ function hasFeatureIntentForQuery(query) {
283
+ const intent = factIntent(tokenizeSemanticQuery(query));
284
+ return Boolean(intent && hasFeatureIntent(intent));
285
+ }
280
286
  function compareFactQuality(left, right) {
281
287
  return factQuality(right) - factQuality(left) || left.title.localeCompare(right.title);
282
288
  }
@@ -368,6 +374,10 @@ function selectEvidenceExcerpt(query, text, facts) {
368
374
  }
369
375
  function evidenceWindows(text, tokens) {
370
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);
371
381
  const lower = normalized.toLowerCase();
372
382
  const windows = [];
373
383
  for (const token of tokens) {
@@ -376,12 +386,34 @@ function evidenceWindows(text, tokens) {
376
386
  const index = lower.indexOf(token);
377
387
  if (index < 0)
378
388
  continue;
379
- const start = Math.max(0, index - 220);
380
- const end = Math.min(normalized.length, index + 620);
381
- 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 ? '...' : ''}`);
382
393
  }
383
394
  return uniqueStrings(windows);
384
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
+ }
385
417
  function expandQueryTokens(tokens) {
386
418
  const expansions = {
387
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,CAyCjE;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"}
@@ -49,6 +49,10 @@ export function isLowValueFeatureOrSpecText(text) {
49
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
50
  return true;
51
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
+ }
52
56
  if (/\b(infrared light|remote control sensor|point (the )?(magic )?remote|aim (the )?(magic )?remote)\b/.test(lower)) {
53
57
  return true;
54
58
  }
@@ -61,7 +65,7 @@ export function isLowValueFeatureOrSpecText(text) {
61
65
  if (/\bbatter(y|ies)\b/.test(lower) && /\b(remote|magic remote|button)\b/.test(lower)) {
62
66
  return true;
63
67
  }
64
- 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)) {
65
69
  return true;
66
70
  }
67
71
  if (/\b(warning|caution|risk|hazard|do not|never)\b/.test(lower) && !/\b(feature|supports?|hdmi|usb|hdr|remote|bluetooth)\b/.test(lower)) {
@@ -80,7 +84,7 @@ function isTruncatedManualFragment(value) {
80
84
  return false;
81
85
  }
82
86
  export function hasConcreteFeatureSignal(text) {
83
- 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());
84
88
  }
85
89
  export function isUsefulHomeGraphPageFact(fact) {
86
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"}