@molroo-io/sdk 0.7.2 → 0.8.2

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 (45) hide show
  1. package/dist/cjs/emotion.d.ts +7 -0
  2. package/dist/cjs/emotion.d.ts.map +1 -0
  3. package/dist/cjs/emotion.js +15 -0
  4. package/dist/cjs/expression/index.d.ts +103 -0
  5. package/dist/cjs/expression/index.d.ts.map +1 -0
  6. package/dist/cjs/expression/index.js +18 -0
  7. package/dist/cjs/index.d.ts +3 -1
  8. package/dist/cjs/index.d.ts.map +1 -1
  9. package/dist/cjs/index.js +4 -1
  10. package/dist/cjs/llm/schema.d.ts +114 -0
  11. package/dist/cjs/llm/schema.d.ts.map +1 -1
  12. package/dist/cjs/llm/schema.js +44 -1
  13. package/dist/cjs/persona/chat-orchestrator.d.ts +2 -1
  14. package/dist/cjs/persona/chat-orchestrator.d.ts.map +1 -1
  15. package/dist/cjs/persona/chat-orchestrator.js +139 -33
  16. package/dist/cjs/persona.d.ts +26 -1
  17. package/dist/cjs/persona.d.ts.map +1 -1
  18. package/dist/cjs/persona.js +34 -1
  19. package/dist/cjs/types.d.ts +18 -5
  20. package/dist/cjs/types.d.ts.map +1 -1
  21. package/dist/cjs/world/world-persona.d.ts +3 -2
  22. package/dist/cjs/world/world-persona.d.ts.map +1 -1
  23. package/dist/esm/emotion.d.ts +7 -0
  24. package/dist/esm/emotion.d.ts.map +1 -0
  25. package/dist/esm/emotion.js +12 -0
  26. package/dist/esm/expression/index.d.ts +103 -0
  27. package/dist/esm/expression/index.d.ts.map +1 -0
  28. package/dist/esm/expression/index.js +17 -0
  29. package/dist/esm/index.d.ts +3 -1
  30. package/dist/esm/index.d.ts.map +1 -1
  31. package/dist/esm/index.js +2 -0
  32. package/dist/esm/llm/schema.d.ts +114 -0
  33. package/dist/esm/llm/schema.d.ts.map +1 -1
  34. package/dist/esm/llm/schema.js +43 -0
  35. package/dist/esm/persona/chat-orchestrator.d.ts +2 -1
  36. package/dist/esm/persona/chat-orchestrator.d.ts.map +1 -1
  37. package/dist/esm/persona/chat-orchestrator.js +139 -33
  38. package/dist/esm/persona.d.ts +26 -1
  39. package/dist/esm/persona.d.ts.map +1 -1
  40. package/dist/esm/persona.js +34 -1
  41. package/dist/esm/types.d.ts +18 -5
  42. package/dist/esm/types.d.ts.map +1 -1
  43. package/dist/esm/world/world-persona.d.ts +3 -2
  44. package/dist/esm/world/world-persona.d.ts.map +1 -1
  45. package/package.json +25 -15
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @molroo-io/sdk/expression — StyleProfile type definitions
3
+ *
4
+ * Style extraction is now handled server-side via the API.
5
+ * Use `persona.extractStyleProfile(corpus)` to extract and save a StyleProfile.
6
+ *
7
+ * Types inlined from @molroo-io/expression (private package).
8
+ * These must stay in sync with lib/expression/src/types/index.ts.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * import type { StyleProfile } from '@molroo-io/sdk/expression';
13
+ *
14
+ * const profile = await persona.extractStyleProfile(chatCorpus);
15
+ * ```
16
+ */
17
+ export interface ExtractionOptions {
18
+ /** Timestamps for turn grouping (same length as messages) */
19
+ timestamps?: number[];
20
+ /** Messages from other participants (for TF-IDF signature detection) */
21
+ otherMessages?: string[];
22
+ }
23
+ export interface LexicalFeatures {
24
+ /** Type-Token Ratio: unique_words / total_words */
25
+ vocabRichness: number;
26
+ /** Yule's K characteristic: 10^4 * (M2 - M1) / M1^2 */
27
+ yuleK: number;
28
+ /** Words appearing only once / total words */
29
+ hapaxRatio: number;
30
+ /** Average word length in characters */
31
+ avgWordLength: number;
32
+ /** Function word (particles, conjunctions) frequency distribution */
33
+ functionWordDist: Record<string, number>;
34
+ }
35
+ export interface StructuralFeatures {
36
+ /** Average message length in characters */
37
+ avgMessageLength: number;
38
+ /** Standard deviation of message length */
39
+ messageLengthStd: number;
40
+ /** Ratio of turns with multiple messages */
41
+ multiMessageRatio: number;
42
+ /** Average number of messages per turn */
43
+ avgMessagesPerTurn: number;
44
+ /** Ratio of messages ending with ? */
45
+ questionRatio: number;
46
+ }
47
+ export interface PunctuationFeatures {
48
+ /** Period usage style */
49
+ periodStyle: 'none' | 'single' | 'double' | 'triple';
50
+ /** Emoji count per message (mean) */
51
+ emojiFrequency: number;
52
+ /** Top N most-used emoji */
53
+ emojiSet: string[];
54
+ /** Laugh expression patterns (e.g. ㅋㅋ, ㅎㅎ, ㅋㅋㅋㅋ) */
55
+ laughStyle: string[];
56
+ /** Laugh expressions per message (mean) */
57
+ laughFrequency: number;
58
+ /** Exclamation mark usage rate */
59
+ exclamationRate: number;
60
+ /** Ellipsis (...) usage rate */
61
+ ellipsisRate: number;
62
+ }
63
+ export interface RegisterFeatures {
64
+ /** 0 (casual/banmal) ~ 1 (formal/jondaenmal) */
65
+ formalityScore: number;
66
+ /** Honorific patterns used */
67
+ honorificPatterns: string[];
68
+ /** How the person addresses the interlocutor */
69
+ addressTerms: string[];
70
+ }
71
+ export interface IdiosyncraticFeatures {
72
+ /** Filler words (아, 음, 근데, etc.) */
73
+ fillerWords: string[];
74
+ /** Contraction patterns (ㄱㅊ, ㅇㅇ, ㄴㄴ, etc.) */
75
+ contractions: string[];
76
+ /** Statistically significant personal expressions */
77
+ signaturePatterns: string[];
78
+ /** Sentence ending pattern distribution */
79
+ sentenceEnders: Record<string, number>;
80
+ }
81
+ export interface ResponsePatterns {
82
+ /** Ratio of conversation initiations */
83
+ initiationRatio: number;
84
+ /** Topic change style description */
85
+ topicChangeStyle: string;
86
+ }
87
+ export interface StatisticalSignature {
88
+ /** Character n-gram frequency distribution (n=2,3) */
89
+ charNgramDist: Record<string, number>;
90
+ /** Word n-gram frequency distribution (n=2) */
91
+ wordNgramDist: Record<string, number>;
92
+ }
93
+ /** Complete individual expression fingerprint */
94
+ export interface StyleProfile {
95
+ lexical: LexicalFeatures;
96
+ structural: StructuralFeatures;
97
+ punctuation: PunctuationFeatures;
98
+ register: RegisterFeatures;
99
+ idiosyncratic: IdiosyncraticFeatures;
100
+ response: ResponsePatterns;
101
+ signature: StatisticalSignature;
102
+ }
103
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/expression/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAID,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,yBAAyB;IACzB,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrD,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oDAAoD;IACpD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gDAAgD;IAChD,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,WAAW,EAAE,mBAAmB,CAAC;IACjC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,aAAa,EAAE,qBAAqB,CAAC;IACrC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,EAAE,oBAAoB,CAAC;CACjC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @molroo-io/sdk/expression — StyleProfile type definitions
3
+ *
4
+ * Style extraction is now handled server-side via the API.
5
+ * Use `persona.extractStyleProfile(corpus)` to extract and save a StyleProfile.
6
+ *
7
+ * Types inlined from @molroo-io/expression (private package).
8
+ * These must stay in sync with lib/expression/src/types/index.ts.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * import type { StyleProfile } from '@molroo-io/sdk/expression';
13
+ *
14
+ * const profile = await persona.extractStyleProfile(chatCorpus);
15
+ * ```
16
+ */
17
+ export {};
@@ -37,10 +37,12 @@ export type { LLMAdapter, Message, GenerateTextOptions, GenerateObjectOptions, }
37
37
  export type { LLMInput } from './llm/resolve';
