@agentsky/sky 0.2.1 → 2.3.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.
@@ -0,0 +1,207 @@
1
+ import {
2
+ REASONING_EFFORT_VALUES,
3
+ capabilitiesSchema,
4
+ external_exports,
5
+ instructionFileSchema,
6
+ mcpServersSchema,
7
+ sessionResourcesParamSchema,
8
+ skillsArraySchema,
9
+ systemMessageEventSchema,
10
+ userMessageEventSchema
11
+ } from "./chunk-2KQLWHHC.js";
12
+
13
+ // ../../packages/spec/src/compatibility.ts
14
+ var capabilityInputsSchema = capabilitiesSchema;
15
+
16
+ // ../../packages/spec/src/products.ts
17
+ var budgetSchema = external_exports.object({
18
+ type: external_exports.literal("limit"),
19
+ max_list_cost: external_exports.object({
20
+ amount: external_exports.string().min(1).max(15).describe('Whole US cents as an integer decimal string, e.g. "125" for $1.25'),
21
+ currency: external_exports.literal("USD")
22
+ })
23
+ });
24
+ var productRefSchema = external_exports.string().min(1).max(240);
25
+ var agentAddonsSchema = external_exports.object({
26
+ vault_ids: external_exports.array(external_exports.string().min(1)).max(10).optional(),
27
+ environment_id: external_exports.string().min(1).optional(),
28
+ resources: sessionResourcesParamSchema.optional(),
29
+ instructions: external_exports.array(instructionFileSchema).max(20).optional(),
30
+ skills: skillsArraySchema.optional(),
31
+ mcp_servers: mcpServersSchema.optional(),
32
+ capabilities: capabilityInputsSchema.optional(),
33
+ model: external_exports.string().min(1).optional(),
34
+ reasoning_effort: external_exports.enum(REASONING_EFFORT_VALUES).nullable().optional(),
35
+ vcpus: external_exports.number().int().positive().optional(),
36
+ memory_mb: external_exports.number().int().positive().optional(),
37
+ model_billing: external_exports.enum(["platform", "account"]).optional(),
38
+ session_budget: budgetSchema.optional()
39
+ }).strict();
40
+ var modelAddonsSchema = external_exports.object({
41
+ max_output_tokens: external_exports.number().int().positive().optional(),
42
+ temperature: external_exports.number().finite().optional(),
43
+ top_p: external_exports.number().finite().optional(),
44
+ stop: external_exports.union([external_exports.string(), external_exports.array(external_exports.string())]).optional(),
45
+ response_format: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
46
+ tools: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
47
+ tool_choice: external_exports.union([external_exports.string(), external_exports.record(external_exports.string(), external_exports.unknown())]).optional()
48
+ }).strict();
49
+ var modelNativeEnvelopeSchema = external_exports.discriminatedUnion("wire", [
50
+ external_exports.object({ wire: external_exports.literal("openai"), path: external_exports.enum(["/v1/chat/completions", "/v1/responses", "/v1/embeddings"]), body: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict(),
51
+ external_exports.object({ wire: external_exports.literal("anthropic"), path: external_exports.literal("/v1/messages"), body: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict(),
52
+ external_exports.object({ wire: external_exports.literal("decisions"), path: external_exports.literal("/api/alpha/decisions"), body: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict()
53
+ ]);
54
+ var modelRunInputSchema = external_exports.union([external_exports.string().min(1), modelNativeEnvelopeSchema, external_exports.record(external_exports.string(), external_exports.unknown())]).superRefine((input, context) => {
55
+ if (typeof input === "object" && ["wire", "path", "body"].some((key) => key in input) && !modelNativeEnvelopeSchema.safeParse(input).success) {
56
+ context.addIssue({ code: "custom", message: "Native model envelopes require a registered wire, path and object body, with no additional fields" });
57
+ }
58
+ });
59
+ var createProductAgentSchema = external_exports.object({
60
+ product: productRefSchema,
61
+ name: external_exports.string().max(60).optional(),
62
+ instructions: external_exports.string().max(1e5).optional(),
63
+ addons: agentAddonsSchema.optional(),
64
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
65
+ }).strict();
66
+ var prepareProductSessionSchema = external_exports.object({
67
+ product: productRefSchema,
68
+ addons: agentAddonsSchema.optional(),
69
+ title: external_exports.string().max(120).optional(),
70
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
71
+ }).strict();
72
+ var createRunSchema = external_exports.object({
73
+ product: productRefSchema,
74
+ input: external_exports.unknown().refine((value) => value !== void 0 && value !== null, "input is required"),
75
+ addons: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
76
+ session_id: external_exports.string().min(1).optional(),
77
+ stream: external_exports.boolean().optional(),
78
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
79
+ }).strict();
80
+ var agentRunInputSchema = external_exports.union([
81
+ external_exports.string().min(1).max(5e5),
82
+ external_exports.object({ events: external_exports.array(external_exports.union([userMessageEventSchema, systemMessageEventSchema])).min(1).max(2).refine((events) => events[0]?.type === "user.message" && (events.length === 1 || events[1]?.type === "system.message"), "A Run starts with one user message and an optional trailing system message") }).strict()
83
+ ]);
84
+ var runEventsSchema = external_exports.object({
85
+ events: external_exports.array(external_exports.union([
86
+ userMessageEventSchema,
87
+ systemMessageEventSchema,
88
+ external_exports.object({ type: external_exports.literal("user.interrupt") }).strict()
89
+ ])).min(1).max(2).refine(
90
+ (events) => events.length === 1 && events[0]?.type === "user.interrupt" || events[0]?.type === "user.message" && (events.length === 1 || events[1]?.type === "system.message"),
91
+ "Controls accept one interrupt or one user message with an optional trailing system message"
92
+ )
93
+ }).strict();
94
+ var publishProductSchema = external_exports.object({
95
+ slug: external_exports.string().regex(/^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/).max(180).optional(),
96
+ description: external_exports.string().max(2e3).optional()
97
+ }).strict();
98
+ var migrateSessionExecutionSchema = external_exports.object({
99
+ execution: external_exports.object({ product: productRefSchema, expected_generation: external_exports.number().int().min(0) }).strict()
100
+ }).strict();
101
+ var sessionAddonsPatchSchema = external_exports.object({
102
+ addons: external_exports.object({ skills: skillsArraySchema.optional(), capabilities: capabilityInputsSchema.optional() }).strict().refine((value) => value.skills !== void 0 || value.capabilities !== void 0, "Supply a skills or capabilities overlay"),
103
+ expected_addons_revision: external_exports.number().int().min(0),
104
+ metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
105
+ }).strict();
106
+ var publicRunSchema = external_exports.object({
107
+ id: external_exports.string(),
108
+ product: external_exports.string().nullable(),
109
+ session_id: external_exports.string().nullable(),
110
+ status: external_exports.enum(["queued", "running", "waiting_input", "stopping", "completed", "interrupted", "failed", "blocked", "reconciling"]),
111
+ output: external_exports.unknown(),
112
+ output_available: external_exports.boolean().optional(),
113
+ usage: external_exports.unknown(),
114
+ billing: external_exports.unknown(),
115
+ error: external_exports.unknown(),
116
+ artifact: external_exports.object({ id: external_exports.string(), mediaType: external_exports.string(), url: external_exports.string().url() }).optional(),
117
+ source: external_exports.object({ goal_id: external_exports.string().optional(), iteration: external_exports.number().int().optional(), routine_run_id: external_exports.string().optional(), routine_id: external_exports.string().optional() }).optional(),
118
+ created_at: external_exports.string(),
119
+ completed_at: external_exports.string().nullable()
120
+ });
121
+
122
+ // src/products.ts
123
+ var ProductApiError = class extends Error {
124
+ constructor(status, code, message) {
125
+ super(message);
126
+ this.status = status;
127
+ this.code = code;
128
+ this.name = "ProductApiError";
129
+ }
130
+ status;
131
+ code;
132
+ };
133
+ function createProductClient(options) {
134
+ const transport = options.fetch ?? fetch;
135
+ const base = (options.baseUrl ?? "https://api.agentsky.dev/v1").replace(/\/$/, "");
136
+ const pathId = (id) => encodeURIComponent(id);
137
+ async function request(method, path, body, requestOptions, stream = false) {
138
+ const serializedBody = body === void 0 ? void 0 : JSON.stringify(body);
139
+ const token = typeof options.token === "function" ? await options.token() : options.token;
140
+ const response = await transport(`${base}${path}`, {
141
+ method,
142
+ signal: requestOptions?.signal,
143
+ headers: {
144
+ authorization: `Bearer ${token}`,
145
+ "x-universe": options.universe,
146
+ ...body === void 0 ? {} : { "content-type": "application/json" },
147
+ ...stream ? { accept: "text/event-stream" } : {},
148
+ ...requestOptions?.idempotencyKey ? { "idempotency-key": requestOptions.idempotencyKey } : {}
149
+ },
150
+ ...serializedBody === void 0 ? {} : { body: serializedBody }
151
+ });
152
+ if (!response.ok) {
153
+ const error = await response.json().catch(() => null);
154
+ throw new ProductApiError(
155
+ response.status,
156
+ typeof error?.error?.code === "string" ? error.error.code : "http_error",
157
+ typeof error?.error?.message === "string" ? error.error.message : response.statusText
158
+ );
159
+ }
160
+ return response;
161
+ }
162
+ function admissionKey(value) {
163
+ if (typeof value?.idempotencyKey !== "string" || !/^[\x21-\x7e]{1,200}$/.test(value.idempotencyKey)) throw new Error("Provide a stable Idempotency-Key containing 1\u2013200 visible ASCII characters.");
164
+ return { idempotencyKey: value.idempotencyKey, signal: value.signal };
165
+ }
166
+ return {
167
+ async list(signal) {
168
+ return (await (await request("GET", "/products", void 0, { signal })).json()).products;
169
+ },
170
+ async prepare(input, context) {
171
+ const result = await (await request("POST", "/sessions", prepareProductSessionSchema.parse(input), admissionKey(context))).json();
172
+ return result.session;
173
+ },
174
+ async create(input, context) {
175
+ const result = await (await request("POST", "/agents", createProductAgentSchema.parse(input), admissionKey(context))).json();
176
+ return result.agent;
177
+ },
178
+ async publish(agentId, input, context) {
179
+ return (await request("POST", `/agents/${pathId(agentId)}/publish`, publishProductSchema.parse(input), admissionKey(context))).json();
180
+ },
181
+ async delist(agentId, context) {
182
+ return (await request("DELETE", `/agents/${pathId(agentId)}/publish`, void 0, admissionKey(context))).json();
183
+ },
184
+ async start(input, context) {
185
+ const response = await request("POST", "/runs", createRunSchema.parse({ ...input, stream: false }), admissionKey(context));
186
+ return (await response.json()).run;
187
+ },
188
+ async read(runId, signal) {
189
+ return (await (await request("GET", `/runs/${pathId(runId)}`, void 0, { signal })).json()).run;
190
+ },
191
+ async control(runId, input, context) {
192
+ return (await request("POST", `/runs/${pathId(runId)}/events`, runEventsSchema.parse(input), admissionKey(context))).json();
193
+ },
194
+ async events(runId, context = {}) {
195
+ const query = context.cursor ? `?cursor=${encodeURIComponent(context.cursor)}` : "";
196
+ return (await request("GET", `/runs/${pathId(runId)}/events${query}`, void 0, { signal: context.signal })).json();
197
+ },
198
+ async observe(runId, context = {}) {
199
+ const query = context.cursor ? `?cursor=${encodeURIComponent(context.cursor)}` : "";
200
+ return request("GET", `/runs/${pathId(runId)}/events${query}`, void 0, { signal: context.signal }, true);
201
+ }
202
+ };
203
+ }
204
+ export {
205
+ ProductApiError,
206
+ createProductClient
207
+ };
@@ -0,0 +1,281 @@
1
+ import {
2
+ external_exports,
3
+ messagePartSchema
4
+ } from "./chunk-2KQLWHHC.js";
5
+
6
+ // ../../packages/chat/src/stream.ts
7
+ async function* parseSseStream(body) {
8
+ const reader = body.getReader();
9
+ const decoder = new TextDecoder();
10
+ let buffer = "";
11
+ try {
12
+ while (true) {
13
+ const { done, value } = await reader.read();
14
+ if (done) break;
15
+ buffer += decoder.decode(value, { stream: true });
16
+ let sep;
17
+ while ((sep = buffer.match(/\r?\n\r?\n/)) && sep.index !== void 0) {
18
+ const raw = buffer.slice(0, sep.index);
19
+ buffer = buffer.slice(sep.index + sep[0].length);
20
+ const frame = { data: "" };
21
+ const dataLines = [];
22
+ for (const line of raw.split(/\r?\n/)) {
23
+ if (!line || line.startsWith(":")) continue;
24
+ const colon = line.indexOf(":");
25
+ const field = colon === -1 ? line : line.slice(0, colon);
26
+ const value2 = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /, "");
27
+ if (field === "id") frame.id = value2;
28
+ else if (field === "event") frame.event = value2;
29
+ else if (field === "data") dataLines.push(value2);
30
+ }
31
+ frame.data = dataLines.join("\n");
32
+ if (frame.id !== void 0 || frame.event !== void 0 || frame.data) yield frame;
33
+ }
34
+ }
35
+ } finally {
36
+ reader.releaseLock();
37
+ }
38
+ }
39
+ async function* streamAgentEvents(baseUrl, options = {}) {
40
+ const headers = {
41
+ accept: "text/event-stream",
42
+ ...options.headers ?? {}
43
+ };
44
+ if (options.lastEventId) headers["last-event-id"] = options.lastEventId;
45
+ const watchdog = new AbortController();
46
+ const onOuterAbort = () => watchdog.abort();
47
+ options.signal?.addEventListener("abort", onOuterAbort, { once: true });
48
+ if (options.signal?.aborted) watchdog.abort();
49
+ let idleTimer;
50
+ const armIdle = () => {
51
+ if (!options.idleTimeoutMs) return;
52
+ clearTimeout(idleTimer);
53
+ idleTimer = setTimeout(() => watchdog.abort(), options.idleTimeoutMs);
54
+ };
55
+ try {
56
+ armIdle();
57
+ const res = await fetch(`${baseUrl}/stream`, { headers, signal: watchdog.signal });
58
+ if (!res.ok) throw new Error(`pod stream failed ${res.status}: ${await res.text()}`);
59
+ if (!res.body) throw new Error("pod stream returned no body");
60
+ options.onOpen?.();
61
+ for await (const frame of parseSseStream(res.body)) {
62
+ armIdle();
63
+ let payload = {};
64
+ try {
65
+ payload = frame.data ? JSON.parse(frame.data) : {};
66
+ } catch {
67
+ continue;
68
+ }
69
+ yield {
70
+ id: frame.id ?? "",
71
+ type: frame.event ?? (typeof payload.type === "string" ? payload.type : "unknown"),
72
+ detail: payload.detail ?? null,
73
+ data: payload.data ?? payload,
74
+ created_at: payload.created_at
75
+ };
76
+ }
77
+ } catch (error) {
78
+ if (!(error instanceof DOMException && error.name === "AbortError")) throw error;
79
+ } finally {
80
+ clearTimeout(idleTimer);
81
+ options.signal?.removeEventListener("abort", onOuterAbort);
82
+ }
83
+ }
84
+
85
+ // ../../packages/chat/src/index.ts
86
+ var internalEventSchema = external_exports.object({
87
+ sessionId: external_exports.string().min(1).optional(),
88
+ /** Deploy-skew alias for sessionId; dropped one release after the cutover. */
89
+ agentInstanceId: external_exports.string().min(1).optional(),
90
+ message: external_exports.object({
91
+ id: external_exports.string().optional(),
92
+ podId: external_exports.string().min(1).optional(),
93
+ parts: external_exports.array(messagePartSchema).min(1)
94
+ }).optional(),
95
+ /** A pre-built lifecycle event from the web host (session.updated /
96
+ * session.deleted) — emitted verbatim; the host already persisted it. */
97
+ lifecycle: external_exports.object({ id: external_exports.string().min(1), type: external_exports.string().min(1) }).passthrough().optional()
98
+ });
99
+ function podMessageBody(messageId, turn, resourcesRevision = 0) {
100
+ if ("events" in turn) {
101
+ const envelope = {
102
+ events: turn.events.system ? [turn.events.message, turn.events.system] : [turn.events.message],
103
+ ...resourcesRevision > 0 ? { resources_revision: resourcesRevision } : {}
104
+ };
105
+ return { id: messageId, ...envelope, parts: legacyPartsOf(envelope) };
106
+ }
107
+ return { id: messageId, parts: turn.parts };
108
+ }
109
+ var UNREACHABLE_CODES = /* @__PURE__ */ new Set([
110
+ "ECONNREFUSED",
111
+ "ENOTFOUND",
112
+ "EAI_AGAIN",
113
+ "EHOSTUNREACH",
114
+ "ENETUNREACH",
115
+ "UND_ERR_CONNECT_TIMEOUT"
116
+ ]);
117
+ var UNREACHABLE_PREFIXES = ["CERT_", "ERR_TLS_", "UNABLE_TO_", "DEPTH_ZERO_", "SELF_SIGNED_"];
118
+ function errorCode(error) {
119
+ const cause = error?.cause ?? error;
120
+ const code = cause?.code;
121
+ if (typeof code === "string") return code;
122
+ const nested = cause?.errors?.find(
123
+ (e) => typeof e?.code === "string"
124
+ );
125
+ return nested ? nested.code : void 0;
126
+ }
127
+ function classifyPodSendError(error) {
128
+ const detail = error instanceof Error ? error.message : String(error);
129
+ const name = error?.name;
130
+ if (name === "TimeoutError" || name === "AbortError") return { kind: "uncertain", reason: "timeout", detail };
131
+ const code = errorCode(error);
132
+ if (code && (UNREACHABLE_CODES.has(code) || UNREACHABLE_PREFIXES.some((prefix) => code.startsWith(prefix)))) {
133
+ return { kind: "undelivered", reason: "unreachable", detail: `${detail} (${code})` };
134
+ }
135
+ return { kind: "uncertain", reason: "reset", detail: code ? `${detail} (${code})` : detail };
136
+ }
137
+ function classifyPodSendStatus(status, detail) {
138
+ if (status >= 200 && status < 300) return { kind: "accepted", status };
139
+ if (status === 403) return { kind: "undelivered", reason: "forbidden", status, detail };
140
+ if (status === 409) return { kind: "undelivered", reason: "parked", status, detail };
141
+ if (status === 502 || status === 503) return { kind: "undelivered", reason: "not_serving", status, detail };
142
+ if (status === 504) return { kind: "uncertain", reason: "gateway_timeout", status, detail };
143
+ if (status >= 500) return { kind: "uncertain", reason: "server_error", status, detail };
144
+ return { kind: "rejected", status, detail };
145
+ }
146
+ async function sendPodMessage(baseUrl, body, options = {}) {
147
+ const headers = {
148
+ "content-type": "application/json",
149
+ ...options.headers ?? {}
150
+ };
151
+ if (options.idempotencyKey) headers["idempotency-key"] = options.idempotencyKey;
152
+ let res;
153
+ try {
154
+ res = await fetch(`${baseUrl}/messages`, {
155
+ method: "POST",
156
+ headers,
157
+ body: JSON.stringify(body),
158
+ signal: AbortSignal.timeout(options.timeoutMs ?? 2e4)
159
+ });
160
+ } catch (error) {
161
+ return classifyPodSendError(error);
162
+ }
163
+ const detail = res.ok ? "" : await res.text().catch(() => "");
164
+ return classifyPodSendStatus(res.status, detail);
165
+ }
166
+ async function getPodHealth(baseUrl, options = {}) {
167
+ try {
168
+ const res = await fetch(`${baseUrl}/health`, {
169
+ headers: options.headers ?? {},
170
+ signal: AbortSignal.timeout(options.timeoutMs ?? 5e3)
171
+ });
172
+ const body = await res.json().catch(() => ({}));
173
+ const open = body.open_message_id ?? body.open_turn_id;
174
+ return {
175
+ ok: res.ok,
176
+ status: res.status,
177
+ state: typeof body.state === "string" ? body.state : void 0,
178
+ openMessageId: typeof open === "string" && open ? open : null
179
+ };
180
+ } catch {
181
+ return { ok: false, openMessageId: null };
182
+ }
183
+ }
184
+ function legacyPartsOf(body) {
185
+ const parts = [];
186
+ const user = body.events[0];
187
+ if (user.type !== "user.message") return parts;
188
+ for (const block of user.content) {
189
+ const index = parts.length;
190
+ if (block.type === "text") {
191
+ parts.push({ type: "text", index, text: block.text });
192
+ continue;
193
+ }
194
+ if (block.source.type !== "file") continue;
195
+ const uri = `blob://assets/${block.source.file_id.replace(/^file_/, "")}`;
196
+ if (block.type === "image") parts.push({ type: "image", index, media_type: "image/*", uri });
197
+ else parts.push({ type: "file", index, name: block.title ?? "document", media_type: "application/octet-stream", uri });
198
+ }
199
+ return parts;
200
+ }
201
+ function textFromParts(parts) {
202
+ const texts = [];
203
+ let previous;
204
+ for (const part of parts) {
205
+ const stream = part.type === "text" && part.stream_id && typeof part.stream_index === "number" && Number.isInteger(part.stream_index) && part.stream_index >= 0 ? { id: part.stream_id, index: part.stream_index } : void 0;
206
+ if (part.type === "text") {
207
+ if (stream && previous && stream.id === previous.id && stream.index === previous.index + 1) {
208
+ texts[texts.length - 1] += part.text;
209
+ } else {
210
+ texts.push(part.text);
211
+ }
212
+ }
213
+ previous = stream;
214
+ }
215
+ return texts.filter(Boolean).join(" ").trim();
216
+ }
217
+ function normalizeBaseUrl(baseUrl) {
218
+ return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
219
+ }
220
+ var PROMOTION_SCOPE_HEADER = "x-agentsky-promotion-scope";
221
+ async function postSessionEvents(args) {
222
+ const url = new URL(
223
+ `/api/v1/sessions/${encodeURIComponent(args.sessionId)}/events`,
224
+ normalizeBaseUrl(args.baseUrl)
225
+ );
226
+ const body = JSON.stringify({ events: args.events });
227
+ const send = async (token) => fetch(url, {
228
+ method: "POST",
229
+ headers: {
230
+ authorization: `Bearer ${token}`,
231
+ "content-type": "application/json",
232
+ ...args.idempotencyKey ? { "idempotency-key": args.idempotencyKey } : {},
233
+ ...args.routineRunId ? { "x-agentsky-routine-run": args.routineRunId } : {},
234
+ ...args.promotionScope ? { [PROMOTION_SCOPE_HEADER]: args.promotionScope } : {}
235
+ },
236
+ body,
237
+ signal: AbortSignal.timeout(args.timeoutMs ?? 95e3)
238
+ });
239
+ let response = await send(await args.credentials.token());
240
+ if (response.status === 401) response = await send(await args.credentials.renew());
241
+ return readResult(response);
242
+ }
243
+ async function interruptSession(args) {
244
+ const url = new URL(
245
+ `/api/v1/sessions/${encodeURIComponent(args.sessionId)}/interrupt`,
246
+ normalizeBaseUrl(args.baseUrl)
247
+ );
248
+ const send = async (token) => fetch(url, {
249
+ method: "POST",
250
+ headers: { authorization: `Bearer ${token}` },
251
+ signal: AbortSignal.timeout(args.timeoutMs ?? 1e4)
252
+ });
253
+ let response = await send(await args.credentials.token());
254
+ if (response.status === 401) response = await send(await args.credentials.renew());
255
+ return readResult(response);
256
+ }
257
+ async function readResult(response) {
258
+ const payload = await response.json().catch(() => ({}));
259
+ if (response.ok) return { ok: true, status: response.status, data: payload.data ?? [] };
260
+ return {
261
+ ok: false,
262
+ status: response.status,
263
+ code: payload.error?.code ?? `http_${response.status}`,
264
+ message: payload.error?.message ?? `conversation plane answered ${response.status}`
265
+ };
266
+ }
267
+ export {
268
+ PROMOTION_SCOPE_HEADER,
269
+ classifyPodSendError,
270
+ classifyPodSendStatus,
271
+ getPodHealth,
272
+ internalEventSchema,
273
+ interruptSession,
274
+ legacyPartsOf,
275
+ parseSseStream,
276
+ podMessageBody,
277
+ postSessionEvents,
278
+ sendPodMessage,
279
+ streamAgentEvents,
280
+ textFromParts
281
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsky/sky",
3
- "version": "0.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "sky — the AgentSky developer CLI: launch and talk to long-lived agents from your terminal.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,13 +15,14 @@
15
15
  },
16
16
  "scripts": {
17
17
  "dev": "tsx src/index.ts",
18
- "build": "tsup src/index.ts --format esm --target node20 --clean",
18
+ "build": "tsup src/index.ts src/products.ts --format esm --target node20 --clean",
19
19
  "test": "vitest run",
20
20
  "typecheck": "tsc --noEmit"
21
21
  },
22
22
  "dependencies": {
23
23
  "commander": "^14.0.0",
24
- "smol-toml": "^1.4.2"
24
+ "smol-toml": "^1.4.2",
25
+ "zod": "4.5.4"
25
26
  },
26
27
  "devDependencies": {
27
28
  "@agent/chat": "*",
@@ -30,14 +31,28 @@
30
31
  "tsup": "^8.5.0",
31
32
  "tsx": "^4.22.4",
32
33
  "typescript": "^5",
33
- "vitest": "^3.0.0",
34
- "zod": "^4.4.3"
34
+ "vitest": "^3.0.0"
35
35
  },
36
36
  "tsup": {
37
37
  "noExternal": [
38
38
  "@agent/chat",
39
39
  "@agent/spec",
40
40
  "zod"
41
- ]
41
+ ],
42
+ "dts": {
43
+ "compilerOptions": {
44
+ "ignoreDeprecations": "6.0"
45
+ },
46
+ "resolve": [
47
+ "@agent/spec",
48
+ "@agent/spec/products"
49
+ ]
50
+ }
51
+ },
52
+ "exports": {
53
+ "./products": {
54
+ "types": "./dist/products.d.ts",
55
+ "import": "./dist/products.js"
56
+ }
42
57
  }
43
58
  }
@@ -1,9 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- export {
8
- __export
9
- };
@@ -1,39 +0,0 @@
1
- // src/config.ts
2
- import { mkdirSync, readFileSync, writeFileSync } from "fs";
3
- import { homedir } from "os";
4
- import { dirname, join } from "path";
5
- var DEFAULT_API_BASE = "https://agentsky.dev";
6
- function configPath() {
7
- return join(process.env.SKY_CONFIG_DIR ?? join(homedir(), ".config", "sky"), "config.json");
8
- }
9
- function loadConfig() {
10
- try {
11
- return JSON.parse(readFileSync(configPath(), "utf8"));
12
- } catch {
13
- return {};
14
- }
15
- }
16
- function saveConfig(config) {
17
- const path = configPath();
18
- mkdirSync(dirname(path), { recursive: true });
19
- writeFileSync(path, `${JSON.stringify(config, null, 2)}
20
- `, { mode: 384 });
21
- }
22
- function apiBase() {
23
- return (process.env.SKY_API_URL ?? loadConfig().apiBase ?? DEFAULT_API_BASE).replace(/\/$/, "");
24
- }
25
- function apiToken() {
26
- return process.env.SKY_API_TOKEN ?? loadConfig().token;
27
- }
28
- function currentUniverse() {
29
- return process.env.SKY_UNIVERSE ?? loadConfig().currentUniverse;
30
- }
31
-
32
- export {
33
- configPath,
34
- loadConfig,
35
- saveConfig,
36
- apiBase,
37
- apiToken,
38
- currentUniverse
39
- };
@@ -1,17 +0,0 @@
1
- import {
2
- apiBase,
3
- apiToken,
4
- configPath,
5
- currentUniverse,
6
- loadConfig,
7
- saveConfig
8
- } from "./chunk-NLEDGUN7.js";
9
- import "./chunk-MLKGABMK.js";
10
- export {
11
- apiBase,
12
- apiToken,
13
- configPath,
14
- currentUniverse,
15
- loadConfig,
16
- saveConfig
17
- };