@skaile/workspaces 5.1.1 → 5.1.3
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.
- package/CHANGELOG.md +18 -0
- package/README.md +5 -4
- package/dist/{asset-feeds-TU5CS6QL.js → asset-feeds-C4X4RTZV.js} +4 -4
- package/dist/{asset-feeds-TU5CS6QL.js.map → asset-feeds-C4X4RTZV.js.map} +1 -1
- package/dist/asset-manager/index.js +1 -1
- package/dist/bridge/drivers/claude-sdk.js +98 -12
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +2 -2
- package/dist/bridge/drivers/continue.js +3 -3
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/gemini.js +5 -5
- package/dist/bridge/drivers/goose.js +3 -3
- package/dist/bridge/drivers/omp.js +2 -2
- package/dist/bridge/drivers/opencode.js +3 -3
- package/dist/bridge/drivers/qwen.js +5 -5
- package/dist/bridge/index.js +3 -3
- package/dist/bridge/src/drivers/claude-sdk.d.ts +16 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/{chunk-3NGPZC44.js → chunk-2HR3RPWD.js} +6 -6
- package/dist/{chunk-3NGPZC44.js.map → chunk-2HR3RPWD.js.map} +1 -1
- package/dist/{chunk-JUXQUZOQ.js → chunk-37FTLYFP.js} +26 -3
- package/dist/chunk-37FTLYFP.js.map +1 -0
- package/dist/{chunk-E67J56FJ.js → chunk-5S4ZK75K.js} +3 -3
- package/dist/{chunk-E67J56FJ.js.map → chunk-5S4ZK75K.js.map} +1 -1
- package/dist/{chunk-CI6FQ654.js → chunk-AZYIEK3F.js} +3 -3
- package/dist/{chunk-CI6FQ654.js.map → chunk-AZYIEK3F.js.map} +1 -1
- package/dist/{chunk-6LDUA57J.js → chunk-BEOKEK3B.js} +2 -2
- package/dist/{chunk-6LDUA57J.js.map → chunk-BEOKEK3B.js.map} +1 -1
- package/dist/{chunk-IYIIT4R3.js → chunk-BJZHNSQO.js} +4 -4
- package/dist/{chunk-IYIIT4R3.js.map → chunk-BJZHNSQO.js.map} +1 -1
- package/dist/{chunk-KAYH6AXN.js → chunk-DLLM4U6C.js} +3 -3
- package/dist/{chunk-KAYH6AXN.js.map → chunk-DLLM4U6C.js.map} +1 -1
- package/dist/{chunk-X6E7Y4JD.js → chunk-I75CM2QF.js} +6 -6
- package/dist/{chunk-X6E7Y4JD.js.map → chunk-I75CM2QF.js.map} +1 -1
- package/dist/{chunk-3KSAFYD4.js → chunk-IAGCOAIW.js} +3 -3
- package/dist/{chunk-3KSAFYD4.js.map → chunk-IAGCOAIW.js.map} +1 -1
- package/dist/{chunk-G47EV3V6.js → chunk-KNC55536.js} +2 -2
- package/dist/{chunk-G47EV3V6.js.map → chunk-KNC55536.js.map} +1 -1
- package/dist/{chunk-P5UQ56RA.js → chunk-KVAI5DGL.js} +3 -3
- package/dist/{chunk-P5UQ56RA.js.map → chunk-KVAI5DGL.js.map} +1 -1
- package/dist/{chunk-57DVX53V.js → chunk-KWP4RVTJ.js} +32 -11
- package/dist/chunk-KWP4RVTJ.js.map +1 -0
- package/dist/{chunk-QFZFZXQW.js → chunk-M4ISBWXR.js} +30 -11
- package/dist/chunk-M4ISBWXR.js.map +1 -0
- package/dist/{chunk-EPHQWHOH.js → chunk-O4U7OL6D.js} +6 -6
- package/dist/{chunk-EPHQWHOH.js.map → chunk-O4U7OL6D.js.map} +1 -1
- package/dist/{chunk-YIVB7GIP.js → chunk-QU4J5YSJ.js} +3 -3
- package/dist/{chunk-YIVB7GIP.js.map → chunk-QU4J5YSJ.js.map} +1 -1
- package/dist/{chunk-E3ZACBHD.js → chunk-RNOIDD3Y.js} +3 -3
- package/dist/{chunk-E3ZACBHD.js.map → chunk-RNOIDD3Y.js.map} +1 -1
- package/dist/{chunk-2Y6DSR36.js → chunk-RO4Z2CBP.js} +3 -3
- package/dist/{chunk-2Y6DSR36.js.map → chunk-RO4Z2CBP.js.map} +1 -1
- package/dist/{chunk-AYNPGPT5.js → chunk-WPWJRDR3.js} +3 -3
- package/dist/{chunk-AYNPGPT5.js.map → chunk-WPWJRDR3.js.map} +1 -1
- package/dist/{chunk-AOMWF2OE.js → chunk-Y6V6NUEV.js} +3 -3
- package/dist/{chunk-AOMWF2OE.js.map → chunk-Y6V6NUEV.js.map} +1 -1
- package/dist/{chunk-RDTHJSGY.js → chunk-ZD7CX25M.js} +2 -2
- package/dist/{chunk-RDTHJSGY.js.map → chunk-ZD7CX25M.js.map} +1 -1
- package/dist/{chunk-2EOPGGLY.js → chunk-ZVKJNNME.js} +3 -3
- package/dist/{chunk-2EOPGGLY.js.map → chunk-ZVKJNNME.js.map} +1 -1
- package/dist/cli/index.js +36 -36
- package/dist/connectors/index.js +5 -5
- package/dist/{connectors-VX7YRFFS.js → connectors-BQXFKISC.js} +8 -8
- package/dist/{connectors-VX7YRFFS.js.map → connectors-BQXFKISC.js.map} +1 -1
- package/dist/{ensure-sources-2XQS32WI.js → ensure-sources-CMHOTYFS.js} +4 -4
- package/dist/{ensure-sources-2XQS32WI.js.map → ensure-sources-CMHOTYFS.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +5 -5
- package/dist/factory-assets/connectors/deploy.js +5 -5
- package/dist/factory-assets/connectors/devserver.js +5 -5
- package/dist/factory-assets/connectors/flow/adapter.d.ts +3 -1
- package/dist/factory-assets/connectors/flow/adapter.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/adapter.js +5 -5
- package/dist/factory-assets/connectors/flow/contract/index.d.ts +1 -1
- package/dist/factory-assets/connectors/flow/contract/index.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract/sub-flow-output.d.ts +20 -0
- package/dist/factory-assets/connectors/flow/contract/sub-flow-output.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/contract.js +1 -1
- package/dist/factory-assets/connectors/flow/index.d.ts +1 -0
- package/dist/factory-assets/connectors/flow/index.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/inline-sub-flow-host.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow/run-flow.js +6 -6
- package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts +8 -0
- package/dist/factory-assets/connectors/flow/sub-flow-runner.d.ts.map +1 -1
- package/dist/factory-assets/connectors/flow.js +5 -5
- package/dist/factory-assets/connectors/git.js +5 -5
- package/dist/factory-assets/connectors/gmail.js +5 -5
- package/dist/factory-assets/connectors/googledrive.js +5 -5
- package/dist/factory-assets/connectors/local.js +5 -5
- package/dist/factory-assets/connectors/mattermost.js +5 -5
- package/dist/factory-assets/connectors/memory.js +5 -5
- package/dist/factory-assets/connectors/minio.js +5 -5
- package/dist/factory-assets/connectors/postgres.js +5 -5
- package/dist/factory-assets/connectors/s3.js +5 -5
- package/dist/factory-assets/connectors/sharepoint.js +5 -5
- package/dist/factory-assets/connectors/sqlite.js +5 -5
- package/dist/factory-assets/connectors/static-server.js +5 -5
- package/dist/factory-assets/connectors/tunnel.js +5 -5
- package/dist/factory-assets/connectors/webdav.js +5 -5
- package/dist/factory-assets/connectors/xstate-store.js +5 -5
- package/dist/factory-assets/connectors/xstate.js +5 -5
- package/dist/{helpers-IELQGVGB.js → helpers-R3GLTAER.js} +4 -4
- package/dist/{helpers-IELQGVGB.js.map → helpers-R3GLTAER.js.map} +1 -1
- package/dist/{library-publish-TCFU3X5L.js → library-publish-EL7VYICU.js} +7 -7
- package/dist/{library-publish-TCFU3X5L.js.map → library-publish-EL7VYICU.js.map} +1 -1
- package/dist/{open-library-SSBN4FX2.js → open-library-MTD34YX3.js} +5 -5
- package/dist/{open-library-SSBN4FX2.js.map → open-library-MTD34YX3.js.map} +1 -1
- package/dist/{project-PJ37PM6N.js → project-HCNWJP7J.js} +5 -5
- package/dist/{project-PJ37PM6N.js.map → project-HCNWJP7J.js.map} +1 -1
- package/dist/runner/index.js +10 -10
- package/dist/runner/src/ai-provider-switch.d.ts +10 -0
- package/dist/runner/src/ai-provider-switch.d.ts.map +1 -1
- package/dist/runner/src/reply-routing.d.ts +8 -0
- package/dist/runner/src/reply-routing.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +1 -1
- package/dist/sdk/bridge.js +3 -3
- package/dist/sdk/index.js +10 -10
- package/dist/sdk/runner.js +10 -10
- package/dist/{setup-JW2ZGCUG.js → setup-HTXNR2CZ.js} +8 -8
- package/dist/{setup-JW2ZGCUG.js.map → setup-HTXNR2CZ.js.map} +1 -1
- package/dist/{source-F2VO32W6.js → source-UIFC2PFC.js} +6 -6
- package/dist/{source-F2VO32W6.js.map → source-UIFC2PFC.js.map} +1 -1
- package/dist/{source-manifest-publish-AXNII2J4.js → source-manifest-publish-QKAKXDVH.js} +8 -8
- package/dist/{source-manifest-publish-AXNII2J4.js.map → source-manifest-publish-QKAKXDVH.js.map} +1 -1
- package/dist/tui/index.js +10 -10
- package/dist/workspace-plugin/adapters/mcp.js +7 -7
- package/dist/workspace-plugin/adapters/omp.js +7 -7
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-57DVX53V.js.map +0 -1
- package/dist/chunk-JUXQUZOQ.js.map +0 -1
- package/dist/chunk-QFZFZXQW.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1007](https://github.com/skaile-ai/workspaces/pull/1007) [`30dd4ef`](https://github.com/skaile-ai/workspaces/commit/30dd4efb5c9098b6a2c758729a8c74c8b0255eaa) Thanks [@Frozen666](https://github.com/Frozen666)! - A turn that the claude-sdk driver replays on another AI provider seat after a usage limit no longer shows a fatal "Agent stopped" error before the replayed reply. A turn still running on the old seat after a `credentialRotated` switch is now replayed on the new seat when it hits the old seat's limit, instead of ending with the limit error.
|
|
8
|
+
|
|
9
|
+
## 5.1.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1002](https://github.com/skaile-ai/workspaces/pull/1002) [`c7d560d`](https://github.com/skaile-ai/workspaces/commit/c7d560dde036ba1ad20c031e03804fae2c55d940) Thanks [@Frozen666](https://github.com/Frozen666)! - A sub-flow node now fails at start, before the child runs, when a field the parent reads has a different declared type in the child's output schema (new `mismatchedSubFlowOutputTypes`). A node-start contract mismatch (`SubFlowContractError`) no longer spends `control.retries`.
|
|
14
|
+
|
|
15
|
+
- [#1005](https://github.com/skaile-ai/workspaces/pull/1005) [`d22c544`](https://github.com/skaile-ai/workspaces/commit/d22c544cd360a7e884552faedd4e0d1520fed706) Thanks [@Frozen666](https://github.com/Frozen666)! - Docs: run the CLI with `bun packages/workspaces/cli/src/index.ts` (there is no `cli` script) and fix repo-root paths in the connector manual-testing guide.
|
|
16
|
+
|
|
17
|
+
- [#1001](https://github.com/skaile-ai/workspaces/pull/1001) [`00d905f`](https://github.com/skaile-ai/workspaces/commit/00d905f43e31a22e6a9e95328c3633744d3e2a43) Thanks [@Frozen666](https://github.com/Frozen666)! - Runner: an answer to a question card that arrives after a wake now tells the agent which question it answers. The answer becomes a new prompt, and its last line names the question, so the agent no longer has to guess what "Option 2" refers to.
|
|
18
|
+
|
|
19
|
+
- [#1003](https://github.com/skaile-ai/workspaces/pull/1003) [`4baead0`](https://github.com/skaile-ai/workspaces/commit/4baead03c14d8aba8b52ff17e5eb57f1ca19267d) Thanks [@Frozen666](https://github.com/Frozen666)! - Runner: an answer to a question card that a driver cannot take as a new prompt (managed Codex after a wake) no longer disappears. The runner now sends a non-fatal `error` event: "This question is no longer open, so the agent did not get your answer. Send it as a new message." An answer that a still-open question rejects stays silent, as before, because that card is still live.
|
|
20
|
+
|
|
3
21
|
## 5.1.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -77,10 +77,11 @@ cli (top-level CLI — orchestrates everything below)
|
|
|
77
77
|
## Quick Start
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
# From the
|
|
81
|
-
bun run
|
|
82
|
-
bun
|
|
83
|
-
bun
|
|
80
|
+
# From the repo root; the CLI imports the built dist/, so build first
|
|
81
|
+
bun run build
|
|
82
|
+
bun packages/workspaces/cli/src/index.ts --help # run the skaile CLI
|
|
83
|
+
bun packages/workspaces/cli/src/index.ts skill list # list available skills
|
|
84
|
+
bun packages/workspaces/cli/src/index.ts run mvp # run a flow
|
|
84
85
|
```
|
|
85
86
|
|
|
86
87
|
Flow authors and editor integrations can import the v2 contract independently:
|
|
@@ -23,7 +23,7 @@ import * as path from 'path';
|
|
|
23
23
|
async function libraryAssets() {
|
|
24
24
|
const notes = [];
|
|
25
25
|
try {
|
|
26
|
-
const { openLibraryManager, authoringLibraries } = await import('./open-library-
|
|
26
|
+
const { openLibraryManager, authoringLibraries } = await import('./open-library-MTD34YX3.js');
|
|
27
27
|
const { manager, close } = await openLibraryManager();
|
|
28
28
|
try {
|
|
29
29
|
const libs = authoringLibraries(await manager.listLibraries());
|
|
@@ -48,7 +48,7 @@ async function libraryAssets() {
|
|
|
48
48
|
async function storeAssets(projectDir) {
|
|
49
49
|
const notes = [];
|
|
50
50
|
try {
|
|
51
|
-
const { resolveCatalogSource } = await import('./open-library-
|
|
51
|
+
const { resolveCatalogSource } = await import('./open-library-MTD34YX3.js');
|
|
52
52
|
const { source, close } = await resolveCatalogSource({ projectDir });
|
|
53
53
|
try {
|
|
54
54
|
const assets = await source.listAssets();
|
|
@@ -127,5 +127,5 @@ async function gatherAssetFeeds(am, projectDir) {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
export { gatherAssetFeeds };
|
|
130
|
-
//# sourceMappingURL=asset-feeds-
|
|
131
|
-
//# sourceMappingURL=asset-feeds-
|
|
130
|
+
//# sourceMappingURL=asset-feeds-C4X4RTZV.js.map
|
|
131
|
+
//# sourceMappingURL=asset-feeds-C4X4RTZV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-TU5CS6QL.js","sourcesContent":["/**\n * asset-feeds.ts — gather installable assets from every feed the manage TUI\n * surfaces.\n *\n * Four feeds, normalized into `CatalogEntry`:\n * - **Project sources** — `skaile.yaml` `sources:` entries (scanned via\n * `AssetManager.search()`; the new `sources:` field is merged into the\n * legacy repositories map in `AssetManager.loadConfig`).\n * - **Local libraries** — user authoring places from `LocalIndex` (filesystem\n * scan of each library's `path`).\n * - **Factory assets** — the bundled first-party `factory-assets` tree\n * (`factoryAssetRoots()`), scanned from disk. Always present; no network.\n * - **Remote store** — the configured catalog source when `catalog.url` is\n * not `local`. Failures are non-fatal — they surface as notes.\n */\n\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n type AssetKind,\n type CatalogEntry,\n factoryAssetRoots,\n scanRepo,\n} from \"@skaile/workspaces/core\";\n\n/** One non-fatal note returned to the caller for surfacing in the UI. */\nexport interface FeedNote {\n feed: \"sources\" | \"libraries\" | \"store\" | \"factory\";\n message: string;\n}\n\n/**\n * Which feed an asset came from. This is the top-level grouping axis in the\n * manage TUI (\"where is this skill coming from?\") and is intentionally distinct\n * from `publisher` (asset-intrinsic identity): the same publisher can legitimately\n * appear under more than one origin (e.g. a github repo you added as a `source`\n * that is also listed in the remote `store`).\n */\nexport type AssetOrigin = \"source\" | \"library\" | \"factory\" | \"store\";\n\n/** A catalog entry tagged with the feed it was gathered from. */\nexport interface OriginEntry {\n origin: AssetOrigin;\n entry: CatalogEntry;\n /**\n * Second-level grouping label for the manage tree. Defaults (when unset) to the\n * entry's `publisher`; the source feed sets it to the source's short repo name\n * so the Sources band groups by source — \"which repo did this come from\" — not\n * by the asset-intrinsic publisher.\n */\n group?: string;\n}\n\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n notes: FeedNote[];\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/cache/sources/` cache). Each\n * library's `path` is scanned with `scanRepo` and grouped under the bare library\n * name (`group: <name>`) so the manage TUI shows a clean `<name>` band — no\n * `library:` prefix (mirrors the source feed). Plugin grouping (`entry.plugin`)\n * is stamped by `scanRepo`.\n */\nasync function libraryAssets(): Promise<{\n entries: OriginEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { openLibraryManager, authoringLibraries } = await import(\"./open-library.ts\");\n const { manager, close } = await openLibraryManager();\n try {\n // Authoring libraries are the rows that are NOT source clones.\n const libs = authoringLibraries(await manager.listLibraries());\n const entries: OriginEntry[] = [];\n for (const lib of libs) {\n if (!existsSync(lib.path)) continue;\n const libEntries = [...(await scanRepo(lib.path, lib.name))];\n for (const entry of libEntries) entries.push({ origin: \"library\", entry, group: lib.name });\n }\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n notes.push({\n feed: \"libraries\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/**\n * Pull a (best-effort) snapshot of the connected remote store catalog.\n *\n * - Returns no entries when the resolved catalog is local-only or the host\n * is unreachable (the failure becomes a note, not an exception).\n * - Maps `CatalogAsset` → `CatalogEntry`, carrying `publisher`, `repo`, and\n * `category` straight through and using `source = \"store://<id>\"`; per-file\n * `source` paths are not available for remote assets so the canonical ref is\n * a stable placeholder.\n */\nasync function storeAssets(projectDir: string): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { resolveCatalogSource } = await import(\"./open-library.ts\");\n const { source, close } = await resolveCatalogSource({ projectDir });\n try {\n const assets = await source.listAssets();\n const entries: CatalogEntry[] = assets.map((a) => ({\n name: a.name,\n kind: (a.kind as AssetKind) ?? \"skill\",\n description: a.description ?? \"\",\n source: `store://${a.id}`,\n publisher: a.publisher,\n repo: a.repo,\n plugin: a.plugin,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // Local-only catalog throws a recognizable message — silence it; absence\n // is the user's choice, not an error.\n if (!/local/i.test(msg)) {\n notes.push({ feed: \"store\", message: msg });\n }\n return { entries: [], notes };\n }\n}\n\n/** The slice of `AssetManager` the source feed needs (kept narrow for tests). */\ninterface AssetManagerLike {\n search: () => Promise<CatalogEntry[]>;\n searchRepoRoots: () => { repoName: string; root: string }[];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Plugin grouping\n * (`entry.plugin`) is stamped by the scanner, so entries pass through as-is.\n */\nasync function sourceAssets(am: AssetManagerLike): Promise<OriginEntry[]> {\n // The bundled factory tree is injected into the repositories map as an implicit\n // source, so `am.search()` returns it too. It has its own `factory` origin band,\n // so drop it here — otherwise the same first-party skills list twice under Sources.\n const factoryPrefixes = factoryAssetRoots().map((r) => (r.endsWith(path.sep) ? r : r + path.sep));\n const isFactoryPath = (p: string) =>\n factoryPrefixes.some((fp) => p === fp.slice(0, -1) || p.startsWith(fp));\n\n const all = (await am.search()).filter((e) => !isFactoryPath(e.source));\n const entries: OriginEntry[] = [];\n // Group each source's entries under the source node (its short repo name), not\n // the publisher: under Sources the navigational question is \"which repo did\n // this come from\". Each entry's `source` (absolute manifest path) lives under\n // exactly one declared root, so group by prefix. The cache slug is\n // URL-keyed `github.com/<org>/<repo>` — take the trailing segment.\n for (const { repoName, root } of am.searchRepoRoots()) {\n if (isFactoryPath(root)) continue;\n const prefix = root.endsWith(path.sep) ? root : root + path.sep;\n const owned = all.filter((e) => e.source === root || e.source.startsWith(prefix));\n if (owned.length === 0) continue;\n const sourceName = repoName.split(\"/\").pop() || repoName;\n for (const entry of owned) entries.push({ origin: \"source\", entry, group: sourceName });\n }\n return entries;\n}\n\n/**\n * Factory-asset feed: scan the bundled first-party `factory-assets` tree(s)\n * resolved by `factoryAssetRoots()` (the `SKAILE_FACTORY_ASSETS_DIR` override\n * layer ahead of the bundled tree). Local disk only, no network — the entries are\n * the built-in skills / connectors / bundles that ship with `@skaile/workspaces`.\n * `factoryAssetRoots()` already dedupes, so the env override pointing at the\n * bundled dir collapses to one root.\n */\nasync function factoryAssets(): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n entries.push(...(await scanRepo(root, \"skaile-factory\")));\n }\n return { entries, notes };\n } catch (err) {\n notes.push({\n feed: \"factory\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/** Tag a flat entry list with a single origin. */\nfunction tag(origin: AssetOrigin, entries: CatalogEntry[]): OriginEntry[] {\n return entries.map((entry) => ({ origin, entry }));\n}\n\n/**\n * Run all feeds and return a single normalized result.\n *\n * Feeds run in parallel where possible — the store fetch is the slow one\n * (one HTTP call) and is fired alongside the local library walk. The factory\n * scan is local disk only, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: AssetManagerLike,\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = await factoryAssets();\n const src = await sourceAssets(am);\n return {\n entries: [\n ...src,\n ...libs.entries,\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAkEA,eAAe,aAAA,GAGZ;AACD,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,kBAAA,EAAoB,kBAAA,EAAmB,GAAI,MAAM,OAAO,4BAAmB,CAAA;AACnF,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,kBAAA,EAAmB;AACpD,IAAA,IAAI;AAEF,MAAA,MAAM,IAAA,GAAO,kBAAA,CAAmB,MAAM,OAAA,CAAQ,eAAe,CAAA;AAC7D,MAAA,MAAM,UAAyB,EAAC;AAChC,MAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,QAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,EAAG;AAC3B,QAAA,MAAM,UAAA,GAAa,CAAC,GAAI,MAAM,SAAS,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,IAAI,CAAE,CAAA;AAC3D,QAAA,KAAA,MAAW,KAAA,IAAS,UAAA,EAAY,OAAA,CAAQ,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,KAAA,EAAO,GAAA,CAAI,IAAA,EAAM,CAAA;AAAA,MAC5F;AACA,MAAA,OAAO,EAAE,SAAS,KAAA,EAAM;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,KAAA,EAAM;AAAA,IACR;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,WAAA;AAAA,MACN,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,KACzD,CAAA;AACD,IAAA,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,KAAA,EAAM;AAAA,EAC9B;AACF;AAYA,eAAe,YAAY,UAAA,EAGxB;AACD,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,oBAAA,EAAqB,GAAI,MAAM,OAAO,4BAAmB,CAAA;AACjE,IAAA,MAAM,EAAE,QAAQ,KAAA,EAAM,GAAI,MAAM,oBAAA,CAAqB,EAAE,YAAY,CAAA;AACnE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,UAAA,EAAW;AACvC,MAAA,MAAM,OAAA,GAA0B,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,QACjD,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,IAAA,EAAO,EAAE,IAAA,IAAsB,OAAA;AAAA,QAC/B,WAAA,EAAa,EAAE,WAAA,IAAe,EAAA;AAAA,QAC9B,MAAA,EAAQ,CAAA,QAAA,EAAW,CAAA,CAAE,EAAE,CAAA,CAAA;AAAA,QACvB,WAAW,CAAA,CAAE,SAAA;AAAA,QACb,MAAM,CAAA,CAAE,IAAA;AAAA,QACR,QAAQ,CAAA,CAAE,MAAA;AAAA,QACV,UAAU,CAAA,CAAE,QAAA;AAAA,QACZ,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,UAAU,EAAC;AAAA,QACX,cAAc;AAAC,OACjB,CAAE,CAAA;AACF,MAAA,OAAO,EAAE,SAAS,KAAA,EAAM;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,KAAA,EAAM;AAAA,IACR;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,MAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAG3D,IAAA,IAAI,CAAC,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA,EAAG;AACvB,MAAA,KAAA,CAAM,KAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAS,KAAK,CAAA;AAAA,IAC5C;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,KAAA,EAAM;AAAA,EAC9B;AACF;AAaA,eAAe,aAAa,EAAA,EAA8C;AAIxE,EAAA,MAAM,eAAA,GAAkB,iBAAA,EAAkB,CAAE,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAE,QAAA,CAAc,IAAA,CAAA,GAAG,CAAA,GAAI,CAAA,GAAI,CAAA,GAAS,IAAA,CAAA,GAAI,CAAA;AAChG,EAAA,MAAM,gBAAgB,CAAC,CAAA,KACrB,eAAA,CAAgB,IAAA,CAAK,CAAC,EAAA,KAAO,CAAA,KAAM,EAAA,CAAG,KAAA,CAAM,GAAG,EAAE,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,EAAE,CAAC,CAAA;AAExE,EAAA,MAAM,GAAA,GAAA,CAAO,MAAM,EAAA,CAAG,MAAA,EAAO,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,aAAA,CAAc,CAAA,CAAE,MAAM,CAAC,CAAA;AACtE,EAAA,MAAM,UAAyB,EAAC;AAMhC,EAAA,KAAA,MAAW,EAAE,QAAA,EAAU,IAAA,EAAK,IAAK,EAAA,CAAG,iBAAgB,EAAG;AACrD,IAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG;AACzB,IAAA,MAAM,SAAS,IAAA,CAAK,QAAA,CAAc,IAAA,CAAA,GAAG,CAAA,GAAI,OAAO,IAAA,GAAY,IAAA,CAAA,GAAA;AAC5D,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,IAAA,IAAQ,CAAA,CAAE,MAAA,CAAO,UAAA,CAAW,MAAM,CAAC,CAAA;AAChF,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,aAAa,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA,CAAE,KAAI,IAAK,QAAA;AAChD,IAAA,KAAA,MAAW,KAAA,IAAS,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,EAAE,QAAQ,QAAA,EAAU,KAAA,EAAO,KAAA,EAAO,UAAA,EAAY,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,OAAA;AACT;AAUA,eAAe,aAAA,GAGZ;AACD,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,UAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,IAAA,IAAQ,mBAAkB,EAAG;AACtC,MAAA,OAAA,CAAQ,KAAK,GAAI,MAAM,QAAA,CAAS,IAAA,EAAM,gBAAgB,CAAE,CAAA;AAAA,IAC1D;AACA,IAAA,OAAO,EAAE,SAAS,KAAA,EAAM;AAAA,EAC1B,SAAS,GAAA,EAAK;AACZ,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA,EAAM,SAAA;AAAA,MACN,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,KACzD,CAAA;AACD,IAAA,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,KAAA,EAAM;AAAA,EAC9B;AACF;AAGA,SAAS,GAAA,CAAI,QAAqB,OAAA,EAAwC;AACxE,EAAA,OAAO,QAAQ,GAAA,CAAI,CAAC,WAAW,EAAE,MAAA,EAAQ,OAAM,CAAE,CAAA;AACnD;AASA,eAAsB,gBAAA,CACpB,IACA,UAAA,EAC0B;AAC1B,EAAA,MAAM,CAAC,IAAA,EAAM,KAAK,CAAA,GAAI,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,aAAA,EAAc,EAAG,WAAA,CAAY,UAAU,CAAC,CAAC,CAAA;AAClF,EAAA,MAAM,OAAA,GAAU,MAAM,aAAA,EAAc;AACpC,EAAA,MAAM,GAAA,GAAM,MAAM,YAAA,CAAa,EAAE,CAAA;AACjC,EAAA,OAAO;AAAA,IACL,OAAA,EAAS;AAAA,MACP,GAAG,GAAA;AAAA,MACH,GAAG,IAAA,CAAK,OAAA;AAAA,MACR,GAAG,GAAA,CAAI,SAAA,EAAW,OAAA,CAAQ,OAAO,CAAA;AAAA,MACjC,GAAG,GAAA,CAAI,OAAA,EAAS,KAAA,CAAM,OAAO;AAAA,KAC/B;AAAA,IACA,KAAA,EAAO,CAAC,GAAG,IAAA,CAAK,KAAA,EAAO,GAAG,KAAA,CAAM,KAAA,EAAO,GAAG,OAAA,CAAQ,KAAK;AAAA,GACzD;AACF","file":"asset-feeds-C4X4RTZV.js","sourcesContent":["/**\n * asset-feeds.ts — gather installable assets from every feed the manage TUI\n * surfaces.\n *\n * Four feeds, normalized into `CatalogEntry`:\n * - **Project sources** — `skaile.yaml` `sources:` entries (scanned via\n * `AssetManager.search()`; the new `sources:` field is merged into the\n * legacy repositories map in `AssetManager.loadConfig`).\n * - **Local libraries** — user authoring places from `LocalIndex` (filesystem\n * scan of each library's `path`).\n * - **Factory assets** — the bundled first-party `factory-assets` tree\n * (`factoryAssetRoots()`), scanned from disk. Always present; no network.\n * - **Remote store** — the configured catalog source when `catalog.url` is\n * not `local`. Failures are non-fatal — they surface as notes.\n */\n\nimport { existsSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n type AssetKind,\n type CatalogEntry,\n factoryAssetRoots,\n scanRepo,\n} from \"@skaile/workspaces/core\";\n\n/** One non-fatal note returned to the caller for surfacing in the UI. */\nexport interface FeedNote {\n feed: \"sources\" | \"libraries\" | \"store\" | \"factory\";\n message: string;\n}\n\n/**\n * Which feed an asset came from. This is the top-level grouping axis in the\n * manage TUI (\"where is this skill coming from?\") and is intentionally distinct\n * from `publisher` (asset-intrinsic identity): the same publisher can legitimately\n * appear under more than one origin (e.g. a github repo you added as a `source`\n * that is also listed in the remote `store`).\n */\nexport type AssetOrigin = \"source\" | \"library\" | \"factory\" | \"store\";\n\n/** A catalog entry tagged with the feed it was gathered from. */\nexport interface OriginEntry {\n origin: AssetOrigin;\n entry: CatalogEntry;\n /**\n * Second-level grouping label for the manage tree. Defaults (when unset) to the\n * entry's `publisher`; the source feed sets it to the source's short repo name\n * so the Sources band groups by source — \"which repo did this come from\" — not\n * by the asset-intrinsic publisher.\n */\n group?: string;\n}\n\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n notes: FeedNote[];\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/cache/sources/` cache). Each\n * library's `path` is scanned with `scanRepo` and grouped under the bare library\n * name (`group: <name>`) so the manage TUI shows a clean `<name>` band — no\n * `library:` prefix (mirrors the source feed). Plugin grouping (`entry.plugin`)\n * is stamped by `scanRepo`.\n */\nasync function libraryAssets(): Promise<{\n entries: OriginEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { openLibraryManager, authoringLibraries } = await import(\"./open-library.ts\");\n const { manager, close } = await openLibraryManager();\n try {\n // Authoring libraries are the rows that are NOT source clones.\n const libs = authoringLibraries(await manager.listLibraries());\n const entries: OriginEntry[] = [];\n for (const lib of libs) {\n if (!existsSync(lib.path)) continue;\n const libEntries = [...(await scanRepo(lib.path, lib.name))];\n for (const entry of libEntries) entries.push({ origin: \"library\", entry, group: lib.name });\n }\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n notes.push({\n feed: \"libraries\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/**\n * Pull a (best-effort) snapshot of the connected remote store catalog.\n *\n * - Returns no entries when the resolved catalog is local-only or the host\n * is unreachable (the failure becomes a note, not an exception).\n * - Maps `CatalogAsset` → `CatalogEntry`, carrying `publisher`, `repo`, and\n * `category` straight through and using `source = \"store://<id>\"`; per-file\n * `source` paths are not available for remote assets so the canonical ref is\n * a stable placeholder.\n */\nasync function storeAssets(projectDir: string): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const { resolveCatalogSource } = await import(\"./open-library.ts\");\n const { source, close } = await resolveCatalogSource({ projectDir });\n try {\n const assets = await source.listAssets();\n const entries: CatalogEntry[] = assets.map((a) => ({\n name: a.name,\n kind: (a.kind as AssetKind) ?? \"skill\",\n description: a.description ?? \"\",\n source: `store://${a.id}`,\n publisher: a.publisher,\n repo: a.repo,\n plugin: a.plugin,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n return { entries, notes };\n } finally {\n close();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // Local-only catalog throws a recognizable message — silence it; absence\n // is the user's choice, not an error.\n if (!/local/i.test(msg)) {\n notes.push({ feed: \"store\", message: msg });\n }\n return { entries: [], notes };\n }\n}\n\n/** The slice of `AssetManager` the source feed needs (kept narrow for tests). */\ninterface AssetManagerLike {\n search: () => Promise<CatalogEntry[]>;\n searchRepoRoots: () => { repoName: string; root: string }[];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Plugin grouping\n * (`entry.plugin`) is stamped by the scanner, so entries pass through as-is.\n */\nasync function sourceAssets(am: AssetManagerLike): Promise<OriginEntry[]> {\n // The bundled factory tree is injected into the repositories map as an implicit\n // source, so `am.search()` returns it too. It has its own `factory` origin band,\n // so drop it here — otherwise the same first-party skills list twice under Sources.\n const factoryPrefixes = factoryAssetRoots().map((r) => (r.endsWith(path.sep) ? r : r + path.sep));\n const isFactoryPath = (p: string) =>\n factoryPrefixes.some((fp) => p === fp.slice(0, -1) || p.startsWith(fp));\n\n const all = (await am.search()).filter((e) => !isFactoryPath(e.source));\n const entries: OriginEntry[] = [];\n // Group each source's entries under the source node (its short repo name), not\n // the publisher: under Sources the navigational question is \"which repo did\n // this come from\". Each entry's `source` (absolute manifest path) lives under\n // exactly one declared root, so group by prefix. The cache slug is\n // URL-keyed `github.com/<org>/<repo>` — take the trailing segment.\n for (const { repoName, root } of am.searchRepoRoots()) {\n if (isFactoryPath(root)) continue;\n const prefix = root.endsWith(path.sep) ? root : root + path.sep;\n const owned = all.filter((e) => e.source === root || e.source.startsWith(prefix));\n if (owned.length === 0) continue;\n const sourceName = repoName.split(\"/\").pop() || repoName;\n for (const entry of owned) entries.push({ origin: \"source\", entry, group: sourceName });\n }\n return entries;\n}\n\n/**\n * Factory-asset feed: scan the bundled first-party `factory-assets` tree(s)\n * resolved by `factoryAssetRoots()` (the `SKAILE_FACTORY_ASSETS_DIR` override\n * layer ahead of the bundled tree). Local disk only, no network — the entries are\n * the built-in skills / connectors / bundles that ship with `@skaile/workspaces`.\n * `factoryAssetRoots()` already dedupes, so the env override pointing at the\n * bundled dir collapses to one root.\n */\nasync function factoryAssets(): Promise<{\n entries: CatalogEntry[];\n notes: FeedNote[];\n}> {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n entries.push(...(await scanRepo(root, \"skaile-factory\")));\n }\n return { entries, notes };\n } catch (err) {\n notes.push({\n feed: \"factory\",\n message: err instanceof Error ? err.message : String(err),\n });\n return { entries: [], notes };\n }\n}\n\n/** Tag a flat entry list with a single origin. */\nfunction tag(origin: AssetOrigin, entries: CatalogEntry[]): OriginEntry[] {\n return entries.map((entry) => ({ origin, entry }));\n}\n\n/**\n * Run all feeds and return a single normalized result.\n *\n * Feeds run in parallel where possible — the store fetch is the slow one\n * (one HTTP call) and is fired alongside the local library walk. The factory\n * scan is local disk only, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: AssetManagerLike,\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = await factoryAssets();\n const src = await sourceAssets(am);\n return {\n entries: [\n ...src,\n ...libs.entries,\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, NON_DEPLOYABLE_KINDS, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName } from '../chunk-
|
|
1
|
+
export { AssetManager, FACTORY_SOURCE_URL, MissingManifestError, NON_DEPLOYABLE_KINDS, normalizeRepoUrl, parseCanonicalLockKey, parseRefTolerant, renderMcpServerConfig, softDepName } from '../chunk-BEOKEK3B.js';
|
|
2
2
|
import '../chunk-SP47UJKE.js';
|
|
3
3
|
import '../chunk-UVOJSWD2.js';
|
|
4
4
|
import '../chunk-H4EGUQ7M.js';
|
|
@@ -2,10 +2,10 @@ import { formatDroppedToolsNotice, filterInProcessMcpServerTools, checkToolPrope
|
|
|
2
2
|
import { scrubPoisonedTranscript, transcriptStoreForRuntime, resolveClaudeConfigDir, claudeEndpointMode, buildClaudeEndpointEnv } from '../../chunk-TVOODIZE.js';
|
|
3
3
|
import { scopeReconfigureModel } from '../../chunk-EINLFFP6.js';
|
|
4
4
|
import { dispatchCapability } from '../../chunk-RDYI4MML.js';
|
|
5
|
-
import { fetchProviderModels } from '../../chunk-
|
|
5
|
+
import { fetchProviderModels } from '../../chunk-KVAI5DGL.js';
|
|
6
6
|
import { AuthError, stripRunnerPrivateEnv, classifyClaudeSdkError, reclassifyAuthAsAccountUnavailable, AccountUnavailableError, isLongContextEntitlementRejection, LONG_CONTEXT_CREDITS_API_ERROR } from '../../chunk-XBSQ4KMC.js';
|
|
7
7
|
import { agentExecRequested, wrapAgentCommand, resolveAgentExec } from '../../chunk-YROR332M.js';
|
|
8
|
-
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger, entryCredentialValue, registryDriverConfig } from '../../chunk-
|
|
8
|
+
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger, entryCredentialValue, registryDriverConfig } from '../../chunk-ZD7CX25M.js';
|
|
9
9
|
import '../../chunk-6E6PKKAD.js';
|
|
10
10
|
import { withActivityLabelShape } from '../../chunk-IDEA6CYI.js';
|
|
11
11
|
import '../../chunk-IWCCZL7C.js';
|
|
@@ -414,6 +414,43 @@ var MODEL_USAGE_COUNTERS = [
|
|
|
414
414
|
["cacheCreationTokens", "cacheCreationInputTokens"],
|
|
415
415
|
["costUsd", "costUSD"]
|
|
416
416
|
];
|
|
417
|
+
var USAGE_COUNTERS = [
|
|
418
|
+
"inputTokens",
|
|
419
|
+
"outputTokens",
|
|
420
|
+
"cacheReadTokens",
|
|
421
|
+
"cacheCreationTokens",
|
|
422
|
+
"reasoningTokens",
|
|
423
|
+
"totalTokens"
|
|
424
|
+
];
|
|
425
|
+
function addTokens(a, b) {
|
|
426
|
+
const sum = { ...a, ...b };
|
|
427
|
+
for (const key of USAGE_COUNTERS) {
|
|
428
|
+
if (typeof a[key] === "number" && typeof b[key] === "number") {
|
|
429
|
+
sum[key] = a[key] + b[key];
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return sum;
|
|
433
|
+
}
|
|
434
|
+
function addAttemptUsage(event, earlier) {
|
|
435
|
+
const out = {};
|
|
436
|
+
if (typeof event.costUsd === "number" || typeof earlier.costUsd === "number") {
|
|
437
|
+
out.costUsd = (event.costUsd ?? 0) + (earlier.costUsd ?? 0);
|
|
438
|
+
}
|
|
439
|
+
if (event.tokens || earlier.tokens)
|
|
440
|
+
out.tokens = addTokens(event.tokens ?? {}, earlier.tokens ?? {});
|
|
441
|
+
if (event.modelUsage || earlier.modelUsage) {
|
|
442
|
+
const merged = { ...event.modelUsage };
|
|
443
|
+
for (const [model, usage] of Object.entries(earlier.modelUsage ?? {})) {
|
|
444
|
+
const current = merged[model];
|
|
445
|
+
merged[model] = current ? {
|
|
446
|
+
...addTokens(current, usage),
|
|
447
|
+
...typeof current.costUsd === "number" || typeof usage.costUsd === "number" ? { costUsd: (current.costUsd ?? 0) + (usage.costUsd ?? 0) } : {}
|
|
448
|
+
} : usage;
|
|
449
|
+
}
|
|
450
|
+
out.modelUsage = merged;
|
|
451
|
+
}
|
|
452
|
+
return out;
|
|
453
|
+
}
|
|
417
454
|
function diffModelUsage(current, previous) {
|
|
418
455
|
const out = {};
|
|
419
456
|
for (const [model, usage] of Object.entries(current)) {
|
|
@@ -617,6 +654,18 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
617
654
|
* promise) rather than also drawing the runner's fatal "prompt failed".
|
|
618
655
|
*/
|
|
619
656
|
limitTurnRejectedForFailover = false;
|
|
657
|
+
/**
|
|
658
|
+
* The error `result` of an attempt rejected for a seat failover, held back
|
|
659
|
+
* like the error event: a host normalizes it into a fatal "Agent stopped"
|
|
660
|
+
* error, which a replayed turn must not show. Emitted only if the turn is
|
|
661
|
+
* not replayed after all.
|
|
662
|
+
*/
|
|
663
|
+
heldFailoverResult = null;
|
|
664
|
+
/**
|
|
665
|
+
* What a replayed failover attempt billed. Its `result` is dropped, so the
|
|
666
|
+
* replay's own `result` carries this too; seat A's spend is otherwise lost.
|
|
667
|
+
*/
|
|
668
|
+
failoverUsageCarry = null;
|
|
620
669
|
/**
|
|
621
670
|
* Whether this attempt already reported a provider rejection. One upstream
|
|
622
671
|
* failure routinely reaches the driver twice — `rejected` telemetry followed
|
|
@@ -896,12 +945,14 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
896
945
|
this.longContextRejectionLogged = false;
|
|
897
946
|
this.lastLimitInfo = null;
|
|
898
947
|
this.deferredTurnError = null;
|
|
948
|
+
this.heldFailoverResult = null;
|
|
899
949
|
let retrying = false;
|
|
900
950
|
const isFirstAttempt = !_budget.staleResume && !_budget.poison && !_budget.auth && !_budget.queryEnded && !_budget.limit;
|
|
901
951
|
if (isFirstAttempt) {
|
|
902
952
|
this._lastTokens = null;
|
|
903
953
|
this._lastContextTokens = null;
|
|
904
954
|
this._lastModelUsage = null;
|
|
955
|
+
this.failoverUsageCarry = null;
|
|
905
956
|
}
|
|
906
957
|
this.running = true;
|
|
907
958
|
this.prevText = "";
|
|
@@ -969,9 +1020,13 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
969
1020
|
if (await this.attemptLimitFailover(err)) {
|
|
970
1021
|
if (this.abortController?.signal.aborted) {
|
|
971
1022
|
this.log.info("aborted during the seat failover; not replaying the prompt");
|
|
1023
|
+
this.emitHeldFailoverResult();
|
|
972
1024
|
this.emitAgentEnd();
|
|
973
1025
|
return;
|
|
974
1026
|
}
|
|
1027
|
+
const held = this.heldFailoverResult;
|
|
1028
|
+
if (held) this.failoverUsageCarry = addAttemptUsage(held, this.failoverUsageCarry ?? {});
|
|
1029
|
+
this.heldFailoverResult = null;
|
|
975
1030
|
this.retractUnfinishedText();
|
|
976
1031
|
retrying = true;
|
|
977
1032
|
return this.runPrompt(message, { ..._budget, limit: true });
|
|
@@ -994,6 +1049,8 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
994
1049
|
this.limitTurnRejectedForFailover = false;
|
|
995
1050
|
this.lastLimitInfo = null;
|
|
996
1051
|
this.deferredTurnError = null;
|
|
1052
|
+
this.heldFailoverResult = null;
|
|
1053
|
+
this.failoverUsageCarry = null;
|
|
997
1054
|
this.suppressedAuthRenderText = null;
|
|
998
1055
|
this.lastApiErrorRender = null;
|
|
999
1056
|
}
|
|
@@ -1456,6 +1513,7 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
1456
1513
|
this.log.info("no alternative AI provider config available; surfacing the limit error", {
|
|
1457
1514
|
reason: outcome?.reason
|
|
1458
1515
|
});
|
|
1516
|
+
this.emitHeldFailoverResult();
|
|
1459
1517
|
const detail = err?.detail;
|
|
1460
1518
|
this.emitDeferredTurnError({
|
|
1461
1519
|
type: "error",
|
|
@@ -2222,6 +2280,26 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
2222
2280
|
});
|
|
2223
2281
|
}
|
|
2224
2282
|
}
|
|
2283
|
+
/** Fold a replayed failover attempt's usage into the `result` that ends the turn, once. */
|
|
2284
|
+
withFailoverUsage(event) {
|
|
2285
|
+
const carry = this.failoverUsageCarry;
|
|
2286
|
+
if (!carry) return event;
|
|
2287
|
+
this.failoverUsageCarry = null;
|
|
2288
|
+
return { ...event, ...addAttemptUsage(event, carry) };
|
|
2289
|
+
}
|
|
2290
|
+
/** Emit the result {@link handleErrorResult} held for a failover that did not replay. */
|
|
2291
|
+
emitHeldFailoverResult() {
|
|
2292
|
+
const event = this.heldFailoverResult;
|
|
2293
|
+
this.heldFailoverResult = null;
|
|
2294
|
+
if (!event) return;
|
|
2295
|
+
try {
|
|
2296
|
+
this.emit("agent-event", event);
|
|
2297
|
+
} catch (emitErr) {
|
|
2298
|
+
this.log.warn("agent-event listener threw while surfacing a held result; suppressing", {
|
|
2299
|
+
error: emitErr instanceof Error ? emitErr.message : String(emitErr)
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2225
2303
|
/**
|
|
2226
2304
|
* Emit the error {@link failTurn} withheld, exactly once. Called by a
|
|
2227
2305
|
* recovery path that decided NOT to retry, so every failure produces one
|
|
@@ -2613,14 +2691,17 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
2613
2691
|
};
|
|
2614
2692
|
this.emit("agent-event", { type: "message_end", message: agentMsg });
|
|
2615
2693
|
}
|
|
2616
|
-
this.emit(
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2694
|
+
this.emit(
|
|
2695
|
+
"agent-event",
|
|
2696
|
+
this.withFailoverUsage({
|
|
2697
|
+
type: "result",
|
|
2698
|
+
subtype: msg.subtype,
|
|
2699
|
+
summary: result ?? "Task completed",
|
|
2700
|
+
costUsd: this._lastTurnCostUsd,
|
|
2701
|
+
...this._lastTokens ? { tokens: this._lastTokens } : {},
|
|
2702
|
+
...this.turnUsageFields()
|
|
2703
|
+
})
|
|
2704
|
+
);
|
|
2624
2705
|
}
|
|
2625
2706
|
/**
|
|
2626
2707
|
* Handle the non-clean branch (legacy `SDKResultError`, or a `success`
|
|
@@ -2632,14 +2713,19 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
2632
2713
|
const looseMsg = msg;
|
|
2633
2714
|
const errors = looseMsg.errors?.length ? looseMsg.errors : [];
|
|
2634
2715
|
if (looseMsg.is_error && this.handleResultErrorPayload(msg, errors)) return;
|
|
2635
|
-
|
|
2716
|
+
const resultEvent = {
|
|
2636
2717
|
type: "result",
|
|
2637
2718
|
subtype: msg.subtype,
|
|
2638
2719
|
errors,
|
|
2639
2720
|
...this._lastCostReported ? { costUsd: this._lastTurnCostUsd } : {},
|
|
2640
2721
|
...this._lastTokens ? { tokens: this._lastTokens } : {},
|
|
2641
2722
|
...this.turnUsageFields()
|
|
2642
|
-
}
|
|
2723
|
+
};
|
|
2724
|
+
if (this.limitTurnRejectedForFailover) {
|
|
2725
|
+
this.heldFailoverResult = resultEvent;
|
|
2726
|
+
} else {
|
|
2727
|
+
this.emit("agent-event", this.withFailoverUsage(resultEvent));
|
|
2728
|
+
}
|
|
2643
2729
|
const awaitingFollowUpThrow = looseMsg.is_error === true && errors.length === 0;
|
|
2644
2730
|
if (!this.turnCompleted && !awaitingFollowUpThrow) {
|
|
2645
2731
|
this.completeTurn();
|