@versini/sassysaint-common 4.40.1 → 4.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -266,6 +266,18 @@ export declare const getModelsGroupedByProvider: (models: string[]) => Map<strin
266
266
  */
267
267
  export declare const getProvidersFromModels: (models: string[]) => Array<typeof PROVIDER_OPENAI | typeof PROVIDER_ANTHROPIC | typeof PROVIDER_GOOGLE>;
268
268
 
269
+ /**
270
+ * "Hard" categories — durable, high-trust attributes of the user (name/role,
271
+ * demographics/family, requirements, profession) that the system has always
272
+ * captured well. These auto-persist. Every other category is "soft" (vague
273
+ * preferences, one-off interests, behavioral asides) and only persists on an
274
+ * explicit "remember this" or after being seen in enough distinct chats — the
275
+ * precision-first stance (see `isPersistable`). Subset of {@link MEMORY_CATEGORIES}.
276
+ */
277
+ export declare const HARD_CATEGORIES: readonly ["identity", "bio", "constraint", "professional"];
278
+
279
+ export declare type HardCategory = (typeof HARD_CATEGORIES)[number];
280
+
269
281
  /**
270
282
  * Checks if the user has multiple models available for at least one provider.
271
283
  * This function is used to determine if the nested model selection feature
@@ -370,6 +382,11 @@ declare interface IsEntitledOptions {
370
382
  set?: Set<string>;
371
383
  }
372
384
 
385
+ /**
386
+ * True when `category` is a hard (auto-persist) category.
387
+ */
388
+ export declare const isHardCategory: (category: string) => boolean;
389
+
373
390
  /**
374
391
  * Validates if a selected model is allowed for the user based on their current
375
392
  * plan's allowed models. This function is used to prevent users from using
@@ -439,6 +456,21 @@ export declare const MAX_OUTPUT_TOKENS = 16384;
439
456
 
440
457
  export declare const MAX_SEARCH_QUERIES = 5;
441
458
 
459
+ /**
460
+ * Canonical long-term memory category enumeration. This is the single source
461
+ * of truth for memory categories across the whole stack: the Mongoose model
462
+ * enum, every Zod extraction/consolidation schema, and the per-category
463
+ * default-expiration (TTL) map all derive from this one array.
464
+ *
465
+ * It lives in the common layer (rather than the server's DB model) on purpose:
466
+ * the memory inference / consolidation code in `common/memory/` must reference
467
+ * the enum without importing from `services/db/models`, which would invert the
468
+ * intended dependency direction (model → common, never common → model).
469
+ */
470
+ export declare const MEMORY_CATEGORIES: readonly ["preference", "identity", "constraint", "habit", "bio", "device", "location", "finance", "professional", "interest", "style", "behavior", "other"];
471
+
472
+ export declare type MemoryCategory = (typeof MEMORY_CATEGORIES)[number];
473
+
442
474
  export declare const MODEL_AUTO_RESPONDER_ANTHROPIC = "claude-sonnet-4-6";
443
475
 
444
476
  export declare const MODEL_AUTO_RESPONDER_GOOGLE = "gemini-3-flash-preview";
@@ -505,7 +537,7 @@ export declare const MODEL_GPT5_MINI = "gpt-5.4-mini";
505
537
 
506
538
  export declare const MODEL_GPT5_NANO = "gpt-5.4-nano";
507
539
 
508
- export declare const MODEL_MEMORY_INFERENCE = "gpt-5.4-nano";
540
+ export declare const MODEL_MEMORY_INFERENCE = "gpt-5.4-mini";
509
541
 
510
542
  export declare const MODEL_SEARCH_DECOMPOSER = "gpt-5.4-mini";
