@triplef/agent 0.1.16 → 0.1.17

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.
@@ -110,15 +110,18 @@ declare const TEXT_FAMILIARITY_INSTRUCTIONS = "MODE: TEXT \u2014 FAMILIARITY\n\n
110
110
 
111
111
  declare const VIDEOLIST_INSTRUCTIONS = "MODE: VIDEOLIST\n\nGoal: produce a pure video collection \u2014 a titled, captioned playlist of videos about the user's topic. The dashboard renders it as a numbered playlist with embedded players, not an article. The user explicitly asked for videos ONLY (e.g. music videos, trailers, clips), so prose must stay minimal.\n\nSTRUCTURE:\n1. category is a short label such as Videos, Playlist, Music Videos, Trailers.\n2. title states what the playlist contains (e.g. \"Daft Punk \u2014 Music Videos\").\n3. subtitle is ONE short sentence of context (what these videos are and where they come from). No paragraphs.\n4. videoGalleryItems is the core deliverable: every suitable video from the video search results, ordered like a playlist.\n\nRequired fields:\n- category: a short label such as Videos, Playlist, Music Videos, Trailers.\n- title: the playlist title; must not be empty.\n- subtitle: one short sentence of context; empty string if nothing meaningful to add.\n- videoGalleryItems: an array of video objects. This is the entire point of the template \u2014 it MUST contain every suitable retrieved video up to videoTargetCount.\n\nHistory dedupe (ABSOLUTE):\n- The conversation history may contain earlier videolist responses (JSON objects with a videoGalleryItems array).\n- NEVER include a videoUrl that already appeared in an earlier videolist response \u2014 the user has already seen it.\n- When the user asks for more videos (e.g. \"more\", \"weitere\", \"next\"), return ONLY fresh videos that are not in the history.\n- If every retrieved video is already in the history, say so in the subtitle and return an empty videoGalleryItems array.\n\nVideo item rules:\n- Each entry needs videoUrl, title, and caption. title and caption MUST be non-empty.\n- title is the video's real title when known (e.g. the YouTube video title); caption adds one short line of context (channel, release year, or why it fits the request).\n- If the tool result provides no title/caption, derive concise values from the query and topic. Never leave them empty.\n- Carry over the metadata from availableVideos verbatim: duration, channel, date, views, thumbnailUrl, and description. Omit a field only when the tool result did not provide it.\n- Only use direct video pages \u2014 never channel, playlist, user, or profile URLs.\n- Use ONLY video URLs that appear in the tool results. Never invent or guess URLs.\n- Order the videos like a good playlist: most relevant and most popular first.\n- Do not include the same video twice (same music video, trailer, or clip), even from different search tools.\n- Cross-check every candidate videoUrl against the earlier videolist responses in the conversation before including it.\n- When the user asks for videos from a specific platform (e.g. \"on YouTube\"), include ONLY videos from that platform.\n\nDo NOT include:\n- Long descriptions, articles, sections, key findings, or conclusions \u2014 the user wants videos, not prose.\n- Images or image galleries \u2014 the imagelist template handles image collections.\n- Hero videos \u2014 every video lives in videoGalleryItems so the playlist stays uniform.\n\nNo-results rule:\n- If the searches returned no usable videos, set title to a concise statement such as 'No videos found for <topic>' and use subtitle to explain that the search did not return embeddable video sources. Set videoGalleryItems to an empty array.\n- Do not invent video URLs to fill the playlist when no results were retrieved.\n- The dashboard does not render sources for this template. Do not include a sources field.";
112
112
 
