@data-club/ai-hub-server 0.0.9 → 0.0.10
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/auth/encryption.d.ts +5 -5
- package/dist/auth/encryption.js +5 -5
- package/dist/auth/userView.d.ts +8 -15
- package/dist/auth/userView.d.ts.map +1 -1
- package/dist/auth/userView.js +10 -23
- package/dist/auth/userView.js.map +1 -1
- package/dist/bootstrap.d.ts +2 -8
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +2 -35
- package/dist/bootstrap.js.map +1 -1
- package/dist/db/migrate.js +0 -17
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.d.ts +0 -263
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +0 -57
- package/dist/db/schema.js.map +1 -1
- package/dist/db/seed.d.ts +4 -19
- package/dist/db/seed.d.ts.map +1 -1
- package/dist/db/seed.js +6 -33
- package/dist/db/seed.js.map +1 -1
- package/dist/handlers/fetch.d.ts +6 -7
- package/dist/handlers/fetch.d.ts.map +1 -1
- package/dist/handlers/fetch.js +0 -2
- package/dist/handlers/fetch.js.map +1 -1
- package/dist/handlers/types.d.ts +5 -6
- package/dist/handlers/types.d.ts.map +1 -1
- package/dist/letta/client.d.ts +86 -263
- package/dist/letta/client.d.ts.map +1 -1
- package/dist/letta/client.js +99 -404
- package/dist/letta/client.js.map +1 -1
- package/dist/letta/index.d.ts +6 -8
- package/dist/letta/index.d.ts.map +1 -1
- package/dist/letta/index.js +5 -7
- package/dist/letta/index.js.map +1 -1
- package/dist/letta/sandbox.d.ts +45 -9
- package/dist/letta/sandbox.d.ts.map +1 -1
- package/dist/letta/sandbox.js +123 -11
- package/dist/letta/sandbox.js.map +1 -1
- package/dist/letta/types.d.ts +6 -49
- package/dist/letta/types.d.ts.map +1 -1
- package/dist/letta/types.js +5 -10
- package/dist/letta/types.js.map +1 -1
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +0 -2
- package/dist/observability/logger.js.map +1 -1
- package/dist/routes/admin/agents.d.ts.map +1 -1
- package/dist/routes/admin/agents.js +0 -40
- package/dist/routes/admin/agents.js.map +1 -1
- package/dist/routes/admin/settings.d.ts +6 -15
- package/dist/routes/admin/settings.d.ts.map +1 -1
- package/dist/routes/admin/settings.js +9 -107
- package/dist/routes/admin/settings.js.map +1 -1
- package/dist/routes/auth.d.ts +0 -4
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +1 -5
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +9 -30
- package/dist/routes/sessions.js.map +1 -1
- package/dist/state/turnRunner.d.ts.map +1 -1
- package/dist/state/turnRunner.js +1 -75
- package/dist/state/turnRunner.js.map +1 -1
- package/package.json +4 -4
- package/src/auth/encryption.ts +5 -5
- package/src/auth/userView.ts +9 -22
- package/src/bootstrap.ts +4 -43
- package/src/db/migrate.ts +0 -17
- package/src/db/schema.ts +0 -68
- package/src/db/seed.ts +6 -47
- package/src/handlers/fetch.ts +6 -9
- package/src/handlers/types.ts +5 -6
- package/src/letta/client.ts +170 -634
- package/src/letta/index.ts +8 -21
- package/src/letta/sandbox.ts +151 -11
- package/src/letta/types.ts +9 -60
- package/src/observability/logger.ts +0 -2
- package/src/routes/admin/agents.ts +0 -49
- package/src/routes/admin/settings.ts +9 -113
- package/src/routes/auth.ts +1 -5
- package/src/routes/sessions.ts +11 -32
- package/src/state/turnRunner.ts +1 -77
- package/src/letta/lettaCliShim.mjs +0 -40
- package/src/letta/settingsFileSeed.ts +0 -254
package/dist/letta/client.d.ts
CHANGED
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Letta access layer — server-less local backend.
|
|
3
3
|
*
|
|
4
|
-
* **
|
|
4
|
+
* AI Hub drives **Letta Code's local backend** through
|
|
5
|
+
* `@data-club/letta-runtime`: agent/conversation state lives on the local
|
|
6
|
+
* filesystem (`AI_HUB_LETTA_STORE_DIR`), chat turns run in an SDK-spawned
|
|
7
|
+
* Letta Code CLI subprocess, and inference is client-side (Letta Code's Pi
|
|
8
|
+
* provider layer calling Anthropic / AWS Bedrock directly). There is no
|
|
9
|
+
* Letta server and no `@letta-ai/letta-client` anywhere in this path — the
|
|
10
|
+
* server-backed implementation was removed in the local-backend migration
|
|
11
|
+
* (see docs/investigations/2026-07-01-letta-code-local-backend-migration.md).
|
|
5
12
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `streamUserMessage`. Spawns a Letta Code CLI subprocess per turn;
|
|
13
|
-
* the CLI's internal Pi (Provider Interface) + bundled `models.json`
|
|
14
|
-
* handle model selection, reasoning-tier presets, and provider
|
|
15
|
-
* fallback routing (e.g. Anthropic → Bedrock Opus 4.7). This is what
|
|
16
|
-
* keeps ai-hub current with model releases without code changes.
|
|
13
|
+
* **MCP tools.** Letta Code is not an MCP client; with no Letta server, AI
|
|
14
|
+
* Hub is the MCP host. On the first chat turn this module connects to the
|
|
15
|
+
* servers configured in `AI_HUB_MCP_SERVERS` (`name=url,name2=url2`,
|
|
16
|
+
* Streamable HTTP) and injects their tools into every session via the
|
|
17
|
+
* runtime's `tools` option; tool executions round-trip through the SDK's
|
|
18
|
+
* `execute_external_tool` control channel in this process.
|
|
17
19
|
*
|
|
18
|
-
* **
|
|
19
|
-
*
|
|
20
|
+
* **Tool suppression.** Letta Code's bundled tools are hidden from the
|
|
21
|
+
* model via `disallowedTools` (the headless-mode equivalent of the TUI's
|
|
22
|
+
* `/toolset none`). The old `--tools ""` CLI shim is gone — emptying the
|
|
23
|
+
* CLI's tool registry also strips SDK-injected MCP tools (verified
|
|
24
|
+
* empirically), so the disallow list is the only suppression mechanism.
|
|
20
25
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* instance per `(apiKey, baseURL)` pair so super-admin connection
|
|
25
|
-
* edits propagate without restart. The Letta-Code subprocess inherits
|
|
26
|
-
* `process.env` (which must carry `LETTA_BASE_URL` + `LETTA_API_KEY` —
|
|
27
|
-
* the boot script sets these from the same decrypted DB row).
|
|
28
|
-
*
|
|
29
|
-
* @see SPECIFICATIONS.md §6.4 — Letta integration
|
|
30
|
-
* @see SPECIFICATIONS.md §6.4.1 — first-class SDK surfaces
|
|
26
|
+
* This module composes AI-Hub policy (subprocess throttle, tool
|
|
27
|
+
* disallow-lists, sandbox cwd) around the runtime; everything Letta-shaped
|
|
28
|
+
* lives in `@data-club/letta-runtime`.
|
|
31
29
|
*/
|
|
32
|
-
import
|
|
33
|
-
import { resumeSession, type SDKMessage } from "@letta-ai/letta-code-sdk";
|
|
34
|
-
import type { DrizzleDB } from "../db/connection.js";
|
|
30
|
+
import { type LettaMessageRecord, type LettaRuntime, type SDKMessage } from "@data-club/letta-runtime";
|
|
35
31
|
import { type SubprocessThrottle } from "./subprocessThrottle.js";
|
|
36
|
-
import type { LettaMessage } from "./types.js";
|
|
37
32
|
export { ServerOverloadedError, SubprocessThrottle } from "./subprocessThrottle.js";
|
|
38
33
|
/**
|
|
39
|
-
* Thrown when `forkConversation(sourceId)`
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* validation should have caught it before any user-facing session
|
|
44
|
-
* create reached the fork path).
|
|
34
|
+
* Thrown when `forkConversation(sourceId)` resolves to "no such
|
|
35
|
+
* conversation". The admin agents validator catches this and returns
|
|
36
|
+
* `400 fork_source_not_found` inline on the field; the chat route surfaces
|
|
37
|
+
* it as a 500 (admin-side validation should have caught it earlier).
|
|
45
38
|
*
|
|
46
39
|
* @see docs/server/session-sandboxes.md
|
|
47
40
|
*/
|
|
@@ -49,307 +42,137 @@ export declare class ForkSourceNotFoundError extends Error {
|
|
|
49
42
|
readonly conversationId: string;
|
|
50
43
|
constructor(conversationId: string);
|
|
51
44
|
}
|
|
52
|
-
/**
|
|
53
|
-
* Provider-reported token usage for a single Letta run + the run's
|
|
54
|
-
* last assistant-message id (so callers can stamp the badge on the
|
|
55
|
-
* visible bubble). All token fields are nullable because the
|
|
56
|
-
* producing provider may not report every dimension — Anthropic
|
|
57
|
-
* reports `cache_write_tokens`, others don't; reasoning tokens come
|
|
58
|
-
* back only when the model produced any; etc.
|
|
59
|
-
*
|
|
60
|
-
* Sourced via a single `GET /v1/runs/{run_id}/messages` call.
|
|
61
|
-
*/
|
|
62
|
-
export interface RunUsageStats {
|
|
63
|
-
/**
|
|
64
|
-
* Id of the LAST `assistant_message`-typed entry in the run. `null`
|
|
65
|
-
* when the run had no assistant messages (rare — error-only runs).
|
|
66
|
-
* Callers stamp `message_usage` against this id.
|
|
67
|
-
*/
|
|
68
|
-
lastAssistantMessageId: string | null;
|
|
69
|
-
promptTokens: number | null;
|
|
70
|
-
completionTokens: number | null;
|
|
71
|
-
totalTokens: number | null;
|
|
72
|
-
cachedInputTokens: number | null;
|
|
73
|
-
cacheWriteTokens: number | null;
|
|
74
|
-
reasoningTokens: number | null;
|
|
75
|
-
contextTokens: number | null;
|
|
76
|
-
}
|
|
77
45
|
/** Parameters for `streamUserMessage`. */
|
|
78
46
|
export interface StreamUserMessageOpts {
|
|
79
47
|
/** The Letta conversation id (`session.letta_conversation_id`). */
|
|
80
48
|
conversationId: string;
|
|
81
49
|
/**
|
|
82
|
-
* The Letta agent id the session is against.
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* agent-registration-time seed isn't reliable on its own. The
|
|
86
|
-
* seed-on-spawn call below is idempotent (no-op when the entry
|
|
87
|
-
* is already present with the same value).
|
|
50
|
+
* The Letta agent id the session is against. Not needed to spawn a turn
|
|
51
|
+
* on the local backend (the conversation record carries its agent), but
|
|
52
|
+
* kept on the opts shape for logging and interface stability.
|
|
88
53
|
*/
|
|
89
54
|
lettaAgentId: string;
|
|
90
55
|
/**
|
|
91
|
-
* Plain-text user message body. Sent verbatim
|
|
92
|
-
*
|
|
93
|
-
* agent's persisted `system` field), so we don't re-inject it here.
|
|
56
|
+
* Plain-text user message body. Sent verbatim. The admin's system prompt
|
|
57
|
+
* is delivered through the agent record's persisted `system` field.
|
|
94
58
|
*/
|
|
95
59
|
userMessage: string;
|
|
96
60
|
/**
|
|
97
61
|
* Step-12.5 — optional working directory for the spawned Letta Code
|
|
98
|
-
* subprocess. When set,
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* provided, the spawn ALSO drops the `FILESYSTEM_TOOLS` group from
|
|
102
|
-
* the `disallowedTools` list so the agent can actually read / write
|
|
103
|
-
* inside that folder.
|
|
104
|
-
*
|
|
105
|
-
* When `undefined`, no `cwd` is passed (the CLI inherits the
|
|
106
|
-
* ai-hub-server process's working directory, as it always has) AND
|
|
107
|
-
* the filesystem tools remain disallowed — today's stateless agent
|
|
108
|
-
* shape.
|
|
62
|
+
* subprocess (per-session sandbox folder). When set, the filesystem
|
|
63
|
+
* tools are re-enabled so the agent can use the seeded files; when
|
|
64
|
+
* `undefined`, they stay disallowed.
|
|
109
65
|
*
|
|
110
66
|
* @see docs/server/session-sandboxes.md
|
|
111
67
|
*/
|
|
112
68
|
cwd?: string;
|
|
113
69
|
}
|
|
114
70
|
/**
|
|
115
|
-
* Handle returned by `streamUserMessage`. Wraps the
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* Lifecycle expectations:
|
|
71
|
+
* Handle returned by `streamUserMessage`. Wraps the runtime's turn handle +
|
|
72
|
+
* the subprocess-throttle lease so the caller owns one resource bundle to
|
|
73
|
+
* drain, cancel, and clean up.
|
|
120
74
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* during model generation interrupts work cleanly; during a
|
|
125
|
-
* long-running tool call the interrupt is currently queued (see
|
|
126
|
-
* migration plan §7 open question 5).
|
|
127
|
-
* 3. Caller MUST call `close()` in a `finally` regardless of how the
|
|
128
|
-
* iteration ended (done, cancelled, error). `close()` terminates
|
|
129
|
-
* the CLI subprocess + releases the throttle lease. Idempotent.
|
|
75
|
+
* Lifecycle: iterate `events`; `abort()` to interrupt; ALWAYS `close()` in
|
|
76
|
+
* a `finally` (terminates the CLI subprocess + releases the throttle lease;
|
|
77
|
+
* idempotent).
|
|
130
78
|
*/
|
|
131
79
|
export interface ChatTurnHandle {
|
|
132
80
|
/** Async iterable of Letta Code SDK messages — caller drains this. */
|
|
133
81
|
events: AsyncIterable<SDKMessage>;
|
|
134
|
-
/**
|
|
135
|
-
* Sends an `interrupt` control to the spawned CLI. Best-effort; if
|
|
136
|
-
* the CLI is mid-tool the interrupt may be queued. The caller still
|
|
137
|
-
* needs to call `close()` to release subprocess + lease.
|
|
138
|
-
*/
|
|
82
|
+
/** Sends an `interrupt` control to the spawned CLI. Best-effort. */
|
|
139
83
|
abort(): Promise<void>;
|
|
140
|
-
/**
|
|
141
|
-
* Tears down the Letta Code subprocess + releases the throttle slot.
|
|
142
|
-
* Idempotent — safe to call twice. Caller MUST invoke this in a
|
|
143
|
-
* `finally`. Sync because the SDK's `session.close()` is sync.
|
|
144
|
-
*/
|
|
84
|
+
/** Tears down the subprocess + releases the throttle slot. Idempotent. */
|
|
145
85
|
close(): void;
|
|
146
86
|
}
|
|
147
87
|
/**
|
|
148
|
-
* Project-shaped Letta client. The handlers depend on this interface,
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* @see SPECIFICATIONS.md §6.4
|
|
88
|
+
* Project-shaped Letta client. The handlers depend on this interface, not
|
|
89
|
+
* on the underlying runtime, so tests can plug a mock implementation in via
|
|
90
|
+
* `getLettaClient` on the server context.
|
|
153
91
|
*/
|
|
154
92
|
export interface LettaClient {
|
|
155
93
|
/**
|
|
156
|
-
* Retrieves a Letta agent by id
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* error rethrows — the admin handler returns 500.
|
|
161
|
-
*
|
|
162
|
-
* @param lettaAgentId - candidate Letta-side agent id.
|
|
163
|
-
* @returns the agent state or `null` if not found.
|
|
94
|
+
* Retrieves a Letta agent by id from the local store. Returns `null`
|
|
95
|
+
* (not throws) on miss so the agent-validation flow on
|
|
96
|
+
* `POST/PATCH /admin/agents` can return a 400 `letta_agent_not_found`
|
|
97
|
+
* without try/catch noise.
|
|
164
98
|
*/
|
|
165
99
|
retrieveAgent(lettaAgentId: string): Promise<{
|
|
166
100
|
id: string;
|
|
167
101
|
name: string;
|
|
168
|
-
/** Provider-prefixed model handle (e.g. `"anthropic
|
|
102
|
+
/** Provider-prefixed model handle (e.g. `"bedrock/eu.anthropic.claude-opus-4-6-v1"`). */
|
|
169
103
|
model: string;
|
|
170
104
|
} | null>;
|
|
171
|
-
/**
|
|
172
|
-
* Creates a fresh conversation against the given Letta agent (via
|
|
173
|
-
* `@letta-ai/letta-client`). Returns the conversation id we store
|
|
174
|
-
* on the new session row.
|
|
175
|
-
*
|
|
176
|
-
* @param lettaAgentId - the Letta-side agent id.
|
|
177
|
-
* @returns the new conversation's id.
|
|
178
|
-
*/
|
|
105
|
+
/** Creates a fresh conversation against the given agent. */
|
|
179
106
|
createConversation(lettaAgentId: string): Promise<{
|
|
180
107
|
id: string;
|
|
181
108
|
}>;
|
|
182
109
|
/**
|
|
183
|
-
*
|
|
184
|
-
* `
|
|
185
|
-
* validator to verify `fork_source_conversation_id` resolves to a
|
|
186
|
-
* real conversation AND that its `agent_id` matches the agent's
|
|
187
|
-
* `letta_agent_id` (Letta's fork API requires same-agent forking).
|
|
188
|
-
*
|
|
189
|
-
* Returns `null` on Letta 404 so the handler can surface
|
|
190
|
-
* `400 fork_source_not_found` without try/catch noise; non-404
|
|
191
|
-
* SDK errors propagate.
|
|
192
|
-
*
|
|
193
|
-
* @param conversationId - the candidate Letta conversation id.
|
|
194
|
-
* @returns `{ id, agentId }` or `null` if not found.
|
|
110
|
+
* Retrieves a conversation by id (admin fork-source validation). Returns
|
|
111
|
+
* `null` on miss.
|
|
195
112
|
*/
|
|
196
113
|
retrieveConversation(conversationId: string): Promise<{
|
|
197
114
|
id: string;
|
|
198
115
|
agentId: string;
|
|
199
116
|
} | null>;
|
|
200
117
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* source's in-context messages and gets a freshly compiled system
|
|
205
|
-
* message reflecting the agent's current memory-block values.
|
|
118
|
+
* Clones an existing conversation (transcript included) into a new one
|
|
119
|
+
* on the same agent. Powers session creation from a rotating message's
|
|
120
|
+
* prepared conversation.
|
|
206
121
|
*
|
|
207
|
-
*
|
|
208
|
-
* `fork_source_conversation_id` is set. The admin endpoint validates
|
|
209
|
-
* source existence + agent match at write time, so this call is
|
|
210
|
-
* expected to succeed in the happy path; a 404 here is treated as
|
|
211
|
-
* "operator deleted the source conversation between admin-validate
|
|
212
|
-
* and user-session-create" and surfaced as `ForkSourceNotFoundError`.
|
|
213
|
-
*
|
|
214
|
-
* @param sourceConversationId - the Letta conversation id to fork.
|
|
215
|
-
* @returns the new conversation's `{ id, agentId }`.
|
|
216
|
-
* @throws ForkSourceNotFoundError on Letta 404.
|
|
122
|
+
* @throws ForkSourceNotFoundError when the source no longer exists.
|
|
217
123
|
*/
|
|
218
124
|
forkConversation(sourceConversationId: string): Promise<{
|
|
219
125
|
id: string;
|
|
220
126
|
agentId: string;
|
|
221
127
|
}>;
|
|
222
|
-
/**
|
|
223
|
-
* Lists every message in a conversation, oldest first (via
|
|
224
|
-
* `@letta-ai/letta-client`). Used for `GET /sessions/{id}/messages`
|
|
225
|
-
* history rendering.
|
|
226
|
-
*
|
|
227
|
-
* @param conversationId - the Letta conversation id.
|
|
228
|
-
* @returns the (oldest-first) array of messages.
|
|
229
|
-
*/
|
|
128
|
+
/** Lists every message in a conversation, oldest first. */
|
|
230
129
|
listMessages(conversationId: string): Promise<ReadonlyArray<LettaMessage>>;
|
|
231
130
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
* endpoint via the SDK's raw HTTP escape hatch (`sdk.delete(...)`) — the
|
|
237
|
-
* same pattern `getRunUsageStats` uses for `sdk.get(...)`. A 404 is treated
|
|
238
|
-
* as "already gone" and swallowed; other errors propagate.
|
|
239
|
-
*
|
|
240
|
-
* Used by the rotation runner to remove the prompt's `user_message` so a
|
|
241
|
-
* rotating starting message's prepared conversation opens with the agent's
|
|
242
|
-
* reply.
|
|
243
|
-
*
|
|
244
|
-
* @param lettaAgentId - the agent the message belongs to.
|
|
245
|
-
* @param messageId - the message id (from `listMessages`).
|
|
131
|
+
* NO-OP on the local backend. Message deletion was a Letta-server REST
|
|
132
|
+
* capability; per the migration decision, rotating messages now keep
|
|
133
|
+
* their initial prompt message instead of deleting it. The method stays
|
|
134
|
+
* on the interface so the rotation runner's flow is unchanged.
|
|
246
135
|
*/
|
|
247
136
|
deleteMessage(lettaAgentId: string, messageId: string): Promise<void>;
|
|
248
137
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* conversation after a successful rotation produces a fresh one — a 404 is
|
|
252
|
-
* swallowed; other errors propagate to the caller (which logs + continues).
|
|
253
|
-
*
|
|
254
|
-
* @param conversationId - the Letta conversation id to delete.
|
|
138
|
+
* NO-OP on the local backend. Old prepared conversations are left in the
|
|
139
|
+
* local store (orphans are harmless files); a cleanup pass can come later.
|
|
255
140
|
*/
|
|
256
141
|
deleteConversation(conversationId: string): Promise<void>;
|
|
257
142
|
/**
|
|
258
|
-
*
|
|
259
|
-
* prompt-cache hit / write counts. The SDK's `session.stream()`
|
|
260
|
-
* drops `usage_statistics` messages, so we re-fetch via REST after
|
|
261
|
-
* the turn lands; the runner uses this to stamp a usage badge on
|
|
262
|
-
* the last assistant message.
|
|
143
|
+
* Spawns a Letta Code CLI subprocess and streams a chat turn.
|
|
263
144
|
*
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
* @param runId - Letta run id captured from `SDKAssistantMessage.runId`.
|
|
271
|
-
*/
|
|
272
|
-
getRunUsageStats(runId: string): Promise<RunUsageStats | null>;
|
|
273
|
-
/**
|
|
274
|
-
* Spawns a Letta Code CLI subprocess and streams a chat turn against
|
|
275
|
-
* the given conversation. Returns a `ChatTurnHandle` the caller
|
|
276
|
-
* drains + cancels + closes.
|
|
277
|
-
*
|
|
278
|
-
* Pre-flight checks (in order, all may throw):
|
|
279
|
-
* 1. **Subprocess throttle.** `SubprocessThrottle.acquire()` runs
|
|
280
|
-
* first — throws `ServerOverloadedError` if RAM is under the
|
|
281
|
-
* threshold or the hard-cap is reached. The chat route catches
|
|
282
|
-
* this and returns HTTP 503 `server_overloaded`.
|
|
283
|
-
* 2. **Session initialization.** `session.initialize()` may throw if
|
|
284
|
-
* the CLI subprocess fails to spawn or can't reach Letta. The
|
|
285
|
-
* lease is released before the throw so the throttle counter
|
|
286
|
-
* doesn't leak.
|
|
287
|
-
*
|
|
288
|
-
* The Letta Code session is configured for the ai-hub use case:
|
|
289
|
-
* - `permissionMode: "bypassPermissions"` — no interactive approvals
|
|
290
|
-
* (we don't expose them to end-users in v1).
|
|
291
|
-
* - `skillSources: []` — no auto-loaded skills (challenge 2 in the
|
|
292
|
-
* migration brief).
|
|
293
|
-
* - `systemInfoReminder: false` — no first-turn environment dump.
|
|
294
|
-
* - `memfsStartup: "skip"` — no git-backed memory filesystem.
|
|
295
|
-
* - `disallowedTools: ["AskUserQuestion", "EnterPlanMode",
|
|
296
|
-
* "ExitPlanMode"]` — tools that require runtime user input.
|
|
297
|
-
*
|
|
298
|
-
* Toolset suppression is handled out-of-band by the
|
|
299
|
-
* `seedAgentToolsetNone` upsert into `~/.letta/settings.json` at
|
|
300
|
-
* agent-registration time.
|
|
301
|
-
*
|
|
302
|
-
* @param opts - see `StreamUserMessageOpts`.
|
|
303
|
-
* @returns a `ChatTurnHandle` the caller drains and closes.
|
|
304
|
-
* @throws `ServerOverloadedError` when the throttle rejects.
|
|
145
|
+
* Pre-flight (in order, both may throw):
|
|
146
|
+
* 1. `SubprocessThrottle.acquire()` — `ServerOverloadedError` → HTTP 503.
|
|
147
|
+
* 2. MCP bridge connect (first turn only, cached after) — a configured
|
|
148
|
+
* MCP server that can't be reached fails the turn rather than
|
|
149
|
+
* presenting a differently-capable agent.
|
|
305
150
|
*/
|
|
306
151
|
streamUserMessage(opts: StreamUserMessageOpts): Promise<ChatTurnHandle>;
|
|
307
152
|
}
|
|
153
|
+
/** One Letta-format message as consumed by history renderers. */
|
|
154
|
+
export type LettaMessage = LettaMessageRecord;
|
|
308
155
|
/** Dependency bundle for `createDefaultLettaClient`. */
|
|
309
156
|
export interface CreateLettaClientDeps {
|
|
310
|
-
/** Drizzle handle. */
|
|
311
|
-
db: DrizzleDB;
|
|
312
|
-
/** Parsed encryption key for decrypting the Letta API key at rest. */
|
|
313
|
-
encryptionKey: Buffer;
|
|
314
157
|
/** Subprocess-spawn throttle (shared across the server instance). */
|
|
315
158
|
subprocessThrottle: SubprocessThrottle;
|
|
316
159
|
/**
|
|
317
|
-
* Env source
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
160
|
+
* Env source. Reads:
|
|
161
|
+
* - `AI_HUB_LETTA_STORE_DIR` — local-backend store (default
|
|
162
|
+
* `~/.letta/lc-local-backend`; on deployments point this at the
|
|
163
|
+
* persistent encrypted volume, shared with operator SSH sessions).
|
|
164
|
+
* - `AI_HUB_LETTA_CLI_PATH` — Letta Code CLI entry override (default:
|
|
165
|
+
* the installed `@data-club/letta-code` package).
|
|
166
|
+
* - `AI_HUB_MCP_SERVERS` — MCP servers to host (`name=url,...`); empty
|
|
167
|
+
* or unset → no MCP tools.
|
|
322
168
|
*/
|
|
323
169
|
envSource?: Record<string, string | undefined>;
|
|
324
|
-
/**
|
|
325
|
-
|
|
326
|
-
* Production passes the SDK's `Letta` class (or omits to use the
|
|
327
|
-
* default).
|
|
328
|
-
*/
|
|
329
|
-
sdkConstructor?: typeof LettaSdkDefault;
|
|
330
|
-
/**
|
|
331
|
-
* Override `resumeSession` from `@letta-ai/letta-code-sdk` — only
|
|
332
|
-
* used by tests, which inject a fake session factory.
|
|
333
|
-
*/
|
|
334
|
-
resumeSessionFn?: typeof resumeSession;
|
|
170
|
+
/** Override the runtime — only used by tests. */
|
|
171
|
+
runtime?: LettaRuntime;
|
|
335
172
|
}
|
|
336
173
|
/**
|
|
337
|
-
* Constructs the default `LettaClient` implementation
|
|
338
|
-
*
|
|
339
|
-
* Reads `admin_setting.letta_base_url` + `letta_api_key_encrypted` on
|
|
340
|
-
* each Letta-Client call (no in-flight polling — fresh-on-demand) and
|
|
341
|
-
* memoizes the underlying SDK instance against `(apiKey, baseURL)` so
|
|
342
|
-
* super-admin connection-settings edits propagate without restart.
|
|
343
|
-
*
|
|
344
|
-
* Throws on the first Letta-Client call if `admin_setting` has no
|
|
345
|
-
* `letta_base_url` or no decryptable API key.
|
|
346
|
-
*
|
|
347
|
-
* @param deps - see `CreateLettaClientDeps`.
|
|
348
|
-
* @returns the project-shaped Letta client.
|
|
349
|
-
*
|
|
350
|
-
* @see SPECIFICATIONS.md §6.4
|
|
351
|
-
* @see SPECIFICATIONS.md §11 — `admin_setting` schema
|
|
174
|
+
* Constructs the default `LettaClient` implementation over the local
|
|
175
|
+
* backend. See the module doc for the architecture.
|
|
352
176
|
*/
|
|
353
177
|
export declare function createDefaultLettaClient(deps: CreateLettaClientDeps): LettaClient;
|
|
354
|
-
export type { LettaMessage, LettaSdk } from "./types.js";
|
|
355
178
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/letta/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/letta/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,UAAU,EAEhB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAEpF;;;;;;;GAOG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,cAAc,EAAE,MAAM;gBAAtB,cAAc,EAAE,MAAM;CAInD;AAsED,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,sEAAsE;IACtE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAClC,oEAAoE;IACpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,0EAA0E;IAC1E,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAC3C,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,yFAAyF;QACzF,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,IAAI,CAAC,CAAC;IACV,4DAA4D;IAC5D,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE;;;OAGG;IACH,oBAAoB,CAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACnD;;;;;;OAMG;IACH,gBAAgB,CACd,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5C,2DAA2D;IAC3D,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3E;;;;;OAKG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;OAGG;IACH,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D;;;;;;;;OAQG;IACH,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzE;AAED,iEAAiE;AACjE,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAM9C,wDAAwD;AACxD,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,kBAAkB,EAAE,kBAAkB,CAAC;IACvC;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/C,iDAAiD;IACjD,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAQD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,qBAAqB,GAC1B,WAAW,CAiHb"}
|