@happyvertical/smrt-chat 0.38.20 → 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
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { AIInterface, AIMessage, AITool, ChatOptions } from '@happyvertical/ai';
|
|
2
|
+
import { PrincipalAuditSink, PrincipalBinding, PrincipalRun } from '@happyvertical/smrt-agents';
|
|
3
|
+
import { SmrtClassOptions } from '@happyvertical/smrt-core';
|
|
4
|
+
import { PermissionDefinition } from '@happyvertical/smrt-users';
|
|
5
|
+
/** Default ceiling on tool-executing rounds before the loop force-terminates. */
|
|
6
|
+
export declare const DEFAULT_MAX_STEPS = 8;
|
|
7
|
+
/**
|
|
8
|
+
* A single manifest operation the loop can offer and execute. Its {@link slug}
|
|
9
|
+
* is simultaneously the tool's stable name AND its permission-catalog slug — one
|
|
10
|
+
* source of truth for both what the model may call and what the principal must
|
|
11
|
+
* be permitted to do.
|
|
12
|
+
*/
|
|
13
|
+
export interface ManifestTool {
|
|
14
|
+
/** Catalog slug (`collection.action`) — the tool name and the permission slug. */
|
|
15
|
+
slug: string;
|
|
16
|
+
/** Collection (permission resource), e.g. `articles`. */
|
|
17
|
+
collection: string;
|
|
18
|
+
/** Registry class name used to resolve the backing collection, e.g. `Article`. */
|
|
19
|
+
className: string;
|
|
20
|
+
/** Catalog action: `read` / `create` / `update` / `delete`, or a public custom method name. */
|
|
21
|
+
action: string;
|
|
22
|
+
/** Qualified class name, when known. */
|
|
23
|
+
qualifiedName?: string;
|
|
24
|
+
/** Human-readable description surfaced to the model. */
|
|
25
|
+
description?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The record of one tool invocation attempt in a loop turn.
|
|
29
|
+
*/
|
|
30
|
+
export interface ToolInvocation {
|
|
31
|
+
/** The tool name the model asked for. */
|
|
32
|
+
slug: string;
|
|
33
|
+
/** Parsed arguments (best-effort JSON parse of the model's raw arguments). */
|
|
34
|
+
args: Record<string, unknown>;
|
|
35
|
+
/** Whether the operation executed successfully. */
|
|
36
|
+
ok: boolean;
|
|
37
|
+
/** The JSON-serializable observation fed back to the model. */
|
|
38
|
+
observation: unknown;
|
|
39
|
+
/** True when the call was denied (not on the allow-list / not permitted). */
|
|
40
|
+
rejected: boolean;
|
|
41
|
+
/** Error summary when `ok` is false. */
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/** Why {@link runToolLoop} returned. */
|
|
45
|
+
export type ToolLoopStopReason = 'stop' | 'max_steps' | 'no_tools';
|
|
46
|
+
/** The outcome of a {@link runToolLoop} turn. */
|
|
47
|
+
export interface ToolLoopResult {
|
|
48
|
+
/** The model's final assistant text. */
|
|
49
|
+
content: string;
|
|
50
|
+
/** Number of tool-executing rounds completed. */
|
|
51
|
+
steps: number;
|
|
52
|
+
/** Why the loop stopped. */
|
|
53
|
+
stoppedReason: ToolLoopStopReason;
|
|
54
|
+
/** Every tool invocation attempted this turn, in order. */
|
|
55
|
+
invocations: ToolInvocation[];
|
|
56
|
+
/** The full working transcript (input messages + assistant/tool turns). */
|
|
57
|
+
messages: AIMessage[];
|
|
58
|
+
/** Total tokens reported by the AI boundary, when available. */
|
|
59
|
+
totalTokens: number;
|
|
60
|
+
}
|
|
61
|
+
/** Context handed to a custom {@link ToolLoopOptions.executeTool} implementation. */
|
|
62
|
+
export interface ToolExecutionContext {
|
|
63
|
+
/** The principal run whose context bounds this execution. */
|
|
64
|
+
run: PrincipalRun;
|
|
65
|
+
/** The manifest operation to execute. */
|
|
66
|
+
tool: ManifestTool;
|
|
67
|
+
/** Parsed tool arguments. */
|
|
68
|
+
args: Record<string, unknown>;
|
|
69
|
+
/** The database handle to operate against (already the RLS-bound tx when on). */
|
|
70
|
+
db?: SmrtClassOptions['db'];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Options for {@link runToolLoop}.
|
|
74
|
+
*/
|
|
75
|
+
export interface ToolLoopOptions {
|
|
76
|
+
/** The AI boundary (the only thing mocked in tests). */
|
|
77
|
+
ai: AIInterface;
|
|
78
|
+
/** The initial conversation messages (system / history / user). */
|
|
79
|
+
messages: AIMessage[];
|
|
80
|
+
/** The manifest operations available this turn (already allow-list-filtered). */
|
|
81
|
+
tools: ManifestTool[];
|
|
82
|
+
/** The persona principal every tool call runs as. */
|
|
83
|
+
principal: PrincipalBinding;
|
|
84
|
+
/** Database handle the side-door operations run against. */
|
|
85
|
+
db?: SmrtClassOptions['db'];
|
|
86
|
+
/** Max tool-executing rounds before force-termination. Default {@link DEFAULT_MAX_STEPS}. */
|
|
87
|
+
maxSteps?: number;
|
|
88
|
+
/** Model id passed to the AI boundary. */
|
|
89
|
+
model?: string;
|
|
90
|
+
/** Sampling temperature. */
|
|
91
|
+
temperature?: number;
|
|
92
|
+
/** Max tokens per completion. */
|
|
93
|
+
maxTokens?: number;
|
|
94
|
+
/** Tool-choice behaviour while tools are offered. Default `'auto'`. */
|
|
95
|
+
toolChoice?: ChatOptions['toolChoice'];
|
|
96
|
+
/**
|
|
97
|
+
* Override the side-door executor. The default
|
|
98
|
+
* ({@link invokeManifestTool}) enforces the allow-list + catalog gate and
|
|
99
|
+
* dispatches through the ObjectRegistry. Tests inject a stub to exercise loop
|
|
100
|
+
* mechanics without a backing object.
|
|
101
|
+
*/
|
|
102
|
+
executeTool?: (ctx: ToolExecutionContext) => Promise<unknown>;
|
|
103
|
+
/** Notified after each tool invocation (for streaming/telemetry). */
|
|
104
|
+
onInvocation?: (invocation: ToolInvocation) => void | Promise<void>;
|
|
105
|
+
/** The originating user the turn runs on behalf of (audited). */
|
|
106
|
+
onBehalfOfUserId?: string | null;
|
|
107
|
+
/** Canonical agent class, recorded in the audit entry. */
|
|
108
|
+
agentClass?: string;
|
|
109
|
+
/** Audit sink forwarded to {@link executeAsPrincipal}. */
|
|
110
|
+
audit?: PrincipalAuditSink;
|
|
111
|
+
/** Opt into Postgres RLS transaction wrapping. */
|
|
112
|
+
postgresRls?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build the closed catalog of manifest operations available as tools.
|
|
116
|
+
*
|
|
117
|
+
* Reads the manifest-derived {@link PermissionCatalog} and keeps only the
|
|
118
|
+
* entries that name a dispatchable operation (a `(collection, action)` with a
|
|
119
|
+
* resolvable backing class). Pass `allowedTools` to narrow the catalog to a
|
|
120
|
+
* persona's least-privilege allow-list — this is the **offer gate**: a slug not
|
|
121
|
+
* in `allowedTools` is never returned, so it is neither offered to the model nor
|
|
122
|
+
* executed. A missing, `null`, or empty `allowedTools` yields **no tools**
|
|
123
|
+
* (fail-closed) — the same whitelist semantics as `AgentSession`/
|
|
124
|
+
* `PrincipalBinding` (S5 #1392), so forgetting the allow-list can only tighten,
|
|
125
|
+
* never widen, the offered surface. Pass `all: true` to deliberately enumerate
|
|
126
|
+
* the full manifest operation surface (e.g. an admin tool picker) — that is the
|
|
127
|
+
* one explicit escape hatch, never the default.
|
|
128
|
+
*/
|
|
129
|
+
export declare function buildManifestToolCatalog(options?: SmrtClassOptions & {
|
|
130
|
+
/** Least-privilege allow-list to narrow the catalog by (fail-closed). */
|
|
131
|
+
allowedTools?: string[] | null;
|
|
132
|
+
/** Explicitly enumerate the ENTIRE manifest operation surface (no narrowing). */
|
|
133
|
+
all?: boolean;
|
|
134
|
+
/** Supply a pre-built catalog (skips the manifest walk). */
|
|
135
|
+
catalog?: PermissionDefinition[];
|
|
136
|
+
}): ManifestTool[];
|
|
137
|
+
/**
|
|
138
|
+
* A provider-safe function name for a catalog slug.
|
|
139
|
+
*
|
|
140
|
+
* Catalog slugs are `collection.action` and routinely contain a `.`, but many
|
|
141
|
+
* providers (OpenAI) restrict function names to `[A-Za-z0-9_-]{1,64}`. This maps
|
|
142
|
+
* the slug into that charset (dots → `-`) for the wire; {@link runToolLoop} maps
|
|
143
|
+
* the returned name back to the tool, and `tool.slug` remains the internal
|
|
144
|
+
* permission id. Distinct slugs stay distinct (the only substituted char is the
|
|
145
|
+
* single `.` separator).
|
|
146
|
+
*/
|
|
147
|
+
export declare function toolFunctionName(slug: string): string;
|
|
148
|
+
/**
|
|
149
|
+
* Project a manifest operation into an AI function-tool definition. The function
|
|
150
|
+
* name is the provider-safe rendering of the catalog slug
|
|
151
|
+
* ({@link toolFunctionName}), so the model can only ever name a real operation.
|
|
152
|
+
*/
|
|
153
|
+
export declare function manifestToolToAITool(tool: ManifestTool): AITool;
|
|
154
|
+
/**
|
|
155
|
+
* Execute a manifest operation in-process ("side door") under the principal.
|
|
156
|
+
*
|
|
157
|
+
* Enforces both authority dimensions before touching data: the fail-closed tool
|
|
158
|
+
* allow-list ({@link PrincipalRun.assertToolAllowed}) and the catalog permission
|
|
159
|
+
* for the `(collection, action)` ({@link PrincipalRun.assertOperation}) — the
|
|
160
|
+
* door-agnostic teeth that hold on RLS-off adapters and are a redundant second
|
|
161
|
+
* gate under Postgres RLS. Data operations run against the principal context's
|
|
162
|
+
* database (the RLS-bound transaction when RLS is on), so tenant + per-operation
|
|
163
|
+
* enforcement apply exactly as they would through REST or MCP.
|
|
164
|
+
*/
|
|
165
|
+
export declare function invokeManifestTool(run: PrincipalRun, tool: ManifestTool, args: Record<string, unknown>, options?: {
|
|
166
|
+
db?: SmrtClassOptions['db'];
|
|
167
|
+
}): Promise<unknown>;
|
|
168
|
+
/**
|
|
169
|
+
* Run a bounded `tool_call → observe → respond` loop over the manifest operation
|
|
170
|
+
* surface, as the persona's bound principal.
|
|
171
|
+
*
|
|
172
|
+
* The whole turn runs inside a single {@link executeAsPrincipal} context, so
|
|
173
|
+
* every tool call shares one published permission snapshot (matching what a
|
|
174
|
+
* Postgres RLS session enforces) and the turn audits once as on-behalf-of the
|
|
175
|
+
* originating user.
|
|
176
|
+
*
|
|
177
|
+
* @param options - The AI boundary, seed messages, allow-list-filtered tools,
|
|
178
|
+
* principal, and ceiling.
|
|
179
|
+
* @returns The final assistant text plus the invocation log and transcript.
|
|
180
|
+
*/
|
|
181
|
+
export declare function runToolLoop(options: ToolLoopOptions): Promise<ToolLoopResult>;
|
|
182
|
+
//# sourceMappingURL=tool-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-loop.d.ts","sourceRoot":"","sources":["../src/tool-loop.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-chat",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.21",
|
|
4
4
|
"description": "Chat rooms, DMs, threads, and agent conversations for the SMRT framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"smrtRawPrimitives": "strict",
|
|
@@ -56,10 +56,15 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@happyvertical/
|
|
60
|
-
"@happyvertical/
|
|
61
|
-
"@happyvertical/smrt-
|
|
62
|
-
"@happyvertical/smrt-
|
|
59
|
+
"@happyvertical/ai": "^0.77.0",
|
|
60
|
+
"@happyvertical/sql": "^0.77.0",
|
|
61
|
+
"@happyvertical/smrt-agents": "0.38.21",
|
|
62
|
+
"@happyvertical/smrt-core": "0.38.21",
|
|
63
|
+
"@happyvertical/smrt-personas": "0.38.21",
|
|
64
|
+
"@happyvertical/smrt-tenancy": "0.38.21",
|
|
65
|
+
"@happyvertical/smrt-types": "0.38.21",
|
|
66
|
+
"@happyvertical/smrt-ui": "0.38.21",
|
|
67
|
+
"@happyvertical/smrt-users": "0.38.21"
|
|
63
68
|
},
|
|
64
69
|
"peerDependencies": {
|
|
65
70
|
"svelte": "^5.56.4"
|
|
@@ -79,9 +84,8 @@
|
|
|
79
84
|
"typescript": "^5.9.3",
|
|
80
85
|
"vite": "^8.1.3",
|
|
81
86
|
"vitest": "^4.1.9",
|
|
82
|
-
"@happyvertical/smrt-
|
|
83
|
-
"@happyvertical/smrt-
|
|
84
|
-
"@happyvertical/smrt-vitest": "0.38.20"
|
|
87
|
+
"@happyvertical/smrt-profiles": "0.38.21",
|
|
88
|
+
"@happyvertical/smrt-vitest": "0.38.21"
|
|
85
89
|
},
|
|
86
90
|
"scripts": {
|
|
87
91
|
"build": "vite build --mode library && svelte-package -i src/svelte -o dist/svelte --tsconfig tsconfig.svelte.json",
|