38
38
  export type { MemoryAdapter, RecallQuery, SemanticRecallOptions, RecallLimits, Reflection, } from './memory/types';
39
39
  export type { PersonaSummary, PersonaState, PersonaChatResult, } from './persona';
40
- export type { InterlocutorContext, PerceiveOptions, PerceiveEvent, PerceiveContext, } from './types';
40
+ export type { AppraisalMode, EventAppraisal, InterlocutorContext, PerceiveOptions, PerceiveEvent, PerceiveContext, } from './types';
41
41
  export type { AgentResponse, VAD, Velocity, AppraisalVector, State, SoulStage, CatastropheState, MetacogState, AffectDynamicsState, InterpersonalState, RegulationState, RegulationStrategy, RegulationPhase, ActiveRegulation, RegulationRecord, EffectivenessRecord, NeedState, Episode, SocialUpdate, ReflectionPrompt, } from './types';
42
42
  export type { PersonaSnapshot, PersonaConfigData, PersonalityTraits, Identity, Goal, MotivationContext, } from './types';
43
43
  export type { ApiResponse, ApiErrorResponse, PersonaDynamicState, } from './types';
44
44
  export type { LLMPrompt, LLMResponse, } from './llm/types';
45
+ export { EMOTION_LABELS } from './emotion';
46
+ export type { EmotionLabel } from './emotion';
45
47
  export { DEFAULT_PERSONA, withDefaults } from './defaults';
