fruxon 0.9.0__tar.gz → 0.9.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.9.0 → fruxon-0.9.2}/PKG-INFO +1 -1
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/_version.py +2 -2
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/keys.py +1 -1
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/fruxon.py +6 -6
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/telemetry.py +2 -2
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_cli.py +1 -1
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_client.py +5 -5
- {fruxon-0.9.0 → fruxon-0.9.2}/.gitignore +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/HISTORY.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/LICENSE +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/README.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/pyproject.toml +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/__init__.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/__main__.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/_ssl.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/__init__.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/_schema.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/_shared.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/agents.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/agents_budget.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/agents_draft.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/agents_revisions.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/agents_tests.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/auth.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/chat.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/completion.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/config.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/describe.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/doctor.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/examples.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/guides.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/integrations.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/llm_providers.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/run.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/skills.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/tools.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli/trace.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/cli_auth.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/credentials.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/doctor.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/exceptions.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/models.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/output.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/params.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/__init__.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-agent-mode/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-build-agent/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-create-integration/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-debug-revision/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-meet/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/skills/fruxon-use-integrations/SKILL.md +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/ui.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/update_check.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/src/fruxon/validation.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/__init__.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/conftest.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_actor.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_budgets.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_credentials.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_doctor.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_draft_evaluate_cli.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_drafts.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_fruxon.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_guides.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_output.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_params.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_schema.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_skills.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_ssl.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_telemetry.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_test_chats.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_ui.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_update_check.py +0 -0
- {fruxon-0.9.0 → fruxon-0.9.2}/tests/test_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fruxon
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.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.9.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 9,
|
|
21
|
+
__version__ = version = '0.9.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 9, 2)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -148,7 +148,7 @@ def keys_mint(
|
|
|
148
148
|
_ = base_url
|
|
149
149
|
import webbrowser
|
|
150
150
|
|
|
151
|
-
url = f"{dashboard_root()}/settings#
|
|
151
|
+
url = f"{dashboard_root()}/settings#personal-access-tokens"
|
|
152
152
|
stderr.print(f"[yellow]↗[/yellow] Opening [link]{url}[/link]")
|
|
153
153
|
opened = False
|
|
154
154
|
try:
|
|
@@ -319,14 +319,14 @@ class FruxonClient:
|
|
|
319
319
|
def get_execution_trace(self, agent: str, record_id: str) -> dict:
|
|
320
320
|
"""Fetch the step-by-step trace for a past execution.
|
|
321
321
|
|
|
322
|
-
Hits the
|
|
322
|
+
Hits the ``/trace`` sub-resource of the execution record. The trace
|
|
323
323
|
payload is intentionally returned as a raw dict because the
|
|
324
324
|
shape — nested step trees, tool metadata, provider-specific
|
|
325
325
|
fields — is broad and evolves faster than a typed model would
|
|
326
326
|
gracefully handle. Callers wanting structured access should
|
|
327
327
|
peel into the dict; ``fruxon trace`` does so for rendering.
|
|
328
328
|
"""
|
|
329
|
-
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/executionRecords/{record_id}
|
|
329
|
+
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/executionRecords/{record_id}/trace"
|
|
330
330
|
result = self._get_json(url)
|
|
331
331
|
if isinstance(result, dict):
|
|
332
332
|
return result
|
|
@@ -398,14 +398,14 @@ class FruxonClient:
|
|
|
398
398
|
def get_agent_parameters(self, agent: str, revision: int | str) -> list[str]:
|
|
399
399
|
"""Fetch the input parameter names a revision of an agent expects.
|
|
400
400
|
|
|
401
|
-
Hits ``GET /v1/tenants/{tenant}/agents/{agent}/revisions/{rev}
|
|
401
|
+
Hits ``GET /v1/tenants/{tenant}/agents/{agent}/revisions/{rev}/parameters``.
|
|
402
402
|
The server returns an ``{"parameters": ["user_query", …], "metadata":
|
|
403
403
|
[...]}`` shape — this method unwraps to the flat name list because
|
|
404
404
|
most callers (``fruxon agents get``) only need the names. For the
|
|
405
405
|
full typed metadata (types, ranges, options, required flags), use
|
|
406
406
|
:meth:`get_agent_parameter_metadata` instead.
|
|
407
407
|
"""
|
|
408
|
-
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/revisions/{revision}
|
|
408
|
+
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/revisions/{revision}/parameters"
|
|
409
409
|
raw = self._get_json(url)
|
|
410
410
|
if isinstance(raw, dict):
|
|
411
411
|
params = raw.get("parameters") or []
|
|
@@ -416,7 +416,7 @@ class FruxonClient:
|
|
|
416
416
|
def get_agent_parameter_metadata(self, agent: str, revision: int | str) -> dict:
|
|
417
417
|
"""Fetch the rich parameter metadata an agent revision expects.
|
|
418
418
|
|
|
419
|
-
Hits the same
|
|
419
|
+
Hits the same ``/parameters`` endpoint as :meth:`get_agent_parameters`
|
|
420
420
|
but returns the full ``AgentParameters`` envelope — both the flat
|
|
421
421
|
``parameters`` list and the typed ``metadata`` list with per-parameter
|
|
422
422
|
``type``, ``required``, ``description``, ``defaultValue``, integer or
|
|
@@ -432,7 +432,7 @@ class FruxonClient:
|
|
|
432
432
|
we return that envelope verbatim (no shape transform) so the CLI's
|
|
433
433
|
``agents schema`` command can emit it 1:1 as JSON.
|
|
434
434
|
"""
|
|
435
|
-
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/revisions/{revision}
|
|
435
|
+
url = f"{self._base_url}/v1/tenants/{self._org}/agents/{agent}/revisions/{revision}/parameters"
|
|
436
436
|
raw = self._get_json(url)
|
|
437
437
|
if isinstance(raw, dict):
|
|
438
438
|
return raw
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Anonymous CLI usage telemetry.
|
|
2
2
|
|
|
3
|
-
The CLI POSTs a single event per invocation to ``{base_url}/v1/
|
|
3
|
+
The CLI POSTs a single event per invocation to ``{base_url}/v1/cliEvents``
|
|
4
4
|
on a background thread. The backend validates each event against an
|
|
5
5
|
allowlist and forwards to Mixpanel — see
|
|
6
6
|
``fruxon-backend/Server/Controllers/CliTelemetryController.cs`` and
|
|
@@ -79,7 +79,7 @@ _HTTP_TIMEOUT_SECONDS = 2.0
|
|
|
79
79
|
# same env that overrides every other API call), which is what we want
|
|
80
80
|
# for staging / self-hosted deployments.
|
|
81
81
|
_DEFAULT_BASE_URL = "https://api.fruxon.com"
|
|
82
|
-
_EVENT_PATH = "/v1/
|
|
82
|
+
_EVENT_PATH = "/v1/cliEvents"
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def _detect_driver() -> str:
|
|
@@ -1306,7 +1306,7 @@ class TestAgents:
|
|
|
1306
1306
|
assert "should_not_be_used" not in result.stderr
|
|
1307
1307
|
|
|
1308
1308
|
def test_get_swallows_parameters_error(self, runner, monkeypatch):
|
|
1309
|
-
# A 404 / network failure on the
|
|
1309
|
+
# A 404 / network failure on the /parameters endpoint shouldn't
|
|
1310
1310
|
# tank the whole ``agents get`` — the rest of the metadata is
|
|
1311
1311
|
# still useful and should still render.
|
|
1312
1312
|
credentials.save(credentials.StoredCredentials(token="fx_pat_x", org="acme"))
|
|
@@ -596,7 +596,7 @@ class TestGetAgentParameters:
|
|
|
596
596
|
client.get_agent_parameters("my-agent", 7)
|
|
597
597
|
|
|
598
598
|
assert captured["url"] == (
|
|
599
|
-
"https://api.fruxon.com/v1/tenants/test-tenant/agents/my-agent/revisions/7
|
|
599
|
+
"https://api.fruxon.com/v1/tenants/test-tenant/agents/my-agent/revisions/7/parameters"
|
|
600
600
|
)
|
|
601
601
|
# GET-only — must not POST a body to a parameter discovery endpoint.
|
|
602
602
|
assert captured["method"] == "GET"
|
|
@@ -612,7 +612,7 @@ class TestGetAgentParameters:
|
|
|
612
612
|
# Some callers (the CLI today) pass the revision as an int; future
|
|
613
613
|
# surfaces may pass a string. Both should produce the same URL.
|
|
614
614
|
client.get_agent_parameters("my-agent", "12")
|
|
615
|
-
assert captured["url"].endswith("/revisions/12
|
|
615
|
+
assert captured["url"].endswith("/revisions/12/parameters")
|
|
616
616
|
|
|
617
617
|
def test_returns_parameter_names(self, client, monkeypatch):
|
|
618
618
|
monkeypatch.setattr(
|
|
@@ -677,7 +677,7 @@ class TestGetAgentParameterMetadata:
|
|
|
677
677
|
client.get_agent_parameter_metadata("my-agent", 7)
|
|
678
678
|
# Same URL — the rich and flat methods share one backend endpoint.
|
|
679
679
|
assert captured["url"] == (
|
|
680
|
-
"https://api.fruxon.com/v1/tenants/test-tenant/agents/my-agent/revisions/7
|
|
680
|
+
"https://api.fruxon.com/v1/tenants/test-tenant/agents/my-agent/revisions/7/parameters"
|
|
681
681
|
)
|
|
682
682
|
|
|
683
683
|
def test_returns_full_envelope_verbatim(self, client, monkeypatch):
|
|
@@ -1093,7 +1093,7 @@ class TestGetExecutionRecord:
|
|
|
1093
1093
|
|
|
1094
1094
|
|
|
1095
1095
|
class TestGetExecutionTrace:
|
|
1096
|
-
def
|
|
1096
|
+
def test_hits_trace_subresource_url(self, client, monkeypatch):
|
|
1097
1097
|
captured = {}
|
|
1098
1098
|
|
|
1099
1099
|
def mock_urlopen(req, timeout=None, context=None):
|
|
@@ -1102,7 +1102,7 @@ class TestGetExecutionTrace:
|
|
|
1102
1102
|
|
|
1103
1103
|
monkeypatch.setattr(urllib.request, "urlopen", mock_urlopen)
|
|
1104
1104
|
client.get_execution_trace("agent-1", "rec-1")
|
|
1105
|
-
assert captured["url"].endswith("/executionRecords/rec-1
|
|
1105
|
+
assert captured["url"].endswith("/executionRecords/rec-1/trace")
|
|
1106
1106
|
|
|
1107
1107
|
def test_returns_raw_payload(self, client, monkeypatch):
|
|
1108
1108
|
payload = {"trace": {"steps": [{"kind": "llm"}]}, "status": "COMPLETED"}
|
|
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
|
|
File without changes
|