@agentsky/sky 2.2.1 → 2.4.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-FSAF6HIL.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
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  external_exports,
3
3
  messagePartSchema
4
- } from "./chunk-TMLNYYYY.js";
4
+ } from "./chunk-FSAF6HIL.js";
5
5
 
6
6
  // ../../packages/chat/src/stream.ts
7
7
  async function* parseSseStream(body) {
@@ -89,6 +89,7 @@ var internalEventSchema = external_exports.object({
89
89
  agentInstanceId: external_exports.string().min(1).optional(),
90
90
  message: external_exports.object({
91
91
  id: external_exports.string().optional(),
92
+ podId: external_exports.string().min(1).optional(),
92
93
  parts: external_exports.array(messagePartSchema).min(1)
93
94
  }).optional(),
94
95
  /** A pre-built lifecycle event from the web host (session.updated /
@@ -103,7 +104,7 @@ function podMessageBody(messageId, turn, resourcesRevision = 0) {
103
104
  };
104
105
  return { id: messageId, ...envelope, parts: legacyPartsOf(envelope) };
105
106
  }
106
- return { id: messageId, parts: turn.parts };
107
+ return { id: messageId, parts: turn.parts, ...resourcesRevision > 0 ? { resources_revision: resourcesRevision } : {} };
107
108
  }
108
109
  var UNREACHABLE_CODES = /* @__PURE__ */ new Set([
109
110
  "ECONNREFUSED",
@@ -216,18 +217,21 @@ function textFromParts(parts) {
216
217
  function normalizeBaseUrl(baseUrl) {
217
218
  return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
218
219
  }
220
+ var PROMOTION_SCOPE_HEADER = "x-agentsky-promotion-scope";
219
221
  async function postSessionEvents(args) {
220
222
  const url = new URL(
221
223
  `/api/v1/sessions/${encodeURIComponent(args.sessionId)}/events`,
222
224
  normalizeBaseUrl(args.baseUrl)
223
225
  );
224
- const body = JSON.stringify({ events: args.events });
226
+ const body = JSON.stringify({ events: args.events, ...args.requireIdle ? { requireIdle: true } : {} });
225
227
  const send = async (token) => fetch(url, {
226
228
  method: "POST",
227
229
  headers: {
228
230
  authorization: `Bearer ${token}`,
229
231
  "content-type": "application/json",
230
- ...args.idempotencyKey ? { "idempotency-key": args.idempotencyKey } : {}
232
+ ...args.idempotencyKey ? { "idempotency-key": args.idempotencyKey } : {},
233
+ ...args.routineRunId ? { "x-agentsky-routine-run": args.routineRunId } : {},
234
+ ...args.promotionScope ? { [PROMOTION_SCOPE_HEADER]: args.promotionScope } : {}
231
235
  },
232
236
  body,
233
237
  signal: AbortSignal.timeout(args.timeoutMs ?? 95e3)
@@ -261,6 +265,7 @@ async function readResult(response) {
261
265
  };
262
266
  }
263
267
  export {
268
+ PROMOTION_SCOPE_HEADER,
264
269
  classifyPodSendError,
265
270
  classifyPodSendStatus,
266
271
  getPodHealth,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentsky/sky",
3
- "version": "2.2.1",
3
+ "version": "2.4.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
  }