deepflow-openagent-cli 0.1.1__tar.gz → 0.1.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepflow-openagent-cli
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Command-line client for OpenAgent OpenAPI (agents, conversations, SSE chat, tools, channels, knowledge bases).
5
5
  Author: DeepFlow AI
6
6
  Project-URL: Repository, https://github.com/DeepFlowAI/OpenAgent
@@ -67,6 +67,8 @@ deepflow_openagent_cli knowledge list --page 1 --per-page 10
67
67
  deepflow_openagent_cli knowledge documents 1
68
68
  deepflow_openagent_cli knowledge query-document 6670 --slice-id 512208 --line 1720
69
69
  deepflow_openagent_cli chat 1 --message "Hello"
70
+ deepflow_openagent_cli steps 1 42
71
+ deepflow_openagent_cli steps get 1 42 100
70
72
  ```
71
73
 
72
74
  ## Development (build wheel/sdist locally)
@@ -46,6 +46,8 @@ deepflow_openagent_cli knowledge list --page 1 --per-page 10
46
46
  deepflow_openagent_cli knowledge documents 1
47
47
  deepflow_openagent_cli knowledge query-document 6670 --slice-id 512208 --line 1720
48
48
  deepflow_openagent_cli chat 1 --message "Hello"
49
+ deepflow_openagent_cli steps 1 42
50
+ deepflow_openagent_cli steps get 1 42 100
49
51
  ```
50
52
 
51
53
  ## Development (build wheel/sdist locally)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepflow-openagent-cli"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "Command-line client for OpenAgent OpenAPI (agents, conversations, SSE chat, tools, channels, knowledge bases)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """DeepFlow OpenAgent CLI — published PyPI package."""
2
2
 
3
- __version__ = "0.1.1"
3
+ __version__ = "0.1.3"
@@ -241,6 +241,21 @@ ENDPOINTS: tuple[EndpointDoc, ...] = (
241
241
  errors=["401 missing or invalid API key", "404 conversation not found"],
242
242
  example="deepflow_openagent_cli steps 1 42",
243
243
  ),
244
+ EndpointDoc(
245
+ key="steps.get",
246
+ method="GET",
247
+ path="/api/v1/agents/{agent_id}/conversations/{conversation_id}/steps/{step_id}",
248
+ scope="chat",
249
+ summary="Get full execution step detail, including LLM request/response payload fields.",
250
+ path_params=[
251
+ _param("agent_id", "integer", True, "Agent ID."),
252
+ _param("conversation_id", "integer", True, "Conversation ID."),
253
+ _param("step_id", "integer", True, "Step ID."),
254
+ ],
255
+ response="StepDetailResponse with request_messages, request_tools, request_params, response fields, and child tool calls.",
256
+ errors=["401 missing or invalid API key", "404 step not found"],
257
+ example="deepflow_openagent_cli steps get 1 42 100",
258
+ ),
244
259
  EndpointDoc(
245
260
  key="agents.list",
246
261
  method="GET",
@@ -316,7 +331,7 @@ ENDPOINTS: tuple[EndpointDoc, ...] = (
316
331
  summary="Partially update system_prompt, model, selected_tool_ids, context, or pre_recall.",
317
332
  path_params=[_param("agent_id", "integer", True, "Agent ID.")],
318
333
  body_fields=[
319
- _param("system_prompt", "string", False, "System prompt, max 10000 chars."),
334
+ _param("system_prompt", "string", False, "System prompt, max 30000 chars."),
320
335
  _param("model", "object", False, "Model config."),
321
336
  _param("selected_tool_ids", "array[integer]", False, "Enabled tool IDs."),
322
337
  _param("context", "object", False, "Context policy."),
@@ -785,10 +800,24 @@ def handle_chat(args: argparse.Namespace) -> int:
785
800
 
786
801
 
787
802
  def handle_steps(args: argparse.Namespace) -> int:
803
+ action, values = parse_steps_args(args.steps_args)
804
+ if action == "get":
805
+ agent_id, conversation_id, step_id = values
806
+ return run_request(
807
+ args,
808
+ "steps.get",
809
+ {
810
+ "agent_id": agent_id,
811
+ "conversation_id": conversation_id,
812
+ "step_id": step_id,
813
+ },
814
+ )
815
+
816
+ agent_id, conversation_id = values
788
817
  return run_request(
789
818
  args,
790
819
  "steps.list",
791
- {"agent_id": args.agent_id, "conversation_id": args.conversation_id},
820
+ {"agent_id": agent_id, "conversation_id": conversation_id},
792
821
  )
793
822
 
794
823
 
@@ -967,9 +996,16 @@ def build_parser() -> argparse.ArgumentParser:
967
996
  add_json_args(chat)
968
997
  chat.set_defaults(handler=handle_chat)
969
998
 
970
- steps = subparsers.add_parser("steps", help="List conversation execution steps.")
971
- steps.add_argument("agent_id", type=int)
972
- steps.add_argument("conversation_id", type=int)
999
+ steps = subparsers.add_parser(
1000
+ "steps",
1001
+ help="List conversation execution steps or get full step detail.",
1002
+ description=(
1003
+ "List conversation execution steps or get full step detail. "
1004
+ "Forms: steps <agent_id> <conversation_id>; "
1005
+ "steps get <agent_id> <conversation_id> <step_id>."
1006
+ ),
1007
+ )
1008
+ steps.add_argument("steps_args", nargs="+", metavar="ARGS")
973
1009
  steps.set_defaults(handler=handle_steps)
974
1010
 
975
1011
  agents = subparsers.add_parser("agents", help="Agent endpoints.")
@@ -1063,6 +1099,30 @@ def parse_bool(value: str) -> bool:
1063
1099
  raise argparse.ArgumentTypeError("Expected boolean: true/false")
1064
1100
 
1065
1101
 
1102
+ def parse_steps_args(values: list[str]) -> tuple[str, tuple[int, ...]]:
1103
+ action = "list"
1104
+ raw_values = values
1105
+ if values[0] in {"list", "get", "detail"}:
1106
+ action = "get" if values[0] == "detail" else values[0]
1107
+ raw_values = values[1:]
1108
+ elif len(values) == 3:
1109
+ action = "get"
1110
+
1111
+ expected = 3 if action == "get" else 2
1112
+ if len(raw_values) != expected:
1113
+ raise CliError(
1114
+ "Usage: steps <agent_id> <conversation_id> or "
1115
+ "steps get <agent_id> <conversation_id> <step_id>."
1116
+ )
1117
+
1118
+ try:
1119
+ parsed = tuple(int(value) for value in raw_values)
1120
+ except ValueError as exc:
1121
+ raise CliError("steps arguments must be integers.") from exc
1122
+
1123
+ return action, parsed
1124
+
1125
+
1066
1126
  def main(argv: list[str] | None = None) -> int:
1067
1127
  parser = build_parser()
1068
1128
  args = parser.parse_args(argv)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepflow-openagent-cli
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Command-line client for OpenAgent OpenAPI (agents, conversations, SSE chat, tools, channels, knowledge bases).
5
5
  Author: DeepFlow AI
6
6
  Project-URL: Repository, https://github.com/DeepFlowAI/OpenAgent
@@ -67,6 +67,8 @@ deepflow_openagent_cli knowledge list --page 1 --per-page 10
67
67
  deepflow_openagent_cli knowledge documents 1
68
68
  deepflow_openagent_cli knowledge query-document 6670 --slice-id 512208 --line 1720
69
69
  deepflow_openagent_cli chat 1 --message "Hello"
70
+ deepflow_openagent_cli steps 1 42
71
+ deepflow_openagent_cli steps get 1 42 100
70
72
  ```
71
73
 
72
74
  ## Development (build wheel/sdist locally)
@@ -1,4 +1,6 @@
1
1
  import json
2
+ from pathlib import Path
3
+ import tomllib
2
4
 
3
5
  import pytest
4
6
 
@@ -16,7 +18,10 @@ from deepflow_openagent_cli.cli import (
16
18
 
17
19
 
18
20
  def test_version_matches_release() -> None:
19
- assert __version__ == "0.1.1"
21
+ pyproject = Path(__file__).resolve().parents[1] / "pyproject.toml"
22
+ metadata = tomllib.loads(pyproject.read_text(encoding="utf-8"))
23
+
24
+ assert __version__ == metadata["project"]["version"]
20
25
 
21
26
 
22
27
  def test_catalog_has_stable_unique_keys() -> None:
@@ -27,6 +32,7 @@ def test_catalog_has_stable_unique_keys() -> None:
27
32
  assert "knowledge.documents" in keys
28
33
  assert "documents.query" in keys
29
34
  assert "chat.stream" in keys
35
+ assert "steps.get" in keys
30
36
  assert "channels.secret_key" in keys
31
37
 
32
38
 
@@ -129,6 +135,84 @@ def test_query_document_command_posts_body(
129
135
  ]
130
136
 
131
137
 
138
+ def test_steps_list_keeps_legacy_short_form(
139
+ monkeypatch: pytest.MonkeyPatch,
140
+ capsys: pytest.CaptureFixture[str],
141
+ ) -> None:
142
+ calls = []
143
+
144
+ def fake_request(self, endpoint_key, path_params=None, query=None, body=None, *, stream=False):
145
+ calls.append((endpoint_key, path_params, query, body, stream))
146
+ return b'{"ok": true}'
147
+
148
+ monkeypatch.setattr(OpenApiClient, "request", fake_request)
149
+
150
+ exit_code = main(
151
+ [
152
+ "--host",
153
+ "http://localhost:5001",
154
+ "--api-key",
155
+ "sk-test",
156
+ "steps",
157
+ "1",
158
+ "42",
159
+ ]
160
+ )
161
+
162
+ captured = capsys.readouterr()
163
+ assert exit_code == 0
164
+ assert json.loads(captured.out) == {"ok": True}
165
+ assert calls == [
166
+ (
167
+ "steps.list",
168
+ {"agent_id": 1, "conversation_id": 42},
169
+ None,
170
+ None,
171
+ False,
172
+ )
173
+ ]
174
+
175
+
176
+ def test_steps_get_fetches_full_step_detail(
177
+ monkeypatch: pytest.MonkeyPatch,
178
+ capsys: pytest.CaptureFixture[str],
179
+ ) -> None:
180
+ calls = []
181
+
182
+ def fake_request(self, endpoint_key, path_params=None, query=None, body=None, *, stream=False):
183
+ calls.append((endpoint_key, path_params, query, body, stream))
184
+ return b'{"ok": true}'
185
+
186
+ monkeypatch.setattr(OpenApiClient, "request", fake_request)
187
+
188
+ exit_code = main(
189
+ [
190
+ "--host",
191
+ "http://localhost:5001",
192
+ "--api-key",
193
+ "sk-test",
194
+ "steps",
195
+ "get",
196
+ "1",
197
+ "42",
198
+ "100",
199
+ ]
200
+ )
201
+
202
+ captured = capsys.readouterr()
203
+ assert exit_code == 0
204
+ assert json.loads(captured.out) == {"ok": True}
205
+ assert calls == [
206
+ (
207
+ "steps.get",
208
+ {"agent_id": 1, "conversation_id": 42, "step_id": 100},
209
+ None,
210
+ None,
211
+ False,
212
+ )
213
+ ]
214
+
215
+
132
216
  def test_tools_create_accepts_doc_grep(
133
217
  monkeypatch: pytest.MonkeyPatch,
134
218
  capsys: pytest.CaptureFixture[str],