akernel-runtime 0.1.6__tar.gz → 0.1.8__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.
- akernel_runtime-0.1.8/.github/release-notes/v0.1.7.md +32 -0
- akernel_runtime-0.1.8/.github/release-notes/v0.1.8.md +14 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/CHANGELOG.md +20 -0
- {akernel_runtime-0.1.6/src/akernel_runtime.egg-info → akernel_runtime-0.1.8}/PKG-INFO +2 -1
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/packages/npm/akernel/package.json +1 -1
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/pyproject.toml +2 -2
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8/src/akernel_runtime.egg-info}/PKG-INFO +2 -1
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/SOURCES.txt +2 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/requires.txt +1 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/__init__.py +1 -1
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/cli.py +120 -23
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/tests/test_runtime.py +15 -1
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.env.example +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/pull_request_template.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.0.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.1.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.2.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.3.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.4.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.5.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/release-notes/v0.1.6.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/workflows/ci.yml +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/.github/workflows/release.yml +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/CODE_OF_CONDUCT.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/CONTRIBUTING.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/LICENSE +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/MANIFEST.in +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/NOTICE +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/README.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/SECURITY.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/00-vision.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/01-architecture.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/02-execution-plan.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/03-cli-mvp.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/04-evaluation.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/05-local-wake.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/06-skill-compiler.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/07-release-and-ci.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/08-open-source-plan.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/09-product-roadmap.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/10-benchmark-evidence.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/docs/11-publishing-setup.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/phase2/01-routing.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/phase2/02-memory.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/phase2/03-budget-profiles.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/scale/01-context-pressure.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/scale/02-agent-editing.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/scale/03-global-memory-marketplace.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/evals/phase2.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/marketplace/skills/index.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/skills/context_budget.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/skills/edit_file.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/skills/markdown/context_budget.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/packages/npm/akernel/README.md +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/packages/npm/akernel/bin/akernel.js +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/scripts/install_remote.ps1 +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/scripts/release_check.ps1 +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/setup.cfg +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/setup.cmd +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/setup.ps1 +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/dependency_links.txt +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/entry_points.txt +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/top_level.txt +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/__main__.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/agent_reports.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/benchmarks.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/budget.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/context.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/evals.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/global_memory.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/loop.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/context_budget.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/context_compaction.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/edit_file.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/index.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/long_task_planning.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/marketplace_data/skills/multi_file_bugfix.json +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/memory.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/models.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/planner.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/policy.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/project.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/providers.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/report_costs.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/runner.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/skills.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/state_writer.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/storage.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/tasks.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/text.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/tokenizer.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/tools.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/context_kernel/verifier.py +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/wake.cmd +0 -0
- {akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/wake.ps1 +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Context Kernel v0.1.7
|
|
2
|
+
|
|
3
|
+
This release adds real-time interactive completions to `akernel`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Python:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
python -m pip install --user --upgrade akernel-runtime
|
|
11
|
+
akernel setup
|
|
12
|
+
akernel
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
npm launcher:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
npm install -g @context-akernel/akernel
|
|
19
|
+
akernel setup
|
|
20
|
+
akernel
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Highlights
|
|
24
|
+
|
|
25
|
+
- Typing `/` now opens command completions such as `/help`, `/status`, `/model`, and `/cost`.
|
|
26
|
+
- Typing `@` now opens workspace file completions for attaching files.
|
|
27
|
+
- Non-interactive shells and scripts still fall back to standard `input()` behavior.
|
|
28
|
+
|
|
29
|
+
## Verification
|
|
30
|
+
|
|
31
|
+
- Added completion unit coverage for slash commands and `@` file candidates.
|
|
32
|
+
- Ran the full Python test suite.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Context Kernel v0.1.8
|
|
2
|
+
|
|
3
|
+
This patch fixes the default TUI rendering rhythm so chat turns no longer flood the terminal with repeated full-screen layouts.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
- The startup workspace view still appears once.
|
|
8
|
+
- Each normal user message now appends only the user turn, compact status, and assistant result.
|
|
9
|
+
- Full redraw remains available through `/clear` or `AKERNEL_ALT_SCREEN=1`.
|
|
10
|
+
|
|
11
|
+
## Verification
|
|
12
|
+
|
|
13
|
+
- Added regression coverage to ensure normal TUI turns do not repeatedly print the full header.
|
|
14
|
+
- Ran the full Python test suite.
|
|
@@ -8,6 +8,26 @@ The project follows a pragmatic pre-1.0 changelog: breaking changes may occur, b
|
|
|
8
8
|
|
|
9
9
|
No changes yet.
|
|
10
10
|
|
|
11
|
+
## 0.1.8 - 2026-05-14
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Changed the default TUI loop to render the full workspace view once, then append only incremental user/status/assistant updates for each turn.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Prevented normal chat turns from repeatedly printing the full fixed UI layout and filling the terminal scrollback.
|
|
20
|
+
|
|
21
|
+
## 0.1.7 - 2026-05-14
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Added real-time chat input completions for slash commands and `@` workspace file search.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Added `prompt_toolkit` as the interactive input dependency, with automatic fallback to native `input()` in non-interactive terminals.
|
|
30
|
+
|
|
11
31
|
## 0.1.6 - 2026-05-14
|
|
12
32
|
|
|
13
33
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: akernel-runtime
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Agent Kernel: a CLI-first context-native agent runtime prototype.
|
|
5
5
|
Author: Context Kernel contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -20,6 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
License-File: NOTICE
|
|
23
|
+
Requires-Dist: prompt_toolkit>=3.0.43
|
|
23
24
|
Provides-Extra: dev
|
|
24
25
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
25
26
|
Requires-Dist: twine>=5.0; extra == "dev"
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "akernel-runtime"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.8"
|
|
8
8
|
description = "Agent Kernel: a CLI-first context-native agent runtime prototype."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
11
|
license-files = ["LICENSE", "NOTICE"]
|
|
12
12
|
requires-python = ">=3.10"
|
|
13
|
-
dependencies = []
|
|
13
|
+
dependencies = ["prompt_toolkit>=3.0.43"]
|
|
14
14
|
keywords = ["agent", "cli", "context", "llm", "token-budget"]
|
|
15
15
|
authors = [
|
|
16
16
|
{ name = "Context Kernel contributors" },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: akernel-runtime
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Agent Kernel: a CLI-first context-native agent runtime prototype.
|
|
5
5
|
Author: Context Kernel contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -20,6 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
License-File: NOTICE
|
|
23
|
+
Requires-Dist: prompt_toolkit>=3.0.43
|
|
23
24
|
Provides-Extra: dev
|
|
24
25
|
Requires-Dist: build>=1.2; extra == "dev"
|
|
25
26
|
Requires-Dist: twine>=5.0; extra == "dev"
|
|
@@ -22,6 +22,8 @@ wake.ps1
|
|
|
22
22
|
.github/release-notes/v0.1.4.md
|
|
23
23
|
.github/release-notes/v0.1.5.md
|
|
24
24
|
.github/release-notes/v0.1.6.md
|
|
25
|
+
.github/release-notes/v0.1.7.md
|
|
26
|
+
.github/release-notes/v0.1.8.md
|
|
25
27
|
.github/workflows/ci.yml
|
|
26
28
|
.github/workflows/release.yml
|
|
27
29
|
docs/00-vision.md
|
|
@@ -43,6 +43,22 @@ from .verifier import verify_trace
|
|
|
43
43
|
|
|
44
44
|
DEFAULT_PRIMARY_MODEL = "gpt-5.5"
|
|
45
45
|
DEFAULT_AUXILIARY_MODEL = "gpt-5.3-codex"
|
|
46
|
+
CHAT_COMMANDS: list[tuple[str, str]] = [
|
|
47
|
+
("/help", "show command palette"),
|
|
48
|
+
("/status", "show workspace and runtime status"),
|
|
49
|
+
("/model", "show primary and auxiliary model roles"),
|
|
50
|
+
("/config", "show setup and environment guidance"),
|
|
51
|
+
("/compact", "show compact task brief"),
|
|
52
|
+
("/paste", "enter a multi-line task"),
|
|
53
|
+
("/task", "print current task session JSON"),
|
|
54
|
+
("/runs", "list recent agent runs"),
|
|
55
|
+
("/cost", "print last run cost report"),
|
|
56
|
+
("/up", "show older transcript lines"),
|
|
57
|
+
("/down", "move back toward latest messages"),
|
|
58
|
+
("/latest", "jump to latest messages"),
|
|
59
|
+
("/clear", "clear transcript"),
|
|
60
|
+
("/exit", "leave interactive session"),
|
|
61
|
+
]
|
|
46
62
|
OPENAI_ENV_KEYS = {
|
|
47
63
|
"api_key": "AKERNEL_OPENAI_API_KEY",
|
|
48
64
|
"base_url": "AKERNEL_OPENAI_BASE_URL",
|
|
@@ -1075,7 +1091,7 @@ def cmd_chat(args: argparse.Namespace) -> None:
|
|
|
1075
1091
|
print_chat_header(workspace, task_id, args)
|
|
1076
1092
|
while True:
|
|
1077
1093
|
try:
|
|
1078
|
-
request =
|
|
1094
|
+
request = read_chat_input(chat_prompt(args), workspace).strip()
|
|
1079
1095
|
except EOFError:
|
|
1080
1096
|
print("")
|
|
1081
1097
|
break
|
|
@@ -1236,15 +1252,15 @@ def run_chat_loop_tui(
|
|
|
1236
1252
|
render_chat_tui_screen(workspace, task_id, args, transcript, last_report, pending_context, status="ready", state=state, clear=use_alt_screen)
|
|
1237
1253
|
while True:
|
|
1238
1254
|
try:
|
|
1239
|
-
request =
|
|
1255
|
+
request = read_chat_input(tui_prompt(args), workspace).strip()
|
|
1240
1256
|
except EOFError:
|
|
1241
1257
|
break
|
|
1242
1258
|
except KeyboardInterrupt:
|
|
1243
1259
|
transcript.append({"role": "system", "title": "Interrupted", "text": "Keyboard interrupt received."})
|
|
1244
|
-
|
|
1260
|
+
render_chat_tui_update(workspace, task_id, args, transcript, last_report, pending_context, status="interrupted", state=state, clear=use_alt_screen)
|
|
1245
1261
|
break
|
|
1246
1262
|
if not request:
|
|
1247
|
-
|
|
1263
|
+
render_chat_tui_update(workspace, task_id, args, transcript, last_report, pending_context, status="ready", state=state, clear=use_alt_screen)
|
|
1248
1264
|
continue
|
|
1249
1265
|
lowered = request.lower()
|
|
1250
1266
|
if lowered in {"/exit", "/quit", "exit", "quit"}:
|
|
@@ -1267,14 +1283,15 @@ def run_chat_loop_tui(
|
|
|
1267
1283
|
state=state,
|
|
1268
1284
|
):
|
|
1269
1285
|
last_report = state.get("last_report")
|
|
1270
|
-
|
|
1286
|
+
render_chat_tui_update(workspace, task_id, args, transcript, last_report, pending_context, status="ready", state=state, clear=use_alt_screen)
|
|
1271
1287
|
continue
|
|
1272
1288
|
|
|
1273
1289
|
request_for_agent = merge_pending_context(request, pending_context)
|
|
1274
1290
|
pending_context.clear()
|
|
1275
1291
|
state["scroll_offset"] = 0
|
|
1276
1292
|
transcript.append({"role": "user", "title": "You", "text": request_for_agent})
|
|
1277
|
-
|
|
1293
|
+
render_chat_tui_message({"role": "user", "title": "You", "text": request_for_agent})
|
|
1294
|
+
render_chat_tui_status("running", args, pending_context)
|
|
1278
1295
|
last_report = AgentLoop(workspace).run(
|
|
1279
1296
|
request_for_agent,
|
|
1280
1297
|
provider_name=args.provider,
|
|
@@ -1292,7 +1309,8 @@ def run_chat_loop_tui(
|
|
|
1292
1309
|
expect_json=args.expect_json,
|
|
1293
1310
|
)
|
|
1294
1311
|
transcript.append({"role": "assistant", "title": "Assistant", "text": format_tui_report(last_report)})
|
|
1295
|
-
|
|
1312
|
+
render_chat_tui_message({"role": "assistant", "title": "Assistant", "text": format_tui_report(last_report)})
|
|
1313
|
+
render_chat_tui_status("ready", args, pending_context, last_report=last_report)
|
|
1296
1314
|
finally:
|
|
1297
1315
|
if use_alt_screen:
|
|
1298
1316
|
print("\033[?1049l", end="")
|
|
@@ -1392,27 +1410,62 @@ def capture_chat_output(func: Any) -> str:
|
|
|
1392
1410
|
|
|
1393
1411
|
def format_chat_help_text() -> str:
|
|
1394
1412
|
rows = [
|
|
1395
|
-
|
|
1396
|
-
("/status", "show workspace and runtime status"),
|
|
1397
|
-
("/model", "show primary and auxiliary model roles"),
|
|
1398
|
-
("/config", "show setup and environment guidance"),
|
|
1399
|
-
("/compact", "show the compact task brief used for resume context"),
|
|
1400
|
-
("/paste", "enter a multi-line task; finish with /end"),
|
|
1401
|
-
("@path", "attach a workspace file to the next task"),
|
|
1402
|
-
("!command", "run a policy-checked command and attach its summary"),
|
|
1403
|
-
("/task", "print the current task session JSON"),
|
|
1404
|
-
("/runs", "list recent agent runs"),
|
|
1405
|
-
("/cost", "print the last agent run cost report"),
|
|
1406
|
-
("/up", "show older transcript lines in the viewport"),
|
|
1407
|
-
("/down", "move the viewport back toward latest messages"),
|
|
1408
|
-
("/latest", "jump to the newest transcript lines"),
|
|
1409
|
-
("/clear", "clear the transcript"),
|
|
1410
|
-
("/exit", "leave the interactive session"),
|
|
1413
|
+
*CHAT_COMMANDS,
|
|
1411
1414
|
("@query", "search current workspace files; use @1, @2... to attach a listed match"),
|
|
1415
|
+
("!command", "run a policy-checked command and attach its summary"),
|
|
1412
1416
|
]
|
|
1413
1417
|
return "\n".join(f"{name:<10} {description}" for name, description in rows)
|
|
1414
1418
|
|
|
1415
1419
|
|
|
1420
|
+
def read_chat_input(prompt: str, workspace: Workspace) -> str:
|
|
1421
|
+
if not should_use_prompt_toolkit():
|
|
1422
|
+
return input(prompt)
|
|
1423
|
+
try:
|
|
1424
|
+
from prompt_toolkit import PromptSession
|
|
1425
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
1426
|
+
from prompt_toolkit.formatted_text import ANSI
|
|
1427
|
+
from prompt_toolkit.shortcuts import CompleteStyle
|
|
1428
|
+
except ImportError:
|
|
1429
|
+
return input(prompt)
|
|
1430
|
+
|
|
1431
|
+
class ChatCompleter(Completer):
|
|
1432
|
+
def get_completions(self, document: Any, complete_event: Any) -> Any:
|
|
1433
|
+
text = document.text_before_cursor
|
|
1434
|
+
for value, description in chat_completion_items(workspace.root, text):
|
|
1435
|
+
yield Completion(value, start_position=-len(text), display=value, display_meta=description)
|
|
1436
|
+
|
|
1437
|
+
session = PromptSession(
|
|
1438
|
+
completer=ChatCompleter(),
|
|
1439
|
+
complete_while_typing=True,
|
|
1440
|
+
complete_in_thread=True,
|
|
1441
|
+
complete_style=CompleteStyle.MULTI_COLUMN,
|
|
1442
|
+
reserve_space_for_menu=6,
|
|
1443
|
+
)
|
|
1444
|
+
return session.prompt(ANSI(prompt))
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
def should_use_prompt_toolkit() -> bool:
|
|
1448
|
+
if os.environ.get("AKERNEL_NO_COMPLETION"):
|
|
1449
|
+
return False
|
|
1450
|
+
return bool(sys.stdin.isatty() and sys.stdout.isatty())
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
def chat_completion_items(root: Path, text: str, *, limit: int = 12) -> list[tuple[str, str]]:
|
|
1454
|
+
value = text.strip()
|
|
1455
|
+
if value.startswith("/"):
|
|
1456
|
+
query = value.casefold()
|
|
1457
|
+
return [
|
|
1458
|
+
(command, description)
|
|
1459
|
+
for command, description in CHAT_COMMANDS
|
|
1460
|
+
if command.casefold().startswith(query)
|
|
1461
|
+
][:limit]
|
|
1462
|
+
if value.startswith("@"):
|
|
1463
|
+
query = value[1:].strip()
|
|
1464
|
+
matches = find_workspace_files(root, query, limit=limit)
|
|
1465
|
+
return [(f"@{path}", "attach file") for path in matches]
|
|
1466
|
+
return []
|
|
1467
|
+
|
|
1468
|
+
|
|
1416
1469
|
def tui_prompt(args: argparse.Namespace) -> str:
|
|
1417
1470
|
return chat_color("\nakernel", "cyan", bold=True) + chat_color(f" [{primary_model(args)}]", "dim") + "> "
|
|
1418
1471
|
|
|
@@ -1434,6 +1487,50 @@ def render_chat_tui_screen(
|
|
|
1434
1487
|
print(prefix + screen + ("\n" if not clear else ""), end="")
|
|
1435
1488
|
|
|
1436
1489
|
|
|
1490
|
+
def render_chat_tui_update(
|
|
1491
|
+
workspace: Workspace,
|
|
1492
|
+
task_id: str,
|
|
1493
|
+
args: argparse.Namespace,
|
|
1494
|
+
transcript: list[dict[str, str]],
|
|
1495
|
+
last_report: dict[str, Any] | None,
|
|
1496
|
+
pending_context: list[str],
|
|
1497
|
+
*,
|
|
1498
|
+
status: str,
|
|
1499
|
+
state: dict[str, Any] | None = None,
|
|
1500
|
+
clear: bool = True,
|
|
1501
|
+
) -> None:
|
|
1502
|
+
if clear:
|
|
1503
|
+
render_chat_tui_screen(workspace, task_id, args, transcript, last_report, pending_context, status=status, state=state, clear=True)
|
|
1504
|
+
return
|
|
1505
|
+
if transcript:
|
|
1506
|
+
render_chat_tui_message(transcript[-1])
|
|
1507
|
+
render_chat_tui_status(status, args, pending_context, last_report=last_report)
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
def render_chat_tui_message(item: dict[str, str]) -> None:
|
|
1511
|
+
width = chat_width()
|
|
1512
|
+
role = item.get("role", "system")
|
|
1513
|
+
title = item.get("title", role)
|
|
1514
|
+
label = tui_role_label(role, title)
|
|
1515
|
+
prefix = " " if role != "user" else "> "
|
|
1516
|
+
print("")
|
|
1517
|
+
print(chat_color(truncate_line(label, width), "cyan" if role == "system" else "green" if role == "assistant" else "yellow", bold=True))
|
|
1518
|
+
for line in wrap_plain(item.get("text", ""), width=max(20, width - len(prefix))).splitlines():
|
|
1519
|
+
print(truncate_line(prefix + line, width))
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
def render_chat_tui_status(
|
|
1523
|
+
status: str,
|
|
1524
|
+
args: argparse.Namespace,
|
|
1525
|
+
pending_context: list[str],
|
|
1526
|
+
*,
|
|
1527
|
+
last_report: dict[str, Any] | None = None,
|
|
1528
|
+
) -> None:
|
|
1529
|
+
tokens = 0 if not last_report else last_report.get("totals", {}).get("total_tokens", 0)
|
|
1530
|
+
summary = f"{status} | provider {args.provider} | primary {primary_model(args)} | attached {len(pending_context)} | tokens {tokens}"
|
|
1531
|
+
print(chat_color(truncate_line(summary, chat_width()), "dim"))
|
|
1532
|
+
|
|
1533
|
+
|
|
1437
1534
|
def build_chat_tui_screen(
|
|
1438
1535
|
workspace: Workspace,
|
|
1439
1536
|
task_id: str,
|
|
@@ -10,7 +10,7 @@ from unittest.mock import patch
|
|
|
10
10
|
from context_kernel.agent_reports import build_agent_cost_report, render_agent_cost_report
|
|
11
11
|
from context_kernel.benchmarks import BenchmarkRunner, render_benchmark_evidence_markdown, render_benchmark_markdown
|
|
12
12
|
from context_kernel.budget import allocate_budget
|
|
13
|
-
from context_kernel.cli import build_chat_tui_screen, load_batch_patch_specs, main, print_agent_report
|
|
13
|
+
from context_kernel.cli import build_chat_tui_screen, chat_completion_items, load_batch_patch_specs, main, print_agent_report
|
|
14
14
|
from context_kernel.context import ContextBuilder
|
|
15
15
|
from context_kernel.evals import EvalRunner
|
|
16
16
|
from context_kernel.global_memory import pull_global_memories, push_global_memories
|
|
@@ -1357,6 +1357,7 @@ class RuntimeTests(unittest.TestCase):
|
|
|
1357
1357
|
self.assertIn("Assistant", output)
|
|
1358
1358
|
self.assertIn("Mock agent response", output)
|
|
1359
1359
|
self.assertIn("bye", output)
|
|
1360
|
+
self.assertEqual(output.count("AKERNEL // READY"), 1)
|
|
1360
1361
|
|
|
1361
1362
|
def test_tui_screen_can_render_older_history_window(self) -> None:
|
|
1362
1363
|
with tempfile.TemporaryDirectory() as tmp:
|
|
@@ -1417,6 +1418,19 @@ class RuntimeTests(unittest.TestCase):
|
|
|
1417
1418
|
self.assertIn("Attached File", output)
|
|
1418
1419
|
self.assertIn("Mock agent response", output)
|
|
1419
1420
|
|
|
1421
|
+
def test_chat_completion_items_include_commands_and_files(self) -> None:
|
|
1422
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
1423
|
+
root = Path(tmp)
|
|
1424
|
+
(root / "README.md").write_text("demo", encoding="utf-8")
|
|
1425
|
+
(root / "src").mkdir()
|
|
1426
|
+
(root / "src" / "runtime.py").write_text("print('ok')", encoding="utf-8")
|
|
1427
|
+
|
|
1428
|
+
command_items = chat_completion_items(root, "/mo")
|
|
1429
|
+
file_items = chat_completion_items(root, "@run")
|
|
1430
|
+
|
|
1431
|
+
self.assertIn(("/model", "show primary and auxiliary model roles"), command_items)
|
|
1432
|
+
self.assertIn(("@src/runtime.py", "attach file"), file_items)
|
|
1433
|
+
|
|
1420
1434
|
def test_tui_screen_surfaces_task_plan_and_command_strip(self) -> None:
|
|
1421
1435
|
with tempfile.TemporaryDirectory() as tmp:
|
|
1422
1436
|
workspace = Workspace(Path(tmp))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/phase2/03-budget-profiles.json
RENAMED
|
File without changes
|
{akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/scale/01-context-pressure.json
RENAMED
|
File without changes
|
{akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/examples/benchmarks/scale/02-agent-editing.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{akernel_runtime-0.1.6 → akernel_runtime-0.1.8}/src/akernel_runtime.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|