Skip to content

fix(unified): strict item contract, probe fallback, implied kinds, typed SDK 2.1.6 calls (PRO-2196) - #39

Open
harshranjan-ftw wants to merge 3 commits into
soham/pro-1618-unified-contractfrom
harshranjan/pro-2196-cli-unified-fixes
Open

harshranjan-ftw wants to merge 3 commits into
soham/pro-1618-unified-contractfrom
harshranjan/pro-2196-cli-unified-fixes

Conversation

@harshranjan-ftw

Copy link
Copy Markdown

Stacked on #38 (soham/pro-1618-unified-contract). Found by running #38 against staging with the unified switch on, next to the released 0.2.1.

1. Follow the strict unified item contract (hydradb-application#1653)

The server decodes unified items strictly, so three things #38 sent were refused (400):

  • A conversation turn carried name. A turn is now exactly {role, content}, and a turn with name is refused locally, naming the turn. The speaker is the item's user_name, set with --user-name on text and conversations alike. feat(unified): follow the PRO-1618 unified API contract on unified databases #38 refused --user-name on unified.
  • Forceful relations were sent as {ids}. They are now {context_ids}.
  • The 202's context id is read from results[].id, which staging sends. source_id is still read from older servers.

2. A failed layout probe no longer fails every command

In #38, when GET /databases failed, every command failed with it, including on split databases where 0.2.1 works.

  • The probe now has a 5 s budget and no SDK retries. Before, a hanging probe held every command for over 40 s.
  • On a network error, a timeout, a 429 or a 5xx, the command warns on stderr and goes out in the split shape, as it did before layouts existed.
  • If the database then refuses the call as unified (CORPUS_TYPE_UNSUPPORTED, matched by code or message), the command is redone in the unified shape. This covers ingest, delete, list and query.
  • Auth and permission failures are still reported as they are.
  • Unified-only flags (--context-id, --llm, and so on) with an unknown layout: --llm and the forceful-relations switch go out unified, and ingest's unified-only flags ask to retry.

3. Deprecated aliases that picked their own kind

recall full, recall preferences, memories list, memories delete and knowledge delete hard-code a kind. On a unified database #38 refused them with "Re-run without --kind", but the user never typed one. They now act on the one corpus. The write aliases (memories add, knowledge upload*) still refuse, pointing at hydradb ingest. An explicit --kind on a unified database is still refused.

4. Smaller

  • The server's per-item caps are checked before sending: 1 MiB of text, a 1024-byte title, 4000 characters of instructions, and a context id of at most 100 characters with no commas.
  • database create without --type leaves the layout to the server, and current servers make it unified. The help text said split was the default. The help and the success message now say what happens.
  • list drops the per-item Type column on a unified database, where it said memory for every item.

5. Typed SDK calls (hydradb-sdk 2.1.6)

hydradb-sdk 2.1.6 knows the unified contract. The unified query and database create --type are now typed SDK calls instead of the hand-built raw path, and the pin moves to >=2.1.6. The unified answer is dumped with exclude_unset, so --output json is still the server's body verbatim.

The unified ingest stays a JSON body on the raw path. The shared ingest-unified-json conformance vector requires a JSON body, and the SDK sends context only as a multipart form field.

Testing

Not in this PR

  • On staging, forceful relations come back [] on /query, even on a direct call. This is a server issue.

…ps (PRO-2196)

Found by running #38 against staging with the unified switch on.

- Follow the strict unified item contract (hydradb-application#1653): a
  conversation turn is exactly {role, content}, and a turn carrying `name`
  is refused locally; the speaker is the item's `user_name`, now set with
  --user-name on text and conversations alike; forceful relations are sent
  as {context_ids}. The 202's context id is read from `results[].id`.
- A failed layout probe no longer fails every command. The probe gets 5s
  and no retries; on a network error, timeout, 429 or 5xx the command warns
  on stderr and goes out in the split shape, as before layouts existed, and
  is redone in the unified shape if the database refuses it as unified
  (CORPUS_TYPE_UNSUPPORTED, or the unified body the SDK cannot parse). Auth
  and permission failures are still reported as they are.
- The deprecated read/delete aliases (recall full/preferences, memories
  list/delete, knowledge delete) picked their kind themselves, so on a
  unified database they now act on the one corpus instead of telling the
  user to drop a --kind they never typed.
- The server's per-item caps are checked before sending: 1 MiB of text, a
  1024-byte title, 4000 characters of instructions, a context id of at most
  100 characters with no commas.
- `database create` without --type leaves the layout to the server (unified
  on current servers); the help text and the success message now say so.
- `list` drops the per-item type column on a unified database.

Signed-off-by: Harsh Ranjan <harsh.ranjan@hydradb.com>
… create (PRO-2196)

hydradb-sdk 2.1.6 knows the unified contract: /query without `type`, the
four-key SearchQueryResult answer, follow_forceful_relations, and `type` on
database create. The unified query and `database create --type` now go
through it instead of the hand-built raw path, and the pin moves to >=2.1.6.
The unified answer is dumped with exclude_unset, so `--output json` stays
the server's body verbatim (checked live against staging).

The unified ingest stays a JSON body on the raw path: the shared
`ingest-unified-json` conformance vector requires one, and the SDK sends
`context` only as a multipart form field.

With 2.1.6 a type-less query that reaches a unified database while the
layout probe is down now parses on the first request, so no redo is needed.

Signed-off-by: Harsh Ranjan <harsh.ranjan@hydradb.com>
@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with no outstanding correctness, security, or repository-rule violations identified.

Summary

This PR productionizes unified-database support while preserving the existing split-database request contract.

  • Adds bounded layout probing with transient-failure fallback and unified retries.
  • Aligns unified ingest with the strict item schema, response IDs, and server-side limits.
  • Allows deprecated read/delete aliases to operate on unified databases while retaining split behavior.
  • Moves supported query and database-creation operations to hydradb-sdk 2.1.6.
  • Adds focused coverage for request shapes, aliases, probe failures, response parsing, and output behavior.

Greptile automatically discovered a related ticket that helped explain the purpose of this PR: make all CLI operations work end to end on unified databases without changing split-database requests or output.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Command[CLI command] --> Probe[Probe database layout]
    Probe -->|Unified| Unified[Send unified request shape]
    Probe -->|Split| Split[Send split request shape]
    Probe -->|Transient failure| Fallback[Warn and send split request]
    Fallback -->|Accepted| Result[Render result]
    Fallback -->|CORPUS_TYPE_UNSUPPORTED| Retry[Retry in unified shape]
    Unified --> Result
    Split --> Result
    Retry --> Result
Loading

Reviews (2) · Last reviewed commit: "fix(unified): use a 2xx query answer the..."

@openhack-agent

openhack-agent Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

✅ OpenHack Summary

Security review of fix(unified): strict item contract, probe fallback, implied kinds, typed SDK 2.1.6 calls (PRO-2196). 10 changed files; 0 findings at or above the low reporting threshold.

P1: Critical 0   P2: High 0   P3: Medium 0   P4: Low 0

Confidence Score: 5/5

No reportable security findings were detected in this scan.

Security merge-readiness rubric: 1 = critical, 2 = high, 3 = medium, 4 = low, 5 = no reportable findings. This score reflects scan findings, not a guarantee of correctness or complete coverage.

Files Needing Attention: None

Important Files Changed
  • CHANGELOG.md (modified)
  • README.md (modified)
  • pyproject.toml (modified)
  • src/hydradb_cli/commands/_impl.py (modified)
  • src/hydradb_cli/commands/canonical.py (modified)
  • src/hydradb_cli/commands/knowledge.py (modified)
  • src/hydradb_cli/commands/memories.py (modified)
  • src/hydradb_cli/commands/recall.py (modified)
  • src/hydradb_cli/hydra/client.py (modified)
  • tests/test_unified.py (modified)

Last reviewed commit: 8d0694a · View review on OpenHack


TIP: Mention @openhack-agent in a PR comment to request a review or ask a question. Use @openhack-agent fix all for every finding, or @openhack-agent fix unresolved threads for open review threads only.

@openhack-agent openhack-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenHack reviewed this commit. See the OpenHack Summary for the confidence score and fix actions.

…ver sent it (PRO-2196)

hydradb-sdk 2.1.6's four-key SearchQueryResult requires every list key, but
the contract lets `forceful_relations` be absent. Such an answer raised a
ParsingError and the CLI printed an error for a successful query; the
hand-built path it replaced accepted it. The parsed body travels on the
ParsingError, so a 2xx answer is now returned as sent (one request, the
request id kept) and anything else is still translated to the usual error.

Found by the staging pass: a proxied /query with forceful_relations dropped.

Signed-off-by: Harsh Ranjan <harsh.ranjan@hydradb.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant