@happyvertical/smrt-chat 0.38.19 → 0.38.21
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/AGENTS.md +8 -0
- package/dist/chat-feedback.d.ts +95 -0
- package/dist/chat-feedback.d.ts.map +1 -0
- package/dist/chunks/{ChatService-hKK-GI17.js → ChatService-BRsE5HmY.js} +18 -2
- package/dist/chunks/{ChatService-hKK-GI17.js.map → ChatService-BRsE5HmY.js.map} +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +504 -3
- package/dist/index.js.map +1 -1
- package/dist/internal/agent-runtime.js +1 -1
- package/dist/manifest.json +5 -3
- package/dist/persona-conversation.d.ts +207 -0
- package/dist/persona-conversation.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +17 -8
- package/dist/tool-loop.d.ts +182 -0
- package/dist/tool-loop.d.ts.map +1 -0
- package/package.json +12 -8
package/AGENTS.md
CHANGED
|
@@ -25,6 +25,14 @@ Facade: `sendMessage()` (authors as the actor with `role: 'user'`; room-membersh
|
|
|
25
25
|
|
|
26
26
|
`allowedTools` is a JSON array controlled by the consuming app. Fail-closed: an empty/unparseable whitelist permits NO tools. The internal `sendAgentReply(service, params)` function enforces the whitelist before emitting any `tool`/`tool_call` message; a caller cannot supply a `senderProfileId`/`role` to post as the agent, and the function is not reachable from the package index.
|
|
27
27
|
|
|
28
|
+
## Conversational Harness (L3, #1891)
|
|
29
|
+
|
|
30
|
+
The "chat with your learning agent" surface — the real agentic runtime for `AgentSession` (the only shipping chat runtime before this was a single-shot completion). This is the new **acyclic `chat → personas` / `chat → agents` / `chat → users` edge**; keep it that way (personas/agents/users never depend back on chat).
|
|
31
|
+
|
|
32
|
+
- **`runToolLoop(options)`** (`tool-loop.ts`) — a bounded `tool_call → observe → respond` loop. Tools are **manifest operations** of installed packages: `buildManifestToolCatalog({ allowedTools })` reads the `PermissionCatalogService` catalog and keeps only the `(collection, action)` entries named in the persona's allow-list (the **offer gate**; absent/empty ⇒ NO tools). The loop runs inside one `executeAsPrincipal` context, and `invokeManifestTool` executes each op **in-process ("side door")** against `run.context.database` (the RLS tx when Postgres RLS is on), after re-asserting the fail-closed allow-list (`run.assertToolAllowed`) AND the catalog permission (`run.assertOperation`) — the **execution gate**. Bounded by a max-steps ceiling (`DEFAULT_MAX_STEPS = 8`): on the ceiling it disables tools for one final completion so the turn always terminates with text.
|
|
33
|
+
- **`runPersonaConversationTurn(options)`** (`persona-conversation.ts`) — binds a conversation to an `AgentPersona`/`ResolvedPersona`: runs as its principal (`runAsUserId`), offers only its `allowedTools`, speaks its instructions (`resolvePersonaInstructions`, layering approved learned directives), and injects its **recalled learning memory** (`personaLearningMemory`, isolated per `memoryScope`) into the system prompt. `bindPersonaToSession()` mirrors the persona's `allowedTools`/instructions onto the `AgentSession` so the chat authoring gate agrees with the loop's offer gate. Authors the reply (and each executed tool) via the internal `sendAgentReply` bridge.
|
|
34
|
+
- **Chat feedback capture** (`chat-feedback.ts`) — `captureChatFeedback()` + `acceptAppliedChange`/`rejectAppliedChange`/`correctResponse`/`rateResponse`/`thumbsUp`/`thumbsDown` write a `Feedback` row (personas) carrying the conversation's **correlation-id**, and (by default) reinforce the persona's learning memory (`reinforceFromFeedback`). So an in-chat reject decays a strategy below the reuse floor and it stops being recalled; a correction supersedes its stored value.
|
|
35
|
+
|
|
28
36
|
## Gotchas
|
|
29
37
|
|
|
30
38
|
- **sessionContext, not context**: `context` is reserved for slug scoping. Use `getSessionContext()`/`updateSessionContext()` for agent memory.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { LearningMemoryRecord, LearningSemanticSearch, SmrtClassOptions } from '@happyvertical/smrt-core';
|
|
2
|
+
import { Feedback, FeedbackSignalType } from '@happyvertical/smrt-personas';
|
|
3
|
+
/** The minimal persona shape chat feedback needs to route the signal. */
|
|
4
|
+
export interface ChatFeedbackPersona {
|
|
5
|
+
/** Persona id — required (a signal always judges a specific persona). */
|
|
6
|
+
id?: string | null;
|
|
7
|
+
/** Owning tenant. */
|
|
8
|
+
tenantId?: string | null;
|
|
9
|
+
/** Canonical agent class the persona configures (denormalised onto the row). */
|
|
10
|
+
agentClass?: string;
|
|
11
|
+
/** Learning memory partition key. */
|
|
12
|
+
memoryScope?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Options for {@link captureChatFeedback}.
|
|
16
|
+
*/
|
|
17
|
+
export interface CaptureChatFeedbackOptions {
|
|
18
|
+
/** Database handle. */
|
|
19
|
+
db: SmrtClassOptions['db'];
|
|
20
|
+
/** The persona the signal judges. */
|
|
21
|
+
persona: ChatFeedbackPersona;
|
|
22
|
+
/** The kind of signal. */
|
|
23
|
+
signalType: FeedbackSignalType;
|
|
24
|
+
/** Correlation-id of the conversation turn this signal judges. */
|
|
25
|
+
correlationId: string;
|
|
26
|
+
/** What {@link correlationId} names. Default `'chat_message'`. */
|
|
27
|
+
correlationType?: string;
|
|
28
|
+
/** Learning episode scope the signal reinforces (matches recall/capture). */
|
|
29
|
+
scope: string;
|
|
30
|
+
/** Learning episode key the signal reinforces. */
|
|
31
|
+
key: string;
|
|
32
|
+
/** The user id that authored the signal (null for autonomous). */
|
|
33
|
+
actorId?: string | null;
|
|
34
|
+
/** Numeric rating for a `rating` signal. */
|
|
35
|
+
rating?: number | null;
|
|
36
|
+
/** Corrected value for a `correction` signal. */
|
|
37
|
+
correction?: string | null;
|
|
38
|
+
/** Freeform note. */
|
|
39
|
+
comment?: string | null;
|
|
40
|
+
/** Structured metadata persisted on the row. */
|
|
41
|
+
metadata?: Record<string, unknown>;
|
|
42
|
+
/** Apply the signal to memory immediately. Default `true`. */
|
|
43
|
+
reinforce?: boolean;
|
|
44
|
+
/** Optional embedding search wired into the reinforced memory. */
|
|
45
|
+
semanticSearch?: LearningSemanticSearch;
|
|
46
|
+
/** Neutral point of a `rating` scale (see `FeedbackOutcomeOptions`). Default 0. */
|
|
47
|
+
ratingNeutral?: number;
|
|
48
|
+
}
|
|
49
|
+
/** The outcome of capturing chat feedback. */
|
|
50
|
+
export interface ChatFeedbackResult {
|
|
51
|
+
/** The persisted feedback row. */
|
|
52
|
+
feedback: Feedback;
|
|
53
|
+
/** The memory record the signal reinforced, or `null` when it carried none. */
|
|
54
|
+
reinforced: LearningMemoryRecord | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Capture one in-chat feedback signal as a {@link Feedback} row and (by default)
|
|
58
|
+
* reinforce the persona's learning memory from it.
|
|
59
|
+
*
|
|
60
|
+
* @throws when the persona has no id (a signal must name a persisted persona).
|
|
61
|
+
*/
|
|
62
|
+
export declare function captureChatFeedback(options: CaptureChatFeedbackOptions): Promise<ChatFeedbackResult>;
|
|
63
|
+
/** Shared options for the signal-typed convenience wrappers. */
|
|
64
|
+
export type ChatFeedbackBase = Omit<CaptureChatFeedbackOptions, 'signalType' | 'rating' | 'correction'>;
|
|
65
|
+
/**
|
|
66
|
+
* Accept an applied change — reinforces the judged strategy as a success.
|
|
67
|
+
*/
|
|
68
|
+
export declare function acceptAppliedChange(options: ChatFeedbackBase): Promise<ChatFeedbackResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Reject an applied change — decays the judged strategy toward the failure floor
|
|
71
|
+
* so it stops being recalled.
|
|
72
|
+
*/
|
|
73
|
+
export declare function rejectAppliedChange(options: ChatFeedbackBase & {
|
|
74
|
+
comment?: string | null;
|
|
75
|
+
}): Promise<ChatFeedbackResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Record an inline correction — decays the wrong strategy AND supersedes its
|
|
78
|
+
* stored value with the corrected one, so the next recall returns the fix.
|
|
79
|
+
*/
|
|
80
|
+
export declare function correctResponse(options: ChatFeedbackBase & {
|
|
81
|
+
correction: string;
|
|
82
|
+
comment?: string | null;
|
|
83
|
+
}): Promise<ChatFeedbackResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Record a numeric rating for a response (scale is caller-defined; pass
|
|
86
|
+
* `ratingNeutral` for a mid-point).
|
|
87
|
+
*/
|
|
88
|
+
export declare function rateResponse(options: ChatFeedbackBase & {
|
|
89
|
+
rating: number;
|
|
90
|
+
}): Promise<ChatFeedbackResult>;
|
|
91
|
+
/** Thumbs-up — a `+1` rating (reinforces as a success against neutral 0). */
|
|
92
|
+
export declare function thumbsUp(options: ChatFeedbackBase): Promise<ChatFeedbackResult>;
|
|
93
|
+
/** Thumbs-down — a `-1` rating (decays as a failure against neutral 0). */
|
|
94
|
+
export declare function thumbsDown(options: ChatFeedbackBase): Promise<ChatFeedbackResult>;
|
|
95
|
+
//# sourceMappingURL=chat-feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-feedback.d.ts","sourceRoot":"","sources":["../src/chat-feedback.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { ObjectRegistry, SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
|
|
2
2
|
import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
|
+
//#region \0rolldown/runtime.js
|
|
5
|
+
var __defProp$6 = Object.defineProperty;
|
|
6
|
+
var __exportAll = (all, no_symbols) => {
|
|
7
|
+
let target = {};
|
|
8
|
+
for (var name in all) __defProp$6(target, name, {
|
|
9
|
+
get: all[name],
|
|
10
|
+
enumerable: true
|
|
11
|
+
});
|
|
12
|
+
if (!no_symbols) __defProp$6(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
return target;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
4
16
|
//#region src/models/AgentSession.ts
|
|
5
17
|
var __defProp$5 = Object.defineProperty;
|
|
6
18
|
var __getOwnPropDesc$5 = Object.getOwnPropertyDescriptor;
|
|
@@ -1059,6 +1071,10 @@ var ChatThreadCollection = class extends SmrtCollection {
|
|
|
1059
1071
|
};
|
|
1060
1072
|
//#endregion
|
|
1061
1073
|
//#region src/services/ChatService.ts
|
|
1074
|
+
var ChatService_exports = /* @__PURE__ */ __exportAll({
|
|
1075
|
+
ChatService: () => ChatService,
|
|
1076
|
+
sendAgentReply: () => sendAgentReply
|
|
1077
|
+
});
|
|
1062
1078
|
var RUN_AGENT_REPLY = /* @__PURE__ */ Symbol("smrt-chat.runAgentReply");
|
|
1063
1079
|
var ChatService = class ChatService {
|
|
1064
1080
|
#rooms;
|
|
@@ -1737,6 +1753,6 @@ function sendAgentReply(service, params) {
|
|
|
1737
1753
|
return ChatService[RUN_AGENT_REPLY](service, params);
|
|
1738
1754
|
}
|
|
1739
1755
|
//#endregion
|
|
1740
|
-
export {
|
|
1756
|
+
export { ChatRoom as a, ChatMessage as c, ChatThread as i, AgentSession as l, ChatService_exports as n, ChatReaction as o, sendAgentReply as r, ChatParticipant as s, ChatService as t };
|
|
1741
1757
|
|
|
1742
|
-
//# sourceMappingURL=ChatService-
|
|
1758
|
+
//# sourceMappingURL=ChatService-BRsE5HmY.js.map
|