511
543
 
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var e,E=((e={})[e.NewChat=0]="NewChat",e[e.Prompts=1]="Prompts",e[e.Attachment=2]="Attachment",e[e.PrivateChat=3]="PrivateChat",e[e.Reasoning=4]="Reasoning",e[e.Send=5]="Send",e[e.Header=6]="Header",e[e.Provider=7]="Provider",e[e.Logo=8]="Logo",e[e.Placeholder=9]="Placeholder",e[e.Footer=10]="Footer",e);let O="system",t="user",n="assistant",r="OpenAI",o="Anthropic",i="Google",a="Summary",_="Memory",R="Perplexity",T="Mistral",A="Auto",s=r,L=[r,o,i],I="gpt-5.4",M="gpt-5.4-mini",S="gpt-5.4-nano",P="claude-opus-4-8",l="claude-sonnet-4-6",N="claude-haiku-4-5",g="gemini-3-flash-preview",D="gemini-3.1-pro-preview",d="sonar",u="sonar-pro",C="openai/gpt-oss-20b:free",c="mistral-large-latest",h="gpt-5.4-nano",p="gpt-5.4-nano",G="gpt-5.4-mini",U="text-embedding-3-small",m="gemini-3-pro-image",H=S,f=N,y=g,B=M,Y=l,F=g,v=5,w=3e4,V={[I]:"GPT-5.4",[M]:"GPT-5.4 Mini",[S]:"GPT-5.4 Nano",[P]:"Claude Opus 4.8",[l]:"Claude Sonnet 4.6",[N]:"Claude Haiku 4.5",[D]:"Gemini 3.1 Pro",[g]:"Gemini 3 Flash",[d]:"Sonar",[u]:"Sonar Pro",[m]:"Nano Banana 3 Pro",[c]:"Mistral Large"},b=[I,M,S,P,l,N,g,D,m],X=[I,M,S,P,l,D],k={[r]:[I,M,S],[o]:[P,N,l],[i]:[g,D],[R]:[d,u]},x={[r]:[O,t,n],[o]:[t,n],[a]:[t,n],[_]:[t,n],[i]:[t,n],[R]:[t,n],[T]:[t,n]},W={[o]:["claude-opus-4","claude-sonnet-4","claude-haiku-4","claude-3"],[r]:["gpt-","o3","o4"],[i]:["gemini"],[R]:["sonar"],[T]:["mistral"]},z="x-diggidy-chat-id",K="x-diggidy-chat-timestamp",Z="timestamp",j="tokenUsage",Q="Diggidy",q="sassy:basic",J="sassy:plus",$="sassy:advanced",ee={TOOL:{BARCODE:"getProductByBarcode",BUNDLESIZE:"getBundleSize",DATETIME:"getDateTime",GENERATE_IMAGE:"generateImage",IMAGES:"getImages",NUTRITION_FACTS:"getNutritionFacts",POLLUTION:"getAirPollution",WEATHER:"getWeather",URLCONTENTPARSER:"getUrlContent",MEMORIES:"getUserMemories",HUMANIZE:"humanize",WEBSEARCH:"getWebSearch",GITREPOSITORY:"getGitRepoDetails",HOTELS:"getHotelDetails",PRONUNCIATION:"getPronunciation",FRENCH_TEACHINGS:"getFrenchTeachings"},ADDON:{ATTACHMENTS:"addon:attachments",REASONING:"addon:reasoning",CODEINTERPRETER:"addon:codeinterpreter",SHARE_CHAT:"addon:share-chat"}},eE={code_interpreter:"Running code...",web_search:"Searching the web...",[ee.TOOL.WEATHER]:"Checking the weather...",[ee.TOOL.POLLUTION]:"Fetching air pollution data...",[ee.TOOL.BUNDLESIZE]:"Analyzing bundle size...",[ee.TOOL.URLCONTENTPARSER]:"Reading a webpage...",[ee.TOOL.WEBSEARCH]:"Searching the web...",[ee.TOOL.GITREPOSITORY]:"Looking up repository...",[ee.TOOL.HOTELS]:"Searching for hotels...",[ee.TOOL.NUTRITION_FACTS]:"Fetching nutrition facts...",[ee.TOOL.GENERATE_IMAGE]:"Generating image...",[ee.TOOL.BARCODE]:"Looking up product...",[ee.TOOL.PRONUNCIATION]:"Generating pronunciation...",[ee.TOOL.HUMANIZE]:"Rewriting text...",[ee.TOOL.IMAGES]:"Searching for images..."},eO="Using tools...",et=5e4,en=1e5,er=8e5;function eo(e){return e===$?er:en}let ei=16384,ea=4,e_=3,eR="context-compression-summary",eT=new Set(["OpenAI",o,"Google",T]);function eA(e){return"string"==typeof e&&eT.has(e)}let es=e=>{for(let[E,O]of Object.entries(W))if(O.some(E=>e.startsWith(E)))return E;return null},eL=e=>{if(!e||0===e.length)return[];let E=new Set;for(let O of e)for(let[e,t]of Object.entries(k))t.includes(O)&&("OpenAI"===e||e===o||"Google"===e)&&E.add(e);return L.filter(e=>E.has(e))},eI=e=>{let E=new Map;if(!e||0===e.length)return E;for(let O of e)for(let[e,t]of Object.entries(k))if(t.includes(O)){E.has(e)||E.set(e,[]),E.get(e)?.push(O);break}return E},eM=e=>{for(let E of eI(e).values())if(E.length>1)return!0;return!1},eS=(e,E)=>!!e&&!!E&&0!==E.length&&E.includes(e);function eP(e,E,O){if(!E||Array.isArray(E)&&0===E.length)return!0;let t=e instanceof Set?e:e?new Set(e):null;return!!t&&0!==t.size&&("string"==typeof E?t.has(E):O?.any===!0?E.some(e=>t.has(e)):E.every(e=>t.has(e)))}function el(e){return X.includes(e)}export{b as ALL_MODELS,L as ALL_PROVIDERS,X as ALL_REASONING_MODELS,Q as APPLICATION_NAME,W as APPROXIMATE_MODELS_PER_PROVIDER,ee as CAPABILITIES,en as CONTEXT_COMPRESSION_EMERGENCY_THRESHOLD,er as CONTEXT_COMPRESSION_EMERGENCY_THRESHOLD_PREMIUM,e_ as CONTEXT_COMPRESSION_KEEP_IMAGES,ea as CONTEXT_COMPRESSION_KEEP_RECENT,eR as CONTEXT_COMPRESSION_SUMMARY_ID,et as CONTEXT_COMPRESSION_THRESHOLD,s as DEFAULT_PROVIDER,eO as DEFAULT_TOOL_LOADING_LABEL,z as DIGGIDY_CHAT_ID_HEADER,K as DIGGIDY_CHAT_TIMESTAMP_HEADER,ei as MAX_OUTPUT_TOKENS,v as MAX_SEARCH_QUERIES,k as MODELS_PER_PROVIDER,Y as MODEL_AUTO_RESPONDER_ANTHROPIC,F as MODEL_AUTO_RESPONDER_GOOGLE,B as MODEL_AUTO_RESPONDER_OPENAI,f as MODEL_AUTO_ROUTER_ANTHROPIC,y as MODEL_AUTO_ROUTER_GOOGLE,H as MODEL_AUTO_ROUTER_OPENAI,p as MODEL_CHAT_SUMMARY,N as MODEL_CLAUDE_HAIKU,P as MODEL_CLAUDE_OPUS,l as MODEL_CLAUDE_SONNET,C as MODEL_DEV,V as MODEL_DISPLAY_NAMES,U as MODEL_EMBEDDING_TEXT,g as MODEL_GEMINI_FLASH,D as MODEL_GEMINI_PRO,m as MODEL_GENERATE_IMAGE,I as MODEL_GPT5,M as MODEL_GPT5_MINI,S as MODEL_GPT5_NANO,h as MODEL_MEMORY_INFERENCE,G as MODEL_SEARCH_DECOMPOSER,d as MODEL_SONAR,u as MODEL_SONAR_PRO,c as MODEL_TEACHER,q as PLAN_BASIC,J as PLAN_PLUS,$ as PLAN_PREMIUM,o as PROVIDER_ANTHROPIC,A as PROVIDER_AUTO,i as PROVIDER_GOOGLE,_ as PROVIDER_MEMORY,T as PROVIDER_MISTRAL,r as PROVIDER_OPENAI,R as PROVIDER_PERPLEXITY,x as PROVIDER_ROLE_MAP,a as PROVIDER_SUMMARY,n as ROLE_ASSISTANT,O as ROLE_SYSTEM,t as ROLE_USER,w as SEARCH_QUERY_TIMEOUT_MS,Z as SORT_BY_TIMESTAMP,j as SORT_BY_TOKEN_USAGE,eE as TOOL_LOADING_LABELS,es as findProvider,eo as getCompressionEmergencyThreshold,eI as getModelsGroupedByProvider,eL as getProvidersFromModels,eM as hasMultipleModelsPerProvider,eP as isEntitled,eS as isModelAllowedForPlan,eA as isRealProvider,el as isReasoningModel,E as ActionColor};
1
+ let e=["preference","identity","constraint","habit","bio","device","location","finance","professional","interest","style","behavior","other"],E=["identity","bio","constraint","professional"],t=e=>E.includes(e);var O,n=((O={})[O.NewChat=0]="NewChat",O[O.Prompts=1]="Prompts",O[O.Attachment=2]="Attachment",O[O.PrivateChat=3]="PrivateChat",O[O.Reasoning=4]="Reasoning",O[O.Send=5]="Send",O[O.Header=6]="Header",O[O.Provider=7]="Provider",O[O.Logo=8]="Logo",O[O.Placeholder=9]="Placeholder",O[O.Footer=10]="Footer",O);let r="system",i="user",o="assistant",a="OpenAI",_="Anthropic",R="Google",T="Summary",s="Memory",A="Perplexity",I="Mistral",L="Auto",M=a,S=[a,_,R],P="gpt-5.4",l="gpt-5.4-mini",N="gpt-5.4-nano",g="claude-opus-4-8",D="claude-sonnet-4-6",d="claude-haiku-4-5",c="gemini-3-flash-preview",u="gemini-3.1-pro-preview",C="sonar",h="sonar-pro",p="openai/gpt-oss-20b:free",G="mistral-large-latest",U="gpt-5.4-mini",m="gpt-5.4-nano",H="gpt-5.4-mini",f="text-embedding-3-small",y="gemini-3-pro-image",B=N,Y=d,b=c,v=l,F=D,w=c,V=5,X=3e4,k={[P]:"GPT-5.4",[l]:"GPT-5.4 Mini",[N]:"GPT-5.4 Nano",[g]:"Claude Opus 4.8",[D]:"Claude Sonnet 4.6",[d]:"Claude Haiku 4.5",[u]:"Gemini 3.1 Pro",[c]:"Gemini 3 Flash",[C]:"Sonar",[h]:"Sonar Pro",[y]:"Nano Banana 3 Pro",[G]:"Mistral Large"},x=[P,l,N,g,D,d,c,u,y],W=[P,l,N,g,D,u],z={[a]:[P,l,N],[_]:[g,d,D],[R]:[c,u],[A]:[C,h]},K={[a]:[r,i,o],[_]:[i,o],[T]:[i,o],[s]:[i,o],[R]:[i,o],[A]:[i,o],[I]:[i,o]},Z={[_]:["claude-opus-4","claude-sonnet-4","claude-haiku-4","claude-3"],[a]:["gpt-","o3","o4"],[R]:["gemini"],[A]:["sonar"],[I]:["mistral"]},j="x-diggidy-chat-id",Q="x-diggidy-chat-timestamp",q="timestamp",J="tokenUsage",$="Diggidy",ee="sassy:basic",eE="sassy:plus",et="sassy:advanced",eO={TOOL:{BARCODE:"getProductByBarcode",BUNDLESIZE:"getBundleSize",DATETIME:"getDateTime",GENERATE_IMAGE:"generateImage",IMAGES:"getImages",NUTRITION_FACTS:"getNutritionFacts",POLLUTION:"getAirPollution",WEATHER:"getWeather",URLCONTENTPARSER:"getUrlContent",MEMORIES:"getUserMemories",HUMANIZE:"humanize",WEBSEARCH:"getWebSearch",GITREPOSITORY:"getGitRepoDetails",HOTELS:"getHotelDetails",PRONUNCIATION:"getPronunciation",FRENCH_TEACHINGS:"getFrenchTeachings"},ADDON:{ATTACHMENTS:"addon:attachments",REASONING:"addon:reasoning",CODEINTERPRETER:"addon:codeinterpreter",SHARE_CHAT:"addon:share-chat"}},en={code_interpreter:"Running code...",web_search:"Searching the web...",[eO.TOOL.WEATHER]:"Checking the weather...",[eO.TOOL.POLLUTION]:"Fetching air pollution data...",[eO.TOOL.BUNDLESIZE]:"Analyzing bundle size...",[eO.TOOL.URLCONTENTPARSER]:"Reading a webpage...",[eO.TOOL.WEBSEARCH]:"Searching the web...",[eO.TOOL.GITREPOSITORY]:"Looking up repository...",[eO.TOOL.HOTELS]:"Searching for hotels...",[eO.TOOL.NUTRITION_FACTS]:"Fetching nutrition facts...",[eO.TOOL.GENERATE_IMAGE]:"Generating image...",[eO.TOOL.BARCODE]:"Looking up product...",[eO.TOOL.PRONUNCIATION]:"Generating pronunciation...",[eO.TOOL.HUMANIZE]:"Rewriting text...",[eO.TOOL.IMAGES]:"Searching for images..."},er="Using tools...",ei=5e4,eo=1e5,ea=8e5;function e_(e){return e===et?ea:eo}let eR=16384,eT=4,es=3,eA="context-compression-summary",eI=new Set(["OpenAI",_,"Google",I]);function eL(e){return"string"==typeof e&&eI.has(e)}let eM=e=>{for(let[E,t]of Object.entries(Z))if(t.some(E=>e.startsWith(E)))return E;return null},eS=e=>{if(!e||0===e.length)return[];let E=new Set;for(let t of e)for(let[e,O]of Object.entries(z))O.includes(t)&&("OpenAI"===e||e===_||"Google"===e)&&E.add(e);return S.filter(e=>E.has(e))},eP=e=>{let E=new Map;if(!e||0===e.length)return E;for(let t of e)for(let[e,O]of Object.entries(z))if(O.includes(t)){E.has(e)||E.set(e,[]),E.get(e)?.push(t);break}return E},el=e=>{for(let E of eP(e).values())if(E.length>1)return!0;return!1},eN=(e,E)=>!!e&&!!E&&0!==E.length&&E.includes(e);function eg(e,E,t){if(!E||Array.isArray(E)&&0===E.length)return!0;let O=e instanceof Set?e:e?new Set(e):null;return!!O&&0!==O.size&&("string"==typeof E?O.has(E):t?.any===!0?E.some(e=>O.has(e)):E.every(e=>O.has(e)))}function eD(e){return W.includes(e)}export{x as ALL_MODELS,S as ALL_PROVIDERS,W as ALL_REASONING_MODELS,$ as APPLICATION_NAME,Z as APPROXIMATE_MODELS_PER_PROVIDER,eO as CAPABILITIES,eo as CONTEXT_COMPRESSION_EMERGENCY_THRESHOLD,ea as CONTEXT_COMPRESSION_EMERGENCY_THRESHOLD_PREMIUM,es as CONTEXT_COMPRESSION_KEEP_IMAGES,eT as CONTEXT_COMPRESSION_KEEP_RECENT,eA as CONTEXT_COMPRESSION_SUMMARY_ID,ei as CONTEXT_COMPRESSION_THRESHOLD,M as DEFAULT_PROVIDER,er as DEFAULT_TOOL_LOADING_LABEL,j as DIGGIDY_CHAT_ID_HEADER,Q as DIGGIDY_CHAT_TIMESTAMP_HEADER,E as HARD_CATEGORIES,eR as MAX_OUTPUT_TOKENS,V as MAX_SEARCH_QUERIES,e as MEMORY_CATEGORIES,z as MODELS_PER_PROVIDER,F as MODEL_AUTO_RESPONDER_ANTHROPIC,w as MODEL_AUTO_RESPONDER_GOOGLE,v as MODEL_AUTO_RESPONDER_OPENAI,Y as MODEL_AUTO_ROUTER_ANTHROPIC,b as MODEL_AUTO_ROUTER_GOOGLE,B as MODEL_AUTO_ROUTER_OPENAI,m as MODEL_CHAT_SUMMARY,d as MODEL_CLAUDE_HAIKU,g as MODEL_CLAUDE_OPUS,D as MODEL_CLAUDE_SONNET,p as MODEL_DEV,k as MODEL_DISPLAY_NAMES,f as MODEL_EMBEDDING_TEXT,c as MODEL_GEMINI_FLASH,u as MODEL_GEMINI_PRO,y as MODEL_GENERATE_IMAGE,P as MODEL_GPT5,l as MODEL_GPT5_MINI,N as MODEL_GPT5_NANO,U as MODEL_MEMORY_INFERENCE,H as MODEL_SEARCH_DECOMPOSER,C as MODEL_SONAR,h as MODEL_SONAR_PRO,G as MODEL_TEACHER,ee as PLAN_BASIC,eE as PLAN_PLUS,et as PLAN_PREMIUM,_ as PROVIDER_ANTHROPIC,L as PROVIDER_AUTO,R as PROVIDER_GOOGLE,s as PROVIDER_MEMORY,I as PROVIDER_MISTRAL,a as PROVIDER_OPENAI,A as PROVIDER_PERPLEXITY,K as PROVIDER_ROLE_MAP,T as PROVIDER_SUMMARY,o as ROLE_ASSISTANT,r as ROLE_SYSTEM,i as ROLE_USER,X as SEARCH_QUERY_TIMEOUT_MS,q as SORT_BY_TIMESTAMP,J as SORT_BY_TOKEN_USAGE,en as TOOL_LOADING_LABELS,eM as findProvider,e_ as getCompressionEmergencyThreshold,eP as getModelsGroupedByProvider,eS as getProvidersFromModels,el as hasMultipleModelsPerProvider,eg as isEntitled,t as isHardCategory,eN as isModelAllowedForPlan,eL as isRealProvider,eD as isReasoningModel,n as ActionColor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versini/sassysaint-common",
3
- "version": "4.40.1",
3
+ "version": "4.41.0",
4
4
  "license": "MIT",
5
5
  "author": "Arno Versini",
6
6
  "publishConfig": {
@@ -32,5 +32,5 @@
32
32
  "test:watch": "vitest",
33
33
  "watch": "npm-run-all dev"
34
34
  },
35
- "gitHead": "429e5bfbd3f00a0321d3dfd9f64e49cc845be5aa"
35
+ "gitHead": "f28d4ef7ce78021014a1a55a16a59ed4f7186222"
36
36
  }