46
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,YAAY,EACV,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EACV,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,UAAU,GACX,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACV,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,aAAa,EACb,GAAG,EACH,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,OAAO,EACP,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,IAAI,EACJ,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,YAAY,EACV,UAAU,EACV,OAAO,EACP,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EACV,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,UAAU,GACX,MAAM,gBAAgB,CAAC;AAGxB,YAAY,EACV,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,eAAe,GAChB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,aAAa,EACb,GAAG,EACH,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,OAAO,EACP,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,QAAQ,EACR,IAAI,EACJ,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,SAAS,EACT,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/esm/index.js CHANGED
@@ -33,5 +33,7 @@ export { Molroo } from './world/world';
33
33
  export { MolrooApiError, WorldApiError } from './shared/errors';
34
34
  // ── Shared utilities ──
35
35
  export { NEUTRAL_APPRAISAL, toWireAppraisal, fromWireAppraisal } from './shared/appraisal';
36
+ // ── Emotion labels (synced with engine/core) ──
37
+ export { EMOTION_LABELS } from './emotion';
36
38
  // ── Defaults ──
37
39
  export { DEFAULT_PERSONA, withDefaults } from './defaults';
@@ -18,6 +18,43 @@ export declare const AppraisalVectorSchema: z.ZodObject<{
18
18
  adjustment_potential: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
19
19
  urgency: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
20
20
  }, z.core.$strip>;
21
+ export declare const EventAppraisalSchema: z.ZodObject<{
22
+ interaction_type: z.ZodEnum<{
23
+ chat: "chat";
24
+ inform: "inform";
25
+ humor: "humor";
26
+ express: "express";
27
+ goodbye: "goodbye";
28
+ }>;
29
+ event_type: z.ZodOptional<z.ZodEnum<{
30
+ praise: "praise";
31
+ criticism: "criticism";
32
+ support: "support";
33
+ rejection: "rejection";
34
+ apology: "apology";
35
+ request: "request";
36
+ betrayal: "betrayal";
37
+ neglect: "neglect";
38
+ }>>;
39
+ agent_role: z.ZodEnum<{
40
+ user: "user";
41
+ self: "self";
42
+ other: "other";
43
+ }>;
44
+ target_role: z.ZodEnum<{
45
+ user: "user";
46
+ self: "self";
47
+ other: "other";
48
+ }>;
49
+ relationship: z.ZodEnum<{
50
+ friend: "friend";
51
+ romantic: "romantic";
52
+ authority: "authority";
53
+ stranger: "stranger";
54
+ }>;
55
+ intensity: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
56
+ }, z.core.$strip>;
57
+ export type EventAppraisalOutput = z.infer<typeof EventAppraisalSchema>;
21
58
  /**
22
59
  * Full LLM response schema — response text + appraisal vector.
23
60
  */
@@ -36,6 +73,44 @@ export declare const LLMResponseSchema: z.ZodObject<{
36
73
  }, z.core.$strip>;
37
74
  }, z.core.$strip>;
38
75
  export type LLMResponseOutput = z.infer<typeof LLMResponseSchema>;
