@letta-ai/letta-agent-sdk 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/AGENTS.md +47 -0
  2. package/README.md +17 -0
  3. package/dist/client-entry.js +800 -732
  4. package/dist/client-entry.js.map +8 -5
  5. package/dist/cloud-sandbox.d.ts +33 -0
  6. package/dist/cloud-sandbox.d.ts.map +1 -0
  7. package/dist/cloud-session.d.ts.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +799 -732
  11. package/dist/index.js.map +9 -6
  12. package/dist/remote-client-session-core.d.ts +6 -93
  13. package/dist/remote-client-session-core.d.ts.map +1 -1
  14. package/dist/remote-session-protocol.d.ts +130 -0
  15. package/dist/remote-session-protocol.d.ts.map +1 -0
  16. package/dist/remote-turn-coordinator.d.ts +49 -0
  17. package/dist/remote-turn-coordinator.d.ts.map +1 -0
  18. package/dist/types.d.ts +2 -20
  19. package/dist/types.d.ts.map +1 -1
  20. package/package.json +5 -2
  21. package/src/app-server-management.ts +641 -0
  22. package/src/app-server-session.ts +948 -0
  23. package/src/cli-resolver.ts +46 -0
  24. package/src/client-base.ts +482 -0
  25. package/src/client-entry.ts +31 -0
  26. package/src/client.ts +138 -0
  27. package/src/cloud-management.ts +360 -0
  28. package/src/cloud-sandbox.ts +117 -0
  29. package/src/cloud-session.ts +1313 -0
  30. package/src/index.ts +440 -0
  31. package/src/interactiveToolPolicy.ts +62 -0
  32. package/src/local-app-server-session.ts +39 -0
  33. package/src/local-app-server.ts +137 -0
  34. package/src/management-types.ts +133 -0
  35. package/src/management.ts +206 -0
  36. package/src/protocol.ts +249 -0
  37. package/src/remote-client-session-core.ts +786 -0
  38. package/src/remote-session-protocol.ts +660 -0
  39. package/src/remote-turn-coordinator.ts +505 -0
  40. package/src/remote.ts +177 -0
  41. package/src/repositories.ts +340 -0
  42. package/src/request-ids.ts +33 -0
  43. package/src/session.ts +1638 -0
  44. package/src/stream-events.ts +88 -0
  45. package/src/tool-helpers.ts +147 -0
  46. package/src/transport.ts +484 -0
  47. package/src/types.ts +1328 -0
  48. package/src/validation.ts +223 -0
  49. package/src/websocket.ts +22 -0
