{"_id":"@blull/circuitai","_rev":"8-ab865e952c768768a55aba3036b08b1f","name":"@blull/circuitai","dist-tags":{"latest":"0.0.8"},"versions":{"0.0.1":{"name":"@blull/circuitai","version":"0.0.1","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.1","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"d9c018539048e176cb9561840b7efe595e925cd4","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.1.tgz","fileCount":9,"integrity":"sha512-ABADHjvZRaVjs6GEu4t3YGWTmnsL0D9AeoyEzYLedjnnUnR3GUStSEUBUVyzmtEb071UF3p9R+mcg34w4UYc5A==","signatures":[{"sig":"MEQCIBAevtE/+uTylba8LDyuJ9mVd+F4Xp1qZl2LLRHK+1VQAiA4cZN3mJMPzG8K6XaCU6KSoJwPUxen7mSLAVCVKVqDrg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47657},"type":"module","exports":{".":"./dist/index.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"f7c61411cac62f2b269a0f433e5fc75d918cd6e4","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0"},"peerDependencies":{"zod":"^4.0.0","openai":"^6.0.0","@anthropic-ai/sdk":">=0.99.0"},"peerDependenciesMeta":{"openai":{"optional":true},"@anthropic-ai/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.1_1779917798512_0.4085639982757503","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@blull/circuitai","version":"0.0.2","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.2","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"fad946b946be39f40c9333c97393622c6b17f21f","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.2.tgz","fileCount":9,"integrity":"sha512-hAAnCZk7KvEUZ/TZ5QxV49U2xakpOg5MtojSMwIxCnmWw4WVezw6IXGrCbxsEDGcDI1W99soqmWbKQThYyIosg==","signatures":[{"sig":"MEYCIQC5RY07SmoD8GFdT1yu/YVTfOU48VsLyKYlYzwd1H53+QIhAN8RfLi4AVlE9Ohu355lw5rg69bOknG9DtayEiXkHMmc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48600},"type":"module","exports":{".":"./dist/index.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"e133d27d6e58548223d3de9de013d9f3ed852199","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0"},"peerDependencies":{"zod":"^4.0.0","openai":"^6.0.0","@anthropic-ai/sdk":">=0.99.0"},"peerDependenciesMeta":{"openai":{"optional":true},"@anthropic-ai/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.2_1779918426291_0.8551019501236872","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@blull/circuitai","version":"0.0.3","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.3","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"de0bbe50ebb98ffccd5469bfc62a2db3644478e8","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.3.tgz","fileCount":9,"integrity":"sha512-zBAINwfJGLmxyGyIGTcCzABRhXwZizh1f1BYFU/oibWVHXg53RbyQ5Ie1jYEqV/XZ6jVbCwXw/FQhIn1EDns1Q==","signatures":[{"sig":"MEUCIE2QLbCD7b0svG0AMfHBe+Pyw5We5Iccr/bTNUqaOYQvAiEA/2uy5kpEZjJiTf8oSeX8l0M4rhegGivL9PMu1pEWQ6A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61278},"type":"module","exports":{".":"./dist/index.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"8277808893d79d880d7eb33ff9b5c0306d631057","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"pg":"^8.21.0","tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","ioredis":"^5.11.0","@types/pg":"^8.20.0","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0","@opentelemetry/api":"^1.9.1"},"peerDependencies":{"pg":">=8.0.0","zod":"^4.0.0","openai":"^6.0.0","ioredis":">=5.0.0","@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0"},"peerDependenciesMeta":{"pg":{"optional":true},"openai":{"optional":true},"ioredis":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.3_1780182197218_0.9047893201170794","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@blull/circuitai","version":"0.0.4","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.4","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"8d48da7ae8e39460eb0be276398878ecb7583730","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.4.tgz","fileCount":9,"integrity":"sha512-ftXSHRXVc08crZLPfy6JbFwuhIveI5jecLOstozBHW+K1C6OytEC7vr34/bUJXr5BskOLHcQooICkXD9tgYquw==","signatures":[{"sig":"MEQCIF6E3ST08pHrXgztySq9KmRqZ/eL4wgX7JHLuv/HTmZAAiA70NTY7gMpYyQkjGb8IEQod0h1031hMPwR2Mw0CIEgVQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63480},"type":"module","exports":{".":"./dist/index.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"3c0231b863b3fe80c50d68f227394277cf1c964a","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"pg":"^8.21.0","tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","ioredis":"^5.11.0","@types/pg":"^8.20.0","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0","@opentelemetry/api":"^1.9.1"},"peerDependencies":{"pg":">=8.0.0","zod":"^4.0.0","openai":"^6.0.0","ioredis":">=5.0.0","@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0"},"peerDependenciesMeta":{"pg":{"optional":true},"openai":{"optional":true},"ioredis":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.4_1780182938166_0.302771701589593","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@blull/circuitai","version":"0.0.5","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.5","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"31ba376a83f7eeb276b424a72a3beb0e8eb1d103","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.5.tgz","fileCount":12,"integrity":"sha512-Hro8ayk7YE5bDJNb4QqxYzZt0b3cm4a1Axi43/Ldiizmqiu9iFexMmKV50PvJYGdcpLw7iiq4hGnqIYAnPNtIw==","signatures":[{"sig":"MEYCIQC5pjVBJBmlB1GvVwcG+3LLhIEmoGrb4+T7DX5n7RUGYQIhAJ55WitvE4dCioNGE/U1qjUlUIRw31BW+83oA6VLsqiu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124349},"type":"module","exports":{".":"./dist/index.mjs","./studio":"./dist/studio.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"28abbb593e68f38a54cbda89e1140d20940374aa","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"pg":"^8.21.0","tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","ioredis":"^5.11.0","@types/pg":"^8.20.0","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0","@opentelemetry/api":"^1.9.1"},"peerDependencies":{"pg":">=8.0.0","zod":"^4.0.0","openai":"^6.0.0","ioredis":">=5.0.0","@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0"},"peerDependenciesMeta":{"pg":{"optional":true},"openai":{"optional":true},"ioredis":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.5_1780191007117_0.5225050391857504","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@blull/circuitai","version":"0.0.6","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.6","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"0f3fe5b0f4f9f516806caafe2cc1f56810ae18ee","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.6.tgz","fileCount":12,"integrity":"sha512-+iOsUB9MwTJmeDk5x6GUJCJU0IWolUmekzSIDJkgy+wlrmUJr3RGlkMhE0LzXRMzxVLPbyi+A7nfLNQ5omjGfw==","signatures":[{"sig":"MEQCIBU0O7VkC2F/mNwt64s9HI4tRAWc4eFLjhKoPz7Y9IO2AiBnCvyFuf71cDjV6Z4hIG4RU2f7Hur9DHdA2I8XxGOqxQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124349},"type":"module","exports":{".":"./dist/index.mjs","./studio":"./dist/studio.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"524f0ef034a2f04f8d7a52397e7863881f526fd7","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"pg":"^8.21.0","tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","ioredis":"^5.11.0","@types/pg":"^8.20.0","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0","@opentelemetry/api":"^1.9.1"},"peerDependencies":{"pg":">=8.0.0","zod":"^4.0.0","openai":"^6.0.0","ioredis":">=5.0.0","@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0"},"peerDependenciesMeta":{"pg":{"optional":true},"openai":{"optional":true},"ioredis":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.6_1780231369311_0.8750860643653038","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@blull/circuitai","version":"0.0.7","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"author":{"url":"https://github.com/fabiobarboza7","name":"Fabio Barboza","email":"fabio@blull.com.br"},"license":"MIT","_id":"@blull/circuitai@0.0.7","maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"contributors":[{"url":"https://blull.com.br","name":"BLULL"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"dist":{"shasum":"44a0be9451f238866e64f858f52ca5b7a15c7c1b","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.7.tgz","fileCount":12,"integrity":"sha512-STmGN3Zn88rFBC0OAm3g3jtMXEq1uzds7OifFaoGp5f9S3AjHvprmr2fYuOskIwLhq/hPyNbY/7N1eyoeT6hmg==","signatures":[{"sig":"MEYCIQCghXzPQ7bKgnbKUuFdWoNM2FNIVSB7R+5D+sa1Z00+QAIhAPICj54ZxaT+sEDN5G59G3XvLEKX7DvtN9E7jDb5fXfH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":123915},"type":"module","exports":{".":"./dist/index.mjs","./studio":"./dist/studio.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"gitHead":"b79e82a46b4a2fbdfe5686f993a3b426a5731052","private":false,"scripts":{"dev":"tsdown --watch","lint":"biome check .","test":"vitest run","build":"tsdown","check":"biome check . && tsc --noEmit && vitest run","format":"biome format --write .","release":"bash scripts/release.sh","typecheck":"tsc --noEmit","test:watch":"vitest","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"repository":{"url":"git+https://github.com/Blull-AI/circuitai.git","type":"git"},"_npmVersion":"10.9.4","description":"Type-safe, durable, observable orchestration for teams of AI agents.","directories":{},"_nodeVersion":"22.21.0","_hasShrinkwrap":false,"devDependencies":{"pg":"^8.21.0","tsx":"^4.22.3","zod":"^4.4.3","openai":"^6.39.0","tsdown":"^0.22.0","vitest":"^4.1.7","ioredis":"^5.11.0","@types/pg":"^8.20.0","typescript":"^6.0.3","@types/node":"^25.9.1","@biomejs/biome":"^2.4.16","@anthropic-ai/sdk":"^0.99.0","@opentelemetry/api":"^1.9.1"},"peerDependencies":{"pg":">=8.0.0","zod":"^4.0.0","openai":"^6.0.0","ioredis":">=5.0.0","@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0"},"peerDependenciesMeta":{"pg":{"optional":true},"openai":{"optional":true},"ioredis":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/circuitai_0.0.7_1780241896574_0.14701410552795124","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@blull/circuitai","type":"module","version":"0.0.8","private":false,"description":"Type-safe, durable, observable orchestration for teams of AI agents.","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"license":"MIT","author":{"name":"Fabio Barboza","email":"fabio@blull.com.br","url":"https://github.com/fabiobarboza7"},"contributors":[{"name":"BLULL","url":"https://blull.com.br"}],"homepage":"https://github.com/Blull-AI/circuitai#readme","repository":{"type":"git","url":"git+https://github.com/Blull-AI/circuitai.git"},"bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"exports":{".":"./dist/index.mjs","./studio":"./dist/studio.mjs","./testing":"./dist/testing.mjs","./package.json":"./package.json"},"scripts":{"build":"tsdown","dev":"tsdown --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","lint":"biome check .","format":"biome format --write .","check":"biome check . && tsc --noEmit && vitest run","release":"bash scripts/release.sh","sync:public":"bash scripts/sync-public.sh","prepublishOnly":"npm run build"},"peerDependencies":{"@anthropic-ai/sdk":">=0.99.0","@opentelemetry/api":">=1.0.0","ioredis":">=5.0.0","openai":"^6.0.0","pg":">=8.0.0","zod":"^4.0.0"},"peerDependenciesMeta":{"openai":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@opentelemetry/api":{"optional":true},"ioredis":{"optional":true},"pg":{"optional":true}},"devDependencies":{"@anthropic-ai/sdk":"^0.99.0","@biomejs/biome":"^2.4.16","@opentelemetry/api":"^1.9.1","@types/node":"^25.9.1","@types/pg":"^8.20.0","ioredis":"^5.11.0","openai":"^6.39.0","pg":"^8.21.0","tsdown":"^0.22.0","tsx":"^4.22.3","typescript":"^6.0.3","vitest":"^4.1.7","zod":"^4.4.3"},"_id":"@blull/circuitai@0.0.8","gitHead":"a712103e6ea7e152025849c0c7ac81c9beaa71e1","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-sZOfu+3SC3fjDyM4F+gGmQp4eHsVlFEdpXNI+Au5dynnKVZSJkdpttwhy0YTgvyZd4FER+glEhsamjge8RYRDw==","shasum":"5d539cca68d7dc1c51a420c3025a4fed72189bba","tarball":"https://registry.npmjs.org/@blull/circuitai/-/circuitai-0.0.8.tgz","fileCount":12,"unpackedSize":122986,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDYLNKECH3lMzR5l9sOjCGloShHVXYLsApIzTK8t/oUDgIhAL0A8drUpMdmO/zeiRVsFfRTsJxRK+tgLjNrw+6TMX0s"}]},"_npmUser":{"name":"fabiobcsouza","email":"fabio@blull.com.br"},"directories":{},"maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/circuitai_0.0.8_1780318607947_0.9438992968823428"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-27T21:36:37.517Z","modified":"2026-06-01T12:56:48.201Z","0.0.1":"2026-05-27T21:36:38.675Z","0.0.2":"2026-05-27T21:47:06.423Z","0.0.3":"2026-05-30T23:03:17.432Z","0.0.4":"2026-05-30T23:15:38.378Z","0.0.5":"2026-05-31T01:30:07.274Z","0.0.6":"2026-05-31T12:42:49.434Z","0.0.7":"2026-05-31T15:38:16.717Z","0.0.8":"2026-06-01T12:56:48.090Z"},"bugs":{"url":"https://github.com/Blull-AI/circuitai/issues"},"author":{"name":"Fabio Barboza","email":"fabio@blull.com.br","url":"https://github.com/fabiobarboza7"},"license":"MIT","homepage":"https://github.com/Blull-AI/circuitai#readme","keywords":["ai","agents","orchestration","multi-agent","llm","openai","anthropic","zod","typescript"],"repository":{"type":"git","url":"git+https://github.com/Blull-AI/circuitai.git"},"description":"Type-safe, durable, observable orchestration for teams of AI agents.","contributors":[{"name":"BLULL","url":"https://blull.com.br"}],"maintainers":[{"name":"fabiobcsouza","email":"fabio@blull.com.br"}],"readme":"<p align=\"center\">\n  <a href=\"https://sdk.blull.com.br\">\n    <img src=\"https://raw.githubusercontent.com/Blull-AI/circuitai/main/assets/logo.png\" alt=\"Blull\" width=\"260\" />\n  </a>\n</p>\n\n# @blull/circuitai\n\n> Type-safe, durable, observable orchestration for teams of AI agents.\n\n**Official website:** [sdk.blull.com.br](https://sdk.blull.com.br)\n\n@blull/circuitai helps you orchestrate teams of AI agents the way you'd orchestrate a real project team. Each agent has a role, a goal, and rules. A supervisor coordinates them toward a business goal. Everything is typed end-to-end with Zod — the context schema, every agent's input and output, every tool's input — and every run is a stream of structured events you can inspect, persist, and replay.\n\n```ts\nimport { z } from \"zod\";\nimport {\n  createOpenAIProvider,\n  defineAgent,\n  defineProject,\n  defineSupervisor,\n  defineTool,\n} from \"@blull/circuitai\";\n\nconst openai = createOpenAIProvider({\n  apiKey: process.env.OPENAI_API_KEY!,\n  model: \"gpt-5.4-mini\",\n});\n\nconst ContextSchema = z.object({\n  account: z.object({\n    id: z.string(),\n    debtorName: z.string(),\n    outstandingUsd: z.number(),\n    daysPastDue: z.number(),\n    productType: z.enum([\"credit_card\", \"personal_loan\", \"utility\", \"telecom\"]),\n  }),\n  recoverabilityScore: z.number().min(0).max(1).optional(),\n  nextAction: z\n    .enum([\n      \"sms_reminder\",\n      \"outbound_call\",\n      \"settlement_offer\",\n      \"legal_escalation\",\n    ])\n    .optional(),\n});\ntype Ctx = z.infer<typeof ContextSchema>;\n\nconst lookupPaymentHistory = defineTool({\n  name: \"lookupPaymentHistory\",\n  description:\n    \"Fetch 90-day payment, promise-to-pay and contact-attempt history for a debtor.\",\n  schema: z.object({ accountId: z.string() }),\n  handler: async ({ accountId }) => ({\n    accountId,\n    partialPayments: 1,\n    brokenPromises: 2,\n    callAttempts: 5,\n    rightPartyContacts: 1,\n  }),\n});\n\nconst recoverabilityScorer = defineAgent({\n  name: \"recoverability-scorer\",\n  goal: \"Estimate how likely this overdue account is to be collected\",\n  rules: \"You are a collections analyst at a debt-recovery agency. JSON only.\",\n  model: openai,\n  inputSchema: z.object({ account: ContextSchema.shape.account }),\n  outputSchema: z.object({ recoverabilityScore: z.number().min(0).max(1) }),\n  contextSelector: (ctx: Ctx) => ({ account: ctx.account }),\n  tools: [lookupPaymentHistory],\n});\n\nconst actionSelector = defineAgent({\n  name: \"action-selector\",\n  goal: \"Pick the next-best collection action for the call center to dispatch\",\n  rules:\n    \"Map the recoverability score to one action: low → legal_escalation, mid → settlement_offer, high → outbound_call, very high → sms_reminder. JSON only.\",\n  model: openai,\n  inputSchema: z.object({ recoverabilityScore: z.number() }),\n  outputSchema: z.object({\n    nextAction: z.enum([\n      \"sms_reminder\",\n      \"outbound_call\",\n      \"settlement_offer\",\n      \"legal_escalation\",\n    ]),\n  }),\n  contextSelector: (ctx: Ctx) => ({\n    recoverabilityScore: ctx.recoverabilityScore ?? 0,\n  }),\n});\n\nconst project = defineProject({\n  name: \"collection-decisioning\",\n  description:\n    \"Score overdue accounts and route each one to the next-best collection action\",\n  goal: \"Produce a next-best collection action for every overdue account in the queue\",\n  contextSchema: ContextSchema,\n  agents: [recoverabilityScorer, actionSelector],\n  supervisor: defineSupervisor<Ctx>({\n    model: openai,\n    rules:\n      \"Score the account first, then pick the action. Stop when `nextAction` is set.\",\n    terminationCondition: (ctx) => ctx.nextAction !== undefined,\n    maxTurns: 8,\n  }),\n});\n\nconst finalContext = await project.run({\n  account: {\n    id: \"acc_1042\",\n    debtorName: \"John Smith\",\n    outstandingUsd: 4_200,\n    daysPastDue: 47,\n    productType: \"credit_card\",\n  },\n});\nconsole.log(finalContext.nextAction);\n// 'sms_reminder' | 'outbound_call' | 'settlement_offer' | 'legal_escalation'\n```\n\n## Why @blull/circuitai\n\n1. **End-to-end typed with Zod.** Your context schema, every agent's input/output, every tool's input — one Zod schema each. Inference flows from `defineProject` all the way to `project.run(initialContext)`. No `as any`. No DSL.\n2. **Visualizable, serializable graphs.** `project.toJSON()` emits a JSON-Schema description of your agent team. Persist it, diff it in git, or open it in **Studio** (`@blull/circuitai/studio`) — a self-hostable graph viewer and live run debugger.\n3. **Built-in durability.** Every run is a sequence of typed events against a typed context. The in-memory default ships out of the box; implement one `Storage` adapter to plug into Postgres, Redis, or anything else.\n4. **Hierarchical orchestration, not graph wiring.** No DAGs to draw. A supervisor LLM routes work dynamically based on the typed shared context. Bring your routing rules in plain English.\n5. **First-class tools, first-class observability.** Define tools with Zod schemas; @blull/circuitai runs the model → tool → model loop with validation and retries. Every step is a structured event you can stream, log, or replay.\n\n## Concepts\n\n- **Project** — name, description, goal, the Zod-typed shared context (the _blackboard_), agents, supervisor, optional tasks.\n- **Agent** — name, goal, rules (system prompt), an LLM provider, an input/output Zod schema, a `contextSelector` that picks the slice of context this agent needs, and optional tools.\n- **Supervisor** — special agent with privileges. Reads the full context, decides the next action (`invoke` an agent, run a `task`, mark `done`, or `fail`). Powered by its own LLM.\n- **Task** _(optional)_ — a named, ordered list of agent steps with conditional `when` filters. The supervisor may choose to delegate to a task instead of orchestrating step-by-step.\n- **Tool** — a typed function the agent may call during its turn (`schema` Zod + `handler`).\n\nThe supervisor's decision is enforced by a Zod-validated discriminated union; invalid choices (hallucinated agent names, bad JSON) trigger bounded corrective retries before the run aborts.\n\n## Installation\n\n```sh\npnpm add @blull/circuitai zod\n# plus the providers you want:\npnpm add openai @anthropic-ai/sdk\n# plus any durable adapters you want:\npnpm add pg                  # Postgres storage\npnpm add ioredis             # Redis storage\npnpm add @opentelemetry/api  # OpenTelemetry traces\n```\n\n> Requires Zod **v4** (peer). `openai`, `@anthropic-ai/sdk`, `pg`, `ioredis`, and `@opentelemetry/api` are all **optional** peers — install only what you use.\n\n## Run lifecycle and events\n\nEvery run emits a typed event stream. Stream them for live UI, persist them for audit, or replay them for debugging:\n\n```ts\nfor await (const event of project.stream(initialContext)) {\n  switch (event.type) {\n    case \"project.started\":\n      break;\n    case \"supervisor.decision\":\n    case \"agent.started\":\n    case \"agent.tool_called\":\n    case \"agent.completed\":\n    case \"agent.delta\": // streamed content tokens (opt-in, see below)\n    case \"context.updated\":\n    case \"project.paused\": // suspended for human input (see below)\n    case \"project.resumed\":\n    case \"project.completed\":\n    case \"error\":\n      break;\n  }\n}\n```\n\n`project.run(initialContext)` is the same loop, but it awaits to completion and returns the final context directly.\n\n### Streaming tokens\n\nOpt in with `{ stream: true }` to receive token-level `agent.delta` events as each agent's model produces them — ideal for live UIs:\n\n```ts\nfor await (const event of project.stream(initialContext, { stream: true })) {\n  if (event.type === \"agent.delta\") {\n    process.stdout.write(event.delta); // live token-by-token output\n  }\n}\n```\n\nDeltas require the agent's provider to implement streaming (the OpenAI and Anthropic adapters do); providers without it fall back to a single non-streaming call. Deltas are **ephemeral** — they reach live consumers but are never written to storage, since the durable `agent.completed` event already carries the agent's complete output. Without `{ stream: true }` the stream behaves exactly as before.\n\n## Persistence\n\n```ts\nimport { createInMemoryStorage } from \"@blull/circuitai\";\n\nconst project = defineProject({\n  // ...\n  storage: createInMemoryStorage(), // default; swap for your own implementation\n});\n\nconst finalCtx = await project.run(initial);\nconst runs = await project.storage.listRuns({\n  projectName: \"collection-decisioning\",\n});\nconst loaded = await project.storage.loadRun(runs[0]!.id);\nconsole.log(loaded?.events); // full event log\n```\n\nFirst-party durable adapters ship for Postgres and Redis:\n\n```ts\nimport { createPostgresStorage, createRedisStorage } from \"@blull/circuitai\";\n\n// Postgres (requires `pg`)\nconst pg = createPostgresStorage({\n  connectionString: process.env.DATABASE_URL,\n});\nawait pg.ensureSchema(); // create the runs/events tables once — or run pg.schemaSql yourself\n\n// Redis (requires `ioredis`)\nconst redis = createRedisStorage({\n  url: process.env.REDIS_URL,\n  ttlSeconds: 60 * 60 * 24,\n});\n\nconst project = defineProject({\n  // ...\n  storage: pg, // or redis\n});\n```\n\nBoth implement the same `Storage` interface. Pass a pre-built `pool` / `client` instead of a URL when you want full connection control (and trivial test injection). Streamed `agent.delta` events are intentionally **not** persisted. You can still implement `Storage` yourself for any other backend (S3, DynamoDB, …).\n\n## Human-in-the-loop: pause & resume\n\nA run can **suspend itself for human input** and be **resumed later** — even from a different process — without re-running any completed work. The `project.paused` event written to storage _is_ the durable checkpoint: it carries the full blackboard context, the turn cursor, and accumulated usage. `project.resume(runId)` restores that state and continues the supervisor loop.\n\nThere are two ways to pause:\n\n1. **A deterministic gate** — `supervisor.pauseCondition`, checked each turn _before_ the supervisor LLM is consulted (so a gate pause costs zero supervisor calls). This is the robust primitive for approval flows.\n2. **A supervisor decision** — the supervisor LLM can choose `{ kind: 'pause', reason, awaiting }` when it decides it needs a human.\n\n```ts\nconst project = defineProject({\n  // ...\n  contextSchema: z.object({\n    amount: z.number(),\n    prepared: z.boolean().optional(),\n    approval: z.enum([\"approved\", \"rejected\"]).optional(),\n    executed: z.boolean().optional(),\n  }),\n  agents: [preparer, executor],\n  supervisor: defineSupervisor({\n    model: openai,\n    rules: \"Prepare the action, then execute it only once it is approved.\",\n    terminationCondition: (ctx) => ctx.executed === true,\n    // Pause once the action is prepared but not yet approved. The gate MUST be\n    // resolved by the resume input — otherwise the resumed run pauses again.\n    pauseCondition: (ctx) =>\n      ctx.prepared && !ctx.approval\n        ? { reason: \"approval required\", awaiting: \"approve | reject\" }\n        : undefined,\n  }),\n});\n\n// Run until it pauses. `run()` throws `run_paused` (it has no final context to\n// return); use `stream()` to observe the pause as an event instead.\nlet runId = \"\";\nfor await (const event of project.stream(initialContext)) {\n  if (event.type === \"project.paused\") {\n    runId = event.runId;\n    console.log(event.reason, event.awaiting); // surface to your reviewer UI\n  }\n}\n\n// ...later, possibly in another process — only the runId + shared storage are\n// needed. `resume` returns the same event stream as `stream()`; the human's\n// decision is merged into the restored context.\nlet final;\nfor await (const event of project.resume(runId, {\n  input: { approval: \"approved\" },\n})) {\n  if (event.type === \"project.completed\") final = event.context;\n}\n```\n\nResume continues from the checkpoint: the already-completed `preparer` is **not** re-invoked; the supervisor picks up from the restored context and runs `executor`. The full lifecycle (`project.started → … → project.paused → project.resumed → … → project.completed`) lives in one event log for audit.\n\n**Requirements and limits**\n\n- Resume needs the **same project definition** (agents, supervisor, tools) and the **same `Storage`** the run was created with. The code is the workflow; storage is the durable state.\n- The restored context must be **JSON-round-trippable** through your storage backend. `z.date()`, `Map`, `Set`, etc. drift through JSON; resume re-validates the restored context against your schema and fails fast at the `resume` stage if it does. Prefer JSON-native context (ISO strings, plain objects).\n- A run is resumable only while **paused** (`resume_not_found` / `resume_not_resumable` otherwise). The resume `input` is merged then re-validated; an invalid merge throws `schema_validation` and leaves the run cleanly paused.\n- **No resume locking (v0.3).** Two concurrent `resume(runId)` calls both load the same checkpoint and proceed — there is no atomic compare-and-swap on status. Serialize resumes of the same run yourself.\n\n## Telemetry\n\n```ts\nimport { createConsoleTelemetry } from \"@blull/circuitai\";\n\nconst project = defineProject({\n  // ...\n  telemetry: createConsoleTelemetry({ enabled: true }), // pretty stdout traces\n});\n```\n\nThe `Telemetry` interface mirrors OpenTelemetry's `Tracer`/`Span` shapes. To export to a real OTel pipeline, hand `createOtelTelemetry` a `Tracer` from your own SDK setup:\n\n```ts\nimport { createOtelTelemetry } from \"@blull/circuitai\";\nimport { trace } from \"@opentelemetry/api\";\n\nconst project = defineProject({\n  // ...\n  telemetry: createOtelTelemetry({ tracer: trace.getTracer(\"my-app\") }),\n});\n```\n\nThe adapter imports **only types** from `@opentelemetry/api`, so the library never pulls in the OTel SDK at runtime — you own sampling, batching, and export.\n\n## Visualizable graph\n\n```ts\nconst graph = project.toJSON();\n// {\n//   schemaVersion: '1.0',\n//   name: 'collection-decisioning',\n//   agents: [{ name, goal, rules, model, inputSchema: <JSONSchema>, outputSchema: <JSONSchema>, tools: [...] }],\n//   supervisor: { model, rules, maxTurns },\n//   tasks: [...],\n//   contextSchema: <JSONSchema>,\n// }\n```\n\nDiff your agent team in git, share it across services, or open it in **Studio** (next section).\n\n## Studio\n\n`@blull/circuitai/studio` is a self-hostable web surface that **visualizes your project graph** and **debugs runs** — replaying a finished run from storage, live-tailing one in flight, and resuming paused runs (HITL) from the browser. It reads everything from the `Storage` your projects already write to, plus `project.toJSON()` for the graph, so there is nothing new to instrument.\n\n```ts\nimport { createStudioServer } from \"@blull/circuitai/studio\";\n\n// `storage` is the SAME instance your projects use, so Studio sees their runs.\nconst studio = createStudioServer({\n  storage,\n  projects: [project], // optional — enables the graph view + HITL resume\n});\nstudio.listen(3030); // http://localhost:3030\n```\n\n`createStudioServer` returns a framework-agnostic Node request `handler` (mount it in Express/etc.) plus a `listen()` convenience — **zero new runtime dependencies** (raw `node:http`). It exposes a small read API over your storage (`GET /api/projects`, `/api/projects/:name/graph`, `/api/runs`, `/api/runs/:id`), live events over SSE (`GET /api/runs/:id/events` — replays a finished run, tails a running one), and `POST /api/runs/:id/resume` for paused runs. Mount it under a sub-path with `basePath`.\n\nTwo views:\n\n- **Graph** — the supervisor → agents → tools graph rendered from `toJSON()`, with each node's context/input/output JSON Schemas inspectable and the **active agent/tool node highlighted as a run streams**. \"Export JSON\" downloads the `ProjectGraph`.\n- **Timeline** — the full event log with a **step scrubber**: scrub any run to see the reconstructed context snapshot and the per-step diff, token/cost totals, and — for paused runs — a resume box that merges your input and continues the run.\n\nStudio is deliberately read-only over your data: it **does not launch runs** (that needs your providers/keys) and ships **no auth** — put it behind your own gateway if you expose it. Pass live `Project` instances to enable the graph view and resume; omit them for a pure run-debugger over any `Storage` backend (e.g. a shared Postgres). The graph view visualizes and exports the `ProjectGraph`; regenerating runnable code from an edited graph (`fromJSON`/codegen) is not part of v0.4.\n\nTry it offline — no API key (mock provider, with seeded and live runs):\n\n```sh\npnpm tsx examples/studio/run.ts   # http://localhost:3030\n```\n\n## Testing without API keys\n\n```ts\nimport { createMockProvider } from \"@blull/circuitai/testing\";\n\nconst agent = defineAgent({\n  // ...\n  model: createMockProvider({\n    responses: [{ structured: { recoverabilityScore: 0.72, flags: [] } }],\n  }),\n});\n```\n\nScripted responses for unit and integration tests. No network. No API keys.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}