diff --git a/README.md b/README.md index 69c4f66..5ed192a 100644 --- a/README.md +++ b/README.md @@ -61,3 +61,13 @@ The default API is `https://api.blazingagents.com`. Override it with See the [CLI documentation](https://docs.blazingagents.com/cli) for setup, authentication, command guides, and CI usage. + +### Thinking level + +In `ba assist`, ask to create an Agent with a Thinking level, read its current +level, set it to a value such as `high`, or clear it to Provider default. +The hosted Agent Tool accepts `thinkingLevel` and preserves update approval. +Known capabilities constrain choices; unknown capabilities accept custom +strings that may still be rejected during execution. `ba chat` and `ba run` +use the resolved Agent Version's selection without a per-Turn override. +Configure the Admin Agent's own Thinking level in the dashboard or SDK. diff --git a/package-lock.json b/package-lock.json index 1950942..50929b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,10 +7,13 @@ "": { "name": "@blazingagents/cli", "version": "0.1.0", + "bundleDependencies": [ + "@blazingagents/sdk" + ], "license": "MIT", "dependencies": { "@ai-sdk/tui": "1.0.85", - "@blazingagents/sdk": "0.2.1", + "@blazingagents/sdk": "file:vendor/blazingagents-sdk-0.2.1.tgz", "@clack/prompts": "1.7.0", "@github/keytar": "7.10.6", "ai": "7.0.84", @@ -37,6 +40,7 @@ "version": "4.0.68", "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-4.0.68.tgz", "integrity": "sha512-XKvZv6HFoMOWK64zXMaQatk4SxBzBDkGg7enXPWsCkxqPP4zDhFewOoBKasf3FPnZP9ceE+Yj3BgW925blAWtw==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@ai-sdk/provider": "4.0.8", @@ -54,6 +58,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-4.0.8.tgz", "integrity": "sha512-aWO7iwhFUGf347tCwNGggggfmZigaSu7TF739IZSrWWABUp7zkb4Cr3fMqvBe5EIS7ABJJu3Cadn0g/zs1G0QQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "json-schema": "^0.4.0" @@ -66,6 +71,7 @@ "version": "5.0.33", "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-5.0.33.tgz", "integrity": "sha512-TfjJqJmRsQyxAlb+3hGmP1o1xLUIT79yhOgtJuTF4hqsB37IC3CufGsuFhU04EeTOg7R9iptQ6Bzm0MW0n/c3g==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@ai-sdk/provider": "4.0.8", @@ -330,8 +336,9 @@ }, "node_modules/@blazingagents/sdk": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@blazingagents/sdk/-/sdk-0.2.1.tgz", - "integrity": "sha512-E7RdwysNJPbjr5XGj8rcLPn6gwoxZqWEunUfNTCL2NJr1IQAWHnx7NTm6Q6DWaU0GKjKYAkXsx7T67HUsNfWpw==", + "resolved": "file:vendor/blazingagents-sdk-0.2.1.tgz", + "integrity": "sha512-rr0YdVMo0ZLlYFPvKJHU5IrvTuIyicZwSfqOx6laYfJP5u2rG6/3REOpoGng6bAsXw3oEY86pOCDUoA3jeWbJw==", + "inBundle": true, "license": "MIT", "dependencies": { "croner": "10.0.1", @@ -706,6 +713,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "inBundle": true, "license": "MIT" }, "node_modules/@types/chai": { @@ -1087,6 +1095,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.2.0.tgz", "integrity": "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==", + "inBundle": true, "license": "Apache-2.0", "engines": { "node": ">= 20" @@ -1240,12 +1249,14 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@workflow/serde/-/serde-4.1.0.tgz", "integrity": "sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==", + "inBundle": true, "license": "Apache-2.0" }, "node_modules/ai": { "version": "7.0.84", "resolved": "https://registry.npmjs.org/ai/-/ai-7.0.84.tgz", "integrity": "sha512-znHNBWADOy79k8EK7636kDm5LmnjF4tMzegC2TfmlLDobDZbs0z0OXD2sxtH3eDTp5Re+pJQESvjinWJ6+kadQ==", + "inBundle": true, "license": "Apache-2.0", "dependencies": { "@ai-sdk/gateway": "4.0.68", @@ -1351,6 +1362,7 @@ "url": "https://github.com/sponsors/hexagon" } ], + "inBundle": true, "license": "MIT", "engines": { "node": ">=18.0" @@ -1412,6 +1424,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz", "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=18.0.0" @@ -1576,6 +1589,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "inBundle": true, "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/jsonc-parser": { @@ -1942,6 +1956,7 @@ "url": "https://github.com/sponsors/ai" } ], + "inBundle": true, "license": "MIT", "bin": { "nanoid": "bin/nanoid.js" @@ -2329,6 +2344,7 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", + "inBundle": true, "license": "MIT", "engines": { "node": ">=20.18.1" @@ -2546,6 +2562,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "inBundle": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -2561,6 +2578,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz", "integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 376f5bb..3a728e8 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "files": [ "dist", "README.md", - "LICENSE" + "LICENSE", + "vendor" ], "scripts": { "build": "rm -rf dist && tsc -p tsconfig.build.json", @@ -33,7 +34,7 @@ }, "dependencies": { "@ai-sdk/tui": "1.0.85", - "@blazingagents/sdk": "0.2.1", + "@blazingagents/sdk": "file:vendor/blazingagents-sdk-0.2.1.tgz", "@clack/prompts": "1.7.0", "@github/keytar": "7.10.6", "ai": "7.0.84", @@ -49,6 +50,9 @@ "ultracite": "7.10.2", "vitest": "4.1.10" }, + "bundleDependencies": [ + "@blazingagents/sdk" + ], "engines": { "node": ">=24" }, diff --git a/src/chat.test.ts b/src/chat.test.ts index 478f475..1b80f2b 100644 --- a/src/chat.test.ts +++ b/src/chat.test.ts @@ -14,6 +14,7 @@ const agent = { model: "openrouter/test-model", name: "Release Agent", providerId: "prv_0123456789abcdef", + thinkingLevel: null, workspaceId: "ws_AAAAAAAAAAAAAAAA", status: "active", tenantId: "ten_AAAAAAAAAAAAAAAA", diff --git a/src/cli.test.ts b/src/cli.test.ts index d329e5d..84a2f89 100644 --- a/src/cli.test.ts +++ b/src/cli.test.ts @@ -20,6 +20,7 @@ const runAgent = { model: "openrouter/test-model", name: "Release Agent", providerId: "prv_0123456789abcdef", + thinkingLevel: null, workspaceId: "ws_AAAAAAAAAAAAAAAA", status: "active", tenantId: "ten_AAAAAAAAAAAAAAAA", diff --git a/src/package-contract.test.ts b/src/package-contract.test.ts index 6ebcbb3..6f39244 100644 --- a/src/package-contract.test.ts +++ b/src/package-contract.test.ts @@ -5,14 +5,14 @@ async function readJson(url: URL) { return JSON.parse(await readFile(url, "utf8")) as Record; } -test("the CLI is an unbundled application package with exact runtime pins", async () => { +test("the CLI bundles the checked SDK with exact runtime pins", async () => { const manifest = await readJson(new URL("../package.json", import.meta.url)); expect(manifest).toMatchObject({ bin: { ba: "dist/bin/ba.js" }, dependencies: { "@ai-sdk/tui": "1.0.85", - "@blazingagents/sdk": "0.2.1", + "@blazingagents/sdk": "file:vendor/blazingagents-sdk-0.2.1.tgz", "@clack/prompts": "1.7.0", "@github/keytar": "7.10.6", ai: "7.0.84", @@ -21,7 +21,7 @@ test("the CLI is an unbundled application package with exact runtime pins", asyn zod: "4.5.4", }, engines: { node: ">=24" }, - files: ["dist", "README.md", "LICENSE"], + files: ["dist", "README.md", "LICENSE", "vendor"], license: "MIT", name: "@blazingagents/cli", type: "module", @@ -36,5 +36,5 @@ test("the CLI depends only on public runtime packages", async () => { expect(cli.dependencies).not.toHaveProperty("@blazing-agents/core"); expect( (cli.dependencies as Record)["@blazingagents/sdk"] - ).toBe("0.2.1"); + ).toBe("file:vendor/blazingagents-sdk-0.2.1.tgz"); }); diff --git a/src/run.test.ts b/src/run.test.ts index 762aca8..8672f2c 100644 --- a/src/run.test.ts +++ b/src/run.test.ts @@ -18,6 +18,7 @@ const agent = { model: "openrouter/test-model", name: "Release Agent", providerId: "prv_0123456789abcdef", + thinkingLevel: null, workspaceId: "ws_AAAAAAAAAAAAAAAA", status: "active", tenantId: "ten_AAAAAAAAAAAAAAAA", diff --git a/src/test/approval-transport.ts b/src/test/approval-transport.ts index b430ffa..6081866 100644 --- a/src/test/approval-transport.ts +++ b/src/test/approval-transport.ts @@ -18,6 +18,7 @@ export const adminAgent = { model: "openrouter/test-model", name: "Admin Agent", providerId: "prv_0123456789abcdef", + thinkingLevel: null, workspaceId: "ws_AAAAAAAAAAAAAAAA", status: "active", tenantId: "ten_AAAAAAAAAAAAAAAA", diff --git a/tests/packed-consumer.fixture.ts b/tests/packed-consumer.fixture.ts index e25622f..3fa99a0 100644 --- a/tests/packed-consumer.fixture.ts +++ b/tests/packed-consumer.fixture.ts @@ -53,6 +53,7 @@ const releaseAgent = { model: "openrouter/test-model", name: "Release Agent", providerId: "prv_0123456789abcdef", + thinkingLevel: null, workspaceId: "ws_AAAAAAAAAAAAAAAA", status: "active", tenantId: "ten_AAAAAAAAAAAAAAAA", diff --git a/tests/packed-shell.test.ts b/tests/packed-shell.test.ts index 68afe4e..0fa2146 100644 --- a/tests/packed-shell.test.ts +++ b/tests/packed-shell.test.ts @@ -16,8 +16,12 @@ import { const repositoryRoot = fileURLToPath(new URL("..", import.meta.url)); const MASK_GLYPHS = /[*•▪]/; -test("the tarball contains only the compiled application and package documents", async () => { - expect(cliPack.files.map(({ path }) => path)).toEqual([ +test("the tarball contains the compiled application, documents and checked SDK", async () => { + expect( + cliPack.files + .map(({ path }) => path) + .filter((path) => !path.startsWith("node_modules/")) + ).toEqual([ "LICENSE", "README.md", "dist/agent-resolution.js", @@ -38,7 +42,13 @@ test("the tarball contains only the compiled application and package documents", "dist/tui.js", "dist/ui-message-stream.js", "package.json", + "vendor/blazingagents-sdk-0.2.1.tgz", ]); + expect( + cliPack.files.some( + ({ path }) => path === "node_modules/@blazingagents/sdk/dist/client.js" + ) + ).toBe(true); const entrypoint = await readFile( join( @@ -60,12 +70,12 @@ test("the clean consumer has exact lockstep package and runtime versions", async const manifests = await Promise.all( [ ["cli", "@blazingagents", "cli"], - ["sdk", "@blazingagents", "sdk"], + ["sdk", "@blazingagents", "cli", "node_modules", "@blazingagents", "sdk"], ["tui", "@ai-sdk", "tui"], ["keytar", "@github", "keytar"], ["ai", "ai"], ["commander", "commander"], - ["yaml", "yaml"], + ["yaml", "@blazingagents", "cli", "node_modules", "yaml"], ].map(async ([label, ...segments]) => { const manifest = JSON.parse( await readFile( @@ -109,7 +119,15 @@ test("the clean consumer has exact lockstep package and runtime versions", async const sdkManifest = JSON.parse( await readFile( - join(packageDirectory, "@blazingagents", "sdk", "package.json"), + join( + packageDirectory, + "@blazingagents", + "cli", + "node_modules", + "@blazingagents", + "sdk", + "package.json" + ), "utf8" ) ) as Record; diff --git a/vendor/blazingagents-sdk-0.2.1.tgz b/vendor/blazingagents-sdk-0.2.1.tgz new file mode 100644 index 0000000..337bb9b Binary files /dev/null and b/vendor/blazingagents-sdk-0.2.1.tgz differ