unique-sdk 2026.28.0.dev12__tar.gz → 2026.28.0.dev14__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.
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/PKG-INFO +1 -1
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/pyproject.toml +1 -1
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/cli.py +41 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/files.py +6 -6
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/folders.py +3 -3
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/mcp.py +59 -6
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/navigation.py +5 -5
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/read.py +1 -1
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/search.py +70 -1
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-search/SKILL.md +40 -1
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/state.py +62 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/README.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/__init__.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_api_requestor.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_api_resource.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_api_version.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_error.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_http_client.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_list_object.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_object_classes.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_request_options.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_unique_object.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_unique_ql.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_unique_response.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_util.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_version.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/_webhook.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/__init__.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_acronyms.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_agentic_table.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_analytics_order.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_benchmarking.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_briefing.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_chat_completion.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_content.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_dynamic_frontend.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_elicitation.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_embedding.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_event.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_folder.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_group.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_integrated.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_llm_models.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_mcp.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_assessment.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_execution.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_log.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_tool.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_module.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_scheduled_task.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_search.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_search_string.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_short_term_memory.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_space.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_user.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_web_search.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/__init__.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/__main__.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/__init__.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/_citation_manifest.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/cite_file.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/dynamic_frontend.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/elicitation.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/scheduled_tasks.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/subagent.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/web_search.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/web_search_config.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/config.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/formatting.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/metadata_filter.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/shell.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-dynamic-frontend/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-elicitation/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-file-management/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-mcp/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-scheduled-tasks/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-subagent/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/skills/unique-cli-web-search/SKILL.md +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/analytics_order_run.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/benchmarking_run.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/chat_history.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/chat_in_space.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/file_io.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/sources.py +0 -0
- {unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/token.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-sdk
|
|
3
|
-
Version: 2026.28.0.
|
|
3
|
+
Version: 2026.28.0.dev14
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Martin Fadler, Konstantin Krauss, Andreas Hauri
|
|
6
6
|
Author-email: Martin Fadler <martin.fadler@unique.ch>, Konstantin Krauss <konstantin@unique.ch>, Andreas Hauri <andreas@unique.ch>
|
|
@@ -53,10 +53,14 @@ from unique_sdk.cli.commands.scheduled_tasks import (
|
|
|
53
53
|
)
|
|
54
54
|
from unique_sdk.cli.commands.search import (
|
|
55
55
|
cmd_search,
|
|
56
|
+
cmd_uploaded_search,
|
|
56
57
|
)
|
|
57
58
|
from unique_sdk.cli.commands.search import (
|
|
58
59
|
is_error_output as _is_search_error_output,
|
|
59
60
|
)
|
|
61
|
+
from unique_sdk.cli.commands.search import (
|
|
62
|
+
is_uploaded_search_error_output as _is_uploaded_search_error_output,
|
|
63
|
+
)
|
|
60
64
|
from unique_sdk.cli.commands.subagent import cmd_subagent
|
|
61
65
|
from unique_sdk.cli.commands.subagent import (
|
|
62
66
|
is_error_output as _is_subagent_error_output,
|
|
@@ -739,6 +743,43 @@ def search(
|
|
|
739
743
|
ctx.exit(1)
|
|
740
744
|
|
|
741
745
|
|
|
746
|
+
@main.command(name="uploaded-search")
|
|
747
|
+
@click.argument("query")
|
|
748
|
+
@click.option(
|
|
749
|
+
"--limit",
|
|
750
|
+
"-l",
|
|
751
|
+
default=200,
|
|
752
|
+
show_default=True,
|
|
753
|
+
help="Maximum number of results to return.",
|
|
754
|
+
)
|
|
755
|
+
@click.pass_context
|
|
756
|
+
def uploaded_search(
|
|
757
|
+
ctx: click.Context,
|
|
758
|
+
query: str,
|
|
759
|
+
limit: int,
|
|
760
|
+
) -> None:
|
|
761
|
+
"""Search the documents uploaded for this task (not the knowledge base).
|
|
762
|
+
|
|
763
|
+
\b
|
|
764
|
+
QUERY is the search text. This searches only the files attached to this
|
|
765
|
+
row/task (e.g. an Agentic Table row's uploaded documents), which are NOT
|
|
766
|
+
part of the knowledge-base folder scope and therefore never appear in
|
|
767
|
+
`unique-cli search`. Results are ranked the same way and cite as
|
|
768
|
+
`[sourceN]`, with numbering continuous across `search` and
|
|
769
|
+
`uploaded-search` within a turn.
|
|
770
|
+
|
|
771
|
+
\b
|
|
772
|
+
Examples:
|
|
773
|
+
unique-cli uploaded-search "target asset classes"
|
|
774
|
+
unique-cli uploaded-search "fee structure" --limit 50
|
|
775
|
+
"""
|
|
776
|
+
state = LazyState.get(ctx)
|
|
777
|
+
output = cmd_uploaded_search(state, query, limit=limit)
|
|
778
|
+
click.echo(output)
|
|
779
|
+
if _is_uploaded_search_error_output(output):
|
|
780
|
+
ctx.exit(1)
|
|
781
|
+
|
|
782
|
+
|
|
742
783
|
@main.command()
|
|
743
784
|
@click.argument("payload", required=False, default=None)
|
|
744
785
|
@click.option(
|
|
@@ -358,7 +358,7 @@ def cmd_upload(
|
|
|
358
358
|
).get("folderPath", scope_id)
|
|
359
359
|
return f"Uploaded: {display_name} ({content_id}) to {folder_path}"
|
|
360
360
|
|
|
361
|
-
except (ValueError, unique_sdk.
|
|
361
|
+
except (ValueError, unique_sdk.UniqueError, OSError) as e:
|
|
362
362
|
return f"upload: {e}"
|
|
363
363
|
|
|
364
364
|
|
|
@@ -384,7 +384,7 @@ def cmd_versions(
|
|
|
384
384
|
)
|
|
385
385
|
data = result.get("data", [])
|
|
386
386
|
return f"Versions for {display_name} ({content_id}):\n{_format_content_versions(data)}"
|
|
387
|
-
except (ValueError, unique_sdk.
|
|
387
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
388
388
|
return f"versions: {e}"
|
|
389
389
|
|
|
390
390
|
|
|
@@ -414,7 +414,7 @@ def cmd_restore_version(state: ShellState, content_version_id: str) -> str:
|
|
|
414
414
|
title = result.get("title") or result.get("key") or result.get("id", "?")
|
|
415
415
|
content_id = result.get("id", "?")
|
|
416
416
|
return f"Restored: {title} ({content_id}) from version {content_version_id}"
|
|
417
|
-
except (ValueError, unique_sdk.
|
|
417
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
418
418
|
return f"restore-version: {e}"
|
|
419
419
|
|
|
420
420
|
|
|
@@ -449,7 +449,7 @@ def cmd_download(
|
|
|
449
449
|
shutil.move(str(downloaded_path), str(final_dest))
|
|
450
450
|
return f"Downloaded: {display_name} -> {final_dest}"
|
|
451
451
|
|
|
452
|
-
except (ValueError, unique_sdk.
|
|
452
|
+
except (ValueError, unique_sdk.UniqueError, OSError) as e:
|
|
453
453
|
return f"download: {e}"
|
|
454
454
|
|
|
455
455
|
|
|
@@ -468,7 +468,7 @@ def cmd_rm(state: ShellState, name_or_id: str) -> str:
|
|
|
468
468
|
contentId=content_id,
|
|
469
469
|
)
|
|
470
470
|
return f"Deleted: {display_name} ({content_id})"
|
|
471
|
-
except (ValueError, unique_sdk.
|
|
471
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
472
472
|
return f"rm: {e}"
|
|
473
473
|
|
|
474
474
|
|
|
@@ -488,7 +488,7 @@ def cmd_mv_file(state: ShellState, old_name: str, new_name: str) -> str:
|
|
|
488
488
|
title=new_name,
|
|
489
489
|
)
|
|
490
490
|
return f"Renamed: {display_name} -> {result.get('title', new_name)}\n{format_content_info(result)}"
|
|
491
|
-
except (ValueError, unique_sdk.
|
|
491
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
492
492
|
return f"mv: {e}"
|
|
493
493
|
|
|
494
494
|
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/folders.py
RENAMED
|
@@ -70,7 +70,7 @@ def cmd_mkdir(state: ShellState, name: str) -> str:
|
|
|
70
70
|
last = created[-1]
|
|
71
71
|
return f"Created: {full_path} ({last['id']})"
|
|
72
72
|
return f"Created: {full_path}"
|
|
73
|
-
except (ValueError, unique_sdk.
|
|
73
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
74
74
|
return f"mkdir: {e}"
|
|
75
75
|
|
|
76
76
|
|
|
@@ -108,7 +108,7 @@ def cmd_rmdir(state: ShellState, target: str, recursive: bool = False) -> str:
|
|
|
108
108
|
recursive=recursive,
|
|
109
109
|
)
|
|
110
110
|
return f"Deleted folder: {target}"
|
|
111
|
-
except (ValueError, unique_sdk.
|
|
111
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
112
112
|
return f"rmdir: {e}"
|
|
113
113
|
|
|
114
114
|
|
|
@@ -145,5 +145,5 @@ def cmd_mvdir(state: ShellState, old_name: str, new_name: str) -> str:
|
|
|
145
145
|
name=new_name,
|
|
146
146
|
)
|
|
147
147
|
return f"Renamed folder -> {result.get('name', new_name)}\n{format_folder_info(result)}"
|
|
148
|
-
except (ValueError, unique_sdk.
|
|
148
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
149
149
|
return f"mvdir: {e}"
|
|
@@ -337,16 +337,25 @@ def _citation_footer(annotated: list[tuple[int, dict[str, Any]]]) -> str:
|
|
|
337
337
|
|
|
338
338
|
|
|
339
339
|
def _append_mcp_output_manifest(
|
|
340
|
-
name: str,
|
|
340
|
+
name: str,
|
|
341
|
+
text: str,
|
|
342
|
+
*,
|
|
343
|
+
server_name: str | None = None,
|
|
344
|
+
output_path: Path | None = None,
|
|
341
345
|
) -> None:
|
|
342
346
|
"""Best-effort append of one MCP tool result to the per-turn manifest.
|
|
343
347
|
|
|
344
348
|
Never raises: a manifest failure must not change what the agent sees as
|
|
345
349
|
the tool result. The groundedness check simply does not fire for this
|
|
346
350
|
call when the write fails.
|
|
351
|
+
|
|
352
|
+
``output_path`` is the full path of the ``mcp-output.jsonl`` manifest. It
|
|
353
|
+
defaults to ``Path.cwd() / .unique / mcp-output.jsonl`` so the CLI flow
|
|
354
|
+
(where cwd is the agent workspace) is unchanged; callers that run outside
|
|
355
|
+
the workspace cwd (e.g. the in-process tools-mode proxy) pass it explicitly.
|
|
347
356
|
"""
|
|
348
357
|
try:
|
|
349
|
-
refs_log_path = Path.cwd() / _MCP_OUTPUT_LOG_RELATIVE_PATH
|
|
358
|
+
refs_log_path = output_path or (Path.cwd() / _MCP_OUTPUT_LOG_RELATIVE_PATH)
|
|
350
359
|
_append_turn_refs_manifest_entry(
|
|
351
360
|
refs_log_path,
|
|
352
361
|
{
|
|
@@ -359,6 +368,47 @@ def _append_mcp_output_manifest(
|
|
|
359
368
|
_LOGGER.warning("mcp: failed to append output manifest: %s", exc)
|
|
360
369
|
|
|
361
370
|
|
|
371
|
+
def record_mcp_citations(
|
|
372
|
+
response: Any,
|
|
373
|
+
*,
|
|
374
|
+
tool_name: str,
|
|
375
|
+
server_name: str | None,
|
|
376
|
+
unique_dir: Path,
|
|
377
|
+
formatted_text: str,
|
|
378
|
+
) -> str:
|
|
379
|
+
"""Write both per-turn MCP manifests under ``unique_dir`` and return the
|
|
380
|
+
``[mcpsourceN]`` citation footer for the agent.
|
|
381
|
+
|
|
382
|
+
Shared by the ``unique-cli mcp`` skills flow (``cmd_mcp``) and the
|
|
383
|
+
in-process tools-mode proxy in assistants-core, so both write identical
|
|
384
|
+
manifests and footers. ``unique_dir`` is the workspace ``.unique`` directory
|
|
385
|
+
(its filenames are joined directly here — do not pass the workspace root).
|
|
386
|
+
|
|
387
|
+
- ``response`` is the raw ``unique_sdk.MCP`` result, used for citation
|
|
388
|
+
extraction (titles from ``resource_link`` names / JSON bodies).
|
|
389
|
+
- ``formatted_text`` is the source text the model actually saw for this
|
|
390
|
+
tool result, recorded as the hallucination groundedness context.
|
|
391
|
+
|
|
392
|
+
Best-effort and never raises: the underlying manifest writers swallow their
|
|
393
|
+
own errors, and ``_annotate_mcp_results_for_citations`` owns the per-turn
|
|
394
|
+
file lock — this function must stay lock-free to avoid a same-process flock
|
|
395
|
+
self-deadlock.
|
|
396
|
+
"""
|
|
397
|
+
_append_mcp_output_manifest(
|
|
398
|
+
tool_name,
|
|
399
|
+
formatted_text,
|
|
400
|
+
server_name=server_name,
|
|
401
|
+
output_path=unique_dir / _MCP_OUTPUT_LOG_RELATIVE_PATH.name,
|
|
402
|
+
)
|
|
403
|
+
annotated = _annotate_mcp_results_for_citations(
|
|
404
|
+
response,
|
|
405
|
+
tool_name=tool_name,
|
|
406
|
+
server_name=server_name,
|
|
407
|
+
refs_log_path=unique_dir / _MCP_REFS_LOG_RELATIVE_PATH.name,
|
|
408
|
+
)
|
|
409
|
+
return _citation_footer(annotated)
|
|
410
|
+
|
|
411
|
+
|
|
362
412
|
def _read_payload(
|
|
363
413
|
payload: str | None,
|
|
364
414
|
file: str | None,
|
|
@@ -440,8 +490,11 @@ def cmd_mcp(
|
|
|
440
490
|
formatted = f"mcp: formatter error ({fmt_exc}); raw response:\n{fallback}"
|
|
441
491
|
|
|
442
492
|
server_name = _server_name_from_tool(name) or getattr(response, "mcpServerId", None)
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
493
|
+
footer = record_mcp_citations(
|
|
494
|
+
response,
|
|
495
|
+
tool_name=name,
|
|
496
|
+
server_name=server_name,
|
|
497
|
+
unique_dir=Path.cwd() / ".unique",
|
|
498
|
+
formatted_text=formatted,
|
|
446
499
|
)
|
|
447
|
-
return formatted +
|
|
500
|
+
return formatted + footer
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/navigation.py
RENAMED
|
@@ -19,7 +19,7 @@ def cmd_cd(state: ShellState, target: str) -> str:
|
|
|
19
19
|
try:
|
|
20
20
|
new_path = state.cd(target)
|
|
21
21
|
return new_path
|
|
22
|
-
except (ValueError, unique_sdk.
|
|
22
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
23
23
|
return f"cd: {e}"
|
|
24
24
|
|
|
25
25
|
|
|
@@ -65,7 +65,7 @@ def cmd_ls(state: ShellState, target: str | None = None) -> str:
|
|
|
65
65
|
scopeId=sid,
|
|
66
66
|
)
|
|
67
67
|
)
|
|
68
|
-
except unique_sdk.
|
|
68
|
+
except unique_sdk.UniqueError:
|
|
69
69
|
pass
|
|
70
70
|
scoped_files: list[Any] = []
|
|
71
71
|
for cid in content_ids:
|
|
@@ -86,7 +86,7 @@ def cmd_ls(state: ShellState, target: str | None = None) -> str:
|
|
|
86
86
|
items = info.get("contentInfo", [])
|
|
87
87
|
if items:
|
|
88
88
|
scoped_files.append(items[0])
|
|
89
|
-
except unique_sdk.
|
|
89
|
+
except unique_sdk.UniqueError:
|
|
90
90
|
pass
|
|
91
91
|
output = format_ls(scoped_folders, scoped_files)
|
|
92
92
|
summary = (
|
|
@@ -107,7 +107,7 @@ def cmd_ls(state: ShellState, target: str | None = None) -> str:
|
|
|
107
107
|
scopeId=ws_id,
|
|
108
108
|
)
|
|
109
109
|
folders.append(info)
|
|
110
|
-
except unique_sdk.
|
|
110
|
+
except unique_sdk.UniqueError:
|
|
111
111
|
pass
|
|
112
112
|
output = format_ls(folders, [])
|
|
113
113
|
summary = f"\n{len(folders)} folder(s), 0 file(s)"
|
|
@@ -161,5 +161,5 @@ def cmd_ls(state: ShellState, target: str | None = None) -> str:
|
|
|
161
161
|
summary = f"\n{total_folders} folder(s), {total_files} file(s)"
|
|
162
162
|
return output + summary
|
|
163
163
|
|
|
164
|
-
except (ValueError, unique_sdk.
|
|
164
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
165
165
|
return f"ls: {e}"
|
|
@@ -30,6 +30,7 @@ from unique_sdk.cli.state import ShellState
|
|
|
30
30
|
DEFAULT_LIMIT = 200
|
|
31
31
|
|
|
32
32
|
SEARCH_ERROR_PREFIX = "search:"
|
|
33
|
+
UPLOADED_SEARCH_ERROR_PREFIX = "uploaded-search:"
|
|
33
34
|
|
|
34
35
|
_REFS_LOG_RELATIVE_PATH = Path(".unique") / "kb-search-refs.jsonl"
|
|
35
36
|
_LOCK_FILENAME = "kb-search-refs.lock"
|
|
@@ -272,7 +273,7 @@ def cmd_search(
|
|
|
272
273
|
**search_params,
|
|
273
274
|
)
|
|
274
275
|
|
|
275
|
-
except (ValueError, unique_sdk.
|
|
276
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
276
277
|
return f"{SEARCH_ERROR_PREFIX} {e}"
|
|
277
278
|
|
|
278
279
|
log_path = refs_log_path or (Path.cwd() / _REFS_LOG_RELATIVE_PATH)
|
|
@@ -282,6 +283,69 @@ def cmd_search(
|
|
|
282
283
|
return f"{SEARCH_ERROR_PREFIX} {exc}"
|
|
283
284
|
|
|
284
285
|
|
|
286
|
+
def cmd_uploaded_search(
|
|
287
|
+
state: ShellState,
|
|
288
|
+
query: str,
|
|
289
|
+
limit: int = DEFAULT_LIMIT,
|
|
290
|
+
*,
|
|
291
|
+
refs_log_path: Path | None = None,
|
|
292
|
+
) -> str:
|
|
293
|
+
"""Search this task's per-row **uploaded** documents.
|
|
294
|
+
|
|
295
|
+
Uploaded files (e.g. an Agentic Table row's attached documents) live
|
|
296
|
+
outside the knowledge-base folder scopes, so the scope-bound
|
|
297
|
+
``unique-cli search`` cannot return them. This mirrors the platform's
|
|
298
|
+
UploadedSearch tool: a chat-scoped ``Search.create`` (``chatOnly=True``)
|
|
299
|
+
over the owning chat and the selected content ids, both written by the
|
|
300
|
+
Swappable Intelligence runner to ``.unique-uploaded.json``. See UN-21780.
|
|
301
|
+
|
|
302
|
+
Results share the same per-turn ``<sourceN>`` manifest as
|
|
303
|
+
``unique-cli search`` (``_format_results_with_citations`` appends under the
|
|
304
|
+
same lock), so ``[sourceN]`` citation numbering stays continuous across
|
|
305
|
+
both commands within a turn.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
state: Shell state carrying user/company credentials and the uploaded
|
|
309
|
+
document scope loaded from ``.unique-uploaded.json``.
|
|
310
|
+
query: Search string.
|
|
311
|
+
limit: Maximum number of results.
|
|
312
|
+
refs_log_path: Override the per-turn citation manifest path — for
|
|
313
|
+
tests; production callers leave this ``None``.
|
|
314
|
+
"""
|
|
315
|
+
if not state.uploaded_search_available:
|
|
316
|
+
return (
|
|
317
|
+
f"{UPLOADED_SEARCH_ERROR_PREFIX} no uploaded documents are "
|
|
318
|
+
"available for this task. Use `unique-cli search` for the "
|
|
319
|
+
"knowledge base."
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
try:
|
|
323
|
+
search_params: dict[str, Any] = {
|
|
324
|
+
"searchString": query,
|
|
325
|
+
"searchType": "COMBINED",
|
|
326
|
+
"chatOnly": True,
|
|
327
|
+
"limit": limit,
|
|
328
|
+
}
|
|
329
|
+
if state.uploaded_search_chat_id:
|
|
330
|
+
search_params["chatId"] = state.uploaded_search_chat_id
|
|
331
|
+
if state.uploaded_search_content_ids:
|
|
332
|
+
search_params["contentIds"] = state.uploaded_search_content_ids
|
|
333
|
+
|
|
334
|
+
results = unique_sdk.Search.create(
|
|
335
|
+
user_id=state.config.user_id,
|
|
336
|
+
company_id=state.config.company_id,
|
|
337
|
+
**search_params,
|
|
338
|
+
)
|
|
339
|
+
except (ValueError, unique_sdk.UniqueError) as e:
|
|
340
|
+
return f"{UPLOADED_SEARCH_ERROR_PREFIX} {e}"
|
|
341
|
+
|
|
342
|
+
log_path = refs_log_path or (Path.cwd() / _REFS_LOG_RELATIVE_PATH)
|
|
343
|
+
try:
|
|
344
|
+
return _format_results_with_citations(results, refs_log_path=log_path)
|
|
345
|
+
except UnsafeRefsLogPathError as exc:
|
|
346
|
+
return f"{UPLOADED_SEARCH_ERROR_PREFIX} {exc}"
|
|
347
|
+
|
|
348
|
+
|
|
285
349
|
def is_error_output(output: str) -> bool:
|
|
286
350
|
"""Return ``True`` when ``output`` is a CLI error message.
|
|
287
351
|
|
|
@@ -290,3 +354,8 @@ def is_error_output(output: str) -> bool:
|
|
|
290
354
|
exit code without changing the existing string-returning contract.
|
|
291
355
|
"""
|
|
292
356
|
return output.startswith(SEARCH_ERROR_PREFIX)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def is_uploaded_search_error_output(output: str) -> bool:
|
|
360
|
+
"""Return ``True`` when ``output`` is an ``uploaded-search`` error message."""
|
|
361
|
+
return output.startswith(UPLOADED_SEARCH_ERROR_PREFIX)
|
|
@@ -7,7 +7,10 @@ description: >-
|
|
|
7
7
|
platform. Use whenever the user asks to find, search, or query documents
|
|
8
8
|
or content on Unique, including filtering by folder or metadata.
|
|
9
9
|
Also covers `unique-cli read <cont_id>` for reading the full indexed text
|
|
10
|
-
of a document when its content ID is already known
|
|
10
|
+
of a document when its content ID is already known, and
|
|
11
|
+
`unique-cli uploaded-search "<query>"` for searching documents uploaded for
|
|
12
|
+
the current task/row, which are NOT in the knowledge-base scope and never
|
|
13
|
+
appear in `unique-cli search`.
|
|
11
14
|
NOTE: This search uses combined vector + full-text indexing. Excel
|
|
12
15
|
(.xlsx/.xls), CSV (.csv), and image files are NOT full-text indexed,
|
|
13
16
|
so they will not appear in search results. To locate these file types,
|
|
@@ -64,6 +67,9 @@ When no `--folder` is given:
|
|
|
64
67
|
- If the task defines a scope (a per-message scope filter): that scope is the
|
|
65
68
|
search boundary, regardless of the current directory. `cd`/cwd does **not**
|
|
66
69
|
narrow further — only an explicit `--folder` ANDs an additional constraint.
|
|
70
|
+
**You do not need `--folder` here** — just run `unique-cli search "<query>"`.
|
|
71
|
+
Passing a folder *path* that isn't navigable to your user errors with
|
|
72
|
+
`Folder ... not found`; only narrow within the scope via a `scope_` id.
|
|
67
73
|
- Otherwise, in interactive mode: searches within the current directory
|
|
68
74
|
- Otherwise, at root `/`: searches the entire knowledge base
|
|
69
75
|
|
|
@@ -89,10 +95,43 @@ unique-cli search "audit" -m department=Legal -m year=2025
|
|
|
89
95
|
unique-cli search "regulatory" -f /Legal -m year=2025 -l 50
|
|
90
96
|
```
|
|
91
97
|
|
|
98
|
+
## Searching Uploaded Documents (`uploaded-search`)
|
|
99
|
+
|
|
100
|
+
Documents **uploaded for the current task** (e.g. an Agentic Table row's
|
|
101
|
+
attached files) are **not** part of the knowledge-base folder scope. They will
|
|
102
|
+
**never** appear in `unique-cli search` results, no matter the folder or
|
|
103
|
+
metadata filters — uploaded files are scoped to the chat, not to a KB folder.
|
|
104
|
+
Use `uploaded-search` to retrieve them:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Search the documents uploaded for this row/task
|
|
108
|
+
unique-cli uploaded-search "target asset classes and investment strategy"
|
|
109
|
+
|
|
110
|
+
# Limit results
|
|
111
|
+
unique-cli uploaded-search "fee structure" --limit 50
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
When to use which:
|
|
115
|
+
|
|
116
|
+
| You want to search… | Command |
|
|
117
|
+
|---------------------|---------|
|
|
118
|
+
| The knowledge base (folders the task scope grants) | `unique-cli search "<query>"` |
|
|
119
|
+
| Documents uploaded for **this** row/task | `unique-cli uploaded-search "<query>"` |
|
|
120
|
+
|
|
121
|
+
`uploaded-search` returns the same `<sourceN>...</sourceN>` blocks as `search`
|
|
122
|
+
and shares the **same per-turn citation manifest**, so `[sourceN]` numbering is
|
|
123
|
+
continuous across both commands within a turn — cite an uploaded-document fact
|
|
124
|
+
exactly the same way (`[sourceN]`). If no documents were uploaded for the task,
|
|
125
|
+
the command reports that and you should fall back to `unique-cli search`.
|
|
126
|
+
|
|
127
|
+
> **Note:** there is no `--folder`/`--metadata` for `uploaded-search` — the set
|
|
128
|
+
> of uploaded documents is fixed by what was attached to the task.
|
|
129
|
+
|
|
92
130
|
## Command Reference
|
|
93
131
|
|
|
94
132
|
```
|
|
95
133
|
unique-cli search <query> [--folder <path|scope_id>] [--metadata <key=value>]... [--limit <N>]
|
|
134
|
+
unique-cli uploaded-search <query> [--limit <N>]
|
|
96
135
|
```
|
|
97
136
|
|
|
98
137
|
| Option | Short | Default | Description |
|
|
@@ -12,6 +12,7 @@ from unique_sdk.cli.config import Config
|
|
|
12
12
|
from unique_sdk.cli.metadata_filter import MetadataFilter
|
|
13
13
|
|
|
14
14
|
_SEARCH_CONFIG_FILENAME = ".unique-search.json"
|
|
15
|
+
_UPLOADED_CONFIG_FILENAME = ".unique-uploaded.json"
|
|
15
16
|
_CHAT_FILES_MANIFEST_PATH = Path(".unique") / "chat-files.json"
|
|
16
17
|
|
|
17
18
|
|
|
@@ -27,6 +28,38 @@ def _load_search_config() -> dict[str, Any]:
|
|
|
27
28
|
return data if isinstance(data, dict) else {}
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
def _load_uploaded_config() -> dict[str, Any]:
|
|
32
|
+
"""Load ``.unique-uploaded.json`` from the cwd, or ``{}`` when absent/invalid.
|
|
33
|
+
|
|
34
|
+
Written by the Swappable Intelligence runner when the task carries per-row
|
|
35
|
+
uploaded documents (an Agentic Table row's ``selectedUploadedFiles``). It
|
|
36
|
+
holds the chat that owns those uploads and their content ids so
|
|
37
|
+
``unique-cli uploaded-search`` can reach them: uploaded files live outside
|
|
38
|
+
the knowledge-base folder scopes, so the scope-bound ``unique-cli search``
|
|
39
|
+
structurally cannot return them. See UN-21780.
|
|
40
|
+
"""
|
|
41
|
+
config_path = Path.cwd() / _UPLOADED_CONFIG_FILENAME
|
|
42
|
+
if not config_path.is_file():
|
|
43
|
+
return {}
|
|
44
|
+
try:
|
|
45
|
+
data = json.loads(config_path.read_text(encoding="utf-8"))
|
|
46
|
+
except (json.JSONDecodeError, OSError):
|
|
47
|
+
return {}
|
|
48
|
+
return data if isinstance(data, dict) else {}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _load_uploaded_content_ids(data: dict[str, Any]) -> list[str]:
|
|
52
|
+
content_ids = data.get("contentIds")
|
|
53
|
+
if isinstance(content_ids, list) and all(isinstance(c, str) for c in content_ids):
|
|
54
|
+
return content_ids
|
|
55
|
+
return []
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _load_uploaded_chat_id(data: dict[str, Any]) -> str | None:
|
|
59
|
+
chat_id = data.get("chatId")
|
|
60
|
+
return chat_id if isinstance(chat_id, str) and chat_id else None
|
|
61
|
+
|
|
62
|
+
|
|
30
63
|
def _load_workspace_scope_ids(data: dict[str, Any]) -> list[str]:
|
|
31
64
|
scope_ids = data.get("scopeIds")
|
|
32
65
|
if isinstance(scope_ids, list) and all(isinstance(s, str) for s in scope_ids):
|
|
@@ -100,6 +133,35 @@ class ShellState:
|
|
|
100
133
|
self._workspace_metadata_filter: dict[str, Any] | None = None
|
|
101
134
|
self._metadata_filter: MetadataFilter | None = None
|
|
102
135
|
self.workspace_metadata_filter = _load_workspace_metadata_filter(_search_config)
|
|
136
|
+
# Per-row uploaded documents reachable via ``unique-cli uploaded-search``.
|
|
137
|
+
# Loaded from ``.unique-uploaded.json`` (written by the runner). The chat
|
|
138
|
+
# id is the chat that *owns* the uploads — for a subagent this is the
|
|
139
|
+
# parent chat — and is required for the chat-scoped uploaded search.
|
|
140
|
+
# See UN-21780.
|
|
141
|
+
_uploaded_config = _load_uploaded_config()
|
|
142
|
+
self.uploaded_search_chat_id: str | None = _load_uploaded_chat_id(
|
|
143
|
+
_uploaded_config
|
|
144
|
+
)
|
|
145
|
+
self.uploaded_search_content_ids: list[str] = _load_uploaded_content_ids(
|
|
146
|
+
_uploaded_config
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def uploaded_search_available(self) -> bool:
|
|
151
|
+
"""True when this task has per-row uploaded documents to search.
|
|
152
|
+
|
|
153
|
+
Requires *both* a non-empty selected content-id set and the owning
|
|
154
|
+
chat id. The owning chat id alone is not enough: ``cmd_uploaded_search``
|
|
155
|
+
would then issue a ``chatOnly`` ``Search.create`` with no ``contentIds``
|
|
156
|
+
filter, silently widening scope from the row's selected files to *every*
|
|
157
|
+
upload in the chat. That degenerate state arises when the runner wrote
|
|
158
|
+
a ``.unique-uploaded.json`` whose ``contentIds`` were absent or
|
|
159
|
+
malformed (e.g. mixed types, rejected wholesale by
|
|
160
|
+
``_load_uploaded_content_ids``) while the ``chatId`` still parsed — so
|
|
161
|
+
we treat it as "no uploaded scope" rather than "all chat uploads".
|
|
162
|
+
See UN-21780.
|
|
163
|
+
"""
|
|
164
|
+
return bool(self.uploaded_search_content_ids and self.uploaded_search_chat_id)
|
|
103
165
|
|
|
104
166
|
@property
|
|
105
167
|
def workspace_metadata_filter(self) -> dict[str, Any] | None:
|
|
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
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/__init__.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_acronyms.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_agentic_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_benchmarking.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_briefing.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_content.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_elicitation.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_embedding.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_event.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_folder.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_group.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_integrated.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_llm_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_log.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_message_tool.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_module.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_search.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_search_string.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_space.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/api_resources/_web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/cite_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/elicitation.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/scheduled_tasks.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/subagent.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/cli/commands/web_search.py
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
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/analytics_order_run.py
RENAMED
|
File without changes
|
{unique_sdk-2026.28.0.dev12 → unique_sdk-2026.28.0.dev14}/unique_sdk/utils/benchmarking_run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|