@almadar/sdk 0.1.0-alpha.2

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.
@@ -0,0 +1,280 @@
1
+ import { PauseController, isTraceEvent, traceToSSE, runRabit, runContextualEdit } from '@almadar-io/rabit';
2
+ import { setupSSE, sendSSEEvent, closeSSE } from '@almadar/server';
3
+
4
+ // src/server/index.ts
5
+ function resolveUserId(opts, req) {
6
+ if (opts.userId) return opts.userId(req);
7
+ const header = req.headers["x-user-id"];
8
+ return typeof header === "string" && header.length > 0 ? header : "anonymous";
9
+ }
10
+ async function resolveExtraProviderConfig(opts, provider) {
11
+ if (!opts.resolveProviderConfig) return void 0;
12
+ return opts.resolveProviderConfig(provider);
13
+ }
14
+ function makeThreadId(workspace) {
15
+ return workspace.appId ?? `sdk-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
16
+ }
17
+ function createGenerateHandler(opts) {
18
+ return async (req, res) => {
19
+ const body = req.body;
20
+ const rawPrompt = body["prompt"] ?? body["message"];
21
+ const prompt = typeof rawPrompt === "string" ? rawPrompt : "";
22
+ if (!prompt) {
23
+ res.status(400).json({ error: "prompt or message is required" });
24
+ return;
25
+ }
26
+ const provider = (typeof body["provider"] === "string" ? body["provider"] : void 0) ?? opts.provider ?? "deepseek";
27
+ const model = (typeof body["model"] === "string" ? body["model"] : void 0) ?? opts.model ?? "deepseek-v4-flash";
28
+ const userId = resolveUserId(opts, req);
29
+ let workspace;
30
+ try {
31
+ workspace = await opts.workspaceFactory(req);
32
+ } catch (err) {
33
+ const message = err instanceof Error ? err.message : String(err);
34
+ res.status(500).json({ error: `Workspace open failed: ${message}` });
35
+ return;
36
+ }
37
+ setupSSE(res);
38
+ const threadId = makeThreadId(workspace);
39
+ const abortController = new AbortController();
40
+ const pauseController = new PauseController();
41
+ const ctx = {
42
+ threadId,
43
+ workDir: workspace.workDir,
44
+ userId,
45
+ ...workspace.appId !== void 0 ? { appId: workspace.appId } : {}
46
+ };
47
+ const unsubscribe = workspace.subscribe({
48
+ onWrite(event) {
49
+ if (event.kind !== "trace") return;
50
+ if (!isTraceEvent(event.event)) return;
51
+ for (const sseEvent of traceToSSE(event.event, ctx)) {
52
+ sendSSEEvent(res, sseEvent);
53
+ }
54
+ }
55
+ });
56
+ sendSSEEvent(res, {
57
+ type: "start",
58
+ data: { threadId, skill: "rabit", workDir: workspace.workDir },
59
+ timestamp: Date.now()
60
+ });
61
+ res.on("close", () => {
62
+ abortController.abort();
63
+ });
64
+ const catalogMode = opts.catalogScope?.mode;
65
+ const stdAllowList = opts.catalogScope?.stdAllowList;
66
+ const extraProviderConfig = await resolveExtraProviderConfig(opts, provider);
67
+ const rabitOpts = {
68
+ prompt,
69
+ workDir: workspace.workDir,
70
+ userId,
71
+ provider,
72
+ model,
73
+ workspace,
74
+ signal: abortController.signal,
75
+ pauseController,
76
+ ...catalogMode !== void 0 ? { catalogMode } : {},
77
+ ...stdAllowList !== void 0 ? { stdAllowList } : {},
78
+ ...extraProviderConfig !== void 0 ? { providerConfig: extraProviderConfig } : {}
79
+ };
80
+ try {
81
+ const result = await runRabit(rabitOpts);
82
+ if (result.success && result.composedSchema !== null) {
83
+ sendSSEEvent(res, {
84
+ type: "complete",
85
+ data: {
86
+ threadId,
87
+ skill: "rabit",
88
+ workDir: workspace.workDir,
89
+ schemaGenerated: true,
90
+ appCompiled: false,
91
+ schema: result.composedSchema,
92
+ ...workspace.appId !== void 0 ? { appId: workspace.appId } : {}
93
+ },
94
+ timestamp: Date.now()
95
+ });
96
+ try {
97
+ await opts.onComplete?.(result.composedSchema, req);
98
+ } catch {
99
+ }
100
+ } else if (result.success) {
101
+ sendSSEEvent(res, {
102
+ type: "complete",
103
+ data: {
104
+ threadId,
105
+ skill: "rabit",
106
+ workDir: workspace.workDir,
107
+ schemaGenerated: false,
108
+ appCompiled: false
109
+ },
110
+ timestamp: Date.now()
111
+ });
112
+ } else {
113
+ const failList = result.failedOrbitals.join(", ");
114
+ sendSSEEvent(res, {
115
+ type: "error",
116
+ data: {
117
+ error: `Generation failed${failList.length > 0 ? `: ${failList}` : ""}`,
118
+ code: "failed"
119
+ },
120
+ timestamp: Date.now()
121
+ });
122
+ }
123
+ } catch (err) {
124
+ const isAbort = err instanceof Error && (err.name === "AbortError" || abortController.signal.aborted);
125
+ if (isAbort) {
126
+ sendSSEEvent(res, {
127
+ type: "cancelled",
128
+ data: { threadId, message: "Generation cancelled" },
129
+ timestamp: Date.now()
130
+ });
131
+ } else {
132
+ const message = err instanceof Error ? err.message : String(err);
133
+ sendSSEEvent(res, {
134
+ type: "error",
135
+ data: { error: message, code: "runtime" },
136
+ timestamp: Date.now()
137
+ });
138
+ }
139
+ } finally {
140
+ try {
141
+ unsubscribe();
142
+ } catch {
143
+ }
144
+ closeSSE(res);
145
+ }
146
+ };
147
+ }
148
+ function createEditHandler(opts) {
149
+ const generateHandler = createGenerateHandler(opts);
150
+ return async (req, res) => {
151
+ const body = req.body;
152
+ const focus = body["focus"];
153
+ if (focus === void 0 || focus === null) {
154
+ return generateHandler(req, res);
155
+ }
156
+ const rawInstruction = body["instruction"] ?? body["message"];
157
+ const instruction = typeof rawInstruction === "string" ? rawInstruction : "";
158
+ if (!instruction) {
159
+ res.status(400).json({ error: "instruction or message is required" });
160
+ return;
161
+ }
162
+ const provider = (typeof body["provider"] === "string" ? body["provider"] : void 0) ?? opts.provider ?? "deepseek";
163
+ const model = (typeof body["model"] === "string" ? body["model"] : void 0) ?? opts.model ?? "deepseek-v4-flash";
164
+ const userId = resolveUserId(opts, req);
165
+ let workspace;
166
+ try {
167
+ workspace = await opts.workspaceFactory(req);
168
+ } catch (err) {
169
+ const message = err instanceof Error ? err.message : String(err);
170
+ res.status(500).json({ error: `Workspace open failed: ${message}` });
171
+ return;
172
+ }
173
+ setupSSE(res);
174
+ const threadId = makeThreadId(workspace);
175
+ const abortController = new AbortController();
176
+ const ctx = {
177
+ threadId,
178
+ workDir: workspace.workDir,
179
+ userId,
180
+ ...workspace.appId !== void 0 ? { appId: workspace.appId } : {}
181
+ };
182
+ const unsubscribe = workspace.subscribe({
183
+ onWrite(event) {
184
+ if (event.kind !== "trace") return;
185
+ if (!isTraceEvent(event.event)) return;
186
+ for (const sseEvent of traceToSSE(event.event, ctx)) {
187
+ sendSSEEvent(res, sseEvent);
188
+ }
189
+ }
190
+ });
191
+ sendSSEEvent(res, {
192
+ type: "start",
193
+ data: { threadId, skill: "rabit", workDir: workspace.workDir },
194
+ timestamp: Date.now()
195
+ });
196
+ res.on("close", () => {
197
+ abortController.abort();
198
+ });
199
+ const extraProviderConfig = await resolveExtraProviderConfig(opts, provider);
200
+ try {
201
+ const editResult = await runContextualEdit({
202
+ // EditFocus is validated at runtime by rabit; we pass through as-is.
203
+ focus,
204
+ instruction,
205
+ workDir: workspace.workDir,
206
+ provider,
207
+ model,
208
+ userId,
209
+ workspace,
210
+ signal: abortController.signal,
211
+ ...extraProviderConfig !== void 0 ? { providerConfig: extraProviderConfig } : {}
212
+ });
213
+ if (!editResult.success) {
214
+ sendSSEEvent(res, {
215
+ type: "error",
216
+ data: {
217
+ error: editResult.error ?? "The edit did not change anything.",
218
+ code: "failed"
219
+ },
220
+ timestamp: Date.now()
221
+ });
222
+ return;
223
+ }
224
+ const rawSchema = workspace.readSchema();
225
+ let composedSchema = null;
226
+ if (rawSchema !== null) {
227
+ try {
228
+ composedSchema = JSON.parse(rawSchema);
229
+ } catch {
230
+ }
231
+ }
232
+ sendSSEEvent(res, {
233
+ type: "complete",
234
+ data: {
235
+ threadId,
236
+ skill: "rabit",
237
+ workDir: workspace.workDir,
238
+ schemaGenerated: composedSchema !== null,
239
+ appCompiled: false,
240
+ schemaPersisted: false,
241
+ ...composedSchema !== null ? { schema: composedSchema } : {},
242
+ ...workspace.appId !== void 0 ? { appId: workspace.appId } : {}
243
+ },
244
+ timestamp: Date.now()
245
+ });
246
+ if (composedSchema !== null) {
247
+ try {
248
+ await opts.onComplete?.(composedSchema, req);
249
+ } catch {
250
+ }
251
+ }
252
+ } catch (err) {
253
+ const isAbort = err instanceof Error && (err.name === "AbortError" || abortController.signal.aborted);
254
+ if (isAbort) {
255
+ sendSSEEvent(res, {
256
+ type: "cancelled",
257
+ data: { threadId, message: "Edit cancelled" },
258
+ timestamp: Date.now()
259
+ });
260
+ } else {
261
+ const message = err instanceof Error ? err.message : String(err);
262
+ sendSSEEvent(res, {
263
+ type: "error",
264
+ data: { error: message, code: "runtime" },
265
+ timestamp: Date.now()
266
+ });
267
+ }
268
+ } finally {
269
+ try {
270
+ unsubscribe();
271
+ } catch {
272
+ }
273
+ closeSSE(res);
274
+ }
275
+ };
276
+ }
277
+
278
+ export { createEditHandler, createGenerateHandler };
279
+ //# sourceMappingURL=index.js.map
280
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `@almadar/sdk/server` — Express handler factories for the Almadar agent.\n *\n * Node-only. Never import this from browser or React code.\n *\n * Usage:\n * import { createGenerateHandler, createEditHandler } from '@almadar/sdk/server';\n */\n\nimport type { Request, Response } from 'express';\nimport type { WorkspaceService } from '@almadar/workspace';\nimport type { OrbitalSchema } from '@almadar/core';\nimport type { ProviderConfig } from '@almadar/llm';\nimport {\n runRabit,\n runContextualEdit,\n PauseController,\n traceToSSE,\n isTraceEvent,\n type RabitOptions,\n type MapperContext,\n} from '@almadar-io/rabit';\nimport {\n setupSSE,\n sendSSEEvent,\n closeSSE,\n} from '@almadar/server';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n// Canonical provider-credential type lives in `@almadar/llm`; re-export it so\n// callers get the exact shape `runRabit` consumes without a local shadow.\nexport type { ProviderConfig };\n\n// ============================================================================\n// Public option surface\n// ============================================================================\n\nexport interface GenerateHandlerOptions {\n /** Open (or return) the workspace for this request. */\n workspaceFactory: (req: Request) => Promise<WorkspaceService> | WorkspaceService;\n /** LLM provider — defaults to `'deepseek'`. */\n provider?: string;\n /** LLM model — defaults to `'deepseek-v4-flash'`. */\n model?: string;\n /** Std-catalog scope forwarded to rabit. */\n catalogScope?: {\n mode: 'extend' | 'subset' | 'replace';\n stdAllowList?: readonly string[];\n };\n /** Return explicit provider credentials for the given provider string. */\n resolveProviderConfig?: (\n provider: string,\n ) => Promise<ProviderConfig | undefined> | ProviderConfig | undefined;\n /** Called once with the final composed schema after a successful generate. */\n onComplete?: (schema: OrbitalSchema, req: Request) => Promise<void> | void;\n /** Derive a stable user id from the request — defaults to `'anonymous'`. */\n userId?: (req: Request) => string;\n}\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\nfunction resolveUserId(opts: GenerateHandlerOptions, req: Request): string {\n if (opts.userId) return opts.userId(req);\n const header = req.headers['x-user-id'];\n return typeof header === 'string' && header.length > 0 ? header : 'anonymous';\n}\n\nasync function resolveExtraProviderConfig(\n opts: GenerateHandlerOptions,\n provider: string,\n): Promise<ProviderConfig | undefined> {\n if (!opts.resolveProviderConfig) return undefined;\n return opts.resolveProviderConfig(provider);\n}\n\nfunction makeThreadId(workspace: WorkspaceService): string {\n return (\n workspace.appId ??\n `sdk-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n );\n}\n\n// ============================================================================\n// createGenerateHandler\n// ============================================================================\n\n/**\n * Returns an Express route handler that streams a rabit generation run as SSE.\n *\n * Body shape accepted:\n * `{ prompt?: string; message?: string; provider?: string; model?: string; appId?: string }`\n *\n * SSE events emitted:\n * `start` → trace fan-out → `complete | error | cancelled`\n */\nexport function createGenerateHandler(\n opts: GenerateHandlerOptions,\n): (req: Request, res: Response) => Promise<void> {\n return async (req: Request, res: Response): Promise<void> => {\n const body = req.body as Record<string, unknown>;\n const rawPrompt = body['prompt'] ?? body['message'];\n const prompt = typeof rawPrompt === 'string' ? rawPrompt : '';\n\n if (!prompt) {\n res.status(400).json({ error: 'prompt or message is required' });\n return;\n }\n\n const provider =\n (typeof body['provider'] === 'string' ? body['provider'] : undefined) ??\n opts.provider ??\n 'deepseek';\n const model =\n (typeof body['model'] === 'string' ? body['model'] : undefined) ??\n opts.model ??\n 'deepseek-v4-flash';\n const userId = resolveUserId(opts, req);\n\n let workspace: WorkspaceService;\n try {\n workspace = await opts.workspaceFactory(req);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n res.status(500).json({ error: `Workspace open failed: ${message}` });\n return;\n }\n\n setupSSE(res);\n\n const threadId = makeThreadId(workspace);\n const abortController = new AbortController();\n const pauseController = new PauseController();\n\n const ctx: MapperContext = {\n threadId,\n workDir: workspace.workDir,\n userId,\n ...(workspace.appId !== undefined ? { appId: workspace.appId } : {}),\n };\n\n const unsubscribe = workspace.subscribe({\n onWrite(event) {\n if (event.kind !== 'trace') return;\n if (!isTraceEvent(event.event)) return;\n for (const sseEvent of traceToSSE(event.event, ctx)) {\n sendSSEEvent(res, sseEvent);\n }\n },\n });\n\n sendSSEEvent(res, {\n type: 'start',\n data: { threadId, skill: 'rabit', workDir: workspace.workDir },\n timestamp: Date.now(),\n });\n\n res.on('close', () => {\n abortController.abort();\n });\n\n const catalogMode = opts.catalogScope?.mode;\n const stdAllowList = opts.catalogScope?.stdAllowList;\n const extraProviderConfig = await resolveExtraProviderConfig(opts, provider);\n\n const rabitOpts: RabitOptions = {\n prompt,\n workDir: workspace.workDir,\n userId,\n provider,\n model,\n workspace,\n signal: abortController.signal,\n pauseController,\n ...(catalogMode !== undefined ? { catalogMode } : {}),\n ...(stdAllowList !== undefined ? { stdAllowList } : {}),\n ...(extraProviderConfig !== undefined ? { providerConfig: extraProviderConfig } : {}),\n };\n\n try {\n const result = await runRabit(rabitOpts);\n\n if (result.success && result.composedSchema !== null) {\n sendSSEEvent(res, {\n type: 'complete',\n data: {\n threadId,\n skill: 'rabit',\n workDir: workspace.workDir,\n schemaGenerated: true,\n appCompiled: false,\n schema: result.composedSchema,\n ...(workspace.appId !== undefined ? { appId: workspace.appId } : {}),\n },\n timestamp: Date.now(),\n });\n try {\n await opts.onComplete?.(result.composedSchema, req);\n } catch {\n // onComplete errors do not fail the SSE stream — schema was generated\n }\n } else if (result.success) {\n sendSSEEvent(res, {\n type: 'complete',\n data: {\n threadId,\n skill: 'rabit',\n workDir: workspace.workDir,\n schemaGenerated: false,\n appCompiled: false,\n },\n timestamp: Date.now(),\n });\n } else {\n const failList = result.failedOrbitals.join(', ');\n sendSSEEvent(res, {\n type: 'error',\n data: {\n error: `Generation failed${failList.length > 0 ? `: ${failList}` : ''}`,\n code: 'failed',\n },\n timestamp: Date.now(),\n });\n }\n } catch (err: unknown) {\n const isAbort =\n err instanceof Error &&\n (err.name === 'AbortError' || abortController.signal.aborted);\n if (isAbort) {\n sendSSEEvent(res, {\n type: 'cancelled',\n data: { threadId, message: 'Generation cancelled' },\n timestamp: Date.now(),\n });\n } else {\n const message = err instanceof Error ? err.message : String(err);\n sendSSEEvent(res, {\n type: 'error',\n data: { error: message, code: 'runtime' },\n timestamp: Date.now(),\n });\n }\n } finally {\n try {\n unsubscribe();\n } catch {\n // best-effort\n }\n closeSSE(res);\n }\n };\n}\n\n// ============================================================================\n// createEditHandler\n// ============================================================================\n\n/**\n * Returns an Express route handler that streams a contextual-edit run as SSE.\n *\n * Body shape accepted:\n * `{ focus: EditFocus; instruction?: string; message?: string; provider?: string; model?: string }`\n *\n * The `focus` field must be a valid `EditFocus` (orbital + trait + patternType\n * + path — see `@almadar/core`'s `EditFocus` type). The handler delegates\n * entirely to `runContextualEdit` from `@almadar-io/rabit`.\n *\n * TODO: when `focus` is absent the handler falls back to a full-regeneration\n * pass (`createGenerateHandler` semantics). Wire a dedicated delta-prompt edit\n * path here once rabit exposes a `runDeltaEdit` entry point.\n */\nexport function createEditHandler(\n opts: GenerateHandlerOptions,\n): (req: Request, res: Response) => Promise<void> {\n const generateHandler = createGenerateHandler(opts);\n\n return async (req: Request, res: Response): Promise<void> => {\n const body = req.body as Record<string, unknown>;\n const focus = body['focus'];\n\n // Without a focus, fall back to a full regeneration pass.\n if (focus === undefined || focus === null) {\n return generateHandler(req, res);\n }\n\n const rawInstruction = body['instruction'] ?? body['message'];\n const instruction =\n typeof rawInstruction === 'string' ? rawInstruction : '';\n\n if (!instruction) {\n res.status(400).json({ error: 'instruction or message is required' });\n return;\n }\n\n const provider =\n (typeof body['provider'] === 'string' ? body['provider'] : undefined) ??\n opts.provider ??\n 'deepseek';\n const model =\n (typeof body['model'] === 'string' ? body['model'] : undefined) ??\n opts.model ??\n 'deepseek-v4-flash';\n const userId = resolveUserId(opts, req);\n\n let workspace: WorkspaceService;\n try {\n workspace = await opts.workspaceFactory(req);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n res.status(500).json({ error: `Workspace open failed: ${message}` });\n return;\n }\n\n setupSSE(res);\n\n const threadId = makeThreadId(workspace);\n const abortController = new AbortController();\n\n const ctx: MapperContext = {\n threadId,\n workDir: workspace.workDir,\n userId,\n ...(workspace.appId !== undefined ? { appId: workspace.appId } : {}),\n };\n\n const unsubscribe = workspace.subscribe({\n onWrite(event) {\n if (event.kind !== 'trace') return;\n if (!isTraceEvent(event.event)) return;\n for (const sseEvent of traceToSSE(event.event, ctx)) {\n sendSSEEvent(res, sseEvent);\n }\n },\n });\n\n sendSSEEvent(res, {\n type: 'start',\n data: { threadId, skill: 'rabit', workDir: workspace.workDir },\n timestamp: Date.now(),\n });\n\n res.on('close', () => {\n abortController.abort();\n });\n\n const extraProviderConfig = await resolveExtraProviderConfig(opts, provider);\n\n try {\n const editResult = await runContextualEdit({\n // EditFocus is validated at runtime by rabit; we pass through as-is.\n focus: focus as Parameters<typeof runContextualEdit>[0]['focus'],\n instruction,\n workDir: workspace.workDir,\n provider,\n model,\n userId,\n workspace,\n signal: abortController.signal,\n ...(extraProviderConfig !== undefined ? { providerConfig: extraProviderConfig } : {}),\n });\n\n if (!editResult.success) {\n sendSSEEvent(res, {\n type: 'error',\n data: {\n error: editResult.error ?? 'The edit did not change anything.',\n code: 'failed',\n },\n timestamp: Date.now(),\n });\n return;\n }\n\n const rawSchema = workspace.readSchema();\n let composedSchema: OrbitalSchema | null = null;\n if (rawSchema !== null) {\n try {\n composedSchema = JSON.parse(rawSchema) as OrbitalSchema;\n } catch {\n // malformed schema — emit complete without it\n }\n }\n\n sendSSEEvent(res, {\n type: 'complete',\n data: {\n threadId,\n skill: 'rabit',\n workDir: workspace.workDir,\n schemaGenerated: composedSchema !== null,\n appCompiled: false,\n schemaPersisted: false,\n ...(composedSchema !== null ? { schema: composedSchema } : {}),\n ...(workspace.appId !== undefined ? { appId: workspace.appId } : {}),\n },\n timestamp: Date.now(),\n });\n\n if (composedSchema !== null) {\n try {\n await opts.onComplete?.(composedSchema, req);\n } catch {\n // best-effort\n }\n }\n } catch (err: unknown) {\n const isAbort =\n err instanceof Error &&\n (err.name === 'AbortError' || abortController.signal.aborted);\n if (isAbort) {\n sendSSEEvent(res, {\n type: 'cancelled',\n data: { threadId, message: 'Edit cancelled' },\n timestamp: Date.now(),\n });\n } else {\n const message = err instanceof Error ? err.message : String(err);\n sendSSEEvent(res, {\n type: 'error',\n data: { error: message, code: 'runtime' },\n timestamp: Date.now(),\n });\n }\n } finally {\n try {\n unsubscribe();\n } catch {\n // best-effort\n }\n closeSSE(res);\n }\n };\n}\n"]}
@@ -0,0 +1,145 @@
1
+ import { OrbitalSchema, EntityData, EventPayload } from '@almadar/core';
2
+
3
+ /**
4
+ * Public SDK types. Canonical schema / payload types come from `@almadar/core`;
5
+ * the SDK adds the typed event union and HTTP-layer option shapes.
6
+ */
7
+
8
+ /**
9
+ * Canonical JSON value type — the closure of every value that survives a
10
+ * `JSON.parse(JSON.stringify(x))` round-trip. Used as the JSON-parse output
11
+ * type so we never widen to `unknown` at HTTP boundaries.
12
+ *
13
+ * Mirrors `packages/almadar-agent/src/api-types.ts:25-31`.
14
+ */
15
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
16
+ [key: string]: JsonValue;
17
+ };
18
+ /**
19
+ * Lifecycle events emitted by the agent during a `generate()` call. Mirrors
20
+ * the SSE event types from
21
+ * `apps/builder/packages/server/src/routes/agent/deepagent.ts` — keep in sync
22
+ * when new events are added on the server.
23
+ */
24
+ type AgentEvent = {
25
+ type: 'start';
26
+ threadId: string;
27
+ workDir: string;
28
+ } | {
29
+ type: 'plan_committed';
30
+ orbitals: readonly string[];
31
+ } | {
32
+ type: 'orbital_added';
33
+ orbital: string;
34
+ } | {
35
+ type: 'schema_update';
36
+ schema: OrbitalSchema;
37
+ } | {
38
+ type: 'app_created';
39
+ appId: string;
40
+ name: string;
41
+ } | {
42
+ type: 'subagent_start';
43
+ subagent: string;
44
+ } | {
45
+ type: 'subagent_progress';
46
+ subagent: string;
47
+ message: string;
48
+ } | {
49
+ type: 'subagent_complete';
50
+ subagent: string;
51
+ } | {
52
+ type: 'coordinator_decision';
53
+ decision: string;
54
+ } | {
55
+ type: 'complete';
56
+ schema: OrbitalSchema;
57
+ appId?: string;
58
+ } | {
59
+ type: 'error';
60
+ message: string;
61
+ code?: number;
62
+ };
63
+ /**
64
+ * Server-emitted error envelope. `code` maps to the SDK error subclasses:
65
+ * 4001 → ApiKeyError, 4029 → RateLimitedError, 4040 → CatalogOutOfScopeError.
66
+ */
67
+ interface ApiErrorBody {
68
+ code: number;
69
+ message: string;
70
+ details?: EventPayload;
71
+ }
72
+ /**
73
+ * Async-mode (`generate({ async: true })`) server response. The client polls
74
+ * `statusUrl` until the job resolves.
75
+ */
76
+ interface AsyncJobHandle {
77
+ jobId: string;
78
+ statusUrl: string;
79
+ }
80
+ interface GenerateOptions {
81
+ prompt: string;
82
+ endUserId?: string;
83
+ appId?: string;
84
+ /** Streaming callback for SSE events. */
85
+ onEvent?: (event: AgentEvent) => void;
86
+ /**
87
+ * When true, server responds with an `AsyncJobHandle` immediately and the
88
+ * client polls. Useful for generations expected to exceed proxy SSE timeouts.
89
+ */
90
+ async?: boolean;
91
+ }
92
+ interface GenerateResult {
93
+ schema: OrbitalSchema;
94
+ appId?: string;
95
+ }
96
+ /**
97
+ * Body of a `PUT /api/v1/agent/edit-schema`. Strictly structural; the SDK
98
+ * does not deep-type the patch — that's the server's job. Field types are
99
+ * `EventPayload`-compatible so callers can't sneak in arbitrary objects.
100
+ */
101
+ interface EditSchemaPatch {
102
+ orbital?: string;
103
+ traitOverrides?: EventPayload;
104
+ config?: EventPayload;
105
+ }
106
+ interface CompileOptions {
107
+ target?: 'express' | 'hono';
108
+ shell?: 'typescript' | 'python' | 'mobile';
109
+ }
110
+ interface CompileResult {
111
+ downloadUrl: string;
112
+ expiresAt: string;
113
+ }
114
+ interface AlmadarClientOptions {
115
+ apiKey: string;
116
+ baseUrl?: string;
117
+ fetch?: typeof fetch;
118
+ }
119
+ /**
120
+ * Props for `<AlmadarApp />` — renders an orbital schema. The runtime mode
121
+ * decides whether effects (persist/fetch/call-service) hit a backend or stay
122
+ * mocked in-browser.
123
+ */
124
+ interface AlmadarAppProps {
125
+ schema: OrbitalSchema;
126
+ /**
127
+ * - `static`: pure client-side, no server effects. Use with `data`.
128
+ * - `mock` (default): in-browser fake server, faker-seeded if `data` is undefined.
129
+ * - `server`: real backend at `serverUrl`.
130
+ */
131
+ mode?: 'static' | 'mock' | 'server';
132
+ /** Seed data keyed by entity name (canonical `EntityData` shape). */
133
+ data?: EntityData;
134
+ /** Required when `mode === 'server'`. */
135
+ serverUrl?: string;
136
+ initialPagePath?: string;
137
+ height?: string;
138
+ className?: string;
139
+ theme?: 'copper' | 'wireframe' | 'default';
140
+ }
141
+ interface AlmadarAppRef {
142
+ emit(eventName: string, payload?: EventPayload): void;
143
+ }
144
+
145
+ export type { AgentEvent as A, CompileOptions as C, EditSchemaPatch as E, GenerateOptions as G, JsonValue as J, AlmadarAppProps as a, AlmadarAppRef as b, AlmadarClientOptions as c, ApiErrorBody as d, AsyncJobHandle as e, CompileResult as f, GenerateResult as g };
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@almadar/sdk",
3
+ "version": "0.1.0-alpha.2",
4
+ "description": "Almadar SDK — embed agent-generated orbital schemas in your React app. AlmadarApp component + AlmadarClient HTTP client.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./client": {
15
+ "types": "./dist/client/index.d.ts",
16
+ "import": "./dist/client/index.js"
17
+ },
18
+ "./react": {
19
+ "types": "./dist/react/index.d.ts",
20
+ "import": "./dist/react/index.js"
21
+ },
22
+ "./server": {
23
+ "types": "./dist/server/index.d.ts",
24
+ "import": "./dist/server/index.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "peerDependencies": {
33
+ "@almadar/core": ">=10",
34
+ "@almadar/runtime": ">=6.13",
35
+ "@almadar/ui": ">=5.32",
36
+ "@almadar-io/rabit": ">=0.1.0",
37
+ "@almadar/workspace": ">=0.1.0",
38
+ "@almadar/server": ">=2.14.0",
39
+ "express": ">=4.0.0",
40
+ "react": ">=18.0.0",
41
+ "react-dom": ">=18.0.0",
42
+ "@almadar/llm": ">=2.24.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "@almadar-io/rabit": {
46
+ "optional": true
47
+ },
48
+ "@almadar/workspace": {
49
+ "optional": true
50
+ },
51
+ "@almadar/server": {
52
+ "optional": true
53
+ },
54
+ "express": {
55
+ "optional": true
56
+ },
57
+ "@almadar/llm": {
58
+ "optional": true
59
+ }
60
+ },
61
+ "devDependencies": {
62
+ "@almadar/core": ">=10",
63
+ "@almadar/eslint-plugin": ">=2.7.0",
64
+ "@almadar/runtime": ">=6.13",
65
+ "@almadar/ui": ">=5.32",
66
+ "@almadar-io/rabit": ">=0.1.0",
67
+ "@almadar/workspace": ">=0.1.0",
68
+ "@almadar/server": ">=2.14.0",
69
+ "@testing-library/react": "^16.1.0",
70
+ "@types/express": "^4.17.21",
71
+ "@types/react": "^18.3.12",
72
+ "@types/react-dom": "^18.3.1",
73
+ "@typescript-eslint/parser": "^8.0.0",
74
+ "eslint": "10.0.0",
75
+ "express": "^4.21.0",
76
+ "happy-dom": "^15.11.7",
77
+ "react": "^18.3.1",
78
+ "react-dom": "^18.3.1",
79
+ "tsup": "^8.3.5",
80
+ "typescript": "^5.7.0",
81
+ "vitest": "^2.1.0",
82
+ "@almadar/llm": ">=2.24.0"
83
+ },
84
+ "publishConfig": {
85
+ "registry": "https://registry.npmjs.org",
86
+ "access": "public"
87
+ },
88
+ "repository": {
89
+ "type": "git",
90
+ "url": "https://github.com/almadar-io/almadar-sdk.git"
91
+ },
92
+ "license": "BSL-1.1",
93
+ "scripts": {
94
+ "build": "tsup",
95
+ "build:watch": "tsup --watch",
96
+ "lint": "eslint src/",
97
+ "typecheck": "tsc --noEmit",
98
+ "test": "vitest --run"
99
+ }
100
+ }