76
+ export declare const LLMEventResponseSchema: z.ZodObject<{
77
+ response: z.ZodString;
78
+ interaction_type: z.ZodEnum<{
79
+ chat: "chat";
80
+ inform: "inform";
81
+ humor: "humor";
82
+ express: "express";
83
+ goodbye: "goodbye";
84
+ }>;
85
+ event_type: z.ZodOptional<z.ZodEnum<{
86
+ praise: "praise";
87
+ criticism: "criticism";
88
+ support: "support";
89
+ rejection: "rejection";
90
+ apology: "apology";
91
+ request: "request";
92
+ betrayal: "betrayal";
93
+ neglect: "neglect";
94
+ }>>;
95
+ agent_role: z.ZodEnum<{
96
+ user: "user";
97
+ self: "self";
98
+ other: "other";
99
+ }>;
100
+ target_role: z.ZodEnum<{
101
+ user: "user";
102
+ self: "self";
103
+ other: "other";
104
+ }>;
105
+ relationship: z.ZodEnum<{
106
+ friend: "friend";
107
+ romantic: "romantic";
108
+ authority: "authority";
109
+ stranger: "stranger";
110
+ }>;
111
+ intensity: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
112
+ }, z.core.$strip>;
113
+ export type LLMEventResponseOutput = z.infer<typeof LLMEventResponseSchema>;
39
114
  /**
40
115
  * Tool-use aware LLM response schema.
41
116
  * The LLM can either produce a normal response or request a memory search.
@@ -57,4 +132,43 @@ export declare const LLMResponseWithToolsSchema: z.ZodObject<{
57
132
  search_memory: z.ZodOptional<z.ZodString>;
58
133
  }, z.core.$strip>;
59
134
  export type LLMResponseWithToolsOutput = z.infer<typeof LLMResponseWithToolsSchema>;
135
+ export declare const LLMEventResponseWithToolsSchema: z.ZodObject<{
136
+ response: z.ZodString;
137
+ interaction_type: z.ZodEnum<{
138
+ chat: "chat";
139
+ inform: "inform";
140
+ humor: "humor";
141
+ express: "express";
142
+ goodbye: "goodbye";
143
+ }>;
144
+ event_type: z.ZodOptional<z.ZodEnum<{
145
+ praise: "praise";
146
+ criticism: "criticism";
147
+ support: "support";
148
+ rejection: "rejection";
149
+ apology: "apology";
150
+ request: "request";
151
+ betrayal: "betrayal";
152
+ neglect: "neglect";
153
+ }>>;
154
+ agent_role: z.ZodEnum<{
155
+ user: "user";
156
+ self: "self";
157
+ other: "other";
158
+ }>;
159
+ target_role: z.ZodEnum<{
160
+ user: "user";
161
+ self: "self";
162
+ other: "other";
163
+ }>;
164
+ relationship: z.ZodEnum<{
165
+ friend: "friend";
166
+ romantic: "romantic";
167
+ authority: "authority";
168
+ stranger: "stranger";
169
+ }>;
170
+ intensity: z.ZodPipe<z.ZodNumber, z.ZodTransform<number, number>>;
171
+ search_memory: z.ZodOptional<z.ZodString>;
172
+ }, z.core.$strip>;
173
+ export type LLMEventResponseWithToolsOutput = z.infer<typeof LLMEventResponseWithToolsSchema>;
60
174
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/llm/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;iBAuDhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;iBAK5B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;iBAarC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/llm/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;iBAuDhC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB/B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;iBAK5B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQjC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;iBAarC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEpF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgB1C,CAAC;AAEH,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC"}
@@ -1,4 +1,14 @@
1
1
  import { z } from 'zod';
2
+ // Ontology constants inlined from @molroo-io/core (private package).
3
+ // These must stay in sync with engine/core/src/modules/ontology/types.ts.
4
+ const INTERACTION_TYPES = ['chat', 'inform', 'humor', 'express', 'goodbye'];
5
+ const EVENT_TYPES = [
6
+ 'praise', 'criticism', 'support', 'rejection',
7
+ 'apology', 'request', 'betrayal', 'neglect',
8
+ ];
9
+ const AGENT_ROLES = ['user', 'self', 'other'];
10
+ const TARGET_ROLES = ['user', 'self', 'other'];
11
+ const RELATIONSHIP_TYPES = ['friend', 'romantic', 'authority', 'stranger'];
2
12
  /** Clamp a number to [lo, hi]. */
3
13
  const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
