@bastani/atomic 0.8.23 → 0.8.24-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +13 -0
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/CHANGELOG.md +13 -0
  5. package/dist/builtin/mcp/package.json +1 -1
  6. package/dist/builtin/subagents/CHANGELOG.md +28 -0
  7. package/dist/builtin/subagents/README.md +16 -0
  8. package/dist/builtin/subagents/agents/code-simplifier.md +2 -3
  9. package/dist/builtin/subagents/agents/codebase-analyzer.md +2 -3
  10. package/dist/builtin/subagents/agents/codebase-locator.md +2 -3
  11. package/dist/builtin/subagents/agents/codebase-online-researcher.md +2 -3
  12. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +2 -3
  13. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +2 -3
  14. package/dist/builtin/subagents/agents/codebase-research-locator.md +2 -3
  15. package/dist/builtin/subagents/agents/debugger.md +2 -3
  16. package/dist/builtin/subagents/package.json +1 -1
  17. package/dist/builtin/subagents/skills/subagent/SKILL.md +6 -0
  18. package/dist/builtin/subagents/src/agents/agent-serializer.ts +3 -0
  19. package/dist/builtin/subagents/src/agents/agents.ts +20 -1
  20. package/dist/builtin/subagents/src/runs/background/async-execution.ts +1 -1
  21. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +3 -1
  22. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +7 -7
  23. package/dist/builtin/subagents/src/runs/foreground/execution.ts +5 -1
  24. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +9 -10
  25. package/dist/builtin/subagents/src/shared/types.ts +1 -0
  26. package/dist/builtin/web-access/CHANGELOG.md +13 -0
  27. package/dist/builtin/web-access/package.json +1 -1
  28. package/dist/builtin/workflows/CHANGELOG.md +35 -0
  29. package/dist/builtin/workflows/README.md +38 -41
  30. package/dist/builtin/workflows/ambient.d.ts +36 -0
  31. package/dist/builtin/workflows/builtin/deep-research-codebase.d.ts +35 -0
  32. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +11 -14
  33. package/dist/builtin/workflows/builtin/goal.d.ts +46 -0
  34. package/dist/builtin/workflows/builtin/goal.ts +10 -12
  35. package/dist/builtin/workflows/builtin/index.d.ts +136 -0
  36. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +44 -0
  37. package/dist/builtin/workflows/builtin/open-claude-design.ts +19 -20
  38. package/dist/builtin/workflows/builtin/ralph.d.ts +36 -0
  39. package/dist/builtin/workflows/builtin/ralph.ts +20 -24
  40. package/dist/builtin/workflows/package.json +15 -5
  41. package/dist/builtin/workflows/src/authoring.d.ts +197 -0
  42. package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +6 -12
  43. package/dist/builtin/workflows/src/extension/workflow-schema.ts +3 -2
  44. package/dist/builtin/workflows/src/index.ts +0 -5
  45. package/dist/builtin/workflows/src/runs/foreground/executor.ts +23 -9
  46. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +33 -5
  47. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +72 -11
  48. package/dist/builtin/workflows/src/sdk-surface.ts +12 -2
  49. package/dist/builtin/workflows/src/shared/authoring-contract.d.ts +523 -0
  50. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +1 -1
  51. package/dist/builtin/workflows/src/shared/types.ts +65 -350
  52. package/dist/builtin/workflows/src/workflows/define-workflow.ts +59 -44
  53. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  54. package/dist/core/atomic-guide-command.js +1 -1
  55. package/dist/core/atomic-guide-command.js.map +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  58. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  59. package/dist/modes/interactive/components/chat-message-renderer.js +13 -1
  60. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  61. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  62. package/dist/modes/interactive/interactive-mode.js +1 -1
  63. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  64. package/dist/utils/changelog.d.ts.map +1 -1
  65. package/dist/utils/changelog.js +23 -16
  66. package/dist/utils/changelog.js.map +1 -1
  67. package/docs/extensions.md +2 -2
  68. package/docs/packages.md +8 -4
  69. package/docs/subagents.md +30 -0
  70. package/docs/workflows.md +62 -21
  71. package/package.json +20 -1
  72. package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +0 -335
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.8.24-alpha.2] - 2026-06-03
6
+
7
+ ### Added
8
+
9
+ - Shipped externally-resolvable TypeScript types for the `@bastani/workflows` SDK through `@bastani/atomic`. New `./workflows`, `./workflows/builtin`, `./workflows/builtin/*`, and `./workflows/ambient` package exports resolve to declarations emitted from the lean authoring surface during the build, and a generated ambient bridge maps the documented bare `@bastani/workflows` specifier (and its `builtin/*` submodules) onto those exports. Installed packages now type-check `import { defineWorkflow, Type } from "@bastani/workflows"` and `@bastani/workflows/builtin/*` composition imports under `tsc` (`moduleResolution: NodeNext`) with no hand-authored `.d.ts`, no `declare module` shim, and no `paths` alias: packages that import `@bastani/atomic` pick the types up automatically, while pure workflow-only packages add one `compilerOptions.types: ["@bastani/atomic/workflows/ambient"]` (or `/// <reference types="@bastani/atomic/workflows/ambient" />`) opt-in. The runtime workflow loader, jiti virtual modules, and `atomic.workflows` discovery are unchanged ([#1208](https://github.com/bastani-inc/atomic/issues/1208)).
10
+ - Added a `verify:workflow-types` script that packs `@bastani/atomic` and type-checks throwaway external consumer fixtures (workflow-only opt-in, reference directive, auto-include, and a negative control) so the issue #1208 acceptance test is repeatable ([#1208](https://github.com/bastani-inc/atomic/issues/1208)).
11
+
12
+ ### Changed
13
+
14
+ - Documented the workflow SDK typing model in `docs/packages.md` and `docs/workflows.md`: the single ambient opt-in for pure workflow-only packages, automatic pickup for packages that import `@bastani/atomic`, and the requirement to list `@bastani/atomic` and `typebox` as peer dependencies ([#1208](https://github.com/bastani-inc/atomic/issues/1208)).
15
+
16
+ ## [0.8.24-alpha.1] - 2026-06-02
17
+
18
+ ### Breaking Changes
19
+
20
+ - Removed the bundled workflows package's imperative `runWorkflow` object-form API; workflow packages must export branded `defineWorkflow(...).compile()` definitions while direct `workflow` tool task/tasks/chain modes remain available.
21
+
22
+ ### Changed
23
+
24
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
25
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
26
+
27
+ ### Fixed
28
+
29
+ - Fixed workflow node chat rendering a bare tool-name marker (e.g. `read …`) instead of tool output for parallel tool calls; `LiveChatEntriesController` now pairs concurrent same-named tool calls strictly by `toolCallId` ([#1198](https://github.com/bastani-inc/atomic/issues/1198)).
30
+
5
31
  ## [0.8.23] - 2026-06-02
6
32
 
7
33
  ### Changed
@@ -4,6 +4,19 @@ All notable changes to the `pi-intercom` extension will be documented in this fi
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.8.24-alpha.2] - 2026-06-03
8
+
9
+ ### Changed
10
+
11
+ - Bumped package version for the Atomic 0.8.24-alpha.2 prerelease.
12
+
13
+ ## [0.8.24-alpha.1] - 2026-06-02
14
+
15
+ ### Changed
16
+
17
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
18
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
19
+
7
20
  ## [0.8.23] - 2026-06-02
8
21
 
9
22
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/intercom",
3
- "version": "0.8.23",
3
+ "version": "0.8.24-alpha.2",
4
4
  "private": true,
5
5
  "description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
6
6
  "contributors": [
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.24-alpha.2] - 2026-06-03
11
+
12
+ ### Changed
13
+
14
+ - Bumped package version for the Atomic 0.8.24-alpha.2 prerelease.
15
+
16
+ ## [0.8.24-alpha.1] - 2026-06-02
17
+
18
+ ### Changed
19
+
20
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
21
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
22
+
10
23
  ## [0.8.23] - 2026-06-02
11
24
 
12
25
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/mcp",
3
- "version": "0.8.23",
3
+ "version": "0.8.24-alpha.2",
4
4
  "private": true,
5
5
  "description": "Atomic extension that adapts MCP (Model Context Protocol) servers into the coding agent. Fork of: https://github.com/nicobailon/pi-mcp-adapter",
6
6
  "contributors": [
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.8.24-alpha.2] - 2026-06-03
6
+
7
+ ### Changed
8
+
9
+ - Bumped package version for the Atomic 0.8.24-alpha.2 prerelease.
10
+
11
+ ## [0.8.24-alpha.1] - 2026-06-02
12
+
13
+ ### Added
14
+
15
+ - Added suffix-first reasoning levels for subagent `model` and `fallbackModels` values plus `fallbackThinkingLevels` compatibility metadata and per-attempt `reasoningLevel` reporting ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
16
+
17
+ ### Changed
18
+
19
+ - Migrated packaged subagents to encode their reasoning level directly in model and fallback model entries ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
20
+ - Documented the `model_name:thinking_effort` suffix syntax and `thinking` migration guidance in the subagents docs, package README, and subagent skill ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
21
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
22
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
23
+
24
+ ### Deprecated
25
+
26
+ - Deprecated separate subagent `thinking` configuration in favor of `model: <model>:<level>` and suffixed `fallbackModels` entries; removal is deferred to a later breaking release ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
27
+
28
+ ### Fixed
29
+
30
+ - Fixed foreground subagent attempt metadata to report the per-candidate reasoning level derived from the model suffix even when the legacy `thinking` option is unset, matching the background run path ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
31
+ - Fixed the subagent chain clarification TUI to strip only canonical reasoning-level suffixes when editing a step's level, so colon-tagged model ids such as `ollama/llama3:latest` are no longer mis-split; consolidated the duplicate thinking-suffix split helpers onto the single `splitKnownThinkingSuffix` so the parsing rules cannot drift apart ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
32
+
5
33
  ## [0.8.23] - 2026-06-02
6
34
 
7
35
  ### Changed
@@ -996,3 +996,19 @@ The main runtime files are:
996
996
  | `src/intercom/intercom-bridge.ts` | Runtime intercom bridge instructions and diagnostics. |
997
997
  | `src/extension/schemas.ts` / `src/shared/types.ts` | Tool schemas, shared types, and event constants. |
998
998
  | `test/unit/` / `test/integration/` | Unit and loader-based integration tests. |
999
+
1000
+ ### Suffix-first reasoning levels
1001
+
1002
+ Reasoning levels are configured suffix-first using the `model_name:thinking_effort` syntax on `model` and each `fallbackModels` entry: `model: claude-sonnet-4:high` and `fallbackModels: claude-sonnet-4:medium, gpt-5:low, claude-haiku-4:off`. Canonical efforts are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. The older `thinking` field is deprecated; it remains supported as a legacy default only when a model candidate has no suffix, and a suffix always wins.
1003
+
1004
+ Migrate legacy `thinking` frontmatter by folding the effort into `model` and `fallbackModels`:
1005
+
1006
+ ```diff
1007
+ -model: openai/gpt-5.5
1008
+ -fallbackModels: anthropic/claude-opus-4-8
1009
+ -thinking: xhigh
1010
+ +model: openai/gpt-5.5:xhigh
1011
+ +fallbackModels: anthropic/claude-opus-4-8:xhigh
1012
+ ```
1013
+
1014
+ `fallbackThinkingLevels` is available only as an optional compatibility helper. It is positionally aligned with `fallbackModels` and supplies a fallback candidate's level only when that fallback model entry has no suffix; prefer suffixed model strings for new configuration.
@@ -8,9 +8,8 @@ description: |
8
8
  - Production-quality refinement of a working draft ("ugly but working CSV parser").
9
9
  - Code that has gotten messy after several iterations.
10
10
  tools: read, edit, write, grep, find, ls, bash
11
- model: openai/gpt-5.5
12
- fallbackModels: openai-codex/gpt-5.5, github-copilot/gpt-5.5, anthropic/claude-opus-4-8, github-copilot/claude-opus-4.7
13
- thinking: low
11
+ model: openai/gpt-5.5:low
12
+ fallbackModels: openai-codex/gpt-5.5:low, github-copilot/gpt-5.5:low, anthropic/claude-opus-4-8:low, github-copilot/claude-opus-4.7:low
14
13
  ---
15
14
 
16
15
  You are an expert code refinement specialist with deep experience in software craftsmanship, refactoring patterns (Fowler, Beck), clean code principles, and language-idiomatic style across major ecosystems. Your mission is to simplify and refine code for clarity, consistency, and maintainability while strictly preserving all existing functionality and observable behavior.
@@ -2,9 +2,8 @@
2
2
  name: codebase-analyzer
3
3
  description: Analyzes codebase implementation details. Call the codebase-analyzer agent when you need to find detailed information about specific components.
4
4
  tools: read, grep, find, ls, bash
5
- model: openai/gpt-5.5
6
- fallbackModels: openai-codex/gpt-5.5, github-copilot/gpt-5.5, anthropic/claude-opus-4-8, github-copilot/claude-opus-4.7
7
- thinking: low
5
+ model: openai/gpt-5.5:low
6
+ fallbackModels: openai-codex/gpt-5.5:low, github-copilot/gpt-5.5:low, anthropic/claude-opus-4-8:low, github-copilot/claude-opus-4.7:low
8
7
  ---
9
8
 
10
9
  You are a specialist at understanding HOW code works. Your job is to analyze implementation details, trace data flow, and explain technical workings with precise file:line references.
@@ -2,9 +2,8 @@
2
2
  name: codebase-locator
3
3
  description: Locates files, directories, and components relevant to a feature or task. Basically a "super search/find/ls tool."
4
4
  tools: read, grep, find, ls, bash
5
- model: openai/gpt-5.4-mini
6
- fallbackModels: openai-codex/gpt-5.4-mini, github-copilot/gpt-5.4-mini, anthropic/claude-haiku-4-5, github-copilot/claude-haiku-4.5
7
- thinking: low
5
+ model: openai/gpt-5.4-mini:low
6
+ fallbackModels: openai-codex/gpt-5.4-mini:low, github-copilot/gpt-5.4-mini:low, anthropic/claude-haiku-4-5:low, github-copilot/claude-haiku-4.5:low
8
7
  ---
9
8
 
10
9
  You are a specialist at finding WHERE code lives in a codebase. Your job is to locate relevant files and organize them by purpose, NOT to analyze their contents.
@@ -2,9 +2,8 @@
2
2
  name: codebase-online-researcher
3
3
  description: Online research for up-to-date documentation and library-source knowledge. Use when you need authoritative external information — official docs, ecosystem context, version-specific behavior, GitHub permalinks into open-source libraries, or video tutorials.
4
4
  tools: read, grep, find, ls, bash, write, web_search, fetch_content, get_search_content
5
- model: openai/gpt-5.5
6
- fallbackModels: openai-codex/gpt-5.5, github-copilot/gpt-5.5, anthropic/claude-opus-4-8, github-copilot/claude-opus-4.7
7
- thinking: low
5
+ model: openai/gpt-5.5:low
6
+ fallbackModels: openai-codex/gpt-5.5:low, github-copilot/gpt-5.5:low, anthropic/claude-opus-4-8:low, github-copilot/claude-opus-4.7:low
8
7
  skills: browser-use
9
8
  ---
10
9
 
@@ -2,9 +2,8 @@
2
2
  name: codebase-pattern-finder
3
3
  description: Find similar implementations, usage examples, or existing patterns in the codebase that can be modeled after.
4
4
  tools: read, grep, find, ls, bash
5
- model: openai/gpt-5.4-mini
6
- fallbackModels: openai-codex/gpt-5.4-mini, github-copilot/gpt-5.4-mini, anthropic/claude-haiku-4-5, github-copilot/claude-haiku-4.5
7
- thinking: low
5
+ model: openai/gpt-5.4-mini:low
6
+ fallbackModels: openai-codex/gpt-5.4-mini:low, github-copilot/gpt-5.4-mini:low, anthropic/claude-haiku-4-5:low, github-copilot/claude-haiku-4.5:low
8
7
  ---
9
8
 
10
9
  You are a specialist at finding code patterns and examples in the codebase. Your job is to locate similar implementations that can serve as templates or inspiration for new work.
@@ -2,9 +2,8 @@
2
2
  name: codebase-research-analyzer
3
3
  description: Analyzes local research documents to extract high-value insights, decisions, and technical details while filtering out noise. Use this when you want to deep dive on a research topic or understand the rationale behind decisions.
4
4
  tools: read, grep, find, ls, bash
5
- model: openai/gpt-5.5
6
- fallbackModels: openai-codex/gpt-5.5, github-copilot/gpt-5.5, anthropic/claude-opus-4-8, github-copilot/claude-opus-4.7
7
- thinking: low
5
+ model: openai/gpt-5.5:low
6
+ fallbackModels: openai-codex/gpt-5.5:low, github-copilot/gpt-5.5:low, anthropic/claude-opus-4-8:low, github-copilot/claude-opus-4.7:low
8
7
  ---
9
8
 
10
9
  You are a specialist at extracting HIGH-VALUE insights from research documents. Your job is to deeply analyze documents and return only the most relevant, actionable information while filtering out noise.
@@ -2,9 +2,8 @@
2
2
  name: codebase-research-locator
3
3
  description: Discovers local research documents that are relevant to the current research task.
4
4
  tools: read, grep, find, ls, bash
5
- model: openai/gpt-5.4-mini
6
- fallbackModels: openai-codex/gpt-5.4-mini, github-copilot/gpt-5.4-mini, anthropic/claude-haiku-4-5, github-copilot/claude-haiku-4.5
7
- thinking: low
5
+ model: openai/gpt-5.4-mini:low
6
+ fallbackModels: openai-codex/gpt-5.4-mini:low, github-copilot/gpt-5.4-mini:low, anthropic/claude-haiku-4-5:low, github-copilot/claude-haiku-4.5:low
8
7
  ---
9
8
 
10
9
  You are a specialist at finding documents in the `research/` directory. Your job is to locate relevant research documents and categorize them, NOT to analyze their contents in depth.
@@ -2,9 +2,8 @@
2
2
  name: debugger
3
3
  description: Debug errors, test failures, and unexpected behavior. Use PROACTIVELY when encountering issues, analyzing stack traces, or investigating system problems.
4
4
  tools: read, edit, write, grep, find, ls, bash, web_search, fetch_content, get_search_content
5
- model: openai/gpt-5.5
6
- fallbackModels: openai-codex/gpt-5.5, github-copilot/gpt-5.5, anthropic/claude-opus-4-8, github-copilot/claude-opus-4.7
7
- thinking: xhigh
5
+ model: openai/gpt-5.5:xhigh
6
+ fallbackModels: openai-codex/gpt-5.5:xhigh, github-copilot/gpt-5.5:xhigh, anthropic/claude-opus-4-8:xhigh, github-copilot/claude-opus-4.7:xhigh
8
7
  skills: tdd, browser-use, tmux
9
8
  ---
10
9
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/subagents",
3
- "version": "0.8.23",
3
+ "version": "0.8.24-alpha.2",
4
4
  "private": true,
5
5
  "description": "Atomic extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification. Fork of: https://github.com/nicobailon/pi-subagents",
6
6
  "contributors": [
@@ -732,3 +732,9 @@ subagent({ action: "doctor" })
732
732
  ```typescript
733
733
  // Inspect `subagent({ action: "status", id: "..." })`, artifact metadata/output logs, and run doctor. Extension loader errors usually appear in child output logs.
734
734
  ```
735
+
736
+ ## Suffix-first reasoning levels
737
+
738
+ Prefer encoding reasoning levels directly in model strings with the `model_name:thinking_effort` syntax: `model: claude-sonnet-4:high` and `fallbackModels: [claude-sonnet-4:medium, gpt-5:low, claude-haiku-4:off]`. Valid efforts are `off`, `minimal`, `low`, `medium`, `high`, and `xhigh`. The separate `thinking` field is deprecated but still works as a legacy default when a candidate has no suffix; suffixes take precedence. If you see a legacy `thinking` override, migrate it by appending the effort to `model` and each `fallbackModels` entry instead (e.g. `thinking: high` + `model: gpt-5` → `model: gpt-5:high`).
739
+
740
+ `fallbackThinkingLevels` is an optional compatibility helper aligned positionally with `fallbackModels`. It only applies to fallback entries without their own suffix and should not be preferred over suffix-first entries.
@@ -8,6 +8,7 @@ export const KNOWN_FIELDS = new Set([
8
8
  "tools",
9
9
  "model",
10
10
  "fallbackModels",
11
+ "fallbackThinkingLevels",
11
12
  "thinking",
12
13
  "systemPromptMode",
13
14
  "inheritProjectContext",
@@ -46,6 +47,8 @@ export function serializeAgent(config: AgentConfig): string {
46
47
  if (config.model) lines.push(`model: ${config.model}`);
47
48
  const fallbackModelsValue = joinComma(config.fallbackModels);
48
49
  if (fallbackModelsValue) lines.push(`fallbackModels: ${fallbackModelsValue}`);
50
+ const fallbackThinkingLevelsValue = joinComma(config.fallbackThinkingLevels);
51
+ if (fallbackThinkingLevelsValue) lines.push(`fallbackThinkingLevels: ${fallbackThinkingLevelsValue}`);
49
52
  if (config.thinking && config.thinking !== "off") lines.push(`thinking: ${config.thinking}`);
50
53
  lines.push(`systemPromptMode: ${config.systemPromptMode}`);
51
54
  lines.push(`inheritProjectContext: ${config.inheritProjectContext ? "true" : "false"}`);
@@ -36,6 +36,7 @@ export function defaultInheritSkills(): boolean {
36
36
  export interface BuiltinAgentOverrideBase {
37
37
  model?: string;
38
38
  fallbackModels?: string[];
39
+ fallbackThinkingLevels?: string[];
39
40
  thinking?: string;
40
41
  systemPromptMode: SystemPromptMode;
41
42
  inheritProjectContext: boolean;
@@ -52,6 +53,7 @@ export interface BuiltinAgentOverrideBase {
52
53
  interface BuiltinAgentOverrideConfig {
53
54
  model?: string | false;
54
55
  fallbackModels?: string[] | false;
56
+ fallbackThinkingLevels?: string[] | false;
55
57
  thinking?: string | false;
56
58
  systemPromptMode?: SystemPromptMode;
57
59
  inheritProjectContext?: boolean;
@@ -79,6 +81,7 @@ export interface AgentConfig {
79
81
  mcpDirectTools?: string[];
80
82
  model?: string;
81
83
  fallbackModels?: string[];
84
+ fallbackThinkingLevels?: string[];
82
85
  thinking?: string;
83
86
  systemPromptMode: SystemPromptMode;
84
87
  inheritProjectContext: boolean;
@@ -184,6 +187,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
184
187
  return {
185
188
  model: agent.model,
186
189
  fallbackModels: agent.fallbackModels ? [...agent.fallbackModels] : undefined,
190
+ fallbackThinkingLevels: agent.fallbackThinkingLevels ? [...agent.fallbackThinkingLevels] : undefined,
187
191
  thinking: agent.thinking,
188
192
  systemPromptMode: agent.systemPromptMode,
189
193
  inheritProjectContext: agent.inheritProjectContext,
@@ -204,6 +208,9 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
204
208
  ...(override.fallbackModels !== undefined
205
209
  ? { fallbackModels: override.fallbackModels === false ? false : [...override.fallbackModels] }
206
210
  : {}),
211
+ ...(override.fallbackThinkingLevels !== undefined
212
+ ? { fallbackThinkingLevels: override.fallbackThinkingLevels === false ? false : [...override.fallbackThinkingLevels] }
213
+ : {}),
207
214
  ...(override.thinking !== undefined ? { thinking: override.thinking } : {}),
208
215
  ...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),
209
216
  ...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),
@@ -375,6 +382,9 @@ function parseBuiltinOverrideEntry(
375
382
  const fallbackModels = parseOverrideStringArrayOrFalse(input.fallbackModels, { filePath, name, field: "fallbackModels" });
376
383
  if (fallbackModels !== undefined) override.fallbackModels = fallbackModels;
377
384
 
385
+ const fallbackThinkingLevels = parseOverrideStringArrayOrFalse(input.fallbackThinkingLevels, { filePath, name, field: "fallbackThinkingLevels" });
386
+ if (fallbackThinkingLevels !== undefined) override.fallbackThinkingLevels = fallbackThinkingLevels;
387
+
378
388
  const skills = parseOverrideStringArrayOrFalse(input.skills, { filePath, name, field: "skills" });
379
389
  if (skills !== undefined) override.skills = skills;
380
390
 
@@ -442,6 +452,9 @@ function applyBuiltinOverride(
442
452
  if (override.fallbackModels !== undefined) {
443
453
  next.fallbackModels = override.fallbackModels === false ? undefined : [...override.fallbackModels];
444
454
  }
455
+ if (override.fallbackThinkingLevels !== undefined) {
456
+ next.fallbackThinkingLevels = override.fallbackThinkingLevels === false ? undefined : [...override.fallbackThinkingLevels];
457
+ }
445
458
  if (override.thinking !== undefined) next.thinking = override.thinking === false ? undefined : override.thinking;
446
459
  if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;
447
460
  if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;
@@ -495,12 +508,13 @@ function applyBuiltinOverrides(
495
508
 
496
509
  export function buildBuiltinOverrideConfig(
497
510
  base: BuiltinAgentOverrideBase,
498
- draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "completionGuard">,
511
+ draft: Pick<AgentConfig, "model" | "fallbackModels" | "fallbackThinkingLevels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "completionGuard">,
499
512
  ): BuiltinAgentOverrideConfig | undefined {
500
513
  const override: BuiltinAgentOverrideConfig = {};
501
514
 
502
515
  if (draft.model !== base.model) override.model = draft.model ?? false;
503
516
  if (!arraysEqual(draft.fallbackModels, base.fallbackModels)) override.fallbackModels = draft.fallbackModels ? [...draft.fallbackModels] : false;
517
+ if (!arraysEqual(draft.fallbackThinkingLevels, base.fallbackThinkingLevels)) override.fallbackThinkingLevels = draft.fallbackThinkingLevels ? [...draft.fallbackThinkingLevels] : false;
504
518
  if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;
505
519
  if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;
506
520
  if (draft.inheritProjectContext !== base.inheritProjectContext) override.inheritProjectContext = draft.inheritProjectContext;
@@ -646,6 +660,10 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
646
660
  ?.split(",")
647
661
  .map((model) => model.trim())
648
662
  .filter(Boolean);
663
+ const fallbackThinkingLevels = frontmatter.fallbackThinkingLevels
664
+ ?.split(",")
665
+ .map((level) => level.trim())
666
+ .filter(Boolean);
649
667
  const systemPromptMode = frontmatter.systemPromptMode === "replace"
650
668
  ? "replace"
651
669
  : frontmatter.systemPromptMode === "append"
@@ -696,6 +714,7 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
696
714
  mcpDirectTools: mcpDirectTools.length > 0 ? mcpDirectTools : undefined,
697
715
  model: frontmatter.model,
698
716
  fallbackModels: fallbackModels && fallbackModels.length > 0 ? fallbackModels : undefined,
717
+ fallbackThinkingLevels: fallbackThinkingLevels && fallbackThinkingLevels.length > 0 ? fallbackThinkingLevels : undefined,
699
718
  thinking: frontmatter.thinking,
700
719
  systemPromptMode,
701
720
  inheritProjectContext,
@@ -334,7 +334,7 @@ export function executeAsyncChain(
334
334
 
335
335
  const primaryModel = resolveModelCandidate(behavior.model ?? a.model, availableModels, ctx.currentModelProvider);
336
336
  const model = applyThinkingSuffix(primaryModel, a.thinking);
337
- const modelCandidates = buildModelCandidates(behavior.model ?? a.model, a.fallbackModels, availableModels, ctx.currentModelProvider, ctx.currentModel)
337
+ const modelCandidates = buildModelCandidates(behavior.model ?? a.model, a.fallbackModels, availableModels, ctx.currentModelProvider, ctx.currentModel, a.fallbackThinkingLevels)
338
338
  .map((candidate) => applyThinkingSuffix(candidate, a.thinking))
339
339
  .filter((candidate): candidate is string => typeof candidate === "string");
340
340
  const fastModeSettings = getSubagentCodexFastModeSettings(stepCwd);
@@ -702,8 +702,10 @@ async function runSingleStep(
702
702
  ? `${hiddenError.errorType} failed (exit ${effectiveExitCode}): ${hiddenError.details}`
703
703
  : `${hiddenError.errorType} failed with exit code ${effectiveExitCode}`
704
704
  : run.error || (run.exitCode !== 0 && run.stderr.trim() ? run.stderr.trim() : undefined));
705
+ const attemptModel = candidate ?? run.model ?? step.model ?? "default";
705
706
  const attempt: ModelAttempt = {
706
- model: candidate ?? run.model ?? step.model ?? "default",
707
+ model: attemptModel,
708
+ reasoningLevel: resolveEffectiveThinking(attemptModel, step.thinking),
707
709
  success: effectiveExitCode === 0 && !error,
708
710
  exitCode: effectiveExitCode,
709
711
  error,
@@ -10,8 +10,8 @@ import type { Component, TUI } from "@earendil-works/pi-tui";
10
10
  import { matchesKey, visibleWidth, truncateToWidth } from "@earendil-works/pi-tui";
11
11
  import type { AgentConfig } from "../../agents/agents.ts";
12
12
  import type { ResolvedStepBehavior } from "../../shared/settings.ts";
13
- import { resolveModelCandidate, splitThinkingSuffix } from "../shared/model-fallback.ts";
14
- import { findModelInfo, getSupportedThinkingLevels, type ModelInfo, type ThinkingLevel } from "../../shared/model-info.ts";
13
+ import { resolveModelCandidate } from "../shared/model-fallback.ts";
14
+ import { findModelInfo, getSupportedThinkingLevels, splitKnownThinkingSuffix, type ModelInfo, type ThinkingLevel } from "../../shared/model-info.ts";
15
15
 
16
16
  type ClarifyMode = 'single' | 'parallel' | 'chain';
17
17
 
@@ -549,7 +549,7 @@ export class ChainClarifyComponent implements Component {
549
549
  this.modelSearchQuery = "";
550
550
  this.modelSelectedIndex = 0;
551
551
  this.filteredModels = [...this.availableModels];
552
- const currentModel = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep)).baseModel;
552
+ const currentModel = splitKnownThinkingSuffix(this.getEffectiveModel(this.selectedStep)).baseModel;
553
553
  const currentIndex = this.filteredModels.findIndex((m) => m.fullId === currentModel || m.id === currentModel);
554
554
  if (currentIndex >= 0) {
555
555
  this.modelSelectedIndex = currentIndex;
@@ -582,7 +582,7 @@ export class ChainClarifyComponent implements Component {
582
582
  if (matchesKey(data, "return")) {
583
583
  const selected = this.filteredModels[this.modelSelectedIndex];
584
584
  if (selected) {
585
- const { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.editingStep!));
585
+ const { thinkingSuffix } = splitKnownThinkingSuffix(this.getEffectiveModel(this.editingStep!));
586
586
  const requestedLevel = thinkingSuffix.slice(1);
587
587
  const selectedModel = findModelInfo(selected.fullId, this.availableModels, this.preferredProvider);
588
588
  const suffix = getSupportedThinkingLevels(selectedModel).some((level) => level === requestedLevel) ? thinkingSuffix : "";
@@ -643,7 +643,7 @@ export class ChainClarifyComponent implements Component {
643
643
  this.editMode = "thinking";
644
644
 
645
645
  const levels = this.getAvailableThinkingLevels(this.selectedStep);
646
- const { thinkingSuffix } = splitThinkingSuffix(this.getEffectiveModel(this.selectedStep));
646
+ const { thinkingSuffix } = splitKnownThinkingSuffix(this.getEffectiveModel(this.selectedStep));
647
647
  const suffix = thinkingSuffix.slice(1);
648
648
  const levelIdx = levels.findIndex((level) => level === suffix);
649
649
  this.thinkingSelectedIndex = levelIdx >= 0 ? levelIdx : Math.max(0, levels.indexOf("off"));
@@ -690,7 +690,7 @@ export class ChainClarifyComponent implements Component {
690
690
  const currentModel = this.getEffectiveBehavior(stepIndex).model;
691
691
  if (!currentModel) return;
692
692
 
693
- const { baseModel } = splitThinkingSuffix(currentModel);
693
+ const { baseModel } = splitKnownThinkingSuffix(currentModel);
694
694
  const newModel = level === "off" ? baseModel : `${baseModel}:${level}`;
695
695
  this.updateBehavior(stepIndex, "model", newModel);
696
696
  }
@@ -922,7 +922,7 @@ export class ChainClarifyComponent implements Component {
922
922
  lines.push(this.row(""));
923
923
 
924
924
  const currentModel = this.getEffectiveModel(this.editingStep!);
925
- const currentModelBase = splitThinkingSuffix(currentModel).baseModel;
925
+ const currentModelBase = splitKnownThinkingSuffix(currentModel).baseModel;
926
926
  const currentLabel = th.fg("dim", "Current: ");
927
927
  lines.push(this.row(` ${currentLabel}${th.fg("warning", currentModel)}`));
928
928
  lines.push(this.row(""));
@@ -69,6 +69,7 @@ import {
69
69
  resolveSubagentCodexFastModeScope,
70
70
  resolveSubagentModelFastMode,
71
71
  } from "../../shared/fast-mode.ts";
72
+ import { resolveEffectiveThinking } from "../../shared/model-info.ts";
72
73
 
73
74
  const artifactOutputByResult = new WeakMap<SingleResult, string>();
74
75
 
@@ -814,6 +815,7 @@ export async function runSync(
814
815
  options.availableModels,
815
816
  options.preferredModelProvider,
816
817
  options.currentModel,
818
+ agent.fallbackThinkingLevels,
817
819
  );
818
820
  const fastModeCwd = options.cwd ?? runtimeCwd;
819
821
  const fastModeSettings = getSubagentCodexFastModeSettings(fastModeCwd);
@@ -861,8 +863,10 @@ export async function runSync(
861
863
  totalToolCount += result.progressSummary?.toolCount ?? 0;
862
864
  totalDurationMs += result.progressSummary?.durationMs ?? 0;
863
865
  const attemptSucceeded = result.exitCode === 0 && !result.error;
866
+ const attemptModel = applyThinkingSuffix(candidate, agent.thinking) ?? result.model ?? agent.model ?? "default";
864
867
  const attempt: ModelAttempt = {
865
- model: candidate ?? result.model ?? agent.model ?? "default",
868
+ model: attemptModel,
869
+ reasoningLevel: resolveEffectiveThinking(attemptModel, agent.thinking),
866
870
  success: attemptSucceeded,
867
871
  exitCode: result.exitCode,
868
872
  error: result.error,
@@ -1,4 +1,4 @@
1
- import type { ModelInfo as AvailableModelInfo } from "../../shared/model-info.ts";
1
+ import { THINKING_LEVELS, splitKnownThinkingSuffix, type ModelInfo as AvailableModelInfo } from "../../shared/model-info.ts";
2
2
  import type { Usage } from "../../shared/types.ts";
3
3
 
4
4
  export type { AvailableModelInfo };
@@ -11,13 +11,10 @@ interface ModelAttemptSummary {
11
11
  usage?: Usage;
12
12
  }
13
13
 
14
- export function splitThinkingSuffix(model: string): { baseModel: string; thinkingSuffix: string } {
15
- const colonIdx = model.lastIndexOf(":");
16
- if (colonIdx === -1) return { baseModel: model, thinkingSuffix: "" };
17
- return {
18
- baseModel: model.substring(0, colonIdx),
19
- thinkingSuffix: model.substring(colonIdx),
20
- };
14
+ function applyFallbackThinkingLevel(model: string, thinkingLevel: string | undefined): string {
15
+ if (!thinkingLevel || !THINKING_LEVELS.some((level) => level === thinkingLevel)) return model;
16
+ const { thinkingSuffix } = splitKnownThinkingSuffix(model);
17
+ return thinkingSuffix ? model : `${model}:${thinkingLevel}`;
21
18
  }
22
19
 
23
20
  export function resolveModelCandidate(
@@ -29,7 +26,7 @@ export function resolveModelCandidate(
29
26
  if (model.includes("/")) return model;
30
27
  if (!availableModels || availableModels.length === 0) return model;
31
28
 
32
- const { baseModel, thinkingSuffix } = splitThinkingSuffix(model);
29
+ const { baseModel, thinkingSuffix } = splitKnownThinkingSuffix(model);
33
30
  const matches = availableModels.filter((entry) => entry.id === baseModel);
34
31
  if (preferredProvider) {
35
32
  const preferredMatch = matches.find((entry) => entry.provider === preferredProvider);
@@ -45,10 +42,12 @@ export function buildModelCandidates(
45
42
  availableModels: AvailableModelInfo[] | undefined,
46
43
  preferredProvider?: string,
47
44
  currentModel?: string,
45
+ fallbackThinkingLevels?: string[],
48
46
  ): string[] {
49
47
  const seen = new Set<string>();
50
48
  const candidates: string[] = [];
51
- for (const raw of [primaryModel, ...(fallbackModels ?? []), currentModel]) {
49
+ const fallbackEntries = (fallbackModels ?? []).map((model, index) => applyFallbackThinkingLevel(model, fallbackThinkingLevels?.[index]));
50
+ for (const raw of [primaryModel, ...fallbackEntries, currentModel]) {
52
51
  if (!raw) continue;
53
52
  const normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);
54
53
  if (!normalized || seen.has(normalized)) continue;
@@ -195,6 +195,7 @@ interface ProgressSummary {
195
195
 
196
196
  export interface ModelAttempt {
197
197
  model: string;
198
+ reasoningLevel?: string;
198
199
  success: boolean;
199
200
  exitCode?: number | null;
200
201
  error?: string;
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.8.24-alpha.2] - 2026-06-03
8
+
9
+ ### Changed
10
+
11
+ - Bumped package version for the Atomic 0.8.24-alpha.2 prerelease.
12
+
13
+ ## [0.8.24-alpha.1] - 2026-06-02
14
+
15
+ ### Changed
16
+
17
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
18
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
19
+
7
20
  ## [0.8.23] - 2026-06-02
8
21
 
9
22
  ### Changed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.8.23",
3
+ "version": "0.8.24-alpha.2",
4
4
  "private": true,
5
5
  "description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
6
6
  "contributors": [
@@ -6,6 +6,41 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.8.24-alpha.2] - 2026-06-03
10
+
11
+ ### Added
12
+
13
+ - The `@bastani/workflows` authoring SDK types are now externally resolvable in installed packages through `@bastani/atomic`'s new `./workflows` exports and ambient bridge, so workflow files type-check `import { defineWorkflow, Type } from "@bastani/workflows"` (and `@bastani/workflows/builtin/*`) under `tsc` (NodeNext) without a hand-authored `.d.ts`, `declare module` shim, or `paths` alias. Workflow packages declare `@bastani/atomic` and `typebox` as peer dependencies; the package continues to distribute raw TypeScript with no build step, and the runtime virtual-module loader is unchanged ([#1208](https://github.com/bastani-inc/atomic/issues/1208)).
14
+
15
+ ### Fixed
16
+
17
+ - Fixed builtin (and any) workflows falling back to the user's currently selected model instead of the stage's defined model. A fully-qualified `provider/model` id that the live model catalog did not list was treated as a hard "not available" failure; because candidate validation throws on any failure and the catalog resolver catches that throw and collapses the whole ordered candidate list down to the user's `currentModel`, a single absent cross-provider fallback discarded the defined primary plus every fallback. Provider-qualified ids are now trusted (passed through with the reasoning suffix split off the last colon), mirroring the subagent resolver, so the defined primary is used and only genuinely failing candidates fall through at runtime. Regressed when bundled workflow model lists were refreshed onto newer multi-provider ids alongside suffix-first reasoning levels ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
18
+
19
+ ## [0.8.24-alpha.1] - 2026-06-02
20
+
21
+ ### Breaking Changes
22
+
23
+ - Removed the imperative `runWorkflow` object-form API from `@bastani/workflows`; workflow authors must export definitions produced by `defineWorkflow(...).compile()`, and forged `__piWorkflow: true` objects are rejected by discovery and composition.
24
+
25
+ ### Added
26
+
27
+ - Added suffix-first workflow reasoning levels for `model` and `fallbackModels` entries such as `openai/gpt-5:high`, plus `WorkflowModelAttempt.reasoningLevel` metadata and optional `fallbackThinkingLevels` compatibility mapping ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
28
+
29
+ ### Changed
30
+
31
+ - Changed bundled workflows to encode their existing reasoning levels directly on model and fallback model strings ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
32
+ - Documented the `model_name:thinking_effort` suffix syntax and `thinkingLevel` migration guidance in the workflows docs and package README ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
33
+ - Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
34
+ - Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.
35
+
36
+ ### Deprecated
37
+
38
+ - Deprecated workflow `thinkingLevel` stage options in favor of per-candidate `:off|minimal|low|medium|high|xhigh` model suffixes; removal is deferred ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
39
+
40
+ ### Fixed
41
+
42
+ - Made workflow reasoning-suffix parsing lenient so it no longer rejects legitimate colon-tagged model ids (for example OpenRouter `:free`/`:exacto` variants and Ollama `llama3:latest`); only canonical `:off|minimal|low|medium|high|xhigh` suffixes are stripped as reasoning levels, and unknown ids still surface the generic catalog "not available" error ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
43
+
9
44
  ## [0.8.23] - 2026-06-02
10
45
 
11
46
  ### Changed