@@ -0,0 +1,88 @@
1
+ import type { SDKStreamEventPayload } from "./types.js";
2
+
3
+ export type StreamTextKind = "assistant" | "reasoning";
4
+
5
+ export interface StreamTextDelta {
6
+ kind: StreamTextKind;
7
+ text: string;
8
+ }
9
+
10
+ function extractTextFromContent(content: unknown): string | null {
11
+ if (typeof content === "string") {
12
+ return content;
13
+ }
14
+
15
+ if (Array.isArray(content)) {
16
+ const pieces: string[] = [];
17
+ for (const part of content) {
18
+ if (typeof part === "string") {
19
+ pieces.push(part);
20
+ continue;
21
+ }
22
+ if (!part || typeof part !== "object") {
23
+ continue;
24
+ }
25
+ const rec = part as Record<string, unknown>;
26
+ if (typeof rec.text === "string") {
27
+ pieces.push(rec.text);
28
+ }
29
+ }
30
+ const joined = pieces.join("");
31
+ return joined.length > 0 ? joined : null;
32
+ }
33
+
34
+ if (content && typeof content === "object") {
35
+ const rec = content as Record<string, unknown>;
36
+ if (typeof rec.text === "string") {
37
+ return rec.text;
38
+ }
39
+ }
40
+
41
+ return null;
42
+ }
43
+
44
+ /**
45
+ * Extract appendable assistant/reasoning text from a stream_event payload.
46
+ *
47
+ * Supports both shapes currently emitted by headless mode:
48
+ * 1) content_block style: { type, delta: { text|reasoning } }
49
+ * 2) message chunk style: { message_type: "assistant_message"|"reasoning_message", ... }
50
+ */
51
+ export function extractStreamTextDelta(event: SDKStreamEventPayload): StreamTextDelta | null {
52
+ if (!event || typeof event !== "object") {
53
+ return null;
54
+ }
55
+
56
+ const rec = event as Record<string, unknown>;
57
+
58
+ const maybeDelta = rec.delta;
59
+ if (maybeDelta && typeof maybeDelta === "object") {
60
+ const delta = maybeDelta as Record<string, unknown>;
61
+
62
+ if (typeof delta.reasoning === "string" && delta.reasoning.length > 0) {
63
+ return { kind: "reasoning", text: delta.reasoning };
64
+ }
65
+
66
+ if (typeof delta.text === "string" && delta.text.length > 0) {
67
+ return { kind: "assistant", text: delta.text };
68
+ }
69
+ }
70
+
71
+ const messageType = rec.message_type;
72
+ if (messageType === "reasoning_message") {
73
+ const reasoningText =
74
+ typeof rec.reasoning === "string" ? rec.reasoning : extractTextFromContent(rec.content);
75
+ if (reasoningText && reasoningText.length > 0) {
76
+ return { kind: "reasoning", text: reasoningText };
77
+ }
78
+ }
79
+
80
+ if (messageType === "assistant_message") {
81
+ const assistantText = extractTextFromContent(rec.content);
82
+ if (assistantText && assistantText.length > 0) {
83
+ return { kind: "assistant", text: assistantText };
84
+ }
85
+ }
86
+
87
+ return null;
88
+ }
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Tool Helpers
3
+ *
4
+ * Helper functions for creating tool results and parsing parameters.
5
+ * Matches the API from pi-coding-agent.
6
+ */
7
+
8
+ import type { AgentToolResult } from "./types.js";
9
+
10
+ /**
11
+ * Create a JSON tool result
12
+ */
13
+ export function jsonResult(payload: unknown): AgentToolResult<unknown> {
14
+ return {
15
+ content: [
16
+ {
17
+ type: "text",
18
+ text: JSON.stringify(payload, null, 2),
19
+ },
20
+ ],
21
+ details: payload,
22
+ };
23
+ }
24
+
25
+ /**
26
+ * Options for reading string parameters
27
+ */
28
+ export interface StringParamOptions {
29
+ required?: boolean;
30
+ trim?: boolean;
31
+ label?: string;
32
+ allowEmpty?: boolean;
33
+ }
34
+
35
+ /**
36
+ * Read a string parameter from tool args
37
+ */
38
+ export function readStringParam(
39
+ params: Record<string, unknown>,
40
+ key: string,
41
+ options?: StringParamOptions & { required: true },
42
+ ): string;
43
+ export function readStringParam(
44
+ params: Record<string, unknown>,
45
+ key: string,
46
+ options?: StringParamOptions,
47
+ ): string | undefined;
48
+ export function readStringParam(
49
+ params: Record<string, unknown>,
50
+ key: string,
51
+ options: StringParamOptions = {},
52
+ ): string | undefined {
53
+ const { required = false, trim = true, label = key, allowEmpty = false } = options;
54
+ const raw = params[key];
55
+ if (typeof raw !== "string") {
56
+ if (required) throw new Error(`${label} required`);
57
+ return undefined;
58
+ }
59
+ const value = trim ? raw.trim() : raw;
60
+ if (!value && !allowEmpty) {
61
+ if (required) throw new Error(`${label} required`);
62
+ return undefined;
63
+ }
64
+ return value;
65
+ }
66
+
67
+ /**
68
+ * Read a number parameter from tool args
69
+ */
70
+ export function readNumberParam(
71
+ params: Record<string, unknown>,
72
+ key: string,
73
+ options: { required?: boolean; label?: string; integer?: boolean } = {},
74
+ ): number | undefined {
75
+ const { required = false, label = key, integer = false } = options;
76
+ const raw = params[key];
77
+ let value: number | undefined;
78
+ if (typeof raw === "number" && Number.isFinite(raw)) {
79
+ value = raw;
80
+ } else if (typeof raw === "string") {
81
+ const trimmed = raw.trim();
82
+ if (trimmed) {
83
+ const parsed = Number.parseFloat(trimmed);
84
+ if (Number.isFinite(parsed)) value = parsed;
85
+ }
86
+ }
87
+ if (value === undefined) {
88
+ if (required) throw new Error(`${label} required`);
89
+ return undefined;
90
+ }
91
+ return integer ? Math.trunc(value) : value;
92
+ }
93
+
94
+ /**
95
+ * Read a boolean parameter from tool args
96
+ */
97
+ export function readBooleanParam(
98
+ params: Record<string, unknown>,
99
+ key: string,
100
+ options: { required?: boolean; label?: string } = {},
101
+ ): boolean | undefined {
102
+ const { required = false, label = key } = options;
103
+ const raw = params[key];
104
+ if (typeof raw === "boolean") {
105
+ return raw;
106
+ }
107
+ if (typeof raw === "string") {
108
+ const lower = raw.toLowerCase().trim();
109
+ if (lower === "true" || lower === "1" || lower === "yes") return true;
110
+ if (lower === "false" || lower === "0" || lower === "no") return false;
111
+ }
112
+ if (required) throw new Error(`${label} required`);
113
+ return undefined;
114
+ }
115
+
116
+ /**
117
+ * Read a string array parameter from tool args
118
+ */
119
+ export function readStringArrayParam(
120
+ params: Record<string, unknown>,
121
+ key: string,
122
+ options: StringParamOptions = {},
123
+ ): string[] | undefined {
124
+ const { required = false, label = key } = options;
125
+ const raw = params[key];
126
+ if (Array.isArray(raw)) {
127
+ const values = raw
128
+ .filter((entry): entry is string => typeof entry === "string")
129
+ .map((entry) => entry.trim())
130
+ .filter(Boolean);
131
+ if (values.length === 0) {
132
+ if (required) throw new Error(`${label} required`);
133
+ return undefined;
134
+ }
135
+ return values;
136
+ }
137
+ if (typeof raw === "string") {
138
+ const value = raw.trim();
139
+ if (!value) {
140
+ if (required) throw new Error(`${label} required`);
141
+ return undefined;
142
+ }
143
+ return [value];
144
+ }
145
+ if (required) throw new Error(`${label} required`);
146
+ return undefined;
147
+ }