4
14
  /**
@@ -47,6 +57,17 @@ export const AppraisalVectorSchema = z.object({
47
57
  .describe('How much time pressure or immediate action is needed? 0: settled/past event/no rush, 0.5: moderate, 1: immediate action required/acute emergency. For past losses: low. For active threats: high. Use 0-1 range.')
48
58
  .transform((v) => clamp(v, 0, 1)),
49
59
  });
60
+ export const EventAppraisalSchema = z.object({
61
+ interaction_type: z.enum(INTERACTION_TYPES).describe('Conversation mode: chat (small talk), inform (sharing info/news), humor (jokes), express (emotional/relational event), goodbye (farewell).'),
62
+ event_type: z.enum(EVENT_TYPES).optional().describe('Relationship event type. Required when interaction_type is "express". Omit for chat/inform/humor/goodbye. One of: praise, criticism, support, rejection, apology, request, betrayal, neglect.'),
63
+ agent_role: z.enum(AGENT_ROLES).describe('Primary role responsible for the event from the persona perspective: user, self, or other.'),
64
+ target_role: z.enum(TARGET_ROLES).describe('Who is affected by or receives the event: self (persona), user (conversation partner), or other (third party).'),
65
+ relationship: z.enum(RELATIONSHIP_TYPES).describe('Relationship context for this event: friend, romantic, authority, or stranger.'),
66
+ intensity: z
67
+ .number()
68
+ .describe('Impact strength from 0 to 1.5. Use 1.0 for a normal event and >1.0 for unusually strong events.')
69
+ .transform((v) => clamp(v, 0, 1.5)),
70
+ });
50
71
  /**
51
72
  * Full LLM response schema — response text + appraisal vector.
52
73
  */
@@ -54,6 +75,15 @@ export const LLMResponseSchema = z.object({
54
75
  response: z.string().describe('Response message from persona to user'),
55
76
  appraisal: AppraisalVectorSchema.describe("Scherer 9-dimensional emotion appraisal of user input from persona's perspective"),
56
77
  });
78
+ export const LLMEventResponseSchema = z.object({
79
+ response: z.string().describe('Response message from persona to user'),
80
+ interaction_type: EventAppraisalSchema.shape.interaction_type,
81
+ event_type: EventAppraisalSchema.shape.event_type,
82
+ agent_role: EventAppraisalSchema.shape.agent_role,
83
+ target_role: EventAppraisalSchema.shape.target_role,
84
+ relationship: EventAppraisalSchema.shape.relationship,
85
+ intensity: EventAppraisalSchema.shape.intensity,
86
+ });
57
87
  /**
58
88
  * Tool-use aware LLM response schema.
59
89
  * The LLM can either produce a normal response or request a memory search.
@@ -67,3 +97,16 @@ export const LLMResponseWithToolsSchema = z.object({
67
97
  .optional()
68
98
  .describe('If you need to recall a specific memory before responding, set this to your search query. Leave empty/omit when you can respond without searching.'),
69
99
  });
100
+ export const LLMEventResponseWithToolsSchema = z.object({
101
+ response: z.string().describe('Response message from persona to user. Set to empty string "" if you need to search memory first.'),
102
+ interaction_type: EventAppraisalSchema.shape.interaction_type,
103
+ event_type: EventAppraisalSchema.shape.event_type,
104
+ agent_role: EventAppraisalSchema.shape.agent_role,
105
+ target_role: EventAppraisalSchema.shape.target_role,
106
+ relationship: EventAppraisalSchema.shape.relationship,
107
+ intensity: EventAppraisalSchema.shape.intensity,
108
+ search_memory: z
109
+ .string()
110
+ .optional()
111
+ .describe('If you need to recall a specific memory before responding, set this to your search query. Leave empty/omit when you can respond without searching.'),
112
+ });
@@ -5,7 +5,7 @@
5
5
  * All external dependencies are injected via ChatOrchestratorDeps.
6
6
  */
7
7
  import type { LLMAdapter, Message } from '../llm/adapter';
8
- import type { AgentResponse, InterlocutorContext, PerceiveOptions } from '../types';
8
+ import type { AgentResponse, AppraisalMode, InterlocutorContext, PerceiveOptions } from '../types';
9
9
  import type { RecallLimits } from '../memory/types';
10
10
  import type { MemoryAdapter } from '../memory/types';
11
11
  import type { EventAdapter } from '../events/types';