113
- declare const BELIEF_INSTRUCTIONS = "You synthesize higher-level beliefs from a user's memory facts.\n\nGiven a numbered list of EVIDENCE (facts the user stated or asked to remember), synthesize durable, higher-level beliefs \u2014 conclusions that are true of the evidence but not merely restated from it. Every belief picks its lane (\"target\"), and the choice is PURPOSE-based, never cosmetic:\n\n- \"conviction\" \u2014 a durable conclusion about THE USER (or your own working relationship with them): a pattern in their behavior, a standing judgment the facts support, a trait or tendency you now hold true. Convictions deepen your understanding of the user and yourself; they are YOURS, never statements the user made. (\"the user bought a dog\" + \"the user keeps comparing dog food brands\" + \"the user researches every purchase for days\" \u2192 conviction: \"the user is a deliberate, research-first buyer\")\n- \"bridge\" \u2014 a synthesized claim that CLOSES A GAP between facts: without it, two stored facts look unrelated; with it, they form one coherent story about the user's world. Bridges are the connective tissue of the fact graph. (\"the user bought dog food X\" + \"the user's dog refuses to eat\" \u2192 bridge: \"the dog refuses the brand-X food the user bought\")\n\nA belief is a synthesis, not a restatement:\n- combine multiple facts into one conclusion (\"learning Rust\" + \"rewriting the payments service\" \u2192 \"the user is migrating the payments service to Rust\")\n- a belief MUST cite the evidence indices that support it (the [n] numbers)\n- never invent facts not present in the evidence\n- never restate a single evidence item verbatim as a belief \u2014 that is not synthesis\n- a belief with no supporting evidence is invalid \u2014 omit it\n- when neither a conviction nor a bridge clearly fits, emit nothing for it \u2014 a forced target blurs the lanes and is worse than no belief\n\nRespond with JSON only:\n{\n \"beliefs\": [\n { \"text\": \"one self-contained sentence\", \"target\": \"conviction\", \"evidence\": [0, 2, 5] }\n ]\n}\n\nRules:\n- target is exactly \"conviction\" or \"bridge\" \u2014 every belief carries one\n- evidence indices are the [n] numbers from the EVIDENCE list \u2014 never invent an index\n- return an empty beliefs array when the evidence is too thin to synthesize anything\n- keep each belief to one sentence";
114
- interface BeliefEvidenceItem {
113
+ declare const CONVICTION_INSTRUCTIONS = "You synthesize higher-level convictions and bridges from a user's memory facts.\n\nGiven a numbered list of EVIDENCE (facts the user stated or asked to remember), synthesize durable, higher-level statements \u2014 conclusions that are true of the evidence but not merely restated from it. Every statement picks its lane (\"target\"), and the choice is PURPOSE-based, never cosmetic:\n\n- \"conviction\" \u2014 a durable conclusion about THE USER (or your own working relationship with them): a pattern in their behavior, a standing judgment the facts support, a trait or tendency you now hold true. Convictions deepen your understanding of the user and yourself; they are YOURS, never statements the user made. (\"the user bought a dog\" + \"the user keeps comparing dog food brands\" + \"the user researches every purchase for days\" \u2192 conviction: \"the user is a deliberate, research-first buyer\")\n- \"bridge\" \u2014 a synthesized claim that CLOSES A GAP between facts: without it, two stored facts look unrelated; with it, they form one coherent story about the user's world. Bridges are the connective tissue of the fact graph. (\"the user bought dog food X\" + \"the user's dog refuses to eat\" \u2192 bridge: \"the dog refuses the brand-X food the user bought\")\n\nA synthesized statement is a synthesis, not a restatement:\n- combine multiple facts into one conclusion (\"learning Rust\" + \"rewriting the payments service\" \u2192 \"the user is migrating the payments service to Rust\")\n- every statement MUST cite the evidence indices that support it (the [n] numbers)\n- never invent facts not present in the evidence\n- never restate a single evidence item verbatim \u2014 that is not synthesis\n- a statement with no supporting evidence is invalid \u2014 omit it\n- when neither a conviction nor a bridge clearly fits, emit nothing for it \u2014 a forced target blurs the lanes and is worse than no statement\n\nEVIDENCE METADATA \u2014 each line may show \"(subject: \u2026; category: \u2026; kind: \u2026; stability: \u2026)\":\n- subject groups the evidence lines about one entity \u2014 convictions about a subject cite that subject's lines\n- durable evidence carries more weight for a conviction; a volatile state alone rarely supports a durable conclusion\n- kind sharpens conclusions: a pattern of \"preference\" evidence supports a taste conclusion; \"decision\" evidence supports a commitment conclusion\n\nRespond with JSON only:\n{\n \"convictions\": [\n { \"text\": \"one self-contained sentence\", \"target\": \"conviction\", \"evidence\": [0, 2, 5] }\n ]\n}\n\nRules:\n- target is exactly \"conviction\" or \"bridge\" \u2014 every statement carries one\n- evidence indices are the [n] numbers from the EVIDENCE list \u2014 never invent an index\n- return an empty convictions array when the evidence is too thin to synthesize anything\n- keep each statement to one sentence";
114
+ interface ConvictionEvidenceItem {
115
115
  id: string;
116
116
  text: string;
117
117
  category?: string;
118
+ subject?: string;
119
+ kind?: string;
120
+ stability?: string;
118
121
  }
119
- declare function buildBeliefSynthesisPrompt(evidence: readonly BeliefEvidenceItem[]): string;
122
+ declare function buildConvictionSynthesisPrompt(evidence: readonly ConvictionEvidenceItem[]): string;
120
123
 
121
- declare function buildEncyclopediaClassifyPrompt(knownCategories?: readonly string[]): string;
124
+ declare function buildEncyclopediaClassifyPrompt(knownCategories?: readonly string[], knownTopics?: readonly string[]): string;
122
125
 
123
126
  declare function formatProvenanceLine(line: {
124
127
  text: string;
@@ -126,11 +129,15 @@ declare function formatProvenanceLine(line: {
126
129
  createdAt?: string;
127
130
  }): string;
128
131
 
129
- declare const FRICTION_INSTRUCTIONS = "You screen memory records for contradictions.\n\nGiven one RECORD and a list of CANDIDATES (near-neighbor records), decide whether the RECORD contradicts any CANDIDATE.\n\nA contradiction is a genuine semantic conflict:\n- a negation or polarity flip (\"likes X\" vs \"dislikes X\")\n- a superseding update (\"lives in Berlin\" vs \"moved to Munich\")\n- mutually exclusive claims about the same subject\n\nNOT a contradiction:\n- mere redundancy or restatement (that is handled elsewhere)\n- different subjects or unrelated facts\n- a more specific statement that does not actually conflict with a general one\n\nRespond with JSON only:\n{\n \"contradicts\": boolean,\n \"conflictingId\": \"the candidate id that conflicts (omit when contradicts is false)\",\n \"winnerId\": \"the id that is correct \u2014 the record's id or the conflictingId (omit when neither is clearly right)\",\n \"reason\": \"one sentence: the conflict, and why the winner wins when one is named\"\n}\n\nRules:\n- Name a winner only when one side is clearly correct (e.g. the later statement supersedes the earlier). When both could be true or the truth is unclear, omit winnerId so the conflict stays open.\n- Never invent a conflictingId or winnerId that is not in the input.";
132
+ declare const FRICTION_INSTRUCTIONS = "You screen memory records for contradictions.\n\nGiven one RECORD and a list of CANDIDATES (near-neighbor records), decide whether the RECORD contradicts any CANDIDATE.\n\nA contradiction is a genuine semantic conflict:\n- a negation or polarity flip (\"likes X\" vs \"dislikes X\")\n- a superseding update (\"lives in Berlin\" vs \"moved to Munich\")\n- mutually exclusive claims about the same subject\n\nNOT a contradiction:\n- mere redundancy or restatement (that is handled elsewhere)\n- different subjects or unrelated facts\n- a more specific statement that does not actually conflict with a general one\n\nMETADATA \u2014 each record may show \"(subject: \u2026; category: \u2026; kind: \u2026; stability: \u2026)\":\n- subject: a contradiction requires the SAME subject. Candidates about a different subject are never conflicts, however similar they read.\n- stability: \"volatile\" records describe a current state \u2014 a NEWER volatile statement supersedes the older one (name the newer as winner). \"durable\" statements rarely supersede each other: when neither side is clearly right, omit winnerId so the conflict stays open.\n- kind: polarity flips are the expected contradiction for \"preference\" and \"relationship\" records. For \"fact\", \"project\", \"contact\" and \"possession\" records a conflict means one statement is outdated or wrong \u2014 prefer the newer statement when the dates say which is current.\n- category: conflicts almost always live inside one category family; treat a candidate from a clearly different family skeptically, but never dismiss it on category alone.\n\nRespond with JSON only:\n{\n \"contradicts\": boolean,\n \"conflictingId\": \"the candidate id that conflicts (omit when contradicts is false)\",\n \"winnerId\": \"the id that is correct \u2014 the record's id or the conflictingId (omit when neither is clearly right)\",\n \"reason\": \"one sentence: the conflict, and why the winner wins when one is named\"\n}\n\nRules:\n- Name a winner only when one side is clearly correct (e.g. the later statement supersedes the earlier). When both could be true or the truth is unclear, omit winnerId so the conflict stays open.\n- Never invent a conflictingId or winnerId that is not in the input.";
130
133
  interface FrictionFact {
131
134
  id: string;
132
135
  text: string;
133
136
  createdAt?: string;
137
+ subject?: string;
138
+ category?: string;
139
+ kind?: string;
140
+ stability?: string;
134
141
  }
135
142
  declare function buildFrictionPrompt(input: {
136
143
  record: FrictionFact;
@@ -151,6 +158,10 @@ interface ConsolidateProvenanceLine {
151
158
  text: string;
152
159
  role: string;
153
160
  createdAt?: string;
161
+ subject?: string;
162
+ category?: string;
163
+ kind?: string;
164
+ stability?: string;
154
165
  }
155
166
  declare function buildConsolidatePrompt(params: {
156
167
  newFact: ConsolidateProvenanceLine;
@@ -357,4 +368,4 @@ declare const verdictSpineSnippet: TemplateSnippet;
357
368
 
358
369
  declare const videoGallerySnippet: TemplateSnippet;
359
370
 
360
- export { BELIEF_INSTRUCTIONS, COMMONMARK_FORMAT, COMPARE_INSTRUCTIONS, COMPARE_VISUAL_INSTRUCTIONS, type ContentSystemPromptParams, DESCRIBE_CONCISE_INSTRUCTIONS, DESCRIBE_DETAILED_INSTRUCTIONS, DESCRIBE_INSTRUCTIONS, FINAL_REMINDER, FRICTION_INSTRUCTIONS, type FrictionFact, HISTORY_URLS_RULES, IMAGELIST_INSTRUCTIONS, IMAGE_TASK_RULE, INTERNATIONAL_COVERAGE_INSTRUCTIONS, ITEM_SHAPES, JSON_RULES, MEDIA_COUNTS, MEDIA_RULES, MEMORY_CLUSTER_INSTRUCTIONS, MEMORY_CONSOLIDATE_INSTRUCTIONS, MEMORY_PROFILE_INSTRUCTIONS, MEMORY_WRITE_INSTRUCTIONS, MERGE_MEDIA_RULES, MERGE_TOPIC_RULE, MULTIMODAL_POLICY, NOISE_RULES, OCR_INSTRUCTIONS, OCR_VERBATIM_INSTRUCTIONS, PRECEDENCE_RULES, PRODUCT_INSTRUCTIONS, RESPONSE_LAYOUTS, type ResponseLayout, SECURITY_RULES, SHOPLIST_INSTRUCTIONS, SNIPPET_TEMPLATE_PRESETS, SOURCE_TRUTH_RULES, SOURCE_VOICE_RULES, STOCKMARKET_ITEM_INSTRUCTIONS, STOCKMARKET_LIST_INSTRUCTIONS, SUMMARY_INSTRUCTIONS, type SnippetTemplatePreset, type SourcePolicyConfig, type StructuredPromptTemplate, TEMPLATE_VARIANTS, TEXT_CODING_INSTRUCTIONS, TEXT_FAMILIARITY_INSTRUCTIONS, TEXT_INSTRUCTIONS, TOOL_RESULTS_RULES, type TemplateSnippet, VIDEOLIST_INSTRUCTIONS, articlePreset, assessmentListsSnippet, authorMetaSnippet, bodyBriefSnippet, bodyExtensiveSnippet, buildBaseSystemPrompt, buildBeliefSynthesisPrompt, buildClarificationTranslationSystemPrompt, buildClarificationTranslationUserPrompt, buildClassifyTranscript, buildClusterSummaryPrompt, buildConsolidatePrompt, buildContentSystemPrompt, buildContextSummarySection, buildCorrectionPrompt, buildEncyclopediaClassifyPrompt, buildEnrichPrompt, buildExecuteLanguageInstruction, buildExtractionCorrectionPrompt, buildExtractionPrompt, buildFrictionPrompt, buildImageExecutePrompt, buildIntentCorrectionPrompt, buildIntentSelectionPrompt, buildLanguageRule, buildLayoutInstruction, buildLocalizationRule, buildMemoryProbeSection, buildMemoryProfilePrompt, buildMemoryWritePrompt, buildMergeDirective, buildMissingToolsPrompt, buildOutputContract, buildSnippetInstruction, buildSourcePolicyPrompt, buildStockmarketNote, buildStructuredJsonPrompt, buildStructuredPrompt, buildToolExecutePrompt, buildVocabularySection, bylineDatelineSnippet, cardsSnippet, comparisonSchema, comparisonSnippet, composeSnippetKeys, composeSnippetSchema, conclusionSnippet, evaluationPreset, formatCurrentTimestamp, formatProvenanceLine, formatToolAvailabilityCatalog, formatVariantCatalog, gallerySnippet, getSnippetTemplateKeys, getSnippetTemplateSchema, headerArticleSnippet, headerNewsSnippet, heroMediaSnippet, internationalCoverageSnippet, introductionSnippet, isSnippetTemplate, keyFindingsSnippet, languageCorrectionPrompt, leadSnippet, mergePreset, mergedEvaluationsSnippet, newsKeyFindingsSnippet, newsPreset, quoteSnippet, reasoningSnippet, relatedStoriesSnippet, resolveLanguageName, resolveVariantInstructions, responseLayoutSchema, sourcesSnippet, subjectSchema, subjectsSnippet, summarySnippet, verdictSpineSnippet, videoGallerySnippet };
371
+ export { COMMONMARK_FORMAT, COMPARE_INSTRUCTIONS, COMPARE_VISUAL_INSTRUCTIONS, CONVICTION_INSTRUCTIONS, type ContentSystemPromptParams, DESCRIBE_CONCISE_INSTRUCTIONS, DESCRIBE_DETAILED_INSTRUCTIONS, DESCRIBE_INSTRUCTIONS, FINAL_REMINDER, FRICTION_INSTRUCTIONS, type FrictionFact, HISTORY_URLS_RULES, IMAGELIST_INSTRUCTIONS, IMAGE_TASK_RULE, INTERNATIONAL_COVERAGE_INSTRUCTIONS, ITEM_SHAPES, JSON_RULES, MEDIA_COUNTS, MEDIA_RULES, MEMORY_CLUSTER_INSTRUCTIONS, MEMORY_CONSOLIDATE_INSTRUCTIONS, MEMORY_PROFILE_INSTRUCTIONS, MEMORY_WRITE_INSTRUCTIONS, MERGE_MEDIA_RULES, MERGE_TOPIC_RULE, MULTIMODAL_POLICY, NOISE_RULES, OCR_INSTRUCTIONS, OCR_VERBATIM_INSTRUCTIONS, PRECEDENCE_RULES, PRODUCT_INSTRUCTIONS, RESPONSE_LAYOUTS, type ResponseLayout, SECURITY_RULES, SHOPLIST_INSTRUCTIONS, SNIPPET_TEMPLATE_PRESETS, SOURCE_TRUTH_RULES, SOURCE_VOICE_RULES, STOCKMARKET_ITEM_INSTRUCTIONS, STOCKMARKET_LIST_INSTRUCTIONS, SUMMARY_INSTRUCTIONS, type SnippetTemplatePreset, type SourcePolicyConfig, type StructuredPromptTemplate, TEMPLATE_VARIANTS, TEXT_CODING_INSTRUCTIONS, TEXT_FAMILIARITY_INSTRUCTIONS, TEXT_INSTRUCTIONS, TOOL_RESULTS_RULES, type TemplateSnippet, VIDEOLIST_INSTRUCTIONS, articlePreset, assessmentListsSnippet, authorMetaSnippet, bodyBriefSnippet, bodyExtensiveSnippet, buildBaseSystemPrompt, buildClarificationTranslationSystemPrompt, buildClarificationTranslationUserPrompt, buildClassifyTranscript, buildClusterSummaryPrompt, buildConsolidatePrompt, buildContentSystemPrompt, buildContextSummarySection, buildConvictionSynthesisPrompt, buildCorrectionPrompt, buildEncyclopediaClassifyPrompt, buildEnrichPrompt, buildExecuteLanguageInstruction, buildExtractionCorrectionPrompt, buildExtractionPrompt, buildFrictionPrompt, buildImageExecutePrompt, buildIntentCorrectionPrompt, buildIntentSelectionPrompt, buildLanguageRule, buildLayoutInstruction, buildLocalizationRule, buildMemoryProbeSection, buildMemoryProfilePrompt, buildMemoryWritePrompt, buildMergeDirective, buildMissingToolsPrompt, buildOutputContract, buildSnippetInstruction, buildSourcePolicyPrompt, buildStockmarketNote, buildStructuredJsonPrompt, buildStructuredPrompt, buildToolExecutePrompt, buildVocabularySection, bylineDatelineSnippet, cardsSnippet, comparisonSchema, comparisonSnippet, composeSnippetKeys, composeSnippetSchema, conclusionSnippet, evaluationPreset, formatCurrentTimestamp, formatProvenanceLine, formatToolAvailabilityCatalog, formatVariantCatalog, gallerySnippet, getSnippetTemplateKeys, getSnippetTemplateSchema, headerArticleSnippet, headerNewsSnippet, heroMediaSnippet, internationalCoverageSnippet, introductionSnippet, isSnippetTemplate, keyFindingsSnippet, languageCorrectionPrompt, leadSnippet, mergePreset, mergedEvaluationsSnippet, newsKeyFindingsSnippet, newsPreset, quoteSnippet, reasoningSnippet, relatedStoriesSnippet, resolveLanguageName, resolveVariantInstructions, responseLayoutSchema, sourcesSnippet, subjectSchema, subjectsSnippet, summarySnippet, verdictSpineSnippet, videoGallerySnippet };
@@ -513,13 +513,48 @@ var MemoryEnrichmentSchema = z.object({
513
513
  */
514
514
  tags: z.array(z.string())
515
515
  });
516
+ var FACT_KINDS = [
517
+ "preference",
518
+ "decision",
519
+ "state",
520
+ "contact",
521
+ "project",
522
+ "possession",
523
+ "relationship",
524
+ "fact"
525
+ ];
526
+ var FACT_STABILITIES = ["durable", "volatile"];
527
+ var ExtractedFactSchema = z.object({
528
+ /**
529
+ * The self-contained durable statement — third person, subject up front,
530
+ * no "this"/"that" references.
531
+ */
532
+ text: z.string(),
533
+ /**
534
+ * The lowercase entity the fact is about (default `user`; a person,
535
+ * product, or project name). Maintenance adjudication only ever compares
536
+ * facts about the SAME subject.
537
+ */
538
+ subject: z.string().optional(),
539
+ /**
540
+ * One broad lowercase PLURAL family label for THIS fact (e.g. `stocks`,
541
+ * `pets`, `games`) — inherits the turn-side category when omitted. Never
542
+ * a specific entity, product, company, or game title.
543
+ */
544
+ category: z.string().optional(),
545
+ /** What kind of durable thing this is (see FACT_KINDS). */
546
+ kind: z.enum(FACT_KINDS),
547
+ /** Whether a newer statement is expected to replace this one (see FACT_STABILITIES). */
548
+ stability: z.enum(FACT_STABILITIES)
549
+ });
516
550
  var ExtractionSchema = z.object({
517
551
  /**
518
552
  * Durable, self-contained facts worth remembering in a later, unrelated
519
- * conversation (preferences, decisions, contact details, project facts).
520
- * Empty when nothing in the text is worth remembering.
553
+ * conversation (preferences, decisions, contact details, project facts),
554
+ * each carrying its maintenance metadata (subject, category, kind,
555
+ * stability). Empty when nothing in the text is worth remembering.
521
556
  */
522
- facts: z.array(z.string()),
557
+ facts: z.array(ExtractedFactSchema),
523
558
  /**
524
559
  * 2–6 stable, reusable lowercase topic labels describing the text; the open
525
560
  * vocabulary that powers topic-filtered recall. Tags are NARROW and
@@ -531,9 +566,10 @@ var ExtractionSchema = z.object({
531
566
  * One broad lowercase PLURAL family label for the whole turn-side (e.g.
532
567
  * `stocks`, `pets`, `games`) — groups the narrow tags into one topic family
533
568
  * for the constellation's community tier and the relink job's per-category
534
- * passes. Never a specific entity, product, company, or game title: `amd`
535
- * belongs under `stocks`; `stellar blade` belongs under `games`. Optional:
536
- * a turn with nothing durable may omit it.
569
+ * passes, and backstops facts that omit their own `category`. Never a
570
+ * specific entity, product, company, or game title: `amd` belongs under
571
+ * `stocks`; `stellar blade` belongs under `games`. Optional: a turn with
572
+ * nothing durable may omit it.
537
573
  */
538
574
  category: z.string().optional()
539
575
  });
@@ -3478,39 +3514,54 @@ Ensure the "language" field is present and has the correct value.
3478
3514
  FINAL REMINDER:
3479
3515
  - Return ONLY a single valid JSON object with all required keys, including "language". No markdown code fences, no explanations, no extra text.`;
3480
3516
 
3481
- // src/prompts/memory/belief-synthesis-prompt.constant.ts
3482
- var BELIEF_INSTRUCTIONS = `You synthesize higher-level beliefs from a user's memory facts.
3517
+ // src/prompts/memory/format-fact-metadata.helper.ts
3518
+ function formatFactMetadata(fact) {
3519
+ const parts = [
3520
+ fact.subject ? `subject: ${fact.subject}` : "",
3521
+ fact.category ? `category: ${fact.category}` : "",
3522
+ fact.kind ? `kind: ${fact.kind}` : "",
3523
+ fact.stability ? `stability: ${fact.stability}` : ""
3524
+ ].filter(Boolean);
3525
+ return parts.length ? ` (${parts.join("; ")})` : "";
3526
+ }
3483
3527
 
3484
- Given a numbered list of EVIDENCE (facts the user stated or asked to remember), synthesize durable, higher-level beliefs \u2014 conclusions that are true of the evidence but not merely restated from it. Every belief picks its lane ("target"), and the choice is PURPOSE-based, never cosmetic:
3528
+ // src/prompts/memory/conviction-synthesis-prompt.constant.ts
3529
+ var CONVICTION_INSTRUCTIONS = `You synthesize higher-level convictions and bridges from a user's memory facts.
3530
+
3531
+ Given a numbered list of EVIDENCE (facts the user stated or asked to remember), synthesize durable, higher-level statements \u2014 conclusions that are true of the evidence but not merely restated from it. Every statement picks its lane ("target"), and the choice is PURPOSE-based, never cosmetic:
3485
3532
 
3486
3533
  - "conviction" \u2014 a durable conclusion about THE USER (or your own working relationship with them): a pattern in their behavior, a standing judgment the facts support, a trait or tendency you now hold true. Convictions deepen your understanding of the user and yourself; they are YOURS, never statements the user made. ("the user bought a dog" + "the user keeps comparing dog food brands" + "the user researches every purchase for days" \u2192 conviction: "the user is a deliberate, research-first buyer")
3487
3534
  - "bridge" \u2014 a synthesized claim that CLOSES A GAP between facts: without it, two stored facts look unrelated; with it, they form one coherent story about the user's world. Bridges are the connective tissue of the fact graph. ("the user bought dog food X" + "the user's dog refuses to eat" \u2192 bridge: "the dog refuses the brand-X food the user bought")
3488
3535
 
3489
- A belief is a synthesis, not a restatement:
3536
+ A synthesized statement is a synthesis, not a restatement:
3490
3537
  - combine multiple facts into one conclusion ("learning Rust" + "rewriting the payments service" \u2192 "the user is migrating the payments service to Rust")
3491
- - a belief MUST cite the evidence indices that support it (the [n] numbers)
3538
+ - every statement MUST cite the evidence indices that support it (the [n] numbers)
3492
3539
  - never invent facts not present in the evidence
3493
- - never restate a single evidence item verbatim as a belief \u2014 that is not synthesis
3494
- - a belief with no supporting evidence is invalid \u2014 omit it
3495
- - when neither a conviction nor a bridge clearly fits, emit nothing for it \u2014 a forced target blurs the lanes and is worse than no belief
3540
+ - never restate a single evidence item verbatim \u2014 that is not synthesis
3541
+ - a statement with no supporting evidence is invalid \u2014 omit it
3542
+ - when neither a conviction nor a bridge clearly fits, emit nothing for it \u2014 a forced target blurs the lanes and is worse than no statement
3543
+
3544
+ EVIDENCE METADATA \u2014 each line may show "(subject: \u2026; category: \u2026; kind: \u2026; stability: \u2026)":
3545
+ - subject groups the evidence lines about one entity \u2014 convictions about a subject cite that subject's lines
3546
+ - durable evidence carries more weight for a conviction; a volatile state alone rarely supports a durable conclusion
3547
+ - kind sharpens conclusions: a pattern of "preference" evidence supports a taste conclusion; "decision" evidence supports a commitment conclusion
3496
3548
 
3497
3549
  Respond with JSON only:
3498
3550
  {
3499
- "beliefs": [
3551
+ "convictions": [
3500
3552
  { "text": "one self-contained sentence", "target": "conviction", "evidence": [0, 2, 5] }
3501
3553
  ]
3502
3554
  }
3503
3555
 
3504
3556
  Rules:
3505
- - target is exactly "conviction" or "bridge" \u2014 every belief carries one
3557
+ - target is exactly "conviction" or "bridge" \u2014 every statement carries one
3506
3558
  - evidence indices are the [n] numbers from the EVIDENCE list \u2014 never invent an index
3507
- - return an empty beliefs array when the evidence is too thin to synthesize anything
3508
- - keep each belief to one sentence`;
3509
- function buildBeliefSynthesisPrompt(evidence) {
3559
+ - return an empty convictions array when the evidence is too thin to synthesize anything
3560
+ - keep each statement to one sentence`;
3561
+ function buildConvictionSynthesisPrompt(evidence) {
3510
3562
  const lines = ["EVIDENCE (each item is a fact the user stated or asked to remember):"];
3511
3563
  for (const [index, item] of evidence.entries()) {
3512
- const category = item.category ? ` (category: ${item.category})` : "";
3513
- lines.push(`[${index}] ${item.text}${category}`);
3564
+ lines.push(`[${index}] ${item.text}${formatFactMetadata(item)}`);
3514
3565
  }
3515
3566
  return lines.join("\n");
3516
3567
  }
@@ -3531,15 +3582,16 @@ function buildVocabularySection(knownCategories = [], knownTags = []) {
3531
3582
  }
3532
3583
 
3533
3584
  // src/prompts/memory/encyclopedia-classify-prompt.constant.ts
3534
- function buildEncyclopediaClassifyPrompt(knownCategories = []) {
3585
+ function buildEncyclopediaClassifyPrompt(knownCategories = [], knownTopics = []) {
3535
3586
  return buildStructuredPrompt(EncyclopediaClassifySchema, {
3536
3587
  before: "OUTPUT FORMAT \u2014 output ONLY valid JSON matching this exact schema:",
3537
3588
  after: `
3538
3589
  YOUR TASK \u2014 label one stored source document with its broad category and the topic it is about:
3539
3590
  - The document may be a fetched web page, an uploaded file, or a search-result snippet. Classify by its CONTENT, never by its source shape \u2014 a file has no domain, and that must not matter.
3540
3591
  - category: ONE broad lowercase PLURAL family noun (e.g. "games", "work", "health", "finance") that groups the topic into a family. Never a specific entity, product, company, or title.
3541
- - topic: the narrow subject the document is about (e.g. "wuthering waves", "q3 budget", "rust borrow checker"). A short, specific, reusable label \u2014 not a sentence, not a URL, not a filename.
3542
- ${buildVocabularySection(knownCategories)}
3592
+ - topic: the narrow subject the document is about (e.g. "wuthering waves", "q3 budget", "rust borrow checker"). A short, specific, reusable label \u2014 not a sentence, not a URL, not a filename, never a domain or a site name.
3593
+ - When the document is about a KNOWN TOPIC, output that label VERBATIM \u2014 prefer "neverness to everness" over minting a variant like "nte".
3594
+ ${buildVocabularySection(knownCategories, knownTopics)}
3543
3595
  RULES:
3544
3596
  - Return ONLY a single valid JSON object matching the exact schema above.
3545
3597
  - No markdown code fences, no explanations, preamble, or postscript.
@@ -3565,6 +3617,12 @@ NOT a contradiction:
3565
3617
  - different subjects or unrelated facts
3566
3618
  - a more specific statement that does not actually conflict with a general one
3567
3619
 
3620
+ METADATA \u2014 each record may show "(subject: \u2026; category: \u2026; kind: \u2026; stability: \u2026)":
3621
+ - subject: a contradiction requires the SAME subject. Candidates about a different subject are never conflicts, however similar they read.
3622
+ - stability: "volatile" records describe a current state \u2014 a NEWER volatile statement supersedes the older one (name the newer as winner). "durable" statements rarely supersede each other: when neither side is clearly right, omit winnerId so the conflict stays open.
3623
+ - kind: polarity flips are the expected contradiction for "preference" and "relationship" records. For "fact", "project", "contact" and "possession" records a conflict means one statement is outdated or wrong \u2014 prefer the newer statement when the dates say which is current.
3624
+ - category: conflicts almost always live inside one category family; treat a candidate from a clearly different family skeptically, but never dismiss it on category alone.
3625
+
3568
3626
  Respond with JSON only:
3569
3627
  {
3570
3628
  "contradicts": boolean,
@@ -3578,7 +3636,7 @@ Rules:
3578
3636
  - Never invent a conflictingId or winnerId that is not in the input.`;
3579
3637
  function buildFrictionPrompt(input) {
3580
3638
  const lines = [];
3581
- lines.push(`RECORD (id: ${input.record.id}):`);
3639
+ lines.push(`RECORD (id: ${input.record.id})${formatFactMetadata(input.record)}:`);
3582
3640
  lines.push(input.record.text);
3583
3641
  if (input.record.createdAt) {
3584
3642
  lines.push(`(created: ${input.record.createdAt})`);
@@ -3589,7 +3647,7 @@ function buildFrictionPrompt(input) {
3589
3647
  lines.push("(none)");
3590
3648
  } else {
3591
3649
  for (const candidate of input.candidates) {
3592
- lines.push(`- id: ${candidate.id}`);
3650
+ lines.push(`- id: ${candidate.id}${formatFactMetadata(candidate)}`);
3593
3651
  lines.push(` text: ${candidate.text}`);
3594
3652
  if (candidate.createdAt) {
3595
3653
  lines.push(` created: ${candidate.createdAt}`);
@@ -3640,14 +3698,19 @@ Decide exactly one verdict:
3640
3698
  POLARITY RULE (ABSOLUTE): a flip or addition of negation ("allergic" vs "not allergic", "likes" vs "dislikes") is NEW information \u2014 it is never "redundant"; if it corrects a stored statement, merge with the corrected statement.
3641
3699
  PROVENANCE RULE (ABSOLUTE): a statement the user made outweighs assistant-derived wording \u2014 mergedText preserves the user's claim; when candidate origins conflict on facts, the user's version wins.
3642
3700
 
3701
+ METADATA \u2014 each record may show "(subject: \u2026; category: \u2026; kind: \u2026; stability: \u2026)":
3702
+ - subject: merge requires the SAME subject; facts about different subjects are always "keep".
3703
+ - kind: two "contact" or "state" records about the same subject usually merge into the fuller one. Two "decision" or "preference" records with different content are different facts \u2014 keep both.
3704
+ - stability: a newer "volatile" state normally replaces the older record via merge.
3705
+
3643
3706
  OUTPUT FORMAT \u2014 output ONLY valid JSON:`,
3644
3707
  after: 'No markdown fences, no explanations. mergedText is required with verdict "merge" and omitted otherwise.'
3645
3708
  });
3646
3709
  function buildConsolidatePrompt(params) {
3647
- const candidates = params.candidates.length ? params.candidates.map((c) => `- ${formatProvenanceLine(c)}`).join("\n") : "(none)";
3710
+ const candidates = params.candidates.length ? params.candidates.map((c) => `- ${formatProvenanceLine(c)}${formatFactMetadata(c)}`).join("\n") : "(none)";
3648
3711
  return [
3649
3712
  `NEW FACT:
3650
- - ${formatProvenanceLine(params.newFact)}`,
3713
+ - ${formatProvenanceLine(params.newFact)}${formatFactMetadata(params.newFact)}`,
3651
3714
  `EXISTING CANDIDATES:
3652
3715
  ${candidates}`,
3653
3716
  "Decide exactly one verdict (keep / redundant / merge) and output ONLY the JSON object."
@@ -3809,6 +3872,21 @@ YOUR TASK \u2014 decide what is worth remembering:
3809
3872
  - Facts must be self-contained \u2014 no "this"/"that" references; write them as third-person statements.
3810
3873
  - Storage mechanics: each fact is embedded as a whole and matched sentence-by-sentence at recall time (multi-variant retrieval). One dense sentence is fine \u2014 put the subject up front ("User prefers single-line if statements", not "They prefer that style").
3811
3874
  - Skip transient content: greetings, small talk, one-off instructions, filler \u2014 anything with no future recall value. When in doubt about whether a detail is durable, keep it: a durable detail is cheaper to store than to lose.
3875
+
3876
+ FACT METADATA \u2014 every fact object carries the fields the maintenance passes (consolidate/reflect/conviction) interpret:
3877
+ - text: the statement itself.
3878
+ - subject (optional): the lowercase entity the fact is about \u2014 "user" by default, or a person, product, or project name ("sam", "stellar blade", "payments service"). Maintenance only ever compares facts about the SAME subject, so name it whenever the fact is about a specific entity.
3879
+ - category (optional): ONE broad lowercase PLURAL family label for this fact, reusing the known vocabulary \u2014 inherits the turn-side category when omitted.
3880
+ - kind (required): what kind of durable thing it is:
3881
+ - preference \u2014 likes, dislikes, wants, style choices
3882
+ - decision \u2014 a choice that was made (adoptions, migrations, purchases committed to)
3883
+ - state \u2014 the CURRENT, changeable situation (lives in X, uses version Y, runs Z) \u2014 newer statements supersede these
3884
+ - contact \u2014 contact details of a person (phone, email, address)
3885
+ - project \u2014 facts about ongoing work or projects
3886
+ - possession \u2014 things owned
3887
+ - relationship \u2014 how people relate ("sam is the user's brother")
3888
+ - fact \u2014 any other durable fact
3889
+ - stability (required): "durable" \u2014 a long-term truth that should survive until contradicted (decisions, traits, history) \u2014 or "volatile" \u2014 a current state a newer statement is EXPECTED to replace (location, tooling, versions). When in doubt, choose durable.
3812
3890
  - Tags: 2 to 6 stable, reusable, lowercase topic labels describing what the text is about (e.g. "work", "rust", "contacts", "amd", "stellar blade"). Tags are NARROW and specific \u2014 entity names, product names, game titles. They are the vocabulary for topic-filtered recall later.
3813
3891
  - Category: ONE broad lowercase PLURAL family noun for the whole text (e.g. "stocks", "pets", "games", "health") that groups the narrow tags into one topic family. A category is NEVER a specific entity, product, company, or game title: "amd" belongs under "stocks"; "stellar blade" and "stellar blade blood rain" belong under "games". Always include it when facts are emitted; omit it when nothing durable is found.
3814
3892
  - If nothing durable is found, return an empty facts array; tags may still label the topic when useful.
@@ -3833,8 +3911,8 @@ function buildExtractionCorrectionPrompt(error) {
3833
3911
  Error: ${error}
3834
3912
 
3835
3913
  Return ONLY a single valid JSON object matching the extraction schema exactly:
3836
- {"facts": [string, ...], "tags": [string, ...], "category": "string"}
3837
- All object keys must be quoted with double quotes.
3914
+ {"facts": [{"text": "string", "subject": "string", "category": "string", "kind": "preference|decision|state|contact|project|possession|relationship|fact", "stability": "durable|volatile"}, ...], "tags": [string, ...], "category": "string"}
3915
+ All object keys must be quoted with double quotes. "subject" and the per-fact "category" are optional; "kind" and "stability" are required on every fact.
3838
3916
  Do not add markdown code fences, explanations, or extra text.
3839
3917
 
3840
3918
  FINAL REMINDER:
@@ -3868,4 +3946,4 @@ Compose the response from the snippets below. Include every snippet you can subs
3868
3946
  ${parts.join("\n\n")}`;
3869
3947
  }
3870
3948
 
3871
- export { BELIEF_INSTRUCTIONS, COMMONMARK_FORMAT, COMPARE_INSTRUCTIONS, COMPARE_VISUAL_INSTRUCTIONS, DEFAULT_VARIANT_ID, DESCRIBE_CONCISE_INSTRUCTIONS, DESCRIBE_DETAILED_INSTRUCTIONS, DESCRIBE_INSTRUCTIONS, FINAL_REMINDER, FRICTION_INSTRUCTIONS, HISTORY_URLS_RULES, IMAGELIST_INSTRUCTIONS, IMAGE_TASK_RULE, INTERNATIONAL_COVERAGE_INSTRUCTIONS, ITEM_SHAPES, JSON_RULES, MEDIA_COUNTS, MEDIA_RULES, MEMORY_CLUSTER_INSTRUCTIONS, MEMORY_CONSOLIDATE_INSTRUCTIONS, MEMORY_PROFILE_INSTRUCTIONS, MEMORY_WRITE_INSTRUCTIONS, MERGE_MEDIA_RULES, MERGE_TOPIC_RULE, MULTIMODAL_POLICY, NOISE_RULES, OCR_INSTRUCTIONS, OCR_VERBATIM_INSTRUCTIONS, PRECEDENCE_RULES, PRODUCT_INSTRUCTIONS, RESPONSE_LAYOUTS, SECURITY_RULES, SHOPLIST_INSTRUCTIONS, SNIPPET_TEMPLATE_PRESETS, SOURCE_TRUTH_RULES, SOURCE_VOICE_RULES, STOCKMARKET_ITEM_INSTRUCTIONS, STOCKMARKET_LIST_INSTRUCTIONS, SUMMARY_INSTRUCTIONS, TEMPLATE_VARIANTS, TEXT_CODING_INSTRUCTIONS, TEXT_FAMILIARITY_INSTRUCTIONS, TEXT_INSTRUCTIONS, TOOL_RESULTS_RULES, VIDEOLIST_INSTRUCTIONS, articlePreset, assessmentListsSnippet, authorMetaSnippet, bodyBriefSnippet, bodyExtensiveSnippet, buildBaseSystemPrompt, buildBeliefSynthesisPrompt, buildClarificationTranslationSystemPrompt, buildClarificationTranslationUserPrompt, buildClassifyTranscript, buildClusterSummaryPrompt, buildConsolidatePrompt, buildContentSystemPrompt, buildContextSummarySection, buildCorrectionPrompt, buildEncyclopediaClassifyPrompt, buildEnrichPrompt, buildExecuteLanguageInstruction, buildExtractionCorrectionPrompt, buildExtractionPrompt, buildFrictionPrompt, buildImageExecutePrompt, buildIntentCorrectionPrompt, buildIntentSelectionPrompt, buildLanguageRule, buildLayoutInstruction, buildLocalizationRule, buildMemoryProbeSection, buildMemoryProfilePrompt, buildMemoryWritePrompt, buildMergeDirective, buildMissingToolsPrompt, buildOutputContract, buildSnippetInstruction, buildSourcePolicyPrompt, buildStockmarketNote, buildStructuredJsonPrompt, buildStructuredPrompt, buildToolExecutePrompt, buildVocabularySection, bylineDatelineSnippet, cardsSnippet, comparisonSchema, comparisonSnippet, composeSnippetKeys, composeSnippetSchema, conclusionSnippet, evaluationPreset, formatCurrentTimestamp, formatProvenanceLine, formatToolAvailabilityCatalog, formatVariantCatalog, gallerySnippet, getSnippetTemplateKeys, getSnippetTemplateSchema, headerArticleSnippet, headerNewsSnippet, heroMediaSnippet, internationalCoverageSnippet, introductionSnippet, isSnippetTemplate, keyFindingsSnippet, languageCorrectionPrompt, leadSnippet, mergePreset, mergedEvaluationsSnippet, newsKeyFindingsSnippet, newsPreset, quoteSnippet, reasoningSnippet, relatedStoriesSnippet, resolveLanguageName, resolveVariantInstructions, responseLayoutSchema, sourcesSnippet, subjectSchema, subjectsSnippet, summarySnippet, verdictSpineSnippet, videoGallerySnippet };
3949
+ export { COMMONMARK_FORMAT, COMPARE_INSTRUCTIONS, COMPARE_VISUAL_INSTRUCTIONS, CONVICTION_INSTRUCTIONS, DEFAULT_VARIANT_ID, DESCRIBE_CONCISE_INSTRUCTIONS, DESCRIBE_DETAILED_INSTRUCTIONS, DESCRIBE_INSTRUCTIONS, FINAL_REMINDER, FRICTION_INSTRUCTIONS, HISTORY_URLS_RULES, IMAGELIST_INSTRUCTIONS, IMAGE_TASK_RULE, INTERNATIONAL_COVERAGE_INSTRUCTIONS, ITEM_SHAPES, JSON_RULES, MEDIA_COUNTS, MEDIA_RULES, MEMORY_CLUSTER_INSTRUCTIONS, MEMORY_CONSOLIDATE_INSTRUCTIONS, MEMORY_PROFILE_INSTRUCTIONS, MEMORY_WRITE_INSTRUCTIONS, MERGE_MEDIA_RULES, MERGE_TOPIC_RULE, MULTIMODAL_POLICY, NOISE_RULES, OCR_INSTRUCTIONS, OCR_VERBATIM_INSTRUCTIONS, PRECEDENCE_RULES, PRODUCT_INSTRUCTIONS, RESPONSE_LAYOUTS, SECURITY_RULES, SHOPLIST_INSTRUCTIONS, SNIPPET_TEMPLATE_PRESETS, SOURCE_TRUTH_RULES, SOURCE_VOICE_RULES, STOCKMARKET_ITEM_INSTRUCTIONS, STOCKMARKET_LIST_INSTRUCTIONS, SUMMARY_INSTRUCTIONS, TEMPLATE_VARIANTS, TEXT_CODING_INSTRUCTIONS, TEXT_FAMILIARITY_INSTRUCTIONS, TEXT_INSTRUCTIONS, TOOL_RESULTS_RULES, VIDEOLIST_INSTRUCTIONS, articlePreset, assessmentListsSnippet, authorMetaSnippet, bodyBriefSnippet, bodyExtensiveSnippet, buildBaseSystemPrompt, buildClarificationTranslationSystemPrompt, buildClarificationTranslationUserPrompt, buildClassifyTranscript, buildClusterSummaryPrompt, buildConsolidatePrompt, buildContentSystemPrompt, buildContextSummarySection, buildConvictionSynthesisPrompt, buildCorrectionPrompt, buildEncyclopediaClassifyPrompt, buildEnrichPrompt, buildExecuteLanguageInstruction, buildExtractionCorrectionPrompt, buildExtractionPrompt, buildFrictionPrompt, buildImageExecutePrompt, buildIntentCorrectionPrompt, buildIntentSelectionPrompt, buildLanguageRule, buildLayoutInstruction, buildLocalizationRule, buildMemoryProbeSection, buildMemoryProfilePrompt, buildMemoryWritePrompt, buildMergeDirective, buildMissingToolsPrompt, buildOutputContract, buildSnippetInstruction, buildSourcePolicyPrompt, buildStockmarketNote, buildStructuredJsonPrompt, buildStructuredPrompt, buildToolExecutePrompt, buildVocabularySection, bylineDatelineSnippet, cardsSnippet, comparisonSchema, comparisonSnippet, composeSnippetKeys, composeSnippetSchema, conclusionSnippet, evaluationPreset, formatCurrentTimestamp, formatProvenanceLine, formatToolAvailabilityCatalog, formatVariantCatalog, gallerySnippet, getSnippetTemplateKeys, getSnippetTemplateSchema, headerArticleSnippet, headerNewsSnippet, heroMediaSnippet, internationalCoverageSnippet, introductionSnippet, isSnippetTemplate, keyFindingsSnippet, languageCorrectionPrompt, leadSnippet, mergePreset, mergedEvaluationsSnippet, newsKeyFindingsSnippet, newsPreset, quoteSnippet, reasoningSnippet, relatedStoriesSnippet, resolveLanguageName, resolveVariantInstructions, responseLayoutSchema, sourcesSnippet, subjectSchema, subjectsSnippet, summarySnippet, verdictSpineSnippet, videoGallerySnippet };
@@ -110,8 +110,48 @@ declare const MemoryEnrichmentSchema: z.ZodObject<{
110
110
  }, z.core.$strip>;
111
111
  type MemoryEnrichment = z.infer<typeof MemoryEnrichmentSchema>;
112
112
 
113
+ declare const FACT_KINDS: readonly ["preference", "decision", "state", "contact", "project", "possession", "relationship", "fact"];
114
+ declare const FACT_STABILITIES: readonly ["durable", "volatile"];
115
+ declare const ExtractedFactSchema: z.ZodObject<{
116
+ text: z.ZodString;
117
+ subject: z.ZodOptional<z.ZodString>;
118
+ category: z.ZodOptional<z.ZodString>;
119
+ kind: z.ZodEnum<{
120
+ preference: "preference";
121
+ decision: "decision";
122
+ state: "state";
123
+ contact: "contact";
124
+ project: "project";
125
+ possession: "possession";
126
+ relationship: "relationship";
127
+ fact: "fact";
128
+ }>;
129
+ stability: z.ZodEnum<{
130
+ durable: "durable";
131
+ volatile: "volatile";
132
+ }>;
133
+ }, z.core.$strip>;
134
+ type ExtractedFact = z.infer<typeof ExtractedFactSchema>;
113
135
  declare const ExtractionSchema: z.ZodObject<{
114
- facts: z.ZodArray<z.ZodString>;
136
+ facts: z.ZodArray<z.ZodObject<{
137
+ text: z.ZodString;
138
+ subject: z.ZodOptional<z.ZodString>;
139
+ category: z.ZodOptional<z.ZodString>;
140
+ kind: z.ZodEnum<{
141
+ preference: "preference";
142
+ decision: "decision";
143
+ state: "state";
144
+ contact: "contact";
145
+ project: "project";
146
+ possession: "possession";
147
+ relationship: "relationship";
148
+ fact: "fact";
149
+ }>;
150
+ stability: z.ZodEnum<{
151
+ durable: "durable";
152
+ volatile: "volatile";
153
+ }>;
154
+ }, z.core.$strip>>;
115
155
  tags: z.ZodArray<z.ZodString>;
116
156
  category: z.ZodOptional<z.ZodString>;
117
157
  }, z.core.$strip>;
@@ -833,4 +873,4 @@ declare const videolistSchema: z.ZodObject<{
833
873
  }, z.core.$strip>>>;
834
874
  }, z.core.$strip>;
835
875
 
836
- export { BLOCKED_IMAGE_HOSTS, BLOCKED_URL_HOSTS, COGNITION_LIMIT_DEFAULT, COGNITION_LIMIT_MAX, COGNITION_LIMIT_MIN, COGNITION_PURGE_BATCH, CONVICTION_TAGS, CONVICTION_TEXT_LIMIT, type ConsolidationVerdict, ConsolidationVerdictSchema, DEFAULT_MEDIA_COUNT, EMBEDDABLE_VIDEO_PROVIDER_CLAUSE, EMBEDDABLE_VIDEO_PROVIDER_LABELS, EPISODE_PROBE_LIMIT_DEFAULT, EPISODE_PROBE_LIMIT_MIN, EPISODE_RECENCY_MIDPOINT_DEFAULT, EPISODE_RECENCY_MIDPOINT_MAX, EPISODE_RECENCY_MIDPOINT_MIN, EPISODE_RECENCY_SCALE_SECONDS_DEFAULT, EPISODE_RECENCY_SCALE_SECONDS_MAX, EPISODE_RECENCY_SCALE_SECONDS_MIN, EPISODE_RECENCY_WEIGHT_DEFAULT, EPISODE_RECENCY_WEIGHT_MAX, EPISODE_RECENCY_WEIGHT_MIN, EPISODE_SCORE_THRESHOLD_DEFAULT, EPISODE_SCORE_THRESHOLD_MAX, EPISODE_SCORE_THRESHOLD_MIN, EPISODE_TAGS, EPISODE_TEXT_LIMIT, type EncyclopediaClassification, EncyclopediaClassifySchema, type EncyclopediaSearchResult, type EncyclopediaSelectInput, type EncyclopediaSelectResult, type EncyclopediaSelectedChunk, type EncyclopediaSourceDocument, ExtractionSchema, HERO_VIDEO_TITLE_ISSUE, INSIGHTS_MAX_PER_TURN, INSIGHT_TAGS, INSIGHT_TEXT_LIMIT, MORE_MEDIA_COUNT, type MemoryClusterSummary, MemoryClusterSummarySchema, type MemoryCognitionProfile, type MemoryEnrichment, MemoryEnrichmentSchema, type MemoryExtraction, type MemoryProfileInsight, type MemoryProfileResponse, NON_PAGE_EXTENSIONS, cardSchema, categorizeTools, clampCognitionLimit, clampEpisodeProbeLimit, clampEpisodeRecencyMidpoint, clampEpisodeRecencyScaleSeconds, clampEpisodeRecencyWeight, clampEpisodeScoreThreshold, compareSchema, createTextItemSchema, deriveSchemaKeys, describeSchema, discardedReferenceSchema, formatZodIssues, galleryItemSchema, hasBlockedImageHost, heroVideoHasTitle, imagelistSchema, internationalCoverageSchema, isAllFieldsNullWipe, isPrivateOrLocalhost, isTrustedImageUrl, isTrustedUrl, markerSchema, memoryProfileResponseSchema, mergeCognitionProfiles, normalizeInsightPath, ocrSchema, parseStoredProfile, productSchema, referenceGalleryItemSchema, referenceLineSchema, relatedStorySchema, safeMediaUrl, safeMediaUrlOrEmpty, safeUrl, safeVideoUrl, safeVideoUrlOrEmpty, shoplistSchema, sourceSchema, stockmarketItemSchema, stockmarketListSchema, summarySchema, videoGalleryItemSchema, videolistSchema };
876
+ export { BLOCKED_IMAGE_HOSTS, BLOCKED_URL_HOSTS, COGNITION_LIMIT_DEFAULT, COGNITION_LIMIT_MAX, COGNITION_LIMIT_MIN, COGNITION_PURGE_BATCH, CONVICTION_TAGS, CONVICTION_TEXT_LIMIT, type ConsolidationVerdict, ConsolidationVerdictSchema, DEFAULT_MEDIA_COUNT, EMBEDDABLE_VIDEO_PROVIDER_CLAUSE, EMBEDDABLE_VIDEO_PROVIDER_LABELS, EPISODE_PROBE_LIMIT_DEFAULT, EPISODE_PROBE_LIMIT_MIN, EPISODE_RECENCY_MIDPOINT_DEFAULT, EPISODE_RECENCY_MIDPOINT_MAX, EPISODE_RECENCY_MIDPOINT_MIN, EPISODE_RECENCY_SCALE_SECONDS_DEFAULT, EPISODE_RECENCY_SCALE_SECONDS_MAX, EPISODE_RECENCY_SCALE_SECONDS_MIN, EPISODE_RECENCY_WEIGHT_DEFAULT, EPISODE_RECENCY_WEIGHT_MAX, EPISODE_RECENCY_WEIGHT_MIN, EPISODE_SCORE_THRESHOLD_DEFAULT, EPISODE_SCORE_THRESHOLD_MAX, EPISODE_SCORE_THRESHOLD_MIN, EPISODE_TAGS, EPISODE_TEXT_LIMIT, type EncyclopediaClassification, EncyclopediaClassifySchema, type EncyclopediaSearchResult, type EncyclopediaSelectInput, type EncyclopediaSelectResult, type EncyclopediaSelectedChunk, type EncyclopediaSourceDocument, type ExtractedFact, ExtractedFactSchema, ExtractionSchema, FACT_KINDS, FACT_STABILITIES, HERO_VIDEO_TITLE_ISSUE, INSIGHTS_MAX_PER_TURN, INSIGHT_TAGS, INSIGHT_TEXT_LIMIT, MORE_MEDIA_COUNT, type MemoryClusterSummary, MemoryClusterSummarySchema, type MemoryCognitionProfile, type MemoryEnrichment, MemoryEnrichmentSchema, type MemoryExtraction, type MemoryProfileInsight, type MemoryProfileResponse, NON_PAGE_EXTENSIONS, cardSchema, categorizeTools, clampCognitionLimit, clampEpisodeProbeLimit, clampEpisodeRecencyMidpoint, clampEpisodeRecencyScaleSeconds, clampEpisodeRecencyWeight, clampEpisodeScoreThreshold, compareSchema, createTextItemSchema, deriveSchemaKeys, describeSchema, discardedReferenceSchema, formatZodIssues, galleryItemSchema, hasBlockedImageHost, heroVideoHasTitle, imagelistSchema, internationalCoverageSchema, isAllFieldsNullWipe, isPrivateOrLocalhost, isTrustedImageUrl, isTrustedUrl, markerSchema, memoryProfileResponseSchema, mergeCognitionProfiles, normalizeInsightPath, ocrSchema, parseStoredProfile, productSchema, referenceGalleryItemSchema, referenceLineSchema, relatedStorySchema, safeMediaUrl, safeMediaUrlOrEmpty, safeUrl, safeVideoUrl, safeVideoUrlOrEmpty, shoplistSchema, sourceSchema, stockmarketItemSchema, stockmarketListSchema, summarySchema, videoGalleryItemSchema, videolistSchema };
@@ -513,13 +513,48 @@ var MemoryEnrichmentSchema = z.object({
513
513
  */
514
514
  tags: z.array(z.string())
515
515
  });
516
+ var FACT_KINDS = [
517
+ "preference",
518
+ "decision",
519
+ "state",
520
+ "contact",
521
+ "project",
522
+ "possession",
523
+ "relationship",
524
+ "fact"
525
+ ];
526
+ var FACT_STABILITIES = ["durable", "volatile"];
527
+ var ExtractedFactSchema = z.object({
528
+ /**
529
+ * The self-contained durable statement — third person, subject up front,
530
+ * no "this"/"that" references.
531
+ */
532
+ text: z.string(),
533
+ /**
534
+ * The lowercase entity the fact is about (default `user`; a person,
535
+ * product, or project name). Maintenance adjudication only ever compares
536
+ * facts about the SAME subject.
537
+ */
538
+ subject: z.string().optional(),
539
+ /**
540
+ * One broad lowercase PLURAL family label for THIS fact (e.g. `stocks`,
541
+ * `pets`, `games`) — inherits the turn-side category when omitted. Never
542
+ * a specific entity, product, company, or game title.
543
+ */
544
+ category: z.string().optional(),
545
+ /** What kind of durable thing this is (see FACT_KINDS). */
546
+ kind: z.enum(FACT_KINDS),
547
+ /** Whether a newer statement is expected to replace this one (see FACT_STABILITIES). */
548
+ stability: z.enum(FACT_STABILITIES)
549
+ });
516
550
  var ExtractionSchema = z.object({
517
551
  /**
518
552
  * Durable, self-contained facts worth remembering in a later, unrelated
519
- * conversation (preferences, decisions, contact details, project facts).
520
- * Empty when nothing in the text is worth remembering.
553
+ * conversation (preferences, decisions, contact details, project facts),
554
+ * each carrying its maintenance metadata (subject, category, kind,
555
+ * stability). Empty when nothing in the text is worth remembering.
521
556
  */
522
- facts: z.array(z.string()),
557
+ facts: z.array(ExtractedFactSchema),
523
558
  /**
524
559
  * 2–6 stable, reusable lowercase topic labels describing the text; the open
525
560
  * vocabulary that powers topic-filtered recall. Tags are NARROW and
@@ -531,9 +566,10 @@ var ExtractionSchema = z.object({
531
566
  * One broad lowercase PLURAL family label for the whole turn-side (e.g.
532
567
  * `stocks`, `pets`, `games`) — groups the narrow tags into one topic family
533
568
  * for the constellation's community tier and the relink job's per-category
534
- * passes. Never a specific entity, product, company, or game title: `amd`
535
- * belongs under `stocks`; `stellar blade` belongs under `games`. Optional:
536
- * a turn with nothing durable may omit it.
569
+ * passes, and backstops facts that omit their own `category`. Never a
570
+ * specific entity, product, company, or game title: `amd` belongs under
571
+ * `stocks`; `stellar blade` belongs under `games`. Optional: a turn with
572
+ * nothing durable may omit it.
537
573
  */
538
574
  category: z.string().optional()
539
575
  });
@@ -1117,4 +1153,4 @@ var videolistSchema = z.object({
1117
1153
  internationalCoverage: internationalCoverageSchema.optional()
1118
1154
  });
1119
1155
 
1120
- export { BLOCKED_IMAGE_HOSTS, BLOCKED_URL_HOSTS, BROWSER_TOOL_NAMES, COGNITION_LIMIT_DEFAULT, COGNITION_LIMIT_MAX, COGNITION_LIMIT_MIN, COGNITION_PURGE_BATCH, CONVICTION_TAGS, CONVICTION_TEXT_LIMIT, ConsolidationVerdictSchema, DEFAULT_MEDIA_COUNT, DEFAULT_VARIANT_ID, EMBEDDABLE_VIDEO_PROVIDER_CLAUSE, EMBEDDABLE_VIDEO_PROVIDER_LABELS, EPISODE_PROBE_LIMIT_DEFAULT, EPISODE_PROBE_LIMIT_MIN, EPISODE_RECENCY_MIDPOINT_DEFAULT, EPISODE_RECENCY_MIDPOINT_MAX, EPISODE_RECENCY_MIDPOINT_MIN, EPISODE_RECENCY_SCALE_SECONDS_DEFAULT, EPISODE_RECENCY_SCALE_SECONDS_MAX, EPISODE_RECENCY_SCALE_SECONDS_MIN, EPISODE_RECENCY_WEIGHT_DEFAULT, EPISODE_RECENCY_WEIGHT_MAX, EPISODE_RECENCY_WEIGHT_MIN, EPISODE_SCORE_THRESHOLD_DEFAULT, EPISODE_SCORE_THRESHOLD_MAX, EPISODE_SCORE_THRESHOLD_MIN, EPISODE_TAGS, EPISODE_TEXT_LIMIT, EncyclopediaClassifySchema, ExtractionSchema, HERO_VIDEO_TITLE_ISSUE, IMAGE_TASK_TEMPLATES, INSIGHTS_MAX_PER_TURN, INSIGHT_TAGS, INSIGHT_TEXT_LIMIT, IntentSchema, MEMORY_TOOL_NAMES, MORE_MEDIA_COUNT, MemoryClusterSummarySchema, MemoryEnrichmentSchema, NON_PAGE_EXTENSIONS, TOOL_DESCRIPTIONS, TOOL_NAMES, VARIANT_NAMES, cardSchema, categorizeTools, clampCognitionLimit, clampEpisodeProbeLimit, clampEpisodeRecencyMidpoint, clampEpisodeRecencyScaleSeconds, clampEpisodeRecencyWeight, clampEpisodeScoreThreshold, compareSchema, createTextItemSchema, deriveSchemaKeys, describeSchema, discardedReferenceSchema, formatZodIssues, formatZodShape, galleryItemSchema, hasBlockedImageHost, heroVideoHasTitle, imagelistSchema, internationalCoverageSchema, isAllFieldsNullWipe, isImageTaskTemplate, isPrivateOrLocalhost, isTrustedImageUrl, isTrustedUrl, markerSchema, memoryProfileResponseSchema, mergeCognitionProfiles, normalizeInsightPath, ocrSchema, parseStoredProfile, productSchema, referenceGalleryItemSchema, referenceLineSchema, relatedStorySchema, safeMediaUrl, safeMediaUrlOrEmpty, safeUrl, safeVideoUrl, safeVideoUrlOrEmpty, shoplistSchema, sourceSchema, stockmarketItemSchema, stockmarketListSchema, summarySchema, videoGalleryItemSchema, videolistSchema };
1156
+ export { BLOCKED_IMAGE_HOSTS, BLOCKED_URL_HOSTS, BROWSER_TOOL_NAMES, COGNITION_LIMIT_DEFAULT, COGNITION_LIMIT_MAX, COGNITION_LIMIT_MIN, COGNITION_PURGE_BATCH, CONVICTION_TAGS, CONVICTION_TEXT_LIMIT, ConsolidationVerdictSchema, DEFAULT_MEDIA_COUNT, DEFAULT_VARIANT_ID, EMBEDDABLE_VIDEO_PROVIDER_CLAUSE, EMBEDDABLE_VIDEO_PROVIDER_LABELS, EPISODE_PROBE_LIMIT_DEFAULT, EPISODE_PROBE_LIMIT_MIN, EPISODE_RECENCY_MIDPOINT_DEFAULT, EPISODE_RECENCY_MIDPOINT_MAX, EPISODE_RECENCY_MIDPOINT_MIN, EPISODE_RECENCY_SCALE_SECONDS_DEFAULT, EPISODE_RECENCY_SCALE_SECONDS_MAX, EPISODE_RECENCY_SCALE_SECONDS_MIN, EPISODE_RECENCY_WEIGHT_DEFAULT, EPISODE_RECENCY_WEIGHT_MAX, EPISODE_RECENCY_WEIGHT_MIN, EPISODE_SCORE_THRESHOLD_DEFAULT, EPISODE_SCORE_THRESHOLD_MAX, EPISODE_SCORE_THRESHOLD_MIN, EPISODE_TAGS, EPISODE_TEXT_LIMIT, EncyclopediaClassifySchema, ExtractedFactSchema, ExtractionSchema, FACT_KINDS, FACT_STABILITIES, HERO_VIDEO_TITLE_ISSUE, IMAGE_TASK_TEMPLATES, INSIGHTS_MAX_PER_TURN, INSIGHT_TAGS, INSIGHT_TEXT_LIMIT, IntentSchema, MEMORY_TOOL_NAMES, MORE_MEDIA_COUNT, MemoryClusterSummarySchema, MemoryEnrichmentSchema, NON_PAGE_EXTENSIONS, TOOL_DESCRIPTIONS, TOOL_NAMES, VARIANT_NAMES, cardSchema, categorizeTools, clampCognitionLimit, clampEpisodeProbeLimit, clampEpisodeRecencyMidpoint, clampEpisodeRecencyScaleSeconds, clampEpisodeRecencyWeight, clampEpisodeScoreThreshold, compareSchema, createTextItemSchema, deriveSchemaKeys, describeSchema, discardedReferenceSchema, formatZodIssues, formatZodShape, galleryItemSchema, hasBlockedImageHost, heroVideoHasTitle, imagelistSchema, internationalCoverageSchema, isAllFieldsNullWipe, isImageTaskTemplate, isPrivateOrLocalhost, isTrustedImageUrl, isTrustedUrl, markerSchema, memoryProfileResponseSchema, mergeCognitionProfiles, normalizeInsightPath, ocrSchema, parseStoredProfile, productSchema, referenceGalleryItemSchema, referenceLineSchema, relatedStorySchema, safeMediaUrl, safeMediaUrlOrEmpty, safeUrl, safeVideoUrl, safeVideoUrlOrEmpty, shoplistSchema, sourceSchema, stockmarketItemSchema, stockmarketListSchema, summarySchema, videoGalleryItemSchema, videolistSchema };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@triplef/agent",
3
3
  "description": "tripleF (3F) agent domain — structured-output schemas, prompt builders, and model tools shared across the apps.",
4
- "version": "0.1.16",
4
+ "version": "0.1.17",
5
5
  "packageManager": "pnpm@11.25.0",
6
6
  "license": "MIT",
7
7
  "type": "module",