@skaile/workspaces 0.41.5 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -0
- package/dist/{asset-feeds-FKD5AB2R.js → asset-feeds-UPJJGR3O.js} +8 -8
- package/dist/{asset-feeds-FKD5AB2R.js.map → asset-feeds-UPJJGR3O.js.map} +1 -1
- package/dist/asset-manager/index.js +6 -6
- package/dist/asset-manager/installer.js +5 -5
- package/dist/bridge/drivers/claude-sdk.js +112 -7
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +1 -1
- package/dist/bridge/drivers/continue.js +2 -2
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/gemini.js +3 -3
- package/dist/bridge/drivers/goose.js +2 -2
- package/dist/bridge/drivers/omp.js +1 -1
- package/dist/bridge/drivers/opencode.js +2 -2
- package/dist/bridge/drivers/qwen.js +3 -3
- package/dist/bridge/index.js +2 -2
- package/dist/bridge/src/drivers/claude-sdk.d.ts +6 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts +53 -0
- package/dist/bridge/src/drivers/sanitize-assistant-text.d.ts.map +1 -0
- package/dist/{chunk-J4RF5ABK.js → chunk-2BEDUMTA.js} +3 -3
- package/dist/{chunk-J4RF5ABK.js.map → chunk-2BEDUMTA.js.map} +1 -1
- package/dist/{chunk-IODU6UDT.js → chunk-2MVQ7UAT.js} +2 -2
- package/dist/{chunk-IODU6UDT.js.map → chunk-2MVQ7UAT.js.map} +1 -1
- package/dist/{chunk-5VJVSYXX.js → chunk-3HUUP3JC.js} +41 -3
- package/dist/chunk-3HUUP3JC.js.map +1 -0
- package/dist/{chunk-SBGHNXJD.js → chunk-3K2CYDBT.js} +17 -7
- package/dist/chunk-3K2CYDBT.js.map +1 -0
- package/dist/{chunk-ACB3AOII.js → chunk-4MO456BV.js} +5 -5
- package/dist/{chunk-ACB3AOII.js.map → chunk-4MO456BV.js.map} +1 -1
- package/dist/{chunk-5IXCNMMU.js → chunk-5C3QJSOD.js} +3 -3
- package/dist/{chunk-5IXCNMMU.js.map → chunk-5C3QJSOD.js.map} +1 -1
- package/dist/{chunk-B5PEERRZ.js → chunk-6IDBWPK2.js} +7 -4
- package/dist/chunk-6IDBWPK2.js.map +1 -0
- package/dist/{chunk-TNYWP6EQ.js → chunk-7I4IBYHE.js} +6 -6
- package/dist/{chunk-TNYWP6EQ.js.map → chunk-7I4IBYHE.js.map} +1 -1
- package/dist/{chunk-3KX5W3ZU.js → chunk-7WLJW457.js} +4 -4
- package/dist/{chunk-3KX5W3ZU.js.map → chunk-7WLJW457.js.map} +1 -1
- package/dist/{chunk-ZJ27BHIH.js → chunk-BXYMGZCI.js} +3 -3
- package/dist/{chunk-ZJ27BHIH.js.map → chunk-BXYMGZCI.js.map} +1 -1
- package/dist/{chunk-2JCUYKUN.js → chunk-G6FJZG4C.js} +2 -2
- package/dist/{chunk-2JCUYKUN.js.map → chunk-G6FJZG4C.js.map} +1 -1
- package/dist/{chunk-NQDJQ7WB.js → chunk-GJI6FZ56.js} +8 -4
- package/dist/chunk-GJI6FZ56.js.map +1 -0
- package/dist/{chunk-JAOXG3LL.js → chunk-HVCZLD5Z.js} +4 -4
- package/dist/{chunk-JAOXG3LL.js.map → chunk-HVCZLD5Z.js.map} +1 -1
- package/dist/{chunk-MO2VGW6U.js → chunk-K5TROTFK.js} +3 -3
- package/dist/{chunk-MO2VGW6U.js.map → chunk-K5TROTFK.js.map} +1 -1
- package/dist/{chunk-MVXXAXDW.js → chunk-KYQNWFJV.js} +3 -3
- package/dist/{chunk-MVXXAXDW.js.map → chunk-KYQNWFJV.js.map} +1 -1
- package/dist/{chunk-KM6DCR7A.js → chunk-OCAQH66V.js} +2 -2
- package/dist/{chunk-KM6DCR7A.js.map → chunk-OCAQH66V.js.map} +1 -1
- package/dist/{chunk-X4FCLBI7.js → chunk-R4H6EJW5.js} +7 -5
- package/dist/chunk-R4H6EJW5.js.map +1 -0
- package/dist/{chunk-U3TV7SRR.js → chunk-RSK6FDMV.js} +3 -3
- package/dist/{chunk-U3TV7SRR.js.map → chunk-RSK6FDMV.js.map} +1 -1
- package/dist/{chunk-TB342H55.js → chunk-SURALYSM.js} +4 -4
- package/dist/{chunk-TB342H55.js.map → chunk-SURALYSM.js.map} +1 -1
- package/dist/{chunk-2ZI2FFFN.js → chunk-U3RYXSI4.js} +188 -76
- package/dist/chunk-U3RYXSI4.js.map +1 -0
- package/dist/{chunk-JILPU5VI.js → chunk-VGAHSWDE.js} +98 -50
- package/dist/chunk-VGAHSWDE.js.map +1 -0
- package/dist/{chunk-4NZD7423.js → chunk-WJ3RP2FS.js} +3 -3
- package/dist/{chunk-4NZD7423.js.map → chunk-WJ3RP2FS.js.map} +1 -1
- package/dist/{chunk-4ZACMAT3.js → chunk-Z3GAAIJK.js} +4 -4
- package/dist/{chunk-4ZACMAT3.js.map → chunk-Z3GAAIJK.js.map} +1 -1
- package/dist/cli/index.js +34 -34
- package/dist/connectors/config.js +5 -5
- package/dist/connectors/index.js +7 -7
- package/dist/connectors/rclone.js +1 -1
- package/dist/connectors/src/connector-manager.d.ts +13 -0
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-types.d.ts +26 -0
- package/dist/connectors/src/connector-types.d.ts.map +1 -1
- package/dist/connectors/src/fleet-health-gate.d.ts +53 -36
- package/dist/connectors/src/fleet-health-gate.d.ts.map +1 -1
- package/dist/connectors/src/fleet-utils.d.ts +11 -2
- package/dist/connectors/src/fleet-utils.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +3 -3
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors/src/materialized-connectors.d.ts.map +1 -1
- package/dist/connectors/src/mount-placeholder.d.ts +19 -0
- package/dist/connectors/src/mount-placeholder.d.ts.map +1 -1
- package/dist/connectors/src/rclone-process-manager.d.ts +36 -2
- package/dist/connectors/src/rclone-process-manager.d.ts.map +1 -1
- package/dist/core/index.js +4 -4
- package/dist/core/manifest.js +1 -1
- package/dist/core/runtime-assets.js +3 -3
- package/dist/core/src/index.d.ts +1 -1
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/manifest.d.ts +11 -0
- package/dist/core/src/manifest.d.ts.map +1 -1
- package/dist/core/src/workspace-config.d.ts +2 -0
- package/dist/core/src/workspace-config.d.ts.map +1 -1
- package/dist/core/workspace-config.js +2 -2
- package/dist/deploy/index.js +4 -4
- package/dist/discovery/index.js +2 -2
- package/dist/{ensure-sources-EWK7EXKN.js → ensure-sources-TZHDV3BF.js} +8 -8
- package/dist/{ensure-sources-EWK7EXKN.js.map → ensure-sources-TZHDV3BF.js.map} +1 -1
- package/dist/factory-assets/connectors/deploy.js +7 -7
- package/dist/factory-assets/connectors/devserver.js +7 -7
- package/dist/factory-assets/connectors/flow/adapter.js +7 -7
- package/dist/factory-assets/connectors/flow/engine.js +4 -4
- package/dist/factory-assets/connectors/flow/run-flow.js +8 -8
- package/dist/factory-assets/connectors/flow.js +7 -7
- package/dist/factory-assets/connectors/git.js +7 -7
- package/dist/factory-assets/connectors/gmail.js +7 -7
- package/dist/factory-assets/connectors/googledrive/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/googledrive.js +7 -7
- package/dist/factory-assets/connectors/local.js +7 -7
- package/dist/factory-assets/connectors/mattermost.js +7 -7
- package/dist/factory-assets/connectors/memory.js +7 -7
- package/dist/factory-assets/connectors/minio.js +7 -7
- package/dist/factory-assets/connectors/postgres.js +7 -7
- package/dist/factory-assets/connectors/s3.js +7 -7
- package/dist/factory-assets/connectors/sharepoint/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sharepoint.js +7 -7
- package/dist/factory-assets/connectors/sqlite.js +7 -7
- package/dist/factory-assets/connectors/static-server.js +7 -7
- package/dist/factory-assets/connectors/tunnel.js +7 -7
- package/dist/factory-assets/connectors/webdav/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/webdav.js +7 -7
- package/dist/factory-assets/connectors/xstate-store.js +7 -7
- package/dist/factory-assets/connectors/xstate.js +7 -7
- package/dist/{flows-3MBK2PDN.js → flows-KTBCZ5GQ.js} +3 -3
- package/dist/{flows-3MBK2PDN.js.map → flows-KTBCZ5GQ.js.map} +1 -1
- package/dist/library/index.js +6 -6
- package/dist/library/install.js +4 -4
- package/dist/{open-library-QSIPFN5N.js → open-library-EV7UCOFU.js} +9 -9
- package/dist/{open-library-QSIPFN5N.js.map → open-library-EV7UCOFU.js.map} +1 -1
- package/dist/{paths-KNLBYALO.js → paths-7H5CSBLQ.js} +7 -7
- package/dist/{paths-KNLBYALO.js.map → paths-7H5CSBLQ.js.map} +1 -1
- package/dist/{plugin-store-CL6CTREE.js → plugin-store-LGLN2QUX.js} +6 -6
- package/dist/{plugin-store-CL6CTREE.js.map → plugin-store-LGLN2QUX.js.map} +1 -1
- package/dist/runner/index.js +11 -11
- package/dist/runner/src/fleet-health-flag-dispatcher.d.ts +3 -2
- package/dist/runner/src/fleet-health-flag-dispatcher.d.ts.map +1 -1
- package/dist/runner/src/mcp-prompt.d.ts +8 -0
- package/dist/runner/src/mcp-prompt.d.ts.map +1 -0
- package/dist/runner/src/resource-handler.d.ts +1 -7
- package/dist/runner/src/resource-handler.d.ts.map +1 -1
- package/dist/runner/src/resources.d.ts +6 -0
- package/dist/runner/src/resources.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +8 -2
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/runner/src/session-builder.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +6 -6
- package/dist/sdk/bridge.js +2 -2
- package/dist/sdk/core.js +4 -4
- package/dist/sdk/flow.js +4 -4
- package/dist/sdk/index.js +11 -11
- package/dist/sdk/runner.js +11 -11
- package/dist/sdk/session.js +1 -1
- package/dist/session/index.js +1 -1
- package/dist/session/src/dispatcher.d.ts +8 -0
- package/dist/session/src/dispatcher.d.ts.map +1 -1
- package/dist/{setup-345XOCH3.js → setup-EVNPECSY.js} +8 -8
- package/dist/{setup-345XOCH3.js.map → setup-EVNPECSY.js.map} +1 -1
- package/dist/{store-client-W3HKRE46.js → store-client-4XN7IB3R.js} +7 -7
- package/dist/{store-client-W3HKRE46.js.map → store-client-4XN7IB3R.js.map} +1 -1
- package/dist/tui/index.js +11 -11
- package/dist/types/src/events.d.ts +1 -1
- package/dist/types/src/events.d.ts.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +1 -1
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2ZI2FFFN.js.map +0 -1
- package/dist/chunk-5VJVSYXX.js.map +0 -1
- package/dist/chunk-B5PEERRZ.js.map +0 -1
- package/dist/chunk-JILPU5VI.js.map +0 -1
- package/dist/chunk-NQDJQ7WB.js.map +0 -1
- package/dist/chunk-SBGHNXJD.js.map +0 -1
- package/dist/chunk-X4FCLBI7.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,90 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.42.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#187](https://github.com/skaile-ai/workspaces/pull/187) [`67b88c7`](https://github.com/skaile-ai/workspaces/commit/67b88c75be6ef0aae6a20f28e62de412c7a998d1) Thanks [@peteralbert](https://github.com/peteralbert)! - Runner reads CONNECTOR.md/MCP.md body and injects preset custom instructions into the agent system prompt. `ConnectorDeclaration` and `McpServerDeclaration` gain an optional `instructions` field populated from the materialized markdown body. Connector instructions are emitted eagerly in the `## Connectors` system-prompt section; MCP server instructions in a new `## MCP server guidance` section. When the body is empty (today's platform output) no block is added — safe to ship ahead of the platform side.
|
|
8
|
+
|
|
9
|
+
- [#186](https://github.com/skaile-ai/workspaces/pull/186) [`83c7f9c`](https://github.com/skaile-ai/workspaces/commit/83c7f9c4651aea27df0db220f4e9ff9ce80be89a) Thanks [@peteralbert](https://github.com/peteralbert)! - Fix the rclone VFS stale-tail read bug at the source ([#183](https://github.com/skaile-ai/workspaces/issues/183)). A writable
|
|
10
|
+
rclone-backed mount (SharePoint / OneDrive / WebDAV / Google Drive) can serve a
|
|
11
|
+
**non-truncated** VFS cache item after a remote file is replaced by a _shorter_
|
|
12
|
+
version: the read returns `[new bytes][leftover tail of the older, longer
|
|
13
|
+
version]`, and `statSync` reports the inflated size, so the on-disk length is no
|
|
14
|
+
signal. This used to be masked by the `text/html` `</html>`-truncation heuristic
|
|
15
|
+
removed in 0.41.6.
|
|
16
|
+
|
|
17
|
+
The read path now gates the served bytes against the **authoritative remote
|
|
18
|
+
size** instead of any content heuristic:
|
|
19
|
+
|
|
20
|
+
- `RcloneProcessManager.statSize(handle, relPath)` queries the `operations/stat`
|
|
21
|
+
rc endpoint, which resolves the object against the backend directly and so
|
|
22
|
+
returns the true remote size, bypassing the VFS cache. New exported helpers
|
|
23
|
+
`fetchAuthoritativeSize` (and the internal `_operationsStatTarget`) back it.
|
|
24
|
+
- The `sharepoint` / `webdav` / `googledrive` connectors attach an
|
|
25
|
+
`authoritativeSize(relPath)` hook (new `AuthoritativeSizeProvider` type) to
|
|
26
|
+
their `ConnectorHandle.state`, wired to `statSize`.
|
|
27
|
+
- `handleMountResourceRequest` (now async) duck-types that hook and truncates
|
|
28
|
+
the read to the authoritative size — slicing the Buffer _before_ any utf-8
|
|
29
|
+
decode, so multibyte content is never split mid-character. Absent hook (local
|
|
30
|
+
mounts) or `null` (object missing / rc call failed) ⇒ on-disk bytes served
|
|
31
|
+
unchanged.
|
|
32
|
+
|
|
33
|
+
Other candidate fixes were rejected: `vfs/forget` + re-read (re-downloads on
|
|
34
|
+
every changed read), tuning `--vfs-cache-mode`/`--dir-cache-time` (per-read
|
|
35
|
+
latency, doesn't address the non-truncation), and write-path `O_TRUNC` (our
|
|
36
|
+
write path already truncates via FUSE; the bug is on remote-side rewrites).
|
|
37
|
+
Fleet-managed mounts have no in-container rc server, so the host fleet remains
|
|
38
|
+
responsible for their invalidation — a documented follow-up.
|
|
39
|
+
|
|
40
|
+
All additions are new exports; no public surface was removed.
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- [#189](https://github.com/skaile-ai/workspaces/pull/189) [`81e2da1`](https://github.com/skaile-ai/workspaces/commit/81e2da1a8a1cce5ebca4252afa4e7e2366e1da64) Thanks [@peteralbert](https://github.com/peteralbert)! - Fleet read-only mount barrier now tracks the actual mount state across three surfaces instead of two. A `healthy` fleet-health verdict lifts the connect-time not-ready barrier (previously a late-arriving live bind that propagated under the barrier stayed masked even after it went healthy), and a connector that only had the static boot-time barrier is promoted to a health gate when a fleet verdict arrives, so the authoritative platform signal can lift it. A new `degraded` verdict (live and readable but writes failing) downgrades the barrier to a read-only-readable surface — the live content stays visible while writes are blocked — via the new `MountPlaceholderBarrier.exposeReadOnly` (read-only self-bind, chmod fallback) instead of masking the whole workspace with an opaque tmpfs. The not-live/unreadable `error` verdict keeps the opaque mask. The fleet-health flag dispatcher forwards `degraded` distinctly rather than collapsing it to `error`.
|
|
45
|
+
|
|
46
|
+
- [#190](https://github.com/skaile-ai/workspaces/pull/190) [`b862087`](https://github.com/skaile-ai/workspaces/commit/b8620870f88876cd4fbd023896aecf18a12b31f8) Thanks [@peteralbert](https://github.com/peteralbert)! - Stop an agent assistant message from swallowing the conversation ([#841](https://github.com/skaile-ai/workspaces/issues/841)). A
|
|
47
|
+
single agent `text` block could run three things together: verbatim
|
|
48
|
+
`[function_calls]…[invoke name="Bash"]…[/antml:invoke]` tool-call XML (the same call
|
|
49
|
+
was _also_ executed as a structured tool_use), the genuine answer, and a
|
|
50
|
+
hallucinated `[User]: "…"` follow-up turn — so the user's real next message
|
|
51
|
+
never became its own prompt and the chat looked garbled.
|
|
52
|
+
|
|
53
|
+
Two-part fix:
|
|
54
|
+
|
|
55
|
+
- **Prompt shape (primary).** `enrichPromptWithHistory` (session dispatcher) no
|
|
56
|
+
longer renders prior turns as a bare `[User]:` / `[Assistant]:` transcript,
|
|
57
|
+
which the model latched onto and auto-completed. History is now emitted as
|
|
58
|
+
read-only `<turn role="…">…</turn>` elements inside `<conversation_history>`
|
|
59
|
+
with an explicit "do not continue this — it is context, not a turn to extend"
|
|
60
|
+
instruction, removing the completion affordance.
|
|
61
|
+
|
|
62
|
+
- **Emit-point sanitizer (defense-in-depth).** A new pure
|
|
63
|
+
`sanitizeAssistantText` (bridge, beside `scrub-transcript.ts`) strips leaked
|
|
64
|
+
`[function_calls]…[/function_calls]` / `[invoke]…[/antml:invoke]` blocks and trailing
|
|
65
|
+
fabricated `[User]:` / `[Assistant]:` role turns from assistant text before it
|
|
66
|
+
is emitted/persisted. It is conservative — only clearly-leaked control markup
|
|
67
|
+
is removed; mid-prose bracketed text survives. It runs at every claude-sdk
|
|
68
|
+
emit point that produces durable assistant text: the final `result.summary`
|
|
69
|
+
(the single persisted copy of the answer), per-text-block mapping, and the
|
|
70
|
+
streaming path. For streaming, `streamingSafeSanitize` holds back any trailing
|
|
71
|
+
partial marker and the forwarded `_textDelta` carries the sanitized suffix, so
|
|
72
|
+
a marker split across deltas is never half-emitted into the stored transcript.
|
|
73
|
+
|
|
74
|
+
## 0.41.6
|
|
75
|
+
|
|
76
|
+
### Patch Changes
|
|
77
|
+
|
|
78
|
+
- [#184](https://github.com/skaile-ai/workspaces/pull/184) [`44476f0`](https://github.com/skaile-ai/workspaces/commit/44476f0b3b5882703080da1b2d0bd6078576fc3f) Thanks [@peteralbert](https://github.com/peteralbert)! - runner: stop truncating mount HTML reads at a `</html>` substring. The
|
|
79
|
+
`stripStaleHtmlTail` heuristic cut content at the first `</html>`, which broke any
|
|
80
|
+
legitimate document containing the literal `</html>` (inside a script string, text,
|
|
81
|
+
or example) before its real end. Mount HTML is now served verbatim. The rare
|
|
82
|
+
rclone-VFS stale-tail artifact this guarded against is tracked separately and must be
|
|
83
|
+
fixed at the cache layer (read by authoritative remote size / cache invalidation),
|
|
84
|
+
not by closing-tag string surgery.
|
|
85
|
+
|
|
86
|
+
- [#182](https://github.com/skaile-ai/workspaces/pull/182) [`74b10b3`](https://github.com/skaile-ai/workspaces/commit/74b10b382bc8f3a1229004c31f12639a8c2c00ac) Thanks [@peteralbert](https://github.com/peteralbert)! - fix(runner): report declared/cold-start MCP servers as `live` on the claude-sdk driver so the platform stops showing a false "restart" badge; only servers hot-added to an unrecreated claude-sdk driver stay `live:false`.
|
|
87
|
+
|
|
3
88
|
## 0.41.5
|
|
4
89
|
|
|
5
90
|
### Patch Changes
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import './chunk-
|
|
1
|
+
import './chunk-KYQNWFJV.js';
|
|
2
2
|
import './chunk-ZAP2BDHG.js';
|
|
3
|
-
import { factoryAssetRoots } from './chunk-
|
|
4
|
-
import { scanRepo } from './chunk-
|
|
3
|
+
import { factoryAssetRoots } from './chunk-HVCZLD5Z.js';
|
|
4
|
+
import { scanRepo } from './chunk-GJI6FZ56.js';
|
|
5
5
|
import './chunk-DZCK7GRW.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-6IDBWPK2.js';
|
|
7
7
|
import './chunk-GEEW6SY2.js';
|
|
8
8
|
import './chunk-XGCXFX7X.js';
|
|
9
9
|
import './chunk-O4JH3KUE.js';
|
|
@@ -17,7 +17,7 @@ async function libraryAssets() {
|
|
|
17
17
|
const notes = [];
|
|
18
18
|
try {
|
|
19
19
|
const [{ openLibraryManager }, { skaileHomeDir }] = await Promise.all([
|
|
20
|
-
import('./open-library-
|
|
20
|
+
import('./open-library-EV7UCOFU.js'),
|
|
21
21
|
import('./library/index.js')
|
|
22
22
|
]);
|
|
23
23
|
const { manager, close } = await openLibraryManager();
|
|
@@ -46,7 +46,7 @@ async function libraryAssets() {
|
|
|
46
46
|
async function storeAssets(projectDir) {
|
|
47
47
|
const notes = [];
|
|
48
48
|
try {
|
|
49
|
-
const { resolveCatalogSource } = await import('./open-library-
|
|
49
|
+
const { resolveCatalogSource } = await import('./open-library-EV7UCOFU.js');
|
|
50
50
|
const { source, close } = await resolveCatalogSource({ projectDir });
|
|
51
51
|
try {
|
|
52
52
|
const assets = await source.listAssets();
|
|
@@ -120,5 +120,5 @@ async function gatherAssetFeeds(am, projectDir) {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
export { gatherAssetFeeds };
|
|
123
|
-
//# sourceMappingURL=asset-feeds-
|
|
124
|
-
//# sourceMappingURL=asset-feeds-
|
|
123
|
+
//# sourceMappingURL=asset-feeds-UPJJGR3O.js.map
|
|
124
|
+
//# sourceMappingURL=asset-feeds-UPJJGR3O.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-FKD5AB2R.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 CatalogDomain,\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\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n /**\n * Display-only domain metadata, keyed (by the consumer) on `slug`. Populated\n * from the store's `catalog.listDomains` when the connected catalog source\n * exposes it; empty otherwise. The manage TUI joins `entry.domainSlug` → a\n * domain for grouping headers, descriptions, and relation badges.\n */\n domains: CatalogDomain[];\n notes: FeedNote[];\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/sources/` cache). Each\n * library's `path` is scanned with `scanRepo` and tagged with\n * `repository = \"library:<name>\"` so the manage TUI groups them into their\n * own headers.\n */\nasync function libraryAssets(): Promise<{ entries: CatalogEntry[]; notes: FeedNote[] }> {\n const notes: FeedNote[] = [];\n try {\n const [{ openLibraryManager }, { skaileHomeDir }] = await Promise.all([\n import(\"./open-library.ts\"),\n import(\"@skaile/workspaces/library\"),\n ]);\n const { manager, close } = await openLibraryManager();\n try {\n const sourcesDir = path.join(skaileHomeDir(), \"sources\");\n const libs = (await manager.listLibraries()).filter((l) => !l.path.startsWith(sourcesDir));\n const entries: CatalogEntry[] = [];\n for (const lib of libs) {\n if (!existsSync(lib.path)) continue;\n for (const e of scanRepo(lib.path, `library:${lib.name}`)) {\n entries.push(e);\n }\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 domains: CatalogDomain[];\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 domainSlug: a.domainSlug,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n // Domains are optional on the catalog source — only the store backend\n // (post Part 4 `catalog.listDomains`) exposes them. Duck-type the call so\n // older sources and the local catalog degrade to no domains, not an error.\n const domains = await loadDomains(source);\n return { entries, domains, 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: [], domains: [], notes };\n }\n}\n\n/** Optional `listDomains` capability — returns `[]` when the source lacks it. */\nasync function loadDomains(source: unknown): Promise<CatalogDomain[]> {\n const fn = (source as { listDomains?: () => Promise<CatalogDomain[]> }).listDomains;\n if (typeof fn !== \"function\") return [];\n const domains = await fn.call(source);\n return Array.isArray(domains) ? domains : [];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which now merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Provided as a\n * function rather than an inline call so the caller can supply a fresh\n * `AssetManager` instance.\n */\nfunction sourceAssets(am: { search: () => CatalogEntry[] }): CatalogEntry[] {\n return am.search();\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). Synchronous, 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 */\nfunction factoryAssets(): { entries: CatalogEntry[]; notes: FeedNote[] } {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n for (const e of scanRepo(root, \"skaile-factory\")) entries.push(e);\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 + synchronous, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: { search: () => CatalogEntry[] },\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = factoryAssets();\n return {\n entries: [\n ...tag(\"source\", sourceAssets(am)),\n ...tag(\"library\", libs.entries),\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n domains: store.domains,\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../cli/src/asset-feeds.ts"],"names":[],"mappings":"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","file":"asset-feeds-UPJJGR3O.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 CatalogDomain,\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\nexport interface AssetFeedResult {\n entries: OriginEntry[];\n /**\n * Display-only domain metadata, keyed (by the consumer) on `slug`. Populated\n * from the store's `catalog.listDomains` when the connected catalog source\n * exposes it; empty otherwise. The manage TUI joins `entry.domainSlug` → a\n * domain for grouping headers, descriptions, and relation badges.\n */\n domains: CatalogDomain[];\n notes: FeedNote[];\n}\n\n/**\n * Pull assets from local libraries (the authoring places under\n * `~/.skaile/libraries/<name>/`, not the `~/.skaile/sources/` cache). Each\n * library's `path` is scanned with `scanRepo` and tagged with\n * `repository = \"library:<name>\"` so the manage TUI groups them into their\n * own headers.\n */\nasync function libraryAssets(): Promise<{ entries: CatalogEntry[]; notes: FeedNote[] }> {\n const notes: FeedNote[] = [];\n try {\n const [{ openLibraryManager }, { skaileHomeDir }] = await Promise.all([\n import(\"./open-library.ts\"),\n import(\"@skaile/workspaces/library\"),\n ]);\n const { manager, close } = await openLibraryManager();\n try {\n const sourcesDir = path.join(skaileHomeDir(), \"sources\");\n const libs = (await manager.listLibraries()).filter((l) => !l.path.startsWith(sourcesDir));\n const entries: CatalogEntry[] = [];\n for (const lib of libs) {\n if (!existsSync(lib.path)) continue;\n for (const e of scanRepo(lib.path, `library:${lib.name}`)) {\n entries.push(e);\n }\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 domains: CatalogDomain[];\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 domainSlug: a.domainSlug,\n category: a.category,\n version: a.version,\n requires: [],\n dependencies: [],\n }));\n // Domains are optional on the catalog source — only the store backend\n // (post Part 4 `catalog.listDomains`) exposes them. Duck-type the call so\n // older sources and the local catalog degrade to no domains, not an error.\n const domains = await loadDomains(source);\n return { entries, domains, 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: [], domains: [], notes };\n }\n}\n\n/** Optional `listDomains` capability — returns `[]` when the source lacks it. */\nasync function loadDomains(source: unknown): Promise<CatalogDomain[]> {\n const fn = (source as { listDomains?: () => Promise<CatalogDomain[]> }).listDomains;\n if (typeof fn !== \"function\") return [];\n const domains = await fn.call(source);\n return Array.isArray(domains) ? domains : [];\n}\n\n/**\n * Project-source feed: leans on `AssetManager.search()`, which now merges\n * `skaile.yaml`'s `sources:` field into the repositories map. Provided as a\n * function rather than an inline call so the caller can supply a fresh\n * `AssetManager` instance.\n */\nfunction sourceAssets(am: { search: () => CatalogEntry[] }): CatalogEntry[] {\n return am.search();\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). Synchronous, 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 */\nfunction factoryAssets(): { entries: CatalogEntry[]; notes: FeedNote[] } {\n const notes: FeedNote[] = [];\n try {\n const entries: CatalogEntry[] = [];\n for (const root of factoryAssetRoots()) {\n for (const e of scanRepo(root, \"skaile-factory\")) entries.push(e);\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 + synchronous, so it runs inline.\n */\nexport async function gatherAssetFeeds(\n am: { search: () => CatalogEntry[] },\n projectDir: string,\n): Promise<AssetFeedResult> {\n const [libs, store] = await Promise.all([libraryAssets(), storeAssets(projectDir)]);\n const factory = factoryAssets();\n return {\n entries: [\n ...tag(\"source\", sourceAssets(am)),\n ...tag(\"library\", libs.entries),\n ...tag(\"factory\", factory.entries),\n ...tag(\"store\", store.entries),\n ],\n domains: store.domains,\n notes: [...libs.notes, ...store.notes, ...factory.notes],\n };\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { AssetManager, parseCanonicalLockKey } from '../chunk-
|
|
2
|
-
export { createScaffold, deployAll, installAgent, removeAsset } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
export { AssetManager, parseCanonicalLockKey } from '../chunk-7I4IBYHE.js';
|
|
2
|
+
export { createScaffold, deployAll, installAgent, removeAsset } from '../chunk-SURALYSM.js';
|
|
3
|
+
import '../chunk-KYQNWFJV.js';
|
|
4
4
|
import '../chunk-ZAP2BDHG.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-HVCZLD5Z.js';
|
|
6
|
+
import '../chunk-GJI6FZ56.js';
|
|
7
7
|
import '../chunk-DZCK7GRW.js';
|
|
8
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-6IDBWPK2.js';
|
|
9
9
|
import '../chunk-GEEW6SY2.js';
|
|
10
10
|
import '../chunk-XGCXFX7X.js';
|
|
11
11
|
import '../chunk-O4JH3KUE.js';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { createScaffold, deployAll, deployAsset, removeAsset } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { createScaffold, deployAll, deployAsset, removeAsset } from '../chunk-SURALYSM.js';
|
|
2
|
+
import '../chunk-KYQNWFJV.js';
|
|
3
3
|
import '../chunk-ZAP2BDHG.js';
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
4
|
+
import '../chunk-HVCZLD5Z.js';
|
|
5
|
+
import '../chunk-GJI6FZ56.js';
|
|
6
6
|
import '../chunk-DZCK7GRW.js';
|
|
7
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-6IDBWPK2.js';
|
|
8
8
|
import '../chunk-GEEW6SY2.js';
|
|
9
9
|
import '../chunk-XGCXFX7X.js';
|
|
10
10
|
import '../chunk-O4JH3KUE.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dispatchCapability } from '../../chunk-RRVQAE5D.js';
|
|
2
2
|
import { fetchProviderModels } from '../../chunk-BMQKMOQY.js';
|
|
3
3
|
import { AuthError, classifyClaudeSdkError, reclassifyAuthAsAccountUnavailable, AccountUnavailableError } from '../../chunk-GAH4YRCI.js';
|
|
4
|
-
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-
|
|
4
|
+
import { BUILTIN_DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-OCAQH66V.js';
|
|
5
5
|
import '../../chunk-6E6PKKAD.js';
|
|
6
6
|
import '../../chunk-JB35MVBN.js';
|
|
7
7
|
import '../../chunk-NSBPE2FW.js';
|
|
@@ -12,6 +12,97 @@ import { homedir } from 'os';
|
|
|
12
12
|
import { join } from 'path';
|
|
13
13
|
import * as zNS from 'zod';
|
|
14
14
|
|
|
15
|
+
// bridge/src/drivers/sanitize-assistant-text.ts
|
|
16
|
+
var NS = "(?:[a-z][a-z0-9]*:)?";
|
|
17
|
+
var FUNCTION_CALL_BLOCK = new RegExp(
|
|
18
|
+
`\\[\\s*${NS}function_calls\\s*\\][\\s\\S]*?\\[\\s*/\\s*${NS}function_calls\\s*\\]`,
|
|
19
|
+
"gi"
|
|
20
|
+
);
|
|
21
|
+
var INVOKE_BLOCK = new RegExp(
|
|
22
|
+
`\\[\\s*${NS}invoke\\b[\\s\\S]*?\\[\\s*/\\s*${NS}invoke\\s*\\]`,
|
|
23
|
+
"gi"
|
|
24
|
+
);
|
|
25
|
+
var ROLE_TURN_LINE = /^\s*\[(?:User|Assistant|System)\]\s*:/i;
|
|
26
|
+
function sanitizeAssistantText(text) {
|
|
27
|
+
if (!text || text.indexOf("[") === -1 && text.indexOf("]") === -1) {
|
|
28
|
+
return text;
|
|
29
|
+
}
|
|
30
|
+
const stripped = text.replace(FUNCTION_CALL_BLOCK, "").replace(INVOKE_BLOCK, "");
|
|
31
|
+
let changed = stripped !== text;
|
|
32
|
+
let out = stripped;
|
|
33
|
+
const lines = out.split("\n");
|
|
34
|
+
let end = lines.length;
|
|
35
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
36
|
+
const line = lines[i] ?? "";
|
|
37
|
+
if (line.trim() === "") {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (ROLE_TURN_LINE.test(line)) {
|
|
41
|
+
end = i;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
if (end < lines.length) {
|
|
47
|
+
out = lines.slice(0, end).join("\n");
|
|
48
|
+
changed = true;
|
|
49
|
+
}
|
|
50
|
+
return changed ? out.replace(/\s+$/, "") : out;
|
|
51
|
+
}
|
|
52
|
+
var TAG_PREFIXES = [
|
|
53
|
+
"function_call",
|
|
54
|
+
"function_cal",
|
|
55
|
+
"function_ca",
|
|
56
|
+
"function_c",
|
|
57
|
+
"function_",
|
|
58
|
+
"function",
|
|
59
|
+
"functio",
|
|
60
|
+
"functi",
|
|
61
|
+
"funct",
|
|
62
|
+
"func",
|
|
63
|
+
"fun",
|
|
64
|
+
"fu",
|
|
65
|
+
"f",
|
|
66
|
+
"invoke",
|
|
67
|
+
"invok",
|
|
68
|
+
"invo",
|
|
69
|
+
"inv",
|
|
70
|
+
"in",
|
|
71
|
+
"i",
|
|
72
|
+
"user",
|
|
73
|
+
"use",
|
|
74
|
+
"us",
|
|
75
|
+
"u",
|
|
76
|
+
"assistant",
|
|
77
|
+
"assistan",
|
|
78
|
+
"assista",
|
|
79
|
+
"assist",
|
|
80
|
+
"assis",
|
|
81
|
+
"assi",
|
|
82
|
+
"ass",
|
|
83
|
+
"as",
|
|
84
|
+
"a",
|
|
85
|
+
"system",
|
|
86
|
+
"syste",
|
|
87
|
+
"syst",
|
|
88
|
+
"sys",
|
|
89
|
+
"sy",
|
|
90
|
+
"s"
|
|
91
|
+
].join("|");
|
|
92
|
+
var PARTIAL_MARKER_TAIL = new RegExp(`\\[\\s*/?\\s*${NS}(?:${TAG_PREFIXES})?[^\\]]*$`, "i");
|
|
93
|
+
var UNCLOSED_OPENER = new RegExp(`\\[\\s*${NS}function_calls\\s*\\]|\\[\\s*${NS}invoke\\b`, "i");
|
|
94
|
+
function streamingSafeSanitize(text) {
|
|
95
|
+
let cleaned = sanitizeAssistantText(text);
|
|
96
|
+
const opener = UNCLOSED_OPENER.exec(cleaned);
|
|
97
|
+
if (opener && opener.index >= 0) {
|
|
98
|
+
cleaned = cleaned.slice(0, opener.index);
|
|
99
|
+
}
|
|
100
|
+
const tail = PARTIAL_MARKER_TAIL.exec(cleaned);
|
|
101
|
+
if (tail && tail.index >= 0) {
|
|
102
|
+
cleaned = cleaned.slice(0, tail.index);
|
|
103
|
+
}
|
|
104
|
+
return cleaned.replace(/\s+$/, "");
|
|
105
|
+
}
|
|
15
106
|
var STUB_TEXT = "[image removed: unprocessable image data]";
|
|
16
107
|
var STUB_TEXT_OVERSIZED = "[image removed: image too large]";
|
|
17
108
|
var MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
@@ -235,6 +326,12 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
235
326
|
sdk = null;
|
|
236
327
|
toolIdToName = /* @__PURE__ */ new Map();
|
|
237
328
|
prevText = "";
|
|
329
|
+
/**
|
|
330
|
+
* Count of sanitized characters already streamed for the current message.
|
|
331
|
+
* Lets {@link handleStreamEvent} emit only the newly-stable sanitized suffix
|
|
332
|
+
* as `_textDelta`, so a leaked marker that spans deltas is never half-sent.
|
|
333
|
+
*/
|
|
334
|
+
emittedSanitizedLen = 0;
|
|
238
335
|
/** Set once the streaming text of the current message classifies as a self-healable auth render. */
|
|
239
336
|
suppressingAuthStream = false;
|
|
240
337
|
/** Active query — may stay alive between turns if streamInput works. */
|
|
@@ -338,6 +435,7 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
338
435
|
if (isFirstAttempt) this._lastTokens = null;
|
|
339
436
|
this.running = true;
|
|
340
437
|
this.prevText = "";
|
|
438
|
+
this.emittedSanitizedLen = 0;
|
|
341
439
|
this.suppressingAuthStream = false;
|
|
342
440
|
this.turnCompleted = false;
|
|
343
441
|
const turnPromise = new Promise((resolve, reject) => {
|
|
@@ -928,6 +1026,7 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
928
1026
|
if (this.isSuppressibleAuthRender(agentMsg)) {
|
|
929
1027
|
this.log.info("suppressing SDK auth-error assistant text; self-heal will retry");
|
|
930
1028
|
this.prevText = "";
|
|
1029
|
+
this.emittedSanitizedLen = 0;
|
|
931
1030
|
this.suppressingAuthStream = false;
|
|
932
1031
|
return;
|
|
933
1032
|
}
|
|
@@ -943,6 +1042,7 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
943
1042
|
}
|
|
944
1043
|
}
|
|
945
1044
|
this.prevText = "";
|
|
1045
|
+
this.emittedSanitizedLen = 0;
|
|
946
1046
|
this.suppressingAuthStream = false;
|
|
947
1047
|
this.emit("agent-event", { type: "message_end", message: agentMsg });
|
|
948
1048
|
}
|
|
@@ -973,14 +1073,18 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
973
1073
|
this.log.info("suppressing SDK auth-error stream; self-heal will retry");
|
|
974
1074
|
}
|
|
975
1075
|
if (this.suppressingAuthStream) return;
|
|
1076
|
+
const safe = streamingSafeSanitize(this.prevText);
|
|
1077
|
+
const sanitizedDelta = safe.slice(this.emittedSanitizedLen);
|
|
1078
|
+
this.emittedSanitizedLen = safe.length;
|
|
1079
|
+
if (sanitizedDelta.length === 0) return;
|
|
976
1080
|
const agentMsg = {
|
|
977
1081
|
role: "assistant",
|
|
978
|
-
content: [{ type: "text", text:
|
|
1082
|
+
content: [{ type: "text", text: safe }]
|
|
979
1083
|
};
|
|
980
1084
|
this.emit("agent-event", {
|
|
981
1085
|
type: "message_update",
|
|
982
1086
|
message: agentMsg,
|
|
983
|
-
_textDelta:
|
|
1087
|
+
_textDelta: sanitizedDelta
|
|
984
1088
|
});
|
|
985
1089
|
}
|
|
986
1090
|
}
|
|
@@ -1029,17 +1133,18 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
1029
1133
|
}
|
|
1030
1134
|
/** Emit the message_end (if any) + success result event for a clean turn. */
|
|
1031
1135
|
handleSuccessResult(msg) {
|
|
1032
|
-
|
|
1136
|
+
const result = msg.result != null ? sanitizeAssistantText(msg.result) : msg.result;
|
|
1137
|
+
if (result) {
|
|
1033
1138
|
const agentMsg = {
|
|
1034
1139
|
role: "assistant",
|
|
1035
|
-
content:
|
|
1140
|
+
content: result
|
|
1036
1141
|
};
|
|
1037
1142
|
this.emit("agent-event", { type: "message_end", message: agentMsg });
|
|
1038
1143
|
}
|
|
1039
1144
|
this.emit("agent-event", {
|
|
1040
1145
|
type: "result",
|
|
1041
1146
|
subtype: msg.subtype,
|
|
1042
|
-
summary:
|
|
1147
|
+
summary: result ?? "Task completed",
|
|
1043
1148
|
costUsd: msg.total_cost_usd ?? 0,
|
|
1044
1149
|
...this._lastTokens ? { tokens: this._lastTokens } : {}
|
|
1045
1150
|
});
|
|
@@ -1121,7 +1226,7 @@ var ClaudeSdkDriver = class extends AgentDriver {
|
|
|
1121
1226
|
if (Array.isArray(content)) {
|
|
1122
1227
|
for (const block of content) {
|
|
1123
1228
|
if (block.type === "text") {
|
|
1124
|
-
contentBlocks.push({ type: "text", text: block.text });
|
|
1229
|
+
contentBlocks.push({ type: "text", text: sanitizeAssistantText(block.text) });
|
|
1125
1230
|
} else if (block.type === "tool_use") {
|
|
1126
1231
|
contentBlocks.push({
|
|
1127
1232
|
type: "tool_use",
|