cluxion-agentplugin-preprocessing 0.3.20__tar.gz → 0.3.22__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.
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/PKG-INFO +1 -1
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/pyproject.toml +1 -1
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/context.rs +6 -4
- cluxion_agentplugin_preprocessing-0.3.22/rust/cluxion_queue/uv.lock +8 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/plugin.py +25 -1
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/plugin.yaml +2 -1
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/runner.py +14 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/schemas.py +52 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/cli.py +66 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/context_compress.py +3 -1
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/harness.py +2 -0
- cluxion_agentplugin_preprocessing-0.3.22/src/cluxion_runtime/core/loop_auto.py +443 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/plan_codec.py +1 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/types.py +1 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_context_compress.py +6 -1
- cluxion_agentplugin_preprocessing-0.3.22/tests/runtime/test_loop_auto.py +106 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_runtime_adapter_cli.py +2 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_plugin.py +1 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/.github/profile/README.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/.gitignore +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/Docs/README.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/LICENSE +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/README.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/adapters/claude/.claude-plugin/plugin.json +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/adapters/claude/skills/preprocess/SKILL.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/adapters/codex/config-snippet.toml +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/README.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/architecture.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/harness-logic.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/honesty-preprocessing.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/install-and-operations.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/cluxion-Docs/security.md +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/Cargo.lock +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/Cargo.toml +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/pyproject.toml +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/dispatch.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/guard.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/lib.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/main.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/queue.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/rust/cluxion_queue/src/types.rs +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/cli.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/doctor/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/doctor/catalog.json +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/doctor/framework.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/doctor/probes.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/guard_watch.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_agentplugin_preprocessing/hermes_config.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/__main__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/adapters/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/adapters/contract.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/adapters/grok_build.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/adapters/hermes.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/adapters/spec.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/bootstrap.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/clarification.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/dispatch_store.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/hybrid_forget.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/intent.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/ledger.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/ledger_codec.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/llm_compress.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/preprocess.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/core/work_queue.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/guard_daemon_host.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/models/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/models/supervisor.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/models/vllm_mlx.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/resources/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/resources/guard_bridge.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/resources/py_queue.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/resources/queue_bridge.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/resources/rust_bridge.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/web/__init__.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/src/cluxion_runtime/web/browser_bridge.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_auto_compress_middleware.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_bin_resolution.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_browser_bridge.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_clarification.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_cluxion_runtime_spine.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_context_compress_llm_forget.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_contract.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_dispatch_store.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_estimate_tokens.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_guard.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_guard_daemon_host.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_ledger.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_py_queue_concurrency.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_queue_backends.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_rust_queue.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/runtime/test_supervisor.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_bootstrap.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_doctor.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_guard_watch.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_hermes_config.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_packaging_policy.py +0 -0
- {cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/tests/test_runner.py +0 -0
{cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cluxion-agentplugin-preprocessing
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.22
|
|
4
4
|
Summary: Universal agent plugin for Cluxion preprocessing, honesty contracts, clarification, Rust work queue, and resource-aware harness handoff.
|
|
5
5
|
Project-URL: Homepage, https://github.com/cluxion/cluxion-Agentplugin-preprocessing
|
|
6
6
|
Project-URL: Repository, https://github.com/cluxion/cluxion-Agentplugin-preprocessing
|
{cluxion_agentplugin_preprocessing-0.3.20 → cluxion_agentplugin_preprocessing-0.3.22}/pyproject.toml
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cluxion-agentplugin-preprocessing"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.22"
|
|
8
8
|
description = "Universal agent plugin for Cluxion preprocessing, honesty contracts, clarification, Rust work queue, and resource-aware harness handoff."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -46,10 +46,12 @@ struct Msg {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
pub fn compress(payload: &Value) -> Result<Value, QueueError> {
|
|
49
|
-
let raw_messages = payload
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
|
|
49
|
+
let raw_messages = match payload.get("messages") {
|
|
50
|
+
None => return Err(QueueError::Usage("missing required field: messages".into())),
|
|
51
|
+
Some(value) => value.as_array().ok_or_else(|| {
|
|
52
|
+
QueueError::Usage("messages must be a list".into())
|
|
53
|
+
})?,
|
|
54
|
+
};
|
|
53
55
|
let mut messages: Vec<Msg> = Vec::with_capacity(raw_messages.len());
|
|
54
56
|
for raw in raw_messages {
|
|
55
57
|
messages.push(Msg {
|
|
@@ -20,6 +20,7 @@ from cluxion_agentplugin_preprocessing.schemas import (
|
|
|
20
20
|
CONTEXT_COMPRESS_SCHEMA,
|
|
21
21
|
GUARD_SCHEMA,
|
|
22
22
|
HERMES_CONFIG_SCHEMA,
|
|
23
|
+
LOOP_AUTO_SCHEMA,
|
|
23
24
|
PLAN_SCHEMA,
|
|
24
25
|
QUEUE_BRIEF_SCHEMA,
|
|
25
26
|
QUEUE_NEXT_SCHEMA,
|
|
@@ -32,6 +33,7 @@ from cluxion_runtime.core.context_compress import (
|
|
|
32
33
|
_resolve_context_limit,
|
|
33
34
|
compress,
|
|
34
35
|
)
|
|
36
|
+
from cluxion_runtime.core.loop_auto import strip_loop_auto_directive
|
|
35
37
|
from cluxion_runtime.core.preprocess import estimate_tokens
|
|
36
38
|
|
|
37
39
|
if TYPE_CHECKING:
|
|
@@ -114,6 +116,14 @@ def register(ctx: object) -> None:
|
|
|
114
116
|
check_fn=_check_runtime_available,
|
|
115
117
|
emoji="📌",
|
|
116
118
|
)
|
|
119
|
+
ctx.register_tool(
|
|
120
|
+
name="cluxion_loop_auto",
|
|
121
|
+
toolset="cluxion",
|
|
122
|
+
schema=LOOP_AUTO_SCHEMA,
|
|
123
|
+
handler=_handle_loop_auto,
|
|
124
|
+
check_fn=_check_runtime_available,
|
|
125
|
+
emoji="🔁",
|
|
126
|
+
)
|
|
117
127
|
ctx.register_tool(
|
|
118
128
|
name="cluxion_context_compress",
|
|
119
129
|
toolset="cluxion",
|
|
@@ -201,7 +211,17 @@ def _check_browser_tool_available() -> bool:
|
|
|
201
211
|
|
|
202
212
|
|
|
203
213
|
def _handle_plan(args: dict[str, object], **_: object) -> str:
|
|
204
|
-
return _json_result(lambda: runner.plan(args).to_json())
|
|
214
|
+
return _json_result(lambda: runner.plan(_plan_args_with_loop_auto(args)).to_json())
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _plan_args_with_loop_auto(args: dict[str, object]) -> dict[str, object]:
|
|
218
|
+
payload = dict(args)
|
|
219
|
+
prompt = str(payload.get("prompt", ""))
|
|
220
|
+
cleaned, had_directive = strip_loop_auto_directive(prompt)
|
|
221
|
+
if had_directive:
|
|
222
|
+
payload["prompt"] = cleaned
|
|
223
|
+
payload["loop_auto"] = True
|
|
224
|
+
return payload
|
|
205
225
|
|
|
206
226
|
|
|
207
227
|
def _handle_clarify(args: dict[str, object], **_: object) -> str:
|
|
@@ -232,6 +252,10 @@ def _handle_queue_brief(args: dict[str, object], **_: object) -> str:
|
|
|
232
252
|
return _json_result(lambda: runner.queue_brief(args).to_json())
|
|
233
253
|
|
|
234
254
|
|
|
255
|
+
def _handle_loop_auto(args: dict[str, object], **_: object) -> str:
|
|
256
|
+
return _json_result(lambda: runner.loop_auto(args).to_json())
|
|
257
|
+
|
|
258
|
+
|
|
235
259
|
def _handle_context_compress(args: dict[str, object], **_: object) -> str:
|
|
236
260
|
return _json_result(lambda: runner.context_compress(args).to_json())
|
|
237
261
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: cluxion-agentplugin-preprocessing
|
|
2
|
-
version: 0.3.
|
|
2
|
+
version: 0.3.22
|
|
3
3
|
description: "Universal agent preprocessing plugin: honesty contracts, clarification, Rust work queue, resource-aware harness handoff. Connected AI calls cluxion tools; plugin does not own models."
|
|
4
4
|
author: cluxion
|
|
5
5
|
kind: standalone
|
|
@@ -12,6 +12,7 @@ provides_tools:
|
|
|
12
12
|
- cluxion_queue_next
|
|
13
13
|
- cluxion_queue_record
|
|
14
14
|
- cluxion_queue_brief
|
|
15
|
+
- cluxion_loop_auto
|
|
15
16
|
- cluxion_context_compress
|
|
16
17
|
- cluxion_guard
|
|
17
18
|
- cluxion_web_search
|
|
@@ -144,6 +144,19 @@ def queue_brief(payload: Mapping[str, object], *, command_runner: CommandRunner
|
|
|
144
144
|
return _execute_json(command, None, command_runner)
|
|
145
145
|
|
|
146
146
|
|
|
147
|
+
def loop_auto(payload: Mapping[str, object], *, command_runner: CommandRunner | None = None) -> RuntimeResult:
|
|
148
|
+
"""Autonomously drain the dispatch queue via Hermes oneshot calls (/loopAuto)."""
|
|
149
|
+
command = (
|
|
150
|
+
_runtime_binary(None),
|
|
151
|
+
"loop-auto",
|
|
152
|
+
"--work-id",
|
|
153
|
+
_required_str(payload, "work_id"),
|
|
154
|
+
"--json-stdin",
|
|
155
|
+
)
|
|
156
|
+
stdin = json.dumps(dict(payload), ensure_ascii=False)
|
|
157
|
+
return _execute_json(command, stdin, command_runner)
|
|
158
|
+
|
|
159
|
+
|
|
147
160
|
def context_compress(payload: Mapping[str, object], *, command_runner: CommandRunner | None = None) -> RuntimeResult:
|
|
148
161
|
"""Compress conversation context deterministically once it exceeds the trigger ratio."""
|
|
149
162
|
messages = payload.get("messages")
|
|
@@ -367,6 +380,7 @@ __all__ = [
|
|
|
367
380
|
"context_compress",
|
|
368
381
|
"guard",
|
|
369
382
|
"hermes_config",
|
|
383
|
+
"loop_auto",
|
|
370
384
|
"plan",
|
|
371
385
|
"queue_brief",
|
|
372
386
|
"queue_next",
|
|
@@ -58,6 +58,31 @@ PLAN_SCHEMA = {
|
|
|
58
58
|
"default": "",
|
|
59
59
|
"description": "Answers that resolve a prior clarification gate; required to enqueue an ambiguous or large task.",
|
|
60
60
|
},
|
|
61
|
+
"loop_auto": {
|
|
62
|
+
"type": "boolean",
|
|
63
|
+
"default": True,
|
|
64
|
+
"description": "After a queued plan is stored, autonomously drain segments via Hermes oneshot calls.",
|
|
65
|
+
},
|
|
66
|
+
"loop_auto_dry_run": {
|
|
67
|
+
"type": "boolean",
|
|
68
|
+
"default": False,
|
|
69
|
+
"description": "Simulate Hermes segment execution without calling the hermes binary.",
|
|
70
|
+
},
|
|
71
|
+
"loop_auto_timeout_s": {
|
|
72
|
+
"type": "number",
|
|
73
|
+
"default": 600,
|
|
74
|
+
"description": "Maximum seconds for the full autonomous drain loop.",
|
|
75
|
+
},
|
|
76
|
+
"hermes_bin": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"default": "hermes",
|
|
79
|
+
"description": "Hermes CLI binary used for each segment oneshot.",
|
|
80
|
+
},
|
|
81
|
+
"model": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"default": "",
|
|
84
|
+
"description": "Optional Hermes model override (-m) for segment oneshots.",
|
|
85
|
+
},
|
|
61
86
|
},
|
|
62
87
|
"required": ["prompt"],
|
|
63
88
|
},
|
|
@@ -142,6 +167,32 @@ QUEUE_BRIEF_SCHEMA = {
|
|
|
142
167
|
},
|
|
143
168
|
}
|
|
144
169
|
|
|
170
|
+
LOOP_AUTO_SCHEMA = {
|
|
171
|
+
"name": "cluxion_loop_auto",
|
|
172
|
+
"description": (
|
|
173
|
+
"Autonomously drain the Cluxion dispatch queue via Hermes oneshot calls. "
|
|
174
|
+
"Equivalent to /loopAuto: next segment -> hermes -z -> record -> ... -> briefing. "
|
|
175
|
+
"Use after cluxion_plan queued a durable work bundle, or pass loop_auto on plan."
|
|
176
|
+
),
|
|
177
|
+
"parameters": {
|
|
178
|
+
"type": "object",
|
|
179
|
+
"properties": {
|
|
180
|
+
"work_id": {"type": "string", "description": "Queued work bundle id from cluxion_plan."},
|
|
181
|
+
"cwd": {"type": "string", "default": ""},
|
|
182
|
+
"hermes_bin": {"type": "string", "default": "hermes"},
|
|
183
|
+
"model": {"type": "string", "default": ""},
|
|
184
|
+
"timeout_seconds": {"type": "number", "default": 600},
|
|
185
|
+
"max_segment_retries": {"type": "integer", "minimum": 0, "default": 2},
|
|
186
|
+
"dry_run": {
|
|
187
|
+
"type": "boolean",
|
|
188
|
+
"default": False,
|
|
189
|
+
"description": "Simulate Hermes without calling the binary (tests and diagnostics).",
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
"required": ["work_id"],
|
|
193
|
+
},
|
|
194
|
+
}
|
|
195
|
+
|
|
145
196
|
CONTEXT_COMPRESS_SCHEMA = {
|
|
146
197
|
"name": "cluxion_context_compress",
|
|
147
198
|
"description": (
|
|
@@ -370,6 +421,7 @@ __all__ = [
|
|
|
370
421
|
"CONTEXT_COMPRESS_SCHEMA",
|
|
371
422
|
"GUARD_SCHEMA",
|
|
372
423
|
"HERMES_CONFIG_SCHEMA",
|
|
424
|
+
"LOOP_AUTO_SCHEMA",
|
|
373
425
|
"PLAN_SCHEMA",
|
|
374
426
|
"QUEUE_BRIEF_SCHEMA",
|
|
375
427
|
"QUEUE_NEXT_SCHEMA",
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import argparse
|
|
6
6
|
import json
|
|
7
7
|
import sys
|
|
8
|
+
from pathlib import Path
|
|
8
9
|
from typing import TYPE_CHECKING
|
|
9
10
|
|
|
10
11
|
from cluxion_runtime.adapters.contract import work_item_from_adapter_payload
|
|
@@ -23,6 +24,12 @@ from cluxion_runtime.core.dispatch_store import (
|
|
|
23
24
|
record_dispatch_result,
|
|
24
25
|
)
|
|
25
26
|
from cluxion_runtime.core.harness import build_harness_plan
|
|
27
|
+
from cluxion_runtime.core.loop_auto import (
|
|
28
|
+
LoopAutoOptions,
|
|
29
|
+
run_loop_auto,
|
|
30
|
+
should_auto_loop_plan,
|
|
31
|
+
strip_loop_auto_directive,
|
|
32
|
+
)
|
|
26
33
|
from cluxion_runtime.core.plan_codec import plan_to_dict
|
|
27
34
|
from cluxion_runtime.core.types import AgentSurface, ModelRuntimeProfile
|
|
28
35
|
from cluxion_runtime.models import LocalModelSupervisor, build_vllm_mlx_profile
|
|
@@ -49,6 +56,8 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
49
56
|
return _run_queue_record(args)
|
|
50
57
|
if args.command == "queue-brief":
|
|
51
58
|
return _run_queue_brief(args)
|
|
59
|
+
if args.command == "loop-auto":
|
|
60
|
+
return _run_loop_auto(args)
|
|
52
61
|
if args.command == "context-compress":
|
|
53
62
|
return _run_context_compress(args)
|
|
54
63
|
if args.command == "guard":
|
|
@@ -111,6 +120,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
111
120
|
"queue-brief", help="Build the final briefing prompt from stored segment results"
|
|
112
121
|
)
|
|
113
122
|
queue_brief.add_argument("--work-id", required=True)
|
|
123
|
+
loop_auto = subparsers.add_parser(
|
|
124
|
+
"loop-auto",
|
|
125
|
+
help="Autonomously drain the dispatch queue via Hermes oneshot calls (/loopAuto)",
|
|
126
|
+
)
|
|
127
|
+
loop_auto.add_argument("--work-id", required=True)
|
|
128
|
+
loop_auto.add_argument("--cwd", default="")
|
|
129
|
+
loop_auto.add_argument("--hermes-bin", default="hermes")
|
|
130
|
+
loop_auto.add_argument("--model", default="")
|
|
131
|
+
loop_auto.add_argument("--timeout-seconds", type=float, default=600.0)
|
|
132
|
+
loop_auto.add_argument("--max-segment-retries", type=int, default=2)
|
|
133
|
+
loop_auto.add_argument("--dry-run", action="store_true")
|
|
134
|
+
loop_auto.add_argument("--json-stdin", action="store_true")
|
|
114
135
|
context_compress = subparsers.add_parser(
|
|
115
136
|
"context-compress",
|
|
116
137
|
help="Deterministically compress conversation context to the target ratio once past the trigger ratio",
|
|
@@ -137,6 +158,7 @@ def _run_bootstrap(args: argparse.Namespace) -> int:
|
|
|
137
158
|
def _run_plan(args: argparse.Namespace) -> int:
|
|
138
159
|
surface = AgentSurface(str(args.surface))
|
|
139
160
|
payload = _payload_from_stdin() if args.json_stdin else _payload_from_args(args)
|
|
161
|
+
payload = _apply_loop_auto_directive(payload)
|
|
140
162
|
item = work_item_from_adapter_payload(payload, default_surface=surface)
|
|
141
163
|
plan = build_harness_plan(item)
|
|
142
164
|
persisted = persist_dispatch_bundle(plan)
|
|
@@ -146,10 +168,43 @@ def _run_plan(args: argparse.Namespace) -> int:
|
|
|
146
168
|
if isinstance(item_output, dict):
|
|
147
169
|
item_output["original_prompt_stored"] = True
|
|
148
170
|
output["dispatch_store"] = {"stored": True, "path": str(persisted)}
|
|
171
|
+
loop_auto_flag = payload.get("loop_auto") if isinstance(payload, dict) else None
|
|
172
|
+
if should_auto_loop_plan(output, loop_auto=bool(loop_auto_flag) if loop_auto_flag is not None else None):
|
|
173
|
+
cwd = str(payload.get("cwd", "")) if isinstance(payload, dict) else ""
|
|
174
|
+
loop_result = run_loop_auto(
|
|
175
|
+
LoopAutoOptions(
|
|
176
|
+
work_id=plan.item.work_id,
|
|
177
|
+
cwd=Path(cwd).expanduser() if cwd else Path.cwd(),
|
|
178
|
+
hermes_bin=str(payload.get("hermes_bin", "hermes")) if isinstance(payload, dict) else "hermes",
|
|
179
|
+
model=str(payload.get("model", "")) if isinstance(payload, dict) else "",
|
|
180
|
+
timeout_seconds=float(payload.get("loop_auto_timeout_s", 600)) if isinstance(payload, dict) else 600.0,
|
|
181
|
+
dry_run=bool(payload.get("loop_auto_dry_run", False)) if isinstance(payload, dict) else False,
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
output["loop_auto"] = loop_result.to_dict()
|
|
149
185
|
print(json.dumps(output, ensure_ascii=False, sort_keys=True))
|
|
150
186
|
return 0
|
|
151
187
|
|
|
152
188
|
|
|
189
|
+
def _run_loop_auto(args: argparse.Namespace) -> int:
|
|
190
|
+
payload = _payload_from_stdin() if args.json_stdin else {}
|
|
191
|
+
work_id = str(payload.get("work_id", args.work_id))
|
|
192
|
+
cwd_raw = str(payload.get("cwd", args.cwd))
|
|
193
|
+
result = run_loop_auto(
|
|
194
|
+
LoopAutoOptions(
|
|
195
|
+
work_id=work_id,
|
|
196
|
+
cwd=Path(cwd_raw).expanduser() if cwd_raw else Path.cwd(),
|
|
197
|
+
hermes_bin=str(payload.get("hermes_bin", args.hermes_bin)),
|
|
198
|
+
model=str(payload.get("model", args.model)),
|
|
199
|
+
timeout_seconds=float(payload.get("timeout_seconds", args.timeout_seconds)),
|
|
200
|
+
max_segment_retries=int(payload.get("max_segment_retries", args.max_segment_retries)),
|
|
201
|
+
dry_run=bool(payload.get("dry_run", args.dry_run)),
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
print(json.dumps(result.to_dict(), ensure_ascii=False, sort_keys=True))
|
|
205
|
+
return 0 if result.ok else 1
|
|
206
|
+
|
|
207
|
+
|
|
153
208
|
def _run_queue_next(args: argparse.Namespace) -> int:
|
|
154
209
|
try:
|
|
155
210
|
payload = next_dispatch_step(str(args.work_id))
|
|
@@ -389,6 +444,17 @@ def _payload_from_args(args: argparse.Namespace) -> dict[str, object]:
|
|
|
389
444
|
}
|
|
390
445
|
|
|
391
446
|
|
|
447
|
+
def _apply_loop_auto_directive(payload: dict[str, object]) -> dict[str, object]:
|
|
448
|
+
prompt = str(payload.get("prompt", ""))
|
|
449
|
+
cleaned, had_directive = strip_loop_auto_directive(prompt)
|
|
450
|
+
if not had_directive:
|
|
451
|
+
return payload
|
|
452
|
+
updated = dict(payload)
|
|
453
|
+
updated["prompt"] = cleaned
|
|
454
|
+
updated["loop_auto"] = True
|
|
455
|
+
return updated
|
|
456
|
+
|
|
457
|
+
|
|
392
458
|
if __name__ == "__main__":
|
|
393
459
|
raise SystemExit(main())
|
|
394
460
|
|
|
@@ -58,8 +58,10 @@ class _Msg:
|
|
|
58
58
|
|
|
59
59
|
def compress(payload: Mapping[str, object]) -> dict[str, object]:
|
|
60
60
|
raw_messages = payload.get("messages")
|
|
61
|
-
if
|
|
61
|
+
if raw_messages is None:
|
|
62
62
|
raise RuntimeError("missing required field: messages")
|
|
63
|
+
if not isinstance(raw_messages, list):
|
|
64
|
+
raise RuntimeError("messages must be a list")
|
|
63
65
|
messages = [
|
|
64
66
|
_Msg(
|
|
65
67
|
role=str(raw.get("role", "user")) if isinstance(raw, dict) else "user",
|
|
@@ -201,10 +201,12 @@ def _host_execution_plan_for(
|
|
|
201
201
|
next_tool="cluxion_queue_next",
|
|
202
202
|
record_tool="cluxion_queue_record",
|
|
203
203
|
brief_tool="cluxion_queue_brief",
|
|
204
|
+
loop_tool="cluxion_loop_auto",
|
|
204
205
|
performance_notes=(
|
|
205
206
|
*base_notes,
|
|
206
207
|
"queued_plan_stores_segment_content_out_of_band",
|
|
207
208
|
"initial_plan_returns_metadata_not_full_segment_payload",
|
|
209
|
+
"use_cluxion_loop_auto_or_slash_loopAuto_for_autonomous_drain",
|
|
208
210
|
),
|
|
209
211
|
)
|
|
210
212
|
return HostExecutionPlan(
|