fruxon 0.8.0__tar.gz → 0.8.2__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.
- {fruxon-0.8.0 → fruxon-0.8.2}/PKG-INFO +1 -1
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/_version.py +2 -2
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/examples.py +2 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/run.py +18 -3
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-meet/SKILL.md +1 -1
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_cli.py +31 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/.gitignore +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/HISTORY.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/LICENSE +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/README.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/pyproject.toml +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/__init__.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/__main__.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/_ssl.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/__init__.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/_schema.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/_shared.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/agents.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/agents_budget.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/agents_draft.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/agents_revisions.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/agents_tests.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/auth.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/chat.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/completion.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/config.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/describe.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/doctor.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/guides.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/integrations.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/keys.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/llm_providers.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/skills.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/tools.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli/trace.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/cli_auth.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/credentials.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/doctor.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/exceptions.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/fruxon.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/models.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/output.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/params.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/__init__.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-agent-mode/SKILL.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-build-agent/SKILL.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-create-integration/SKILL.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-debug-revision/SKILL.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/skills/fruxon-use-integrations/SKILL.md +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/ui.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/update_check.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/src/fruxon/validation.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/__init__.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/conftest.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_actor.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_budgets.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_client.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_credentials.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_doctor.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_draft_evaluate_cli.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_drafts.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_fruxon.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_guides.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_output.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_params.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_schema.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_skills.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_ssl.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_test_chats.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_ui.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_update_check.py +0 -0
- {fruxon-0.8.0 → fruxon-0.8.2}/tests/test_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fruxon
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
4
4
|
Summary: The Fruxon SDK is a lightweight Python client for integrating with the Fruxon platform.
|
|
5
5
|
Project-URL: bugs, https://github.com/fruxon-ai/fruxon-sdk/issues
|
|
6
6
|
Project-URL: changelog, https://github.com/fruxon-ai/fruxon-sdk/blob/main/HISTORY.md
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.8.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 8,
|
|
21
|
+
__version__ = version = '0.8.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 8, 2)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -52,6 +52,8 @@ _EXAMPLES: dict[str, list[tuple[str, str]]] = {
|
|
|
52
52
|
("fruxon agents list", "Browse what's deployed"),
|
|
53
53
|
("fruxon agents get my-agent", "Show one agent's manifest"),
|
|
54
54
|
("fruxon agents schema my-agent", "Param shape — feed to an LLM before `run`"),
|
|
55
|
+
("fruxon agents draft pull my-agent", "Fetch the working copy locally"),
|
|
56
|
+
("fruxon agents draft run my-agent -p user_query='hi'", "Run the draft (Origin=TEST, no prod spend)"),
|
|
55
57
|
("fruxon agents revisions my-agent", "List revisions for an agent"),
|
|
56
58
|
("fruxon agents tests my-agent", "List eval/test runs"),
|
|
57
59
|
("fruxon agents budget get my-agent", "Show per-origin cost cap"),
|
|
@@ -695,6 +695,13 @@ def _run_stream_ndjson(
|
|
|
695
695
|
continue
|
|
696
696
|
|
|
697
697
|
trace = event.data.get("trace") if isinstance(event.data.get("trace"), dict) else {}
|
|
698
|
+
# ``-1`` is the backend's sentinel for "no published
|
|
699
|
+
# revision" / "draft head" / similar non-applicable
|
|
700
|
+
# states. For ``agent_revision`` we drop the field
|
|
701
|
+
# entirely in that case rather than emit a misleading
|
|
702
|
+
# ``-1`` an LLM driver would have to special-case on
|
|
703
|
+
# its own side. Other numeric fields (duration, costs)
|
|
704
|
+
# pass through verbatim since their zero is meaningful.
|
|
698
705
|
for src_key, dst_key, cast in (
|
|
699
706
|
("duration", "duration_ms", int),
|
|
700
707
|
("totalCost", "total_cost", float),
|
|
@@ -703,8 +710,11 @@ def _run_stream_ndjson(
|
|
|
703
710
|
("agentRevision", "agent_revision", int),
|
|
704
711
|
):
|
|
705
712
|
val = trace.get(src_key) if isinstance(trace, dict) else None
|
|
706
|
-
if isinstance(val, (int, float)):
|
|
707
|
-
|
|
713
|
+
if not isinstance(val, (int, float)):
|
|
714
|
+
continue
|
|
715
|
+
if src_key == "agentRevision" and val <= 0:
|
|
716
|
+
continue
|
|
717
|
+
done[dst_key] = cast(val)
|
|
708
718
|
_emit_ndjson(done)
|
|
709
719
|
continue
|
|
710
720
|
|
|
@@ -1292,7 +1302,12 @@ def _render_done(data: dict[str, object], *, agent: str | None = None) -> None:
|
|
|
1292
1302
|
parts.append(format_duration(duration))
|
|
1293
1303
|
if isinstance(total_cost, (int, float)) and total_cost:
|
|
1294
1304
|
parts.append(f"${float(total_cost):.4f}")
|
|
1295
|
-
|
|
1305
|
+
# Only surface a real revision number. The backend sends ``-1`` as
|
|
1306
|
+
# a sentinel for "no published revision yet" / "draft head" /
|
|
1307
|
+
# similar non-applicable states — printing it verbatim ("rev -1")
|
|
1308
|
+
# is worse than dropping the field entirely, because it looks like
|
|
1309
|
+
# a real but bizarre revision id.
|
|
1310
|
+
if isinstance(agent_revision, (int, float)) and agent_revision > 0:
|
|
1296
1311
|
parts.append(f"rev [bold]{int(agent_revision)}[/bold]")
|
|
1297
1312
|
if isinstance(record_id, str) and record_id:
|
|
1298
1313
|
parts.append(f"record [cyan]{record_id}[/cyan]")
|
|
@@ -31,7 +31,7 @@ fruxon agents list / get / create / test
|
|
|
31
31
|
fruxon agents schema <agent> # typed parameter metadata
|
|
32
32
|
fruxon agents validate <agent> -p k=v # pre-flight a payload (no execution)
|
|
33
33
|
fruxon agents revisions create [--deploy] / deploy
|
|
34
|
-
fruxon agents draft pull / push / status / evaluate / discard
|
|
34
|
+
fruxon agents draft pull / push / status / run / evaluate / undo / redo / reset / discard
|
|
35
35
|
fruxon run <id> -p key=value # execute deployed revision
|
|
36
36
|
fruxon integrations list / create
|
|
37
37
|
fruxon tools list <integration> / create
|
|
@@ -3471,6 +3471,37 @@ class TestRunAgentModeNdjson:
|
|
|
3471
3471
|
# two ``done`` flavors.
|
|
3472
3472
|
assert "status" not in done
|
|
3473
3473
|
|
|
3474
|
+
def test_stream_drops_sentinel_agent_revision(self, runner, monkeypatch):
|
|
3475
|
+
"""The backend sends ``agentRevision: -1`` as a sentinel for
|
|
3476
|
+
"no published revision yet" / "draft head" / similar non-
|
|
3477
|
+
applicable states. Drop the field entirely in that case
|
|
3478
|
+
rather than emit a misleading ``-1`` an LLM driver would have
|
|
3479
|
+
to special-case on its own side."""
|
|
3480
|
+
credentials.save(credentials.StoredCredentials(api_key="fxn_x", org="acme"))
|
|
3481
|
+
monkeypatch.setenv("FRUXON_AGENT_MODE", "1")
|
|
3482
|
+
|
|
3483
|
+
from fruxon.fruxon import StreamEvent
|
|
3484
|
+
|
|
3485
|
+
self._stub_stream(
|
|
3486
|
+
monkeypatch,
|
|
3487
|
+
[
|
|
3488
|
+
StreamEvent(
|
|
3489
|
+
event="done",
|
|
3490
|
+
data={
|
|
3491
|
+
"executionRecordId": "rec-x",
|
|
3492
|
+
"trace": {"duration": 1234, "totalCost": 0.005, "agentRevision": -1},
|
|
3493
|
+
},
|
|
3494
|
+
),
|
|
3495
|
+
],
|
|
3496
|
+
)
|
|
3497
|
+
result = runner.invoke(app, ["run", "my-agent"])
|
|
3498
|
+
assert result.exit_code == 0, result.stderr
|
|
3499
|
+
done = self._parse_lines(result.stdout)[-1]
|
|
3500
|
+
# Other fields still surface; only ``agent_revision`` is suppressed.
|
|
3501
|
+
assert done["duration_ms"] == 1234
|
|
3502
|
+
assert done["total_cost"] == pytest.approx(0.005)
|
|
3503
|
+
assert "agent_revision" not in done
|
|
3504
|
+
|
|
3474
3505
|
|
|
3475
3506
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
3476
3507
|
# Non-interactive enforcement — paths that would block on human input
|
|
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
|
|
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
|