@@ -21,6 +21,7 @@ export interface ChatOrchestratorDeps {
21
21
  memoryAdapter: MemoryAdapter | null;
22
22
  memoryRecallConfig: RecallLimits | undefined;
23
23
  events: EventAdapter | null;
24
+ appraisalMode: AppraisalMode;
24
25
  getPromptContext: (consumerSuffix?: string, sourceEntity?: string) => Promise<PromptContextResult>;
25
26
  perceive: (message: string, options?: PerceiveOptions) => Promise<AgentResponse>;
26
27
  searchMemory: (query: string) => Promise<Array<Record<string, unknown>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"chat-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/persona/chat-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EACV,aAAa,EAGb,mBAAmB,EACnB,eAAe,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA+BpD,KAAK,mBAAmB,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,kBAAkB,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnG,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACjF,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/F;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,2FAA2F;IAC3F,cAAc,EAAE,OAAO,EAAE,CAAC;CAC3B;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAmJlH"}
1
+ {"version":3,"file":"chat-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/persona/chat-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EAIb,mBAAmB,EACnB,eAAe,EAChB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAIpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA6EpD,KAAK,mBAAmB,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,kBAAkB,EAAE,YAAY,GAAG,SAAS,CAAC;IAC7C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnG,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACjF,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/F;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,2FAA2F;IAC3F,cAAc,EAAE,OAAO,EAAE,CAAC;CAC3B;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAiKlH"}
@@ -29,6 +29,49 @@ function buildInterlocutorBlock(ctx) {
29
29
  }
30
30
  return parts.join('\n');
31
31
  }
