sigit-code 1.6.3__tar.gz → 1.6.5__tar.gz
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.
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/AGENTS.md +36 -2
- sigit_code-1.6.5/.sigit/code-cloud-agent/config.toml +6 -0
- sigit_code-1.6.5/.sigit/code-review/config.toml +3 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/AGENTS.md +36 -2
- {sigit_code-1.6.3 → sigit_code-1.6.5}/CHANGELOG.md +96 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/CLAUDE.md +36 -2
- {sigit_code-1.6.3 → sigit_code-1.6.5}/Cargo.lock +176 -134
- {sigit_code-1.6.3 → sigit_code-1.6.5}/Cargo.toml +4 -4
- {sigit_code-1.6.3 → sigit_code-1.6.5}/PKG-INFO +1 -1
- {sigit_code-1.6.3 → sigit_code-1.6.5}/README.md +30 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/backend.rs +306 -67
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/chat.rs +28 -7
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/client_fs.rs +3 -2
- sigit_code-1.6.5/src/client_terminal.rs +468 -0
- sigit_code-1.6.5/src/harness_markup.rs +381 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/headless.rs +49 -22
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/inline_tool_calls.rs +262 -1
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/main.rs +782 -141
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/provider.rs +18 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/tools.rs +539 -110
- sigit_code-1.6.5/tests/acp_audio.rs +310 -0
- sigit_code-1.6.5/tests/acp_client_terminal.rs +504 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_concurrent_sessions.rs +150 -3
- sigit_code-1.6.5/tests/acp_embedded_context.rs +274 -0
- sigit_code-1.6.5/tests/acp_harness_markup.rs +270 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_permissions.rs +154 -1
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/agent-client-protocol/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/branding/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/sigit-code-release/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.agents/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.cargo/config.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/agent-client-protocol/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/ai-assisted-coding/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/branding/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/run-sigit/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/run-sigit/driver.mjs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/run-sigit/tui-smoke.sh +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/sigit-code-release/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.claude/skills/tool-calling/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/ci.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-aur.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-crates.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-github.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-homebrew.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-npm.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-nuget.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-pypi.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-scoop.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.github/workflows/release-winget.yml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.gitignore +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.nvmrc +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/.sigit/factory/config.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/LICENSE +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/docs/headless.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/docs/hooks.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/docs/mcp.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/examples/settings-with-hooks.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/examples/skills/README.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/examples/skills/commit-message/SKILL.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/README.md.tmpl +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/package-compat.json.tmpl +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/package-main.json.tmpl +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/package.json.tmpl +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/scripts/render-main-package.cjs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/scripts/render-platform-package.cjs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/sigit/.gitignore +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/sigit/README.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/sigit/package.json +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/sigit/src/index.ts +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/npm/sigit/tsconfig.json +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/nuget/.gitignore +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/nuget/sigit/Program.cs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/nuget/sigit/README.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/nuget/sigit/SiGit.Code.csproj +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/aur/PKGBUILD.in +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/nfpm.yaml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/windows/check-static-crt.ps1 +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/winget/getSigit.siGitCode.installer.yaml.in +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/winget/getSigit.siGitCode.locale.en-US.yaml.in +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/packaging/winget/getSigit.siGitCode.yaml.in +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/pypi/README.md +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/pypi/pyproject.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/pyproject.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/rust-toolchain.toml +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/account.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/browser_auth.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/commands.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/credentials.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/frontmatter.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/hooks.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/instructions.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/mcp.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/models.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/permissions.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/session_store.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/settings.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/setup.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/skills.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/subagents.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/src/workspace.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_client_fs.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_endpoint_errors.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_images.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_logout.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_multi_root.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_session_list.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_session_load.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_stop_reasons.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/acp_tool_stdin.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/headless_mode.rs +0 -0
- {sigit_code-1.6.3 → sigit_code-1.6.5}/tests/version_flag.rs +0 -0
|
@@ -152,6 +152,13 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
152
152
|
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
153
153
|
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
154
154
|
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
155
|
+
What that scanner lets through then goes through `src/harness_markup.rs`, which removes
|
|
156
|
+
markup the model makes up in the harness's shape (issue #122): a `<system_warning>`-style
|
|
157
|
+
block (any `system_*`/`system-*` tag) is dropped whole, from the reply and the history, and
|
|
158
|
+
other underscore-named tags like `<Option_Picker>` lose the tags but keep their text. Code is
|
|
159
|
+
never touched, and an opening tag only counts at the start of a line, since prose writes
|
|
160
|
+
placeholders like `<repo_url>` the same way. It has to run after the inline-call scanner,
|
|
161
|
+
because `<tool_call>` matches its underscore rule.
|
|
155
162
|
Image attachments: ACP fixes `promptCapabilities.image` for the whole connection, while the
|
|
156
163
|
model can change on any turn, so the capability is always advertised and the decision is made
|
|
157
164
|
per prompt. `InferenceBackend::accepts_images` answers for the active model (on-device: no;
|
|
@@ -163,6 +170,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
163
170
|
when its model cannot read them, which is what makes a mid-thread switch to a text-only tier
|
|
164
171
|
safe. Read history text through `backend::message_text`, never `content.as_str()`.
|
|
165
172
|
`IMAGE_TIERS` mirrors onde-cloud's `IMAGE_CANDIDATES`; update both together.
|
|
173
|
+
Audio attachments take the same path (`promptCapabilities.audio`, `accepts_audio`,
|
|
174
|
+
`audio_for_turn`, `without_audio`), sent as OpenAI `input_audio` parts. No cloud tier
|
|
175
|
+
takes audio, because onde-cloud drops `input_audio` parts when it parses a request, so
|
|
176
|
+
`provider::model_accepts_audio` says no for every `onde-*` id and yes for a user's own
|
|
177
|
+
endpoint. If onde-cloud ever routes audio, give it a tier table like `IMAGE_TIERS`.
|
|
166
178
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
167
179
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
168
180
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -330,7 +342,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
330
342
|
`execute_tool_impl` asks `route_for` before it dispatches `read_file`, `create_file`,
|
|
331
343
|
`edit_file` or `multi_edit`. Each of those tools is split into a parse step and a pure
|
|
332
344
|
render/apply step (`ReadFileCall`, `CreateFileCall`, `EditCall`) that the disk path and the
|
|
333
|
-
client path share, so the model gets the same result text either way. The
|
|
345
|
+
client path share, so the model gets the same result text either way. The writing tools also
|
|
346
|
+
hand back the file before and after (`tools::FileChange`, via `execute_tool_with_change`), which
|
|
347
|
+
`handle_prompt` sends as ACP `diff` content ahead of the result text. A permission request for
|
|
348
|
+
one of them carries the same diff, worked out by `preview_file_change` without writing anything
|
|
349
|
+
and before the workspace is released, since a relative path resolves against the session's cwd. The two capabilities are
|
|
334
350
|
independent: a client that only reads still gets its edits written to disk. The disk is the
|
|
335
351
|
fallback throughout: nothing is registered in the TUI or headless modes, a path outside the
|
|
336
352
|
session's roots is not routed, and a request the client fails or leaves unanswered for 30
|
|
@@ -338,6 +354,23 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
338
354
|
inside a spawned prompt turn, never from `handle_initialize` itself (deadlock, same as
|
|
339
355
|
permission requests). Existence checks and `create_file`'s parent directories still use the
|
|
340
356
|
disk. `SIGIT_CLIENT_FS=off` turns the routing off. Covered by `tests/acp_client_fs.rs`.
|
|
357
|
+
- **`src/client_terminal.rs`** — `run_command` in the ACP client's terminal. A client that
|
|
358
|
+
advertises `terminal` in `initialize` runs a foreground command itself (`terminal/create`, with
|
|
359
|
+
the platform shell as `command` and the whole command line as one argument), and
|
|
360
|
+
`exec_run_command_via_client` embeds the terminal in the tool call as `terminal` content, so the
|
|
361
|
+
user watches the output live and can stop the command from the editor. The seam is
|
|
362
|
+
`client_fs`'s: `handle_initialize` registers `AcpClientTerminal`, and `execute_tool_impl` asks
|
|
363
|
+
`client_terminal_route` before the blocking path. Embedding needs the tool call's id, which is
|
|
364
|
+
why `execute_tool_with_change` takes one. What `run_command` promises stays put: the 120 s
|
|
365
|
+
timeout ends in `terminal/kill`, the output is capped, and `CommitWatch` still amends the
|
|
366
|
+
co-author trailer, checking HEAD on disk before and after. Background commands stay local
|
|
367
|
+
(`command_output` and `kill_command` read their pipes), and so does a command whose directory
|
|
368
|
+
is outside the session's roots, since nothing says the editor's machine can see it. A
|
|
369
|
+
`terminal/create` the client fails means nothing ran, so the command runs locally; a failure
|
|
370
|
+
after that is reported as the tool's error instead, because running it again could repeat its
|
|
371
|
+
effects. The finished card keeps the terminal and drops the result text, which still goes out
|
|
372
|
+
as `raw_output`. `SIGIT_CLIENT_TERMINAL=off` turns the routing off. Covered by
|
|
373
|
+
`tests/acp_client_terminal.rs`.
|
|
341
374
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
342
375
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
343
376
|
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
@@ -407,7 +440,8 @@ verbosity with `RUST_LOG`.
|
|
|
407
440
|
default `https://sigit.si`), `SIGIT_CLOUD_URL`, `SIGIT_CONFIG_DIR` (default `~/.config/sigit`),
|
|
408
441
|
`SIGIT_MODEL`, `SIGIT_MAX_TOOL_ROUNDS` (1 to 500, default 24; the tool-round cap of a
|
|
409
442
|
headless run or an ACP prompt turn), `SIGIT_MCP` (`off` disables MCP), `SIGIT_CLIENT_FS` (`off` keeps the file tools on disk even when the
|
|
410
|
-
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `
|
|
443
|
+
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `SIGIT_CLIENT_TERMINAL` (`off` runs
|
|
444
|
+
`run_command` locally even when the ACP client offers a terminal), `SIGIT_MCP_SMBCLOUD` (`off` drops the baked-in
|
|
411
445
|
smbCloud CLI server), `SIGIT_MCP_OFFICIAL` (`off` drops the baked-in
|
|
412
446
|
server), `SIGIT_PERMISSIONS` (`allow`/`ask`/`deny` — overrides the default permission mode for
|
|
413
447
|
mutating tools; the escape hatch for clients without permission-request support),
|
|
@@ -152,6 +152,13 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
152
152
|
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
153
153
|
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
154
154
|
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
155
|
+
What that scanner lets through then goes through `src/harness_markup.rs`, which removes
|
|
156
|
+
markup the model makes up in the harness's shape (issue #122): a `<system_warning>`-style
|
|
157
|
+
block (any `system_*`/`system-*` tag) is dropped whole, from the reply and the history, and
|
|
158
|
+
other underscore-named tags like `<Option_Picker>` lose the tags but keep their text. Code is
|
|
159
|
+
never touched, and an opening tag only counts at the start of a line, since prose writes
|
|
160
|
+
placeholders like `<repo_url>` the same way. It has to run after the inline-call scanner,
|
|
161
|
+
because `<tool_call>` matches its underscore rule.
|
|
155
162
|
Image attachments: ACP fixes `promptCapabilities.image` for the whole connection, while the
|
|
156
163
|
model can change on any turn, so the capability is always advertised and the decision is made
|
|
157
164
|
per prompt. `InferenceBackend::accepts_images` answers for the active model (on-device: no;
|
|
@@ -163,6 +170,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
163
170
|
when its model cannot read them, which is what makes a mid-thread switch to a text-only tier
|
|
164
171
|
safe. Read history text through `backend::message_text`, never `content.as_str()`.
|
|
165
172
|
`IMAGE_TIERS` mirrors onde-cloud's `IMAGE_CANDIDATES`; update both together.
|
|
173
|
+
Audio attachments take the same path (`promptCapabilities.audio`, `accepts_audio`,
|
|
174
|
+
`audio_for_turn`, `without_audio`), sent as OpenAI `input_audio` parts. No cloud tier
|
|
175
|
+
takes audio, because onde-cloud drops `input_audio` parts when it parses a request, so
|
|
176
|
+
`provider::model_accepts_audio` says no for every `onde-*` id and yes for a user's own
|
|
177
|
+
endpoint. If onde-cloud ever routes audio, give it a tier table like `IMAGE_TIERS`.
|
|
166
178
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
167
179
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
168
180
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -330,7 +342,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
330
342
|
`execute_tool_impl` asks `route_for` before it dispatches `read_file`, `create_file`,
|
|
331
343
|
`edit_file` or `multi_edit`. Each of those tools is split into a parse step and a pure
|
|
332
344
|
render/apply step (`ReadFileCall`, `CreateFileCall`, `EditCall`) that the disk path and the
|
|
333
|
-
client path share, so the model gets the same result text either way. The
|
|
345
|
+
client path share, so the model gets the same result text either way. The writing tools also
|
|
346
|
+
hand back the file before and after (`tools::FileChange`, via `execute_tool_with_change`), which
|
|
347
|
+
`handle_prompt` sends as ACP `diff` content ahead of the result text. A permission request for
|
|
348
|
+
one of them carries the same diff, worked out by `preview_file_change` without writing anything
|
|
349
|
+
and before the workspace is released, since a relative path resolves against the session's cwd. The two capabilities are
|
|
334
350
|
independent: a client that only reads still gets its edits written to disk. The disk is the
|
|
335
351
|
fallback throughout: nothing is registered in the TUI or headless modes, a path outside the
|
|
336
352
|
session's roots is not routed, and a request the client fails or leaves unanswered for 30
|
|
@@ -338,6 +354,23 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
338
354
|
inside a spawned prompt turn, never from `handle_initialize` itself (deadlock, same as
|
|
339
355
|
permission requests). Existence checks and `create_file`'s parent directories still use the
|
|
340
356
|
disk. `SIGIT_CLIENT_FS=off` turns the routing off. Covered by `tests/acp_client_fs.rs`.
|
|
357
|
+
- **`src/client_terminal.rs`** — `run_command` in the ACP client's terminal. A client that
|
|
358
|
+
advertises `terminal` in `initialize` runs a foreground command itself (`terminal/create`, with
|
|
359
|
+
the platform shell as `command` and the whole command line as one argument), and
|
|
360
|
+
`exec_run_command_via_client` embeds the terminal in the tool call as `terminal` content, so the
|
|
361
|
+
user watches the output live and can stop the command from the editor. The seam is
|
|
362
|
+
`client_fs`'s: `handle_initialize` registers `AcpClientTerminal`, and `execute_tool_impl` asks
|
|
363
|
+
`client_terminal_route` before the blocking path. Embedding needs the tool call's id, which is
|
|
364
|
+
why `execute_tool_with_change` takes one. What `run_command` promises stays put: the 120 s
|
|
365
|
+
timeout ends in `terminal/kill`, the output is capped, and `CommitWatch` still amends the
|
|
366
|
+
co-author trailer, checking HEAD on disk before and after. Background commands stay local
|
|
367
|
+
(`command_output` and `kill_command` read their pipes), and so does a command whose directory
|
|
368
|
+
is outside the session's roots, since nothing says the editor's machine can see it. A
|
|
369
|
+
`terminal/create` the client fails means nothing ran, so the command runs locally; a failure
|
|
370
|
+
after that is reported as the tool's error instead, because running it again could repeat its
|
|
371
|
+
effects. The finished card keeps the terminal and drops the result text, which still goes out
|
|
372
|
+
as `raw_output`. `SIGIT_CLIENT_TERMINAL=off` turns the routing off. Covered by
|
|
373
|
+
`tests/acp_client_terminal.rs`.
|
|
341
374
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
342
375
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
343
376
|
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
@@ -407,7 +440,8 @@ verbosity with `RUST_LOG`.
|
|
|
407
440
|
default `https://sigit.si`), `SIGIT_CLOUD_URL`, `SIGIT_CONFIG_DIR` (default `~/.config/sigit`),
|
|
408
441
|
`SIGIT_MODEL`, `SIGIT_MAX_TOOL_ROUNDS` (1 to 500, default 24; the tool-round cap of a
|
|
409
442
|
headless run or an ACP prompt turn), `SIGIT_MCP` (`off` disables MCP), `SIGIT_CLIENT_FS` (`off` keeps the file tools on disk even when the
|
|
410
|
-
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `
|
|
443
|
+
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `SIGIT_CLIENT_TERMINAL` (`off` runs
|
|
444
|
+
`run_command` locally even when the ACP client offers a terminal), `SIGIT_MCP_SMBCLOUD` (`off` drops the baked-in
|
|
411
445
|
smbCloud CLI server), `SIGIT_MCP_OFFICIAL` (`off` drops the baked-in
|
|
412
446
|
server), `SIGIT_PERMISSIONS` (`allow`/`ask`/`deny` — overrides the default permission mode for
|
|
413
447
|
mutating tools; the escape hatch for clients without permission-request support),
|
|
@@ -1,5 +1,101 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.5
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **An `@file` mention can carry unsaved edits.** siGit Code now advertises
|
|
8
|
+
`promptCapabilities.embeddedContext`, so a client can put a resource's
|
|
9
|
+
contents in the prompt instead of sending a link to it. Before, a client
|
|
10
|
+
that follows the spec only sent `resource_link`, and siGit Code read the
|
|
11
|
+
file from disk, missing whatever the user had not saved yet (#141).
|
|
12
|
+
- **A prompt can carry audio.** siGit Code now advertises
|
|
13
|
+
`promptCapabilities.audio` and sends an attached clip to the model as an
|
|
14
|
+
OpenAI `input_audio` part. It works the way image attachments do: a model on
|
|
15
|
+
an endpoint you configure yourself gets the clip and decides for itself,
|
|
16
|
+
while siGit Code Cloud tiers and on-device models, none of which take audio
|
|
17
|
+
today, get a note in its place and the editor says the clip was left out
|
|
18
|
+
(#143).
|
|
19
|
+
- **The README says what telemetry is sent.** A new Telemetry section covers
|
|
20
|
+
the model-timing events Onde Inference can report for on-device models,
|
|
21
|
+
what they leave out, and how to turn them off with `ONDE_DISABLE_PULSE=1`.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **A turn that cannot get its session back stops.** A turn on an HTTP backend
|
|
26
|
+
gives up the process-wide working directory while it waits and reinstalls
|
|
27
|
+
its session before a tool runs. If the reinstall failed, the turn logged a
|
|
28
|
+
warning and carried on in whichever directory was current. Nothing makes it
|
|
29
|
+
fail today, since a close waits for the turn, but the turn now ends as
|
|
30
|
+
cancelled instead of depending on that.
|
|
31
|
+
- **Dependencies match the rest of the Onde stack.** Onde 1.2.2 to 1.3.1,
|
|
32
|
+
reqwest 0.12 to 0.13 and ratatui 0.29 to 0.30, the versions Ed, OndeCode and
|
|
33
|
+
SplitFire Agent use. ratatui is built with only its crossterm backend, which
|
|
34
|
+
drops the second copy of crossterm (0.28) from the build.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Tags a model makes up no longer show in the reply.** After a long run of
|
|
39
|
+
tool rounds, a model could start writing markup that looked like it came
|
|
40
|
+
from siGit Code: a `<system_warning>` block telling the user the previous
|
|
41
|
+
turn was injected and should be ignored, or a question wrapped in
|
|
42
|
+
`<Option_Picker>`. Neither tag means anything to siGit Code or the editor,
|
|
43
|
+
so both rendered as raw text. A `system_*` block is now dropped from the
|
|
44
|
+
reply and from the history, and other made-up tags are removed while the
|
|
45
|
+
text inside them stays. Code blocks are left alone. The system prompt also
|
|
46
|
+
tells the model to write plain Markdown and to list choices as plain text
|
|
47
|
+
(#122).
|
|
48
|
+
|
|
49
|
+
- **Closing a thread that is waiting at a permission prompt no longer hangs.**
|
|
50
|
+
`session/close` cancels the session's running turn and waits for it to end,
|
|
51
|
+
but a turn stopped at a permission prompt only went on when the client
|
|
52
|
+
answered the request. A client that closed the thread without answering
|
|
53
|
+
left the close, and every later request for that thread, waiting for good.
|
|
54
|
+
The same held for `session/cancel` with a client that did not send the
|
|
55
|
+
cancelled outcome the protocol asks for. The permission wait now ends on
|
|
56
|
+
the cancellation as well, and an approval that arrives after the turn was
|
|
57
|
+
cancelled runs nothing.
|
|
58
|
+
|
|
59
|
+
- **A closed thread no longer leaves its request lock behind.** The process
|
|
60
|
+
kept one lock per session id for as long as it ran, for closed threads and
|
|
61
|
+
for ids no session ever had. The entry now goes with the last request that
|
|
62
|
+
used it.
|
|
63
|
+
|
|
64
|
+
- **A tool call that did not run no longer shows as completed.** When policy
|
|
65
|
+
or plan mode denied a call, when the user picked Deny at the permission
|
|
66
|
+
prompt, or when the repeat guard skipped a call the model made three times,
|
|
67
|
+
the editor's card still ended `completed`. Those cards now end `failed`, the
|
|
68
|
+
same way a call cancelled at the prompt already did. A call denied at the
|
|
69
|
+
prompt also gets its own title back instead of keeping the permission
|
|
70
|
+
request's (#139).
|
|
71
|
+
|
|
72
|
+
- **On-device inference no longer panics on some non-English text.** siGit Code
|
|
73
|
+
now builds on Onde 1.3.1, which fixes a panic when a message longer than 100
|
|
74
|
+
bytes had a multi-byte character (an accented letter, CJK, or an emoji) at
|
|
75
|
+
byte 100. Onde 1.3 also reports Pulse events for streaming inference, which
|
|
76
|
+
is the path on-device turns take, so those turns are now reported alongside
|
|
77
|
+
model loads. `ONDE_DISABLE_PULSE=1` turns Pulse off.
|
|
78
|
+
|
|
79
|
+
## 1.6.4
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **DeepSeek DSML tool calls written into the reply text are recovered.** A
|
|
84
|
+
DeepSeek-family endpoint can render a tool call as literal
|
|
85
|
+
`<|DSML|tool_calls>` text instead of the structured `tool_calls` field,
|
|
86
|
+
which streamed the tag into the editor and ended the turn with nothing run.
|
|
87
|
+
The inline tool-call scanner that already recovered the GLM XML and Kimi K3
|
|
88
|
+
shapes now recovers the DSML shape too, including a marker split across
|
|
89
|
+
stream chunks. A block that fails to parse is still kept out of the reply
|
|
90
|
+
and the history, and the model is told the call did not run (#181).
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
- **The round-cap stop message no longer carries a stray run of spaces.**
|
|
95
|
+
When the tool-round cap ended a turn, the closing message could collapse a
|
|
96
|
+
space run into the wrong spot, which the editor then rendered verbatim
|
|
97
|
+
(#177).
|
|
98
|
+
|
|
3
99
|
## 1.6.3
|
|
4
100
|
|
|
5
101
|
### Added
|
|
@@ -152,6 +152,13 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
152
152
|
well-formed ones. A block that doesn't parse (or never closes) is dropped from both the reply
|
|
153
153
|
and history, and `OpenAiBackend::complete` retries once with a note telling the model the call
|
|
154
154
|
didn't run. Leaving the raw block in history makes the model invent `<function_results>` later.
|
|
155
|
+
What that scanner lets through then goes through `src/harness_markup.rs`, which removes
|
|
156
|
+
markup the model makes up in the harness's shape (issue #122): a `<system_warning>`-style
|
|
157
|
+
block (any `system_*`/`system-*` tag) is dropped whole, from the reply and the history, and
|
|
158
|
+
other underscore-named tags like `<Option_Picker>` lose the tags but keep their text. Code is
|
|
159
|
+
never touched, and an opening tag only counts at the start of a line, since prose writes
|
|
160
|
+
placeholders like `<repo_url>` the same way. It has to run after the inline-call scanner,
|
|
161
|
+
because `<tool_call>` matches its underscore rule.
|
|
155
162
|
Image attachments: ACP fixes `promptCapabilities.image` for the whole connection, while the
|
|
156
163
|
model can change on any turn, so the capability is always advertised and the decision is made
|
|
157
164
|
per prompt. `InferenceBackend::accepts_images` answers for the active model (on-device: no;
|
|
@@ -163,6 +170,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
163
170
|
when its model cannot read them, which is what makes a mid-thread switch to a text-only tier
|
|
164
171
|
safe. Read history text through `backend::message_text`, never `content.as_str()`.
|
|
165
172
|
`IMAGE_TIERS` mirrors onde-cloud's `IMAGE_CANDIDATES`; update both together.
|
|
173
|
+
Audio attachments take the same path (`promptCapabilities.audio`, `accepts_audio`,
|
|
174
|
+
`audio_for_turn`, `without_audio`), sent as OpenAI `input_audio` parts. No cloud tier
|
|
175
|
+
takes audio, because onde-cloud drops `input_audio` parts when it parses a request, so
|
|
176
|
+
`provider::model_accepts_audio` says no for every `onde-*` id and yes for a user's own
|
|
177
|
+
endpoint. If onde-cloud ever routes audio, give it a tier table like `IMAGE_TIERS`.
|
|
166
178
|
- **`src/provider.rs`** — decides *which* backend serves inference. Resolution order, first match
|
|
167
179
|
wins: (1) override via `OPENAI_BASE_URL`+`OPENAI_API_KEY` or active profile in
|
|
168
180
|
`~/.config/sigit/providers.toml`; (2) siGit Code Cloud when logged in; (3) on-device.
|
|
@@ -330,7 +342,11 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
330
342
|
`execute_tool_impl` asks `route_for` before it dispatches `read_file`, `create_file`,
|
|
331
343
|
`edit_file` or `multi_edit`. Each of those tools is split into a parse step and a pure
|
|
332
344
|
render/apply step (`ReadFileCall`, `CreateFileCall`, `EditCall`) that the disk path and the
|
|
333
|
-
client path share, so the model gets the same result text either way. The
|
|
345
|
+
client path share, so the model gets the same result text either way. The writing tools also
|
|
346
|
+
hand back the file before and after (`tools::FileChange`, via `execute_tool_with_change`), which
|
|
347
|
+
`handle_prompt` sends as ACP `diff` content ahead of the result text. A permission request for
|
|
348
|
+
one of them carries the same diff, worked out by `preview_file_change` without writing anything
|
|
349
|
+
and before the workspace is released, since a relative path resolves against the session's cwd. The two capabilities are
|
|
334
350
|
independent: a client that only reads still gets its edits written to disk. The disk is the
|
|
335
351
|
fallback throughout: nothing is registered in the TUI or headless modes, a path outside the
|
|
336
352
|
session's roots is not routed, and a request the client fails or leaves unanswered for 30
|
|
@@ -338,6 +354,23 @@ feeds results back. Neither the loop nor ACP/TUI surfaces depend on a concrete b
|
|
|
338
354
|
inside a spawned prompt turn, never from `handle_initialize` itself (deadlock, same as
|
|
339
355
|
permission requests). Existence checks and `create_file`'s parent directories still use the
|
|
340
356
|
disk. `SIGIT_CLIENT_FS=off` turns the routing off. Covered by `tests/acp_client_fs.rs`.
|
|
357
|
+
- **`src/client_terminal.rs`** — `run_command` in the ACP client's terminal. A client that
|
|
358
|
+
advertises `terminal` in `initialize` runs a foreground command itself (`terminal/create`, with
|
|
359
|
+
the platform shell as `command` and the whole command line as one argument), and
|
|
360
|
+
`exec_run_command_via_client` embeds the terminal in the tool call as `terminal` content, so the
|
|
361
|
+
user watches the output live and can stop the command from the editor. The seam is
|
|
362
|
+
`client_fs`'s: `handle_initialize` registers `AcpClientTerminal`, and `execute_tool_impl` asks
|
|
363
|
+
`client_terminal_route` before the blocking path. Embedding needs the tool call's id, which is
|
|
364
|
+
why `execute_tool_with_change` takes one. What `run_command` promises stays put: the 120 s
|
|
365
|
+
timeout ends in `terminal/kill`, the output is capped, and `CommitWatch` still amends the
|
|
366
|
+
co-author trailer, checking HEAD on disk before and after. Background commands stay local
|
|
367
|
+
(`command_output` and `kill_command` read their pipes), and so does a command whose directory
|
|
368
|
+
is outside the session's roots, since nothing says the editor's machine can see it. A
|
|
369
|
+
`terminal/create` the client fails means nothing ran, so the command runs locally; a failure
|
|
370
|
+
after that is reported as the tool's error instead, because running it again could repeat its
|
|
371
|
+
effects. The finished card keeps the terminal and drops the result text, which still goes out
|
|
372
|
+
as `raw_output`. `SIGIT_CLIENT_TERMINAL=off` turns the routing off. Covered by
|
|
373
|
+
`tests/acp_client_terminal.rs`.
|
|
341
374
|
- **`src/chat.rs`** — the Unix-only ratatui TUI. Loading-spinner phase then chat; uses
|
|
342
375
|
`tokio::select!` to multiplex terminal events with streaming tokens.
|
|
343
376
|
- **`src/headless.rs`** — non-interactive `sigit run` execution for scripts, CI, and Factory
|
|
@@ -407,7 +440,8 @@ verbosity with `RUST_LOG`.
|
|
|
407
440
|
default `https://sigit.si`), `SIGIT_CLOUD_URL`, `SIGIT_CONFIG_DIR` (default `~/.config/sigit`),
|
|
408
441
|
`SIGIT_MODEL`, `SIGIT_MAX_TOOL_ROUNDS` (1 to 500, default 24; the tool-round cap of a
|
|
409
442
|
headless run or an ACP prompt turn), `SIGIT_MCP` (`off` disables MCP), `SIGIT_CLIENT_FS` (`off` keeps the file tools on disk even when the
|
|
410
|
-
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `
|
|
443
|
+
ACP client offers `fs/read_text_file` / `fs/write_text_file`), `SIGIT_CLIENT_TERMINAL` (`off` runs
|
|
444
|
+
`run_command` locally even when the ACP client offers a terminal), `SIGIT_MCP_SMBCLOUD` (`off` drops the baked-in
|
|
411
445
|
smbCloud CLI server), `SIGIT_MCP_OFFICIAL` (`off` drops the baked-in
|
|
412
446
|
server), `SIGIT_PERMISSIONS` (`allow`/`ask`/`deny` — overrides the default permission mode for
|
|
413
447
|
mutating tools; the escape hatch for clients without permission-request support),
|