ai-sdk-letta 0.1.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/CHANGELOG.md +7 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +35 -0
- package/dist/agent.d.ts +108 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +371 -0
- package/dist/agent.js.map +1 -0
- package/dist/definition.d.ts +81 -0
- package/dist/definition.d.ts.map +1 -0
- package/dist/definition.js +87 -0
- package/dist/definition.js.map +1 -0
- package/dist/history.d.ts +38 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +226 -0
- package/dist/history.js.map +1 -0
- package/dist/identity.d.ts +43 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +158 -0
- package/dist/identity.js.map +1 -0
- package/dist/images.d.ts +83 -0
- package/dist/images.d.ts.map +1 -0
- package/dist/images.js +181 -0
- package/dist/images.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/interactions.d.ts +61 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +110 -0
- package/dist/interactions.js.map +1 -0
- package/dist/memory.d.ts +11 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +55 -0
- package/dist/memory.js.map +1 -0
- package/dist/navigation.d.ts +50 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +87 -0
- package/dist/navigation.js.map +1 -0
- package/dist/runtime.d.ts +83 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +246 -0
- package/dist/runtime.js.map +1 -0
- package/dist/state.d.ts +24 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +39 -0
- package/dist/state.js.map +1 -0
- package/dist/tools.d.ts +83 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +162 -0
- package/dist/tools.js.map +1 -0
- package/package.json +67 -0
- package/src/agent.ts +334 -0
- package/src/definition.ts +136 -0
- package/src/history.ts +198 -0
- package/src/identity.ts +125 -0
- package/src/images.ts +184 -0
- package/src/index.ts +23 -0
- package/src/interactions.ts +121 -0
- package/src/memory.ts +42 -0
- package/src/navigation.ts +84 -0
- package/src/runtime.ts +243 -0
- package/src/state.ts +39 -0
- package/src/tools.ts +166 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { loadHistory, projectHistory, sanitizeText } from './history.js';
|
|
2
|
+
/** Newest conversations of one agent (up to 200 plus `default`), excluding archived ones. */
|
|
3
|
+
export async function listNavigationEntries(list, agentId, signal) {
|
|
4
|
+
const entries = [{ id: 'default', title: 'Default conversation', date: 'activity unavailable' }];
|
|
5
|
+
const seen = new Set(['default']);
|
|
6
|
+
let after;
|
|
7
|
+
let limited = false;
|
|
8
|
+
for (let index = 0; index < 3; index++) {
|
|
9
|
+
signal?.throwIfAborted();
|
|
10
|
+
const page = await list({ agentId, limit: 100, order: 'desc', orderBy: 'createdAt', ...(after ? { after } : {}) });
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
if (page.length > 100)
|
|
13
|
+
throw new Error('Oversized conversation page');
|
|
14
|
+
if (!page.length)
|
|
15
|
+
break;
|
|
16
|
+
for (const row of page) {
|
|
17
|
+
if (row.agent_id !== agentId || seen.has(row.id))
|
|
18
|
+
throw new Error('Conversation listing escaped current agent or repeated cursor');
|
|
19
|
+
seen.add(row.id);
|
|
20
|
+
if (index === 2) {
|
|
21
|
+
limited = true;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (!row.archived)
|
|
25
|
+
entries.push({ id: row.id, title: sanitizeText(row.summary || 'Untitled conversation'), date: row.last_message_at || row.updated_at || row.created_at || 'activity unavailable' });
|
|
26
|
+
}
|
|
27
|
+
if (limited)
|
|
28
|
+
break;
|
|
29
|
+
after = page.at(-1).id;
|
|
30
|
+
}
|
|
31
|
+
return { entries, limited };
|
|
32
|
+
}
|
|
33
|
+
export const SEARCH_CONVERSATIONS = 50;
|
|
34
|
+
export const SEARCH_RECORDS = 500;
|
|
35
|
+
export const SEARCH_TOTAL = 5000;
|
|
36
|
+
export const SEARCH_MATCHES = 100;
|
|
37
|
+
export const SEARCH_MILLISECONDS = 30_000;
|
|
38
|
+
const plain = (text) => sanitizeText(text).replace(/\s+/g, ' ').trim();
|
|
39
|
+
/** A short excerpt of `text` around the first match of `query`. */
|
|
40
|
+
export function snippet(text, query) {
|
|
41
|
+
const clean = plain(text);
|
|
42
|
+
const at = clean.toLowerCase().indexOf(query.toLowerCase());
|
|
43
|
+
const start = Math.max(0, at - 65);
|
|
44
|
+
return `${start ? '…' : ''}${clean.slice(start, start + 220)}${clean.length > start + 220 ? '…' : ''}`;
|
|
45
|
+
}
|
|
46
|
+
/** Literal, case-insensitive text search. Only authoritative human/assistant text
|
|
47
|
+
* enters the projection: never tools, reasoning, system or memory records. */
|
|
48
|
+
export async function searchConversations(source, entries, query, signal, progress = () => { }) {
|
|
49
|
+
if (!query.trim() || query.length > 200)
|
|
50
|
+
throw new Error('Search requires 1–200 characters');
|
|
51
|
+
const matches = [];
|
|
52
|
+
let records = 0;
|
|
53
|
+
let scanned = 0;
|
|
54
|
+
let limited = entries.length > SEARCH_CONVERSATIONS;
|
|
55
|
+
const deadline = Date.now() + SEARCH_MILLISECONDS;
|
|
56
|
+
const check = () => { signal.throwIfAborted(); if (Date.now() >= deadline)
|
|
57
|
+
throw new Error('Search deadline reached'); };
|
|
58
|
+
for (const conversation of entries.slice(0, SEARCH_CONVERSATIONS)) {
|
|
59
|
+
check();
|
|
60
|
+
if (records >= SEARCH_TOTAL || matches.length >= SEARCH_MATCHES) {
|
|
61
|
+
limited = true;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
progress(`Searching ${scanned + 1}/${Math.min(entries.length, SEARCH_CONVERSATIONS)} · ${records} records · Esc cancels after current read`);
|
|
65
|
+
const history = await loadHistory(async (options) => {
|
|
66
|
+
check();
|
|
67
|
+
const page = await source.page(conversation.id, options);
|
|
68
|
+
check();
|
|
69
|
+
records += page.messages.length;
|
|
70
|
+
return page;
|
|
71
|
+
}, Math.min(SEARCH_RECORDS, SEARCH_TOTAL - records));
|
|
72
|
+
limited ||= history.truncated;
|
|
73
|
+
scanned++;
|
|
74
|
+
for (const message of projectHistory(history.messages, [], 0)) {
|
|
75
|
+
const text = message.parts.filter(p => p.type === 'text').map(p => p.text).join('\n');
|
|
76
|
+
if (plain(text).toLowerCase().includes(query.toLowerCase())) {
|
|
77
|
+
if (matches.length >= SEARCH_MATCHES) {
|
|
78
|
+
limited = true;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
matches.push({ conversation, role: message.role, snippet: snippet(text, query) });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { matches, records, scanned, limited };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type LettaCodeClientSessionOptions, type LettaConversation, type SessionDeviceStatus } from '@letta-ai/letta-agent-sdk';
|
|
2
|
+
import type { ToolSet } from 'ai';
|
|
3
|
+
import { LettaAgent } from './agent.js';
|
|
4
|
+
import { type AgentDefinition } from './definition.js';
|
|
5
|
+
import { type Identity } from './identity.js';
|
|
6
|
+
import { type NavigationSource } from './navigation.js';
|
|
7
|
+
import { type ToolActivity, type ToolBridge } from './tools.js';
|
|
8
|
+
/** Which conversation to open. `null` means "open nothing" (for example, the user quit a picker). */
|
|
9
|
+
export type ConversationChoice = {
|
|
10
|
+
conversationId: string;
|
|
11
|
+
} | {
|
|
12
|
+
newTitle: string;
|
|
13
|
+
} | null;
|
|
14
|
+
/** Options for {@link openLettaAgent}. */
|
|
15
|
+
export interface OpenAgentOptions {
|
|
16
|
+
/** State root; see {@link resolveStateDirectory}. */
|
|
17
|
+
stateDirectory?: string;
|
|
18
|
+
/** Open this conversation (`'default'` or a Letta conversation ID). */
|
|
19
|
+
conversationId?: string;
|
|
20
|
+
/** Create and open a new conversation with this title. */
|
|
21
|
+
newTitle?: string;
|
|
22
|
+
/** Interactive picker; takes precedence over `conversationId`/`newTitle`. */
|
|
23
|
+
choose?: (identity: Identity, conversations: LettaConversation[]) => Promise<ConversationChoice>;
|
|
24
|
+
/**
|
|
25
|
+
* Keep application tools in the foreground for up to five minutes. Without
|
|
26
|
+
* this, the Letta harness backgrounds a client tool after about 10 seconds,
|
|
27
|
+
* which breaks human approvals and questions. @default true
|
|
28
|
+
*/
|
|
29
|
+
foregroundExternalTools?: boolean;
|
|
30
|
+
/** Tool audit trail: `true` writes private NDJSON under the state directory, or pass a sink. @default true */
|
|
31
|
+
traces?: boolean | ((event: ToolActivity) => void);
|
|
32
|
+
}
|
|
33
|
+
/** An opened agent plus the resources that belong to it. */
|
|
34
|
+
export interface LettaRuntime<TOOLS extends ToolSet = ToolSet> {
|
|
35
|
+
agent: LettaAgent<TOOLS>;
|
|
36
|
+
identity: Identity;
|
|
37
|
+
/** Read-only conversation listing and search for the same agent. */
|
|
38
|
+
navigation: NavigationSource;
|
|
39
|
+
/** Close the session and SDK client, then release the identity lock. Idempotent. */
|
|
40
|
+
close(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
/** Letta local backend directory used to key identity mappings. */
|
|
43
|
+
export declare function localBackendDirectory(env?: NodeJS.ProcessEnv): string;
|
|
44
|
+
/** @throws unless the session is online, idle and has no queued or pending work. */
|
|
45
|
+
export declare function assertIdle(status: SessionDeviceStatus): void;
|
|
46
|
+
/** Letta session options: application tools plus MemFS tools confined to the agent's memory. */
|
|
47
|
+
export declare function sessionOptions(bridge: ToolBridge, getMemoryRoot: () => string | undefined, cwd: string, memoryAuthor?: string): LettaCodeClientSessionOptions;
|
|
48
|
+
/**
|
|
49
|
+
* Runtime-scoped protocol command that keeps application tools in the
|
|
50
|
+
* foreground (no auto-backgrounding) with a five-minute timeout.
|
|
51
|
+
*/
|
|
52
|
+
export declare function foregroundToolsCommand(bridge: Pick<ToolBridge, 'tools'>, agentId: string, conversationId: string): {
|
|
53
|
+
type: string;
|
|
54
|
+
updates: {
|
|
55
|
+
runtimes: {
|
|
56
|
+
agent_id: string;
|
|
57
|
+
conversation_id: string;
|
|
58
|
+
}[];
|
|
59
|
+
external_tools: {
|
|
60
|
+
tools: {
|
|
61
|
+
name: string;
|
|
62
|
+
label: string;
|
|
63
|
+
description: string;
|
|
64
|
+
parameters: any;
|
|
65
|
+
auto_background: boolean;
|
|
66
|
+
timeout_ms: number;
|
|
67
|
+
}[];
|
|
68
|
+
}[];
|
|
69
|
+
}[];
|
|
70
|
+
};
|
|
71
|
+
/** Open an agent, or throw if no conversation was selected. */
|
|
72
|
+
export declare function createLettaAgent<TOOLS extends ToolSet>(definition: AgentDefinition<TOOLS>, options?: Omit<OpenAgentOptions, 'choose'>): Promise<LettaRuntime<TOOLS>>;
|
|
73
|
+
/**
|
|
74
|
+
* Open (creating on first use) the persistent Letta agent for a definition on
|
|
75
|
+
* the local Letta backend, and return a ready {@link LettaAgent}.
|
|
76
|
+
*
|
|
77
|
+
* Steps, each failing closed: acquire the identity lock and mapping; select or
|
|
78
|
+
* create a conversation; resume the session; verify it is idle and its history
|
|
79
|
+
* settled; restore display history; apply project-scoped dreaming and verify
|
|
80
|
+
* it; confirm MemFS. Returns `undefined` if `choose` returned `null`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function openLettaAgent<TOOLS extends ToolSet>(definition: AgentDefinition<TOOLS>, options?: OpenAgentOptions): Promise<LettaRuntime<TOOLS> | undefined>;
|
|
83
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,6BAA6B,EAAyB,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAC1K,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAA2D,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChH,OAAO,EAAwC,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGpF,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE/E,OAAO,EAAqC,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGnG,qGAAqG;AACrG,MAAM,MAAM,kBAAkB,GAAG;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAE1F,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjG;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,8GAA8G;IAC9G,MAAM,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,CAAC;CACpD;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY,CAAC,KAAK,SAAS,OAAO,GAAG,OAAO;IAC3D,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,oEAAoE;IACpE,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oFAAoF;IACpF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAElF;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAE5D;AAED,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,6BAA6B,CAgB7J;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;EAKhH;AAED,+DAA+D;AAC/D,wBAAsB,gBAAgB,CAAC,KAAK,SAAS,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAI9K;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,KAAK,SAAS,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAyIxK"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { LettaAgentClient } from '@letta-ai/letta-agent-sdk';
|
|
4
|
+
import { LettaAgent } from './agent.js';
|
|
5
|
+
import { creationOptions, dreamingCommand, INTERNAL_MEMORY_TOOLS } from './definition.js';
|
|
6
|
+
import { acquireIdentity, validConversationId } from './identity.js';
|
|
7
|
+
import { assertHistorySettled, historyPage, listConversations, loadHistory, projectHistory, sanitizeText } from './history.js';
|
|
8
|
+
import { allowMemoryTool, memoryCommitCommand } from './memory.js';
|
|
9
|
+
import { listNavigationEntries } from './navigation.js';
|
|
10
|
+
import { ToolInteractions } from './interactions.js';
|
|
11
|
+
import { createToolBridge, fileTraceWriter } from './tools.js';
|
|
12
|
+
import { resolveStateDirectory, statePaths } from './state.js';
|
|
13
|
+
const managementClient = (requestTimeoutMs) => new LettaAgentClient({ backend: 'local', appServer: { harnessBackend: 'local', ...(requestTimeoutMs ? { requestTimeoutMs } : {}) } });
|
|
14
|
+
/** Letta local backend directory used to key identity mappings. */
|
|
15
|
+
export function localBackendDirectory(env = process.env) {
|
|
16
|
+
return resolve(env.LETTA_LOCAL_BACKEND_DIR?.trim() || join(homedir(), '.letta', 'lc-local-backend'));
|
|
17
|
+
}
|
|
18
|
+
/** @throws unless the session is online, idle and has no queued or pending work. */
|
|
19
|
+
export function assertIdle(status) {
|
|
20
|
+
if (status.isOnline !== true || status.isProcessing !== false || !Array.isArray(status.pendingControlRequests) || !status.raw || status.pendingControlRequests.length || (Array.isArray(status.raw.queue) && status.raw.queue.length) || (Array.isArray(status.raw.active_run_ids) && status.raw.active_run_ids.length))
|
|
21
|
+
throw new Error('Conversation has unfinished work or is offline; inspect backend before continuing (no retry/repair).');
|
|
22
|
+
}
|
|
23
|
+
/** Letta session options: application tools plus MemFS tools confined to the agent's memory. */
|
|
24
|
+
export function sessionOptions(bridge, getMemoryRoot, cwd, memoryAuthor) {
|
|
25
|
+
return {
|
|
26
|
+
stateless: false, cwd,
|
|
27
|
+
toolset: { base: 'none', include: [...INTERNAL_MEMORY_TOOLS] },
|
|
28
|
+
allowedTools: [...bridge.allowedTools, ...INTERNAL_MEMORY_TOOLS], tools: bridge.tools,
|
|
29
|
+
permissionMode: 'strict', skillSources: [],
|
|
30
|
+
// Avoid the SDK convenience `dreaming` option; app-scoped settings are applied after ready().
|
|
31
|
+
canUseTool: async (name, input, context) => {
|
|
32
|
+
if (INTERNAL_MEMORY_TOOLS.includes(name)) {
|
|
33
|
+
const root = getMemoryRoot();
|
|
34
|
+
if (allowMemoryTool(name, input, root, memoryAuthor))
|
|
35
|
+
return { behavior: 'allow' };
|
|
36
|
+
return { behavior: 'deny', message: `Only own-memory Markdown operations are permitted.${root ? ` The only permitted Bash command is: ${memoryCommitCommand(root, memoryAuthor)}` : ''}` };
|
|
37
|
+
}
|
|
38
|
+
return bridge.canUseTool(name, input, context);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Runtime-scoped protocol command that keeps application tools in the
|
|
44
|
+
* foreground (no auto-backgrounding) with a five-minute timeout.
|
|
45
|
+
*/
|
|
46
|
+
export function foregroundToolsCommand(bridge, agentId, conversationId) {
|
|
47
|
+
return { type: 'runtime_external_tools_update', updates: [{
|
|
48
|
+
runtimes: [{ agent_id: agentId, conversation_id: conversationId }],
|
|
49
|
+
external_tools: [{ tools: bridge.tools.map(tool => ({ name: tool.name, label: tool.label, description: tool.description, parameters: tool.parameters, auto_background: false, timeout_ms: 300_000 })) }],
|
|
50
|
+
}] };
|
|
51
|
+
}
|
|
52
|
+
/** Open an agent, or throw if no conversation was selected. */
|
|
53
|
+
export async function createLettaAgent(definition, options = {}) {
|
|
54
|
+
const runtime = await openLettaAgent(definition, options);
|
|
55
|
+
if (!runtime)
|
|
56
|
+
throw new Error('No conversation selected');
|
|
57
|
+
return runtime;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Open (creating on first use) the persistent Letta agent for a definition on
|
|
61
|
+
* the local Letta backend, and return a ready {@link LettaAgent}.
|
|
62
|
+
*
|
|
63
|
+
* Steps, each failing closed: acquire the identity lock and mapping; select or
|
|
64
|
+
* create a conversation; resume the session; verify it is idle and its history
|
|
65
|
+
* settled; restore display history; apply project-scoped dreaming and verify
|
|
66
|
+
* it; confirm MemFS. Returns `undefined` if `choose` returned `null`.
|
|
67
|
+
*/
|
|
68
|
+
export async function openLettaAgent(definition, options = {}) {
|
|
69
|
+
const paths = statePaths(resolveStateDirectory(options.stateDirectory));
|
|
70
|
+
const cwd = paths.agents;
|
|
71
|
+
const client = new LettaAgentClient({ backend: 'local', appServer: { harnessBackend: 'local', requestTimeoutMs: 180_000, startupTimeoutMs: 60_000 } });
|
|
72
|
+
let session;
|
|
73
|
+
let release;
|
|
74
|
+
let interactions;
|
|
75
|
+
let closing;
|
|
76
|
+
const close = () => closing ??= (async () => {
|
|
77
|
+
try {
|
|
78
|
+
interactions?.close();
|
|
79
|
+
session?.close();
|
|
80
|
+
await client.close();
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
release?.();
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
try {
|
|
87
|
+
const backend = localBackendDirectory();
|
|
88
|
+
const lease = await acquireIdentity(cwd, definition, backend, {
|
|
89
|
+
create: async () => {
|
|
90
|
+
const models = await client.models.list();
|
|
91
|
+
if (!models.entries.some(model => model.handle === definition.model))
|
|
92
|
+
throw new Error(`Model "${definition.model}" is not available on the local Letta backend; connect its provider first`);
|
|
93
|
+
return client.createAgent(creationOptions(definition, cwd));
|
|
94
|
+
},
|
|
95
|
+
validate: async (id) => {
|
|
96
|
+
// Local management snapshots can predate createAgent's separate process.
|
|
97
|
+
const inspector = managementClient();
|
|
98
|
+
try {
|
|
99
|
+
const agent = await inspector.agents.retrieve(id);
|
|
100
|
+
if (agent.id !== id || agent.name !== definition.name)
|
|
101
|
+
throw new Error('Mapped agent identity mismatch; refusing to recreate');
|
|
102
|
+
if (!agent.tags?.includes('git-memory-enabled'))
|
|
103
|
+
throw new Error('Mapped agent has MemFS disabled; refusing to continue');
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
await inspector.close();
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
const { identity, selectConversation, createConversation, assertNoPendingTurn, beginTurn, completeTurn } = lease;
|
|
111
|
+
release = lease.release;
|
|
112
|
+
// A fresh management client sees agents created by the SDK's separate process.
|
|
113
|
+
const manager = managementClient();
|
|
114
|
+
let conversationId = identity.conversationId;
|
|
115
|
+
let conversationTitle = 'Default conversation';
|
|
116
|
+
try {
|
|
117
|
+
const choice = options.choose
|
|
118
|
+
? await options.choose(identity, await listConversations(query => manager.conversations.list(query), identity.agentId))
|
|
119
|
+
: options.newTitle !== undefined ? { newTitle: options.newTitle } : { conversationId: options.conversationId ?? identity.conversationId };
|
|
120
|
+
if (choice === null) {
|
|
121
|
+
await close();
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
if ('newTitle' in choice) {
|
|
125
|
+
if (!choice.newTitle.trim() || choice.newTitle.length > 120)
|
|
126
|
+
throw new Error('Conversation title must contain 1–120 characters');
|
|
127
|
+
conversationId = await createConversation(async (agentId) => {
|
|
128
|
+
const created = await manager.conversations.create({ agentId, summary: sanitizeText(choice.newTitle.trim()) });
|
|
129
|
+
if (created.agent_id !== agentId)
|
|
130
|
+
throw new Error('Created conversation belongs to a different agent');
|
|
131
|
+
return created.id;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else
|
|
135
|
+
conversationId = choice.conversationId;
|
|
136
|
+
if (!validConversationId(conversationId))
|
|
137
|
+
throw new Error('Invalid conversation ID');
|
|
138
|
+
if (conversationId !== 'default') {
|
|
139
|
+
const conversation = await manager.conversations.retrieve(conversationId);
|
|
140
|
+
if (conversation.agent_id !== identity.agentId || conversation.archived)
|
|
141
|
+
throw new Error('Conversation is archived or belongs to another agent');
|
|
142
|
+
conversationTitle = sanitizeText(conversation.summary ?? 'Untitled conversation');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
await manager.close();
|
|
147
|
+
}
|
|
148
|
+
assertNoPendingTurn(conversationId);
|
|
149
|
+
let turnSignal;
|
|
150
|
+
const broker = interactions = new ToolInteractions();
|
|
151
|
+
const persist = options.traces === false ? undefined : typeof options.traces === 'function' ? options.traces : fileTraceWriter(paths.traces);
|
|
152
|
+
// Background harness work must never open a prompt over an idle chat input.
|
|
153
|
+
const bridge = createToolBridge({
|
|
154
|
+
tools: definition.tools, permissions: definition.permissions, timeoutMs: definition.toolTimeoutMs, persist,
|
|
155
|
+
get interactions() { return turnSignal ? broker : undefined; }, get signal() { return turnSignal; },
|
|
156
|
+
});
|
|
157
|
+
let memoryRoot;
|
|
158
|
+
session = client.resumeSession(conversationId === 'default' ? identity.agentId : conversationId, sessionOptions(bridge, () => memoryRoot, cwd, definition.name));
|
|
159
|
+
const ready = await session.ready();
|
|
160
|
+
if (ready.agentId !== identity.agentId || ready.conversationId !== conversationId)
|
|
161
|
+
throw new Error('Backend resumed a different identity/conversation');
|
|
162
|
+
assertIdle(await session.getDeviceStatus());
|
|
163
|
+
if (options.foregroundExternalTools !== false && bridge.tools.length) {
|
|
164
|
+
// The SDK's tools serializer drops auto_background/timeout_ms. Use the
|
|
165
|
+
// supported runtime-scoped protocol rather than global defaults.
|
|
166
|
+
const configured = await session.sendCommand(foregroundToolsCommand(bridge, ready.agentId, ready.conversationId), { responseType: 'runtime_external_tools_update_response' });
|
|
167
|
+
if (configured.success !== true)
|
|
168
|
+
throw new Error('Unable to configure foreground interaction tools');
|
|
169
|
+
}
|
|
170
|
+
const live = session;
|
|
171
|
+
const history = await loadHistory(query => historyPage(live, identity.agentId, conversationId, query));
|
|
172
|
+
assertHistorySettled(history.messages);
|
|
173
|
+
const initialMessages = projectHistory(history.messages, Object.keys(definition.tools));
|
|
174
|
+
// The SDK's dreaming option writes global defaults. Use the protocol
|
|
175
|
+
// command with project scope (the private state cwd) instead.
|
|
176
|
+
const configured = await session.sendCommand(dreamingCommand(definition, ready.agentId, ready.conversationId), { responseType: 'set_reflection_settings_response' });
|
|
177
|
+
if (configured.success !== true)
|
|
178
|
+
throw new Error('Unable to configure project-scoped dreaming');
|
|
179
|
+
const status = await session.getDeviceStatus();
|
|
180
|
+
if (!status.memoryDirectory)
|
|
181
|
+
throw new Error('MemFS unavailable; refusing to run without memory');
|
|
182
|
+
const reflection = status.raw.reflection_settings;
|
|
183
|
+
if (reflection?.trigger !== definition.dreaming.trigger || reflection.step_count !== definition.dreaming.stepCount)
|
|
184
|
+
throw new Error('Persistent dreaming configuration differs from the definition; inspect agent settings before continuing');
|
|
185
|
+
assertIdle(status);
|
|
186
|
+
memoryRoot = status.memoryDirectory;
|
|
187
|
+
selectConversation(conversationId);
|
|
188
|
+
// Navigation reads through this same mapped runtime; it never enumerates other agents.
|
|
189
|
+
let listedIds = new Set(['default']);
|
|
190
|
+
const navigation = {
|
|
191
|
+
agentId: identity.agentId, currentId: conversationId,
|
|
192
|
+
list: async (signal) => {
|
|
193
|
+
assertIdle(await live.getDeviceStatus());
|
|
194
|
+
const reader = managementClient(15_000);
|
|
195
|
+
try {
|
|
196
|
+
const result = await listNavigationEntries(query => reader.conversations.list(query), identity.agentId, signal);
|
|
197
|
+
listedIds = new Set(result.entries.map(entry => entry.id));
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
await reader.close();
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
page: async (id, pageOptions) => {
|
|
205
|
+
if (!listedIds.has(id))
|
|
206
|
+
throw new Error('Conversation outside current-agent listing');
|
|
207
|
+
return historyPage(live, identity.agentId, id, pageOptions, 10_000);
|
|
208
|
+
},
|
|
209
|
+
validate: async (id, signal) => {
|
|
210
|
+
if (!listedIds.has(id) || !validConversationId(id))
|
|
211
|
+
throw new Error('Conversation outside current-agent listing');
|
|
212
|
+
assertIdle(await live.getDeviceStatus());
|
|
213
|
+
assertNoPendingTurn(id);
|
|
214
|
+
const deadline = Date.now() + 30_000;
|
|
215
|
+
const loaded = await loadHistory(pageOptions => {
|
|
216
|
+
signal?.throwIfAborted();
|
|
217
|
+
if (Date.now() >= deadline)
|
|
218
|
+
throw new Error('Selection validation deadline reached');
|
|
219
|
+
return historyPage(live, identity.agentId, id, pageOptions, 10_000);
|
|
220
|
+
});
|
|
221
|
+
signal?.throwIfAborted();
|
|
222
|
+
assertHistorySettled(loaded.messages);
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
const dreamingLine = definition.dreaming.trigger === 'off' ? 'Dreaming: off' : `Dreaming: ${reflection.trigger}${reflection.trigger === 'step-count' ? ` ${reflection.step_count}` : ''} configured (not evidence a dream ran)`;
|
|
226
|
+
const startupStatus = `${definition.name}\nLogical ID: ${definition.id}\nLetta ID: ${identity.agentId}\nConversation: ${conversationTitle} (${conversationId})\nStartup status: idle / ready · MemFS confirmed enabled\n${dreamingLine}\nHistory: ${initialMessages.length} visible records restored${history.truncated ? ' · LIMITED to newest 10,000 backend records; older history omitted' : ' · complete backend pagination'}`;
|
|
227
|
+
// Keep one session alive between turns so background dreaming can progress.
|
|
228
|
+
// LettaAgent closes only its per-turn wrapper, not this shared session.
|
|
229
|
+
const agent = new LettaAgent({
|
|
230
|
+
id: definition.id, tools: definition.tools, memoryTools: INTERNAL_MEMORY_TOOLS, lettaAgentId: identity.agentId, modelId: definition.model, interactions: broker,
|
|
231
|
+
open: signal => {
|
|
232
|
+
turnSignal = signal;
|
|
233
|
+
return { send: message => live.send(message), stream: () => live.stream(), abort: () => live.abort(), close: () => { if (turnSignal === signal)
|
|
234
|
+
turnSignal = undefined; } };
|
|
235
|
+
},
|
|
236
|
+
presentation: { conversationId, title: conversationTitle, initialMessages, status: startupStatus, memoryDirectory: memoryRoot, historyTruncated: history.truncated },
|
|
237
|
+
delivery: { begin: () => beginTurn(conversationId), complete: () => completeTurn(conversationId) },
|
|
238
|
+
});
|
|
239
|
+
return { agent, identity, navigation, close: async () => { agent.close(); await close(); } };
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
await close();
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Environment variable that overrides the state directory. */
|
|
2
|
+
export declare const STATE_DIR_ENV = "AI_SDK_LETTA_STATE_DIR";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the root state directory.
|
|
5
|
+
*
|
|
6
|
+
* Order: explicit argument, `AI_SDK_LETTA_STATE_DIR`, then the platform state
|
|
7
|
+
* location: `$XDG_STATE_HOME/ai-sdk-letta` or `~/.local/state/ai-sdk-letta` on
|
|
8
|
+
* Linux and macOS, `%LOCALAPPDATA%\ai-sdk-letta\state` on Windows.
|
|
9
|
+
*
|
|
10
|
+
* The identity mapping lives in `<stateDir>/agents/`; point this at an
|
|
11
|
+
* existing directory to keep using an agent created earlier.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolveStateDirectory(explicit?: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, home?: string): string;
|
|
14
|
+
/** Well-known subdirectories of a state root. */
|
|
15
|
+
export declare function statePaths(root: string): {
|
|
16
|
+
root: string;
|
|
17
|
+
/** Identity mappings, locks and pending-intent files; also the Letta session cwd. */
|
|
18
|
+
agents: string;
|
|
19
|
+
/** Metadata-only tool audit trail. */
|
|
20
|
+
traces: string;
|
|
21
|
+
/** Per-definition HTTP runtime state (threads, runs). */
|
|
22
|
+
server: (definitionId: string) => string;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAGA,+DAA+D;AAC/D,eAAO,MAAM,aAAa,2BAA2B,CAAC;AAEtD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAAE,IAAI,SAAY,GAAG,MAAM,CASrK;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM;;IAGnC,qFAAqF;;IAErF,sCAAsC;;IAEtC,yDAAyD;2BAClC,MAAM;EAEhC"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
3
|
+
/** Environment variable that overrides the state directory. */
|
|
4
|
+
export const STATE_DIR_ENV = 'AI_SDK_LETTA_STATE_DIR';
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the root state directory.
|
|
7
|
+
*
|
|
8
|
+
* Order: explicit argument, `AI_SDK_LETTA_STATE_DIR`, then the platform state
|
|
9
|
+
* location: `$XDG_STATE_HOME/ai-sdk-letta` or `~/.local/state/ai-sdk-letta` on
|
|
10
|
+
* Linux and macOS, `%LOCALAPPDATA%\ai-sdk-letta\state` on Windows.
|
|
11
|
+
*
|
|
12
|
+
* The identity mapping lives in `<stateDir>/agents/`; point this at an
|
|
13
|
+
* existing directory to keep using an agent created earlier.
|
|
14
|
+
*/
|
|
15
|
+
export function resolveStateDirectory(explicit, env = process.env, platform = process.platform, home = homedir()) {
|
|
16
|
+
const chosen = explicit ?? env[STATE_DIR_ENV];
|
|
17
|
+
if (chosen !== undefined) {
|
|
18
|
+
if (!chosen.trim())
|
|
19
|
+
throw new Error('State directory must not be empty');
|
|
20
|
+
return resolve(chosen);
|
|
21
|
+
}
|
|
22
|
+
if (platform === 'win32')
|
|
23
|
+
return join(env.LOCALAPPDATA ?? join(home, 'AppData', 'Local'), 'ai-sdk-letta', 'state');
|
|
24
|
+
const xdg = env.XDG_STATE_HOME;
|
|
25
|
+
return join(xdg && isAbsolute(xdg) ? xdg : join(home, '.local', 'state'), 'ai-sdk-letta');
|
|
26
|
+
}
|
|
27
|
+
/** Well-known subdirectories of a state root. */
|
|
28
|
+
export function statePaths(root) {
|
|
29
|
+
return {
|
|
30
|
+
root,
|
|
31
|
+
/** Identity mappings, locks and pending-intent files; also the Letta session cwd. */
|
|
32
|
+
agents: join(root, 'agents'),
|
|
33
|
+
/** Metadata-only tool audit trail. */
|
|
34
|
+
traces: join(root, 'tool-traces'),
|
|
35
|
+
/** Per-definition HTTP runtime state (threads, runs). */
|
|
36
|
+
server: (definitionId) => join(root, 'server', definitionId),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEtD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,wBAAwB,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAiB,EAAE,MAAyB,OAAO,CAAC,GAAG,EAAE,WAA4B,OAAO,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,EAAE;IAC3J,MAAM,MAAM,GAAG,QAAQ,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACzE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IACnH,MAAM,GAAG,GAAG,GAAG,CAAC,cAAc,CAAC;IAC/B,OAAO,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC;AAC5F,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO;QACL,IAAI;QACJ,qFAAqF;QACrF,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC5B,sCAAsC;QACtC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,yDAAyD;QACzD,MAAM,EAAE,CAAC,YAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC;KACrE,CAAC;AACJ,CAAC"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { type Tool, type ToolSet } from 'ai';
|
|
2
|
+
import type { AnyAgentTool } from '@letta-ai/letta-agent-sdk';
|
|
3
|
+
import { type Question, type ToolInteractions } from './interactions.js';
|
|
4
|
+
import type { ToolPermission } from './definition.js';
|
|
5
|
+
/** Name of the built-in human question tool. */
|
|
6
|
+
export declare const ASK_USER_TOOL = "ask_user";
|
|
7
|
+
/**
|
|
8
|
+
* Built-in tool that lets the agent ask the human a structured question
|
|
9
|
+
* mid-turn. Add it to a definition's tools as `ask_user: askUserTool`.
|
|
10
|
+
* The answer is supplied by the connected interaction renderer.
|
|
11
|
+
*/
|
|
12
|
+
/** Result of `ask_user`, as returned to the agent. */
|
|
13
|
+
export type AskUserResult = {
|
|
14
|
+
cancelled: boolean;
|
|
15
|
+
selected?: string[];
|
|
16
|
+
text?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const askUserTool: Tool<Question, AskUserResult>;
|
|
19
|
+
/** Metadata-only audit event. Never contains arguments, outputs or raw call IDs. */
|
|
20
|
+
export type ToolActivity = {
|
|
21
|
+
type: 'tool';
|
|
22
|
+
sessionId: string;
|
|
23
|
+
callId: string;
|
|
24
|
+
tool: string;
|
|
25
|
+
status: 'start' | 'completion' | 'error' | 'denied' | 'approved' | 'cancelled';
|
|
26
|
+
durationMs: number;
|
|
27
|
+
code?: string;
|
|
28
|
+
at: string;
|
|
29
|
+
};
|
|
30
|
+
/** Append-only, private (0600) daily NDJSON trace writer. */
|
|
31
|
+
export declare function fileTraceWriter(directory: string): (event: ToolActivity) => void;
|
|
32
|
+
/** Options for {@link createToolBridge}. */
|
|
33
|
+
export interface ToolBridgeOptions {
|
|
34
|
+
/** AI SDK tools available to the agent. */
|
|
35
|
+
tools: ToolSet;
|
|
36
|
+
/** Permission per tool. Tools without an entry, or with `'deny'`, are never exposed. */
|
|
37
|
+
permissions: Readonly<Record<string, ToolPermission>>;
|
|
38
|
+
/** Further restrict exposure to these names (intersection). Defaults to every permitted tool. */
|
|
39
|
+
allowedTools?: readonly string[];
|
|
40
|
+
/** Aborts every in-flight call (for example, when the turn is cancelled). */
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
/** Human interaction broker. Without it, `ask` tools and `ask_user` fail closed. */
|
|
43
|
+
interactions?: ToolInteractions;
|
|
44
|
+
/** Per-call execution deadline in ms, excluding human waits. @default 5000 */
|
|
45
|
+
timeoutMs?: number;
|
|
46
|
+
/** Audit sink; see {@link fileTraceWriter}. @default no persistence */
|
|
47
|
+
persist?: (event: ToolActivity) => void;
|
|
48
|
+
/** Observer for audit events. */
|
|
49
|
+
onTool?: (event: ToolActivity) => void;
|
|
50
|
+
}
|
|
51
|
+
type ToolOutput = {
|
|
52
|
+
content: {
|
|
53
|
+
type: 'text';
|
|
54
|
+
text: string;
|
|
55
|
+
}[];
|
|
56
|
+
isError: boolean;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Map AI SDK tools onto Letta client-side tools with a fail-closed policy:
|
|
60
|
+
* schema validation before anything else, exactly-once execution per call ID,
|
|
61
|
+
* per-call approval bound to a snapshot of the arguments, deadlines,
|
|
62
|
+
* cancellation, bounded output and sanitized errors.
|
|
63
|
+
*/
|
|
64
|
+
export declare function createToolBridge(options: ToolBridgeOptions): {
|
|
65
|
+
/** Letta client-tool descriptors. */
|
|
66
|
+
tools: AnyAgentTool[];
|
|
67
|
+
/** Names exposed to the agent. */
|
|
68
|
+
allowedTools: string[];
|
|
69
|
+
/** Execute one call through the full policy. */
|
|
70
|
+
execute: (name: string, id: string, args: unknown, sdkSignal?: AbortSignal) => Promise<ToolOutput>;
|
|
71
|
+
/** Letta `canUseTool` hook: allow only exposed tools with valid arguments. */
|
|
72
|
+
canUseTool: (name: string, input?: Record<string, unknown>, _context?: unknown) => Promise<{
|
|
73
|
+
behavior: "allow";
|
|
74
|
+
message?: undefined;
|
|
75
|
+
} | {
|
|
76
|
+
behavior: "deny";
|
|
77
|
+
message: string;
|
|
78
|
+
}>;
|
|
79
|
+
};
|
|
80
|
+
/** Return type of {@link createToolBridge}. */
|
|
81
|
+
export type ToolBridge = ReturnType<typeof createToolBridge>;
|
|
82
|
+
export {};
|
|
83
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,IAAI,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI9D,OAAO,EAAoB,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,gDAAgD;AAChD,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC;;;;GAIG;AACH,sDAAsD;AACtD,MAAM,MAAM,aAAa,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvF,eAAO,MAAM,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAKpD,CAAC;AAEH,oFAAoF;AACpF,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5N,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAUhF;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,wFAAwF;IACxF,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IACtD,iGAAiG;IACjG,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oFAAoF;IACpF,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,iCAAiC;IACjC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CACxC;AAED,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAElF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB;IA8EvD,qCAAqC;;IAErC,kCAAkC;;IAElC,gDAAgD;oBA1DrB,MAAM,MAAM,MAAM,QAAQ,OAAO,cAAc,WAAW,KAAG,OAAO,CAAC,UAAU,CAAC;IA4D3G,8EAA8E;uBACrD,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,OAAO;;;;;;;EAMvF;AAED,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|