32
+ function buildDirectAppraisalInstruction() {
33
+ return [
34
+ '',
35
+ '## Appraisal Task',
36
+ "Evaluate how RECEIVING the user's message affects this persona emotionally.",
37
+ 'The event you are appraising is the message itself arriving, not the described situation.',
38
+ "When the user shares their own experience, appraise through the persona's relational goals.",
39
+ "Rate each dimension from the persona's subjective perspective.",
40
+ 'An insult should produce negative goal_congruence and norm_compatibility.',
41
+ 'A compliment should produce positive values. Neutral small talk should be near zero.',
42
+ ].join('\n');
43
+ }
44
+ function buildEventAppraisalInstruction() {
45
+ return [
46
+ '',
47
+ '## Event Classification Task',
48
+ "Classify the user's message into the ontology event format before emotion is computed.",
49
+ '',
50
+ '### Step 1: interaction_type (required)',
51
+ 'Determine the conversation mode: chat (small talk), inform (sharing info/news), humor (jokes/playfulness), express (emotional/relational event), goodbye (farewell/parting).',
52
+ '',
53
+ '### Step 2: event_type (only when interaction_type is "express")',
54
+ 'If the message contains a relationship event, classify it: praise, criticism, support, rejection, apology, request, betrayal, or neglect.',
55
+ 'Omit event_type for chat, inform, humor, or goodbye — these do not carry relationship events.',
56
+ '',
57
+ '### Step 3: agent_role, target_role, relationship, intensity',
58
+ 'agent_role: who performed the action. target_role: who is affected by or receives the action.',
59
+ 'Example: "you did great" → interaction=express, event=praise, agent=user, target=self.',
60
+ 'Example: "nice weather" → interaction=chat, no event_type, agent=user, target=self.',
61
+ 'Example: "my friend betrayed me" → interaction=express, event=betrayal, agent=other, target=user.',
62
+ ].join('\n');
63
+ }
64
+ /** Convert an EventAppraisal to the ontologyEvent shape for API. */
65
+ function toOntologyEvent(event) {
66
+ return {
67
+ interaction_type: event.interaction_type,
68
+ ...(event.event_type ? { event_type: event.event_type } : {}),
69
+ agent_role: event.agent_role,
70
+ target_role: event.target_role,
71
+ relationship: event.relationship,
72
+ intensity: event.intensity,
73
+ };
74
+ }
32
75
  export async function chat(deps, message, options) {
33
76
  const fromOption = options?.from ?? 'user';
34
77
  const from = typeof fromOption === 'string' ? fromOption : fromOption.name;
@@ -62,30 +105,33 @@ export async function chat(deps, message, options) {
62
105
  }
63
106
  let responseText;
64
107
  let appraisal;
108
+ let ontologyEvent;
65
109
  let earlyPerceiveResponse;
66
110
  // Split mode: engineLlm handles appraisal, primary llm handles response text
67
111
  if (deps.engineLlm && deps.engineLlm !== deps.llm) {
68
- const { AppraisalVectorSchema } = await import('../llm/schema');
69
- const appraisalInstruction = [
70
- '',
71
- '## Appraisal Task',
72
- "Evaluate how RECEIVING the user's message affects this persona emotionally.",
73
- 'The event you are appraising is the message itself arriving — not the described situation.',
74
- "When the user shares their own experience (e.g. loss, success), appraise through the persona's relational goals: caring about the speaker makes their suffering relevant and incongruent.",
75
- "Rate each dimension from the persona's subjective perspective.",
76
- 'An insult should produce negative goal_congruence and norm_compatibility.',
77
- 'A compliment should produce positive values. Neutral small talk should be near zero.',
78
- ].join('\n');
79
112
  const appraisalMessages = messages.length <= 5 ? messages : messages.slice(-5);
80
- const { object: appraisalResult } = await deps.engineLlm.generateObject({
81
- system: systemPrompt + appraisalInstruction,
82
- messages: appraisalMessages,
83
- schema: AppraisalVectorSchema,
84
- });
85
- appraisal = clampAppraisal(appraisalResult);
113
+ if (deps.appraisalMode === 'event') {
114
+ const { EventAppraisalSchema } = await import('../llm/schema');
115
+ const { object: appraisalResult } = await deps.engineLlm.generateObject({
116
+ system: systemPrompt + buildEventAppraisalInstruction(),
117
+ messages: appraisalMessages,
118
+ schema: EventAppraisalSchema,
119
+ });
120
+ ontologyEvent = toOntologyEvent(appraisalResult);
121
+ }
122
+ else {
123
+ const { AppraisalVectorSchema } = await import('../llm/schema');
124
+ const { object: appraisalResult } = await deps.engineLlm.generateObject({
125
+ system: systemPrompt + buildDirectAppraisalInstruction(),
126
+ messages: appraisalMessages,
127
+ schema: AppraisalVectorSchema,
128
+ });
129
+ appraisal = clampAppraisal(appraisalResult);
130
+ }
86
131
  earlyPerceiveResponse = await deps.perceive(message, {
87
132
  from,
88
- appraisal,
133
+ ...(appraisal ? { appraisal } : {}),
134
+ ...(ontologyEvent ? { ontologyEvent } : {}),
89
135
  priorEpisodes: recalledEpisodes.length > 0 ? recalledEpisodes : undefined,
90
136
  skipMemory: true,
91
137
  });
@@ -112,17 +158,30 @@ export async function chat(deps, message, options) {
112
158
  else if (hasTools) {
113
159
  const result = await generateWithToolLoop(deps, systemPrompt, messages, options?.onToolCall);
114
160
  responseText = result.text;
115
- appraisal = clampAppraisal(result.appraisal);
161
+ appraisal = result.appraisal;
162
+ ontologyEvent = result.ontologyEvent;
116
163
  }
117
164
  else {
118
- const { LLMResponseSchema } = await import('../llm/schema');
119
- const { object: llmResult } = await deps.llm.generateObject({
120
- system: systemPrompt,
121
- messages,
122
- schema: LLMResponseSchema,
123
- });
124
- responseText = llmResult.response;
125
- appraisal = clampAppraisal(llmResult.appraisal ?? { ...NEUTRAL_APPRAISAL });
165
+ if (deps.appraisalMode === 'event') {
166
+ const { LLMEventResponseSchema } = await import('../llm/schema');
167
+ const { object: llmResult } = await deps.llm.generateObject({
168
+ system: systemPrompt + buildEventAppraisalInstruction(),
169
+ messages,
170
+ schema: LLMEventResponseSchema,
171
+ });
172
+ responseText = llmResult.response;
173
+ ontologyEvent = toOntologyEvent(llmResult);
174
+ }
175
+ else {
176
+ const { LLMResponseSchema } = await import('../llm/schema');
177
+ const { object: llmResult } = await deps.llm.generateObject({
178
+ system: systemPrompt,
179
+ messages,
180
+ schema: LLMResponseSchema,
181
+ });
182
+ responseText = llmResult.response;
183
+ appraisal = clampAppraisal(llmResult.appraisal ?? { ...NEUTRAL_APPRAISAL });
184
+ }
126
185
  }
127
186
  // 4. Send to API for emotion processing (skip if already done in split mode)
128
187
  let response;
@@ -132,7 +191,8 @@ export async function chat(deps, message, options) {
132
191
  else {
133
192
  response = await deps.perceive(responseText, {
134
193
  from,
135
- appraisal: appraisal,
194
+ ...(appraisal ? { appraisal } : {}),
195
+ ...(ontologyEvent ? { ontologyEvent } : {}),
136
196
  priorEpisodes: recalledEpisodes.length > 0 ? recalledEpisodes : undefined,
137
197
  skipMemory: true,
138
198
  });
@@ -158,18 +218,53 @@ export async function chat(deps, message, options) {
158
218
  }
159
219
  async function generateWithToolLoop(deps, system, messages, onToolCall) {
160
220
  const MAX_TOOL_ITERATIONS = 3;
161
- const { LLMResponseWithToolsSchema, LLMResponseSchema } = await import('../llm/schema');
221
+ const { LLMEventResponseSchema, LLMEventResponseWithToolsSchema, LLMResponseSchema, LLMResponseWithToolsSchema, } = await import('../llm/schema');
162
222
  let currentSystem = system;
163
223
  for (let iteration = 0; iteration < MAX_TOOL_ITERATIONS; iteration++) {
224
+ if (deps.appraisalMode === 'event') {
225
+ const { object: llmResult } = await deps.llm.generateObject({
226
+ system: currentSystem + buildEventAppraisalInstruction(),
227
+ messages,
228
+ schema: LLMEventResponseWithToolsSchema,
229
+ });
230
+ if (!llmResult.search_memory) {
231
+ return {
232
+ text: llmResult.response,
233
+ ontologyEvent: toOntologyEvent(llmResult),
234
+ };
235
+ }
236
+ const query = llmResult.search_memory;
237
+ let episodes = [];
238
+ try {
239
+ episodes = await deps.searchMemory(query);
240
+ }
241
+ catch {
242
+ // Memory search failed — continue without results
243
+ }
244
+ if (onToolCall) {
245
+ onToolCall({ name: 'search_memory', args: { query }, result: episodes });
246
+ }
247
+ const resultBlock = episodes.length > 0
248
+ ? `\n\n## Memory Search Results (query: "${query}")\n${episodes.map(ep => {
249
+ const ts = ep.timestamp ? new Date(ep.timestamp).toISOString() : 'unknown';
250
+ const source = ep.sourceEntity ?? 'unknown';
251
+ const context = ep.context ?? 'no context';
252
+ return `- [${ts}] ${source}: ${context}`;
253
+ }).join('\n')}`
254
+ : `\n\n## Memory Search Results (query: "${query}")\nNo matching memories found.`;
255
+ currentSystem = currentSystem + resultBlock;
256
+ continue;
257
+ }
164
258
  const { object: llmResult } = await deps.llm.generateObject({
165
259
  system: currentSystem,
166
260
  messages,
167
261
  schema: LLMResponseWithToolsSchema,
168
262
  });
169
263
  if (!llmResult.search_memory) {
170
- const text = llmResult.response;
171
- const appraisal = llmResult.appraisal ?? { ...NEUTRAL_APPRAISAL };
172
- return { text, appraisal };
264
+ return {
265
+ text: llmResult.response,
266
+ appraisal: clampAppraisal(llmResult.appraisal ?? { ...NEUTRAL_APPRAISAL }),
267
+ };
173
268
  }
174
269
  const query = llmResult.search_memory;
175
270
  let episodes = [];
@@ -192,6 +287,17 @@ async function generateWithToolLoop(deps, system, messages, onToolCall) {
192
287
  : `\n\n## Memory Search Results (query: "${query}")\nNo matching memories found.`;
193
288
  currentSystem = currentSystem + resultBlock;
194
289
  }
290
+ if (deps.appraisalMode === 'event') {
291
+ const { object: finalResult } = await deps.llm.generateObject({
292
+ system: currentSystem + buildEventAppraisalInstruction(),
293
+ messages,
294
+ schema: LLMEventResponseSchema,
295
+ });
296
+ return {
297
+ text: finalResult.response,
298
+ ontologyEvent: toOntologyEvent(finalResult),
299
+ };
300
+ }
195
301
  const { object: finalResult } = await deps.llm.generateObject({
196
302
  system: currentSystem,
197
303
  messages,
@@ -199,6 +305,6 @@ async function generateWithToolLoop(deps, system, messages, onToolCall) {
199
305
  });
200
306
  return {
201
307
  text: finalResult.response,
202
- appraisal: finalResult.appraisal ?? { ...NEUTRAL_APPRAISAL },
308
+ appraisal: clampAppraisal(finalResult.appraisal ?? { ...NEUTRAL_APPRAISAL }),
203
309
  };
204
310
  }