mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-06-04 13:30:32 +08:00
Wire-contract documentation and the CI check that keeps it honest. * cli/README.md gains a verbatim --help block (top-level + subtrees), an Exit codes table covering 0/1/2/3/4/5/6/7/10/124/130, a "Status vs check" verb-pair subtable, and a "doc wait" paragraph spelling out the four exit codes (0 / 1 / 124 / 130). The api passthrough note trims storage provider out of the deep-config list now that kb create --storage-provider is a polished flag. * cli/AGENTS.md becomes the contributor guide: build/test, CRUD flag conventions, the status/check verb pattern, long-poll wait commands, the SetAgentHelp pattern, and a full Error code reference with 35 typed codes mapped to namespaces, exit codes, retryable / hint guidance. Reference section is bracketed by HTML markers so a CI parity test can keep it in sync with AllCodes(). * cli/internal/cmdutil/errors_doc_test.go enforces parity: every code in AllCodes() must appear in AGENTS.md inside the markers, and AGENTS.md must not reference codes that no longer exist. Fails CI if a new typed code is added without documentation. * CHANGELOG.md gets the v0.6 entry: BREAKING (--json / --no-stream / WEKNORA_SDK_DEBUG / kb create --name), Added (--format / --jq / doc wait / --log-level / kb-and-agent status & check / multi-id delete / api --paginate / MCP schema extension / SetAgentHelp / signal-aware ctx / kb create --storage-provider / new operation.* namespace), Changed (multi-id partial-failure exit code, doc upload FlagError, --log-level FlagError, multi-id stdout cleanup, README / AGENTS.md changes), with a Migration from v0.5 section walking every BREAKING through its v0.6 replacement.
19 KiB
19 KiB
Changelog — weknora CLI
All notable changes to the weknora CLI (the binary under cli/ in this
repository) will be documented in this file.
The format follows Keep a Changelog and the CLI follows Semantic Versioning independently of the WeKnora server / frontend release cadence.
CLI history before v0.3 is recorded in the project root CHANGELOG.md under the release that introduced the CLI.
[Unreleased]
v0.6 — agent runtime hardening: --format, doc wait, --log-level, status, multi-id delete, paginate
BREAKING (v0.5 → v0.6)
--jsonflag removed → use--format json(with optional--jq '<expr>'for projection / filtering). The v0.5--json=fields,...per-field projection drops entirely; rewrite as--format json --jq '.[] | {id, name}'(jq is the canonical projection mechanism going forward).--no-streamflag removed onchat/agent invoke→ use--format jsonto buffer the full answer before printing. The bare text-accumulate use case (TTY but no streaming) is dropped.WEKNORA_SDK_DEBUG=1env removed → useWEKNORA_LOG_LEVEL=debug.kb create --name <name>flag removed → use positionalkb create <name>(consistent withagent create <name>).
Added
--format text|json|ndjsonflag selecting the stdout serialization. Registered per-command (only commands that honor--formatregister it; others reject it withunknown flag/ exit 2). Output mode auto-resolves totexton a TTY andjsonwhen stdout is piped, soweknora kb list | jqworks without an explicit flag.--jq '<expr>'flag pairs with--format json|ndjsonto filter or project the JSON output via a jq expression.weknora doc wait <id> [<id>...]— block until every document reaches a terminalparse_status. Always wait-all — use shell composition (wait id1 && wait id2) for fail-fast.--timeout DURATION(default 10m; exit 124 on hit)--interval DURATION(default 2s; exponential backoff to 15s + jitter)- Multi-id concurrent (max 5 parallel); exit code priority 1 > 124 > 0
--log-level error|warn|info|debugpersistent flag +WEKNORA_LOG_LEVELenv. Wires into the SDK's debug logger via the additiveclient.SetDebugLevel(level string)function.kb create --storage-provider <local|minio|cos|tos|s3|oss|ks3>— sets the new KB'sstorage_provider_config.providerat creation time (server only accepts it on create, not update). Required on self-hosted deployments where the server-side default doesn't pre-populate a provider — without it, subsequentdoc uploadreturnskb not found.weknora kb status <id>— fast health snapshot (1 HTTP). Returns reachable / counts / is_processing.weknora kb check <id>— deep verification: status fields +failed_countaggregated via doc list page-walk (1 + N HTTP). The verb split betweenstatus(read state cheaply) andcheck(actively verify) communicates cost to the caller.weknora agent status <id>— fast health snapshot (1 HTTP): reachable / model_id.weknora agent check <id>— deep verification: status fields +kb_scope_all_reachablefrom probing each KB in scope (1 + N HTTP). Same status/check verb split as kb status/check.weknora doc delete <doc-id> [<doc-id>...]— positional multi-id. Default keep-going on failure. Single-y/--yesconfirms the entire batch; non-TTY without-ystill exits 10.weknora session delete <session-id> [<session-id>...]— positional multi-id with the same keep-going semantics asdoc delete.weknora chunk delete <chunk-id> [<chunk-id>...] --doc <doc-id>— positional multi-id, all chunks share the same--docparent (server route requires it).weknora api <path> --paginate— follows weknora's offset-based pagination (?page=N&page_size=M) and merges all pages into a single{data, total}JSON response.- MCP
chatandagent_invoketools output schemas extended withthinking/tool_calls/assistant_message_id. Tool descriptions callout "server-side accumulated, NOT streaming" (MCP tools/call has no standard partial-response). SetAgentHelppattern —cmdutil.SetAgentHelp(cmd, AgentHelp{...})exposes a stable JSON used_for / required_flags / examples / output shape, activated byWEKNORA_AGENT_HELP=1at--helptime. Applied tochatandkb listas proof-of-pattern; extending to another command requires touching only that command'sNewCmd.cli/AGENTS.mdgains an "Error code reference" section (35 typed codes + exit codes + retryable / hint), with<!-- ERROR_REFERENCE_START -->markers and CI parity test (errors_doc_test.go) — every new typed code inAllCodes()must be documented or CI fails.- New
operation.*typed error namespace for CLI-level wait/poll outcomes:operation.timeout→ exit 124 (distinct fromserver.timeout→ exit 7; matches the convention from GNUtimeout(1)). Used bydoc waitand any future CLI-level wait/poll surfaces.operation.failed→ exit 1. Emitted when one or more wait targets reach a terminal failure (doc waitfindsparse_status=failed) or when multi-iddeleterolls up partial failures. Distinct fromserver.errorbecause the failure is the target's own terminal state, not a transient transport issue —server.error's "retry with backoff" hint would be misleading.operation.cancelled→ exit 1, raised to 130 bymain.gowhen the root context was signal-cancelled. Surfaced by chat / agent invoke / doc wait on Ctrl-C or SIGTERM. Carries a hint pointing at the signal, not at-y/--yes(which would have been the misleadinglocal.user_abortedhint).
- Signal-aware root context —
main.gowiressignal.NotifyContextfor SIGINT and SIGTERM so long-running commands observectx.Done()and run their cancellation cleanup (re-emit auto-created session id, returnoperation.cancelled); the process exits 130 whenever the context was signal-cancelled, matching Unix signal convention. - MCP tool input renames for consistency:
doc_viewanddoc_downloadnow acceptdoc_id(wasknowledge_id) so every MCP tool that references a document uses the same parameter name aschunk_listand the CLI's<doc-id>positional. WriteNDJSONhelper ininternal/format/(per http://ndjson.org: arrays split per-line, single records emit one line).
Changed
cli/README.md"Exit codes" subsection extended with124(operation.timeout); rows for1and130now nameoperation.failedandoperation.cancelledalongside the existing groupings.cli/README.mdgains a "Status / check verb pair" subtable under "Health check" and adoc waitparagraph with full exit-code list (0/1/124/130).cli/AGENTS.mdgains design SOPs for Status / check verb pair pattern and Long-poll wait commands, plus a note on the SetAgentHelp pattern and current coverage (chat / kb list).- Multi-id delete partial-failure exit code:
doc delete/session delete/chunk delete(multi-id mode) now exit1(operation.failed) when some targets fail, rather than exit7(server.error). The retry-with-backoff hint for server.* would have misled callers when the actual cause is a target's terminal state. doc uploadwith no path / no--from-urlnow exits2(FlagError, matching cobra'sMinimumNArgsconvention for commands that need a positional), rather than5(input.invalid_argument).--log-levelinvalid value exits2(FlagError) for consistency with--formatinvalid-value behaviour. Env values still fall through silently (env is best-effort).- Multi-id delete stdout contract: pre-flight failures (e.g. missing
-yconfirmation) no longer emit the empty{ok, failed}envelope to stdout — stdout stays empty per the wire contract in README.md, the typed error goes to stderr only. - Positional id help strings now namespaced for clarity in both human
help and agent
--helpparsing:<id>→<kb-id>/<doc-id>/<session-id>on kb / doc / session subtrees.agentandchunksubtrees were already namespaced. Pure help-text change — argument parsing is unchanged. chat "<text>"Use string now shows quotes — matchesagent invokeandsearch chunksquoting hint for queries that contain spaces.
SDK additions (strictly additive)
client.SetDebugLevel(level string)— programmatic control over the SDK's internal slog debug logger.
v0.5 — agent CRUD, chunk subtree, MCP chunk_list, audit-driven cleanup
Added
weknora agent create <name> --model <id>/agent edit <id>/agent delete <id>— hybrid surface (hot-path flags for the common fields +--config-fileYAML/JSON for the long tail +--generate-skeletontemplate emit).--from <agent-id>copies from an existing agent.weknora chunk list --doc <doc-id>/chunk view <chunk-id>/chunk delete <chunk-id> --doc <doc-id>— new subtree for RAG retrieval debug. Paginated with v0.4--limit/--page-size/--all-pagescanon.weknora mcp serveaddschunk_listas the 10th curated tool.weknora agent view <id>human output now renders all 34 AgentConfig fields (previously 7), grouped into 10 presentation sections.--all-pages/--page-sizeonsearch docsandsearch sessions(catching up withsession list/doc listcanon from v0.3+v0.4).weknora doc listgains--keyword/--file-type/--source/--tag-id/--start-time/--end-time(RFC3339) — matches the SDK'sKnowledgeListFiltersurface. Time flags reject malformed input withinput.invalid_argument.- MCP
doc_listtool gains the same 6 filter fields (keyword,file_type,source,tag_id,start_time,end_time) so agents have parity with the CLI. weknora session view --full(with--limit, default 50, bounds 1..1000) loads chat history viaLoadMessagesand renders messages inline after session metadata. JSON mode projects messages into amessagesarray.--limitwithout--fullerrors withinput.invalid_argument.weknora kb viewhuman render now includesTYPE,PINNED(badge, only when set),TEMPORARY(badge),PROCESSING(with doc count, only when active),SUMMARY MODEL, andCREATED. Nested config structs stay JSON-only.weknora doc viewhuman render expands to includeTITLE(when distinct from filename),DESC,SOURCE,CHANNEL,TAG,STORAGE(human-readable bytes),SUMMARY,ENABLED, andHASH(12-char prefix). All omit-empty.weknora doc uploadgains--enable-multimodel(tri-state: unset/true/false), repeatable--metadata key=value, and--channelflags.--enable-multimodeland--channelapply to file /--recursive/--from-url;--metadatais file /--recursiveonly (the URL-ingest request carries no metadata field server-side, so passing it with--from-urlis rejected up-front asinput.invalid_argument). URL mode additionally accepts--title,--file-type, and--tag-id. Threads through to the SDK'sCreateKnowledgeFromFile/CreateKnowledgeFromURLsignatures (previously hardcoded to nil/"api" and dropped URL extras).
Fixed
- MCP
search_chunkstool:limitarg now correctly threads intoSearchParams.MatchCount. Previously the server's default cap won, silently capping below the requested limit. search sessionshuman time format: now renders a relative duration ("2 hours ago") matchingsession list, instead of raw RFC3339.doc upload(file path): re-uploading a file already ingested into the KB now surfaces asresource.already_exists(exit 1) instead of the misleadingnetwork.error("check base URL reachability"). The SDK returns itsErrDuplicateFilesentinel with noHTTP error <n>:prefix because the duplicate is detected via file-hash short-circuit, not by HTTP status; the previous fall-through toWrapHTTPtherefore misclassified it. The--from-urlbranch already handled the symmetricErrDuplicateURLcorrectly.
Breaking changes
weknora search docsnow applies the keyword filter server-side viaListKnowledgeWithFilter(was: page through every doc and substring-match client-side). Smaller wire payload on large KBs. The match is now case-sensitive (server usesLIKE %keyword%), whereas the previous client-side path lowered both sides. Callers that relied on case-insensitive matching (e.g.search docs Q3findingq3 retro) must lower-case the query themselves, or fall back toweknora apiwith a custom filter.
Changed
cli/AGENTS.mdMCP curation rationale rewritten: curated read-only is a deliberate product call gated on the absence of server-side per-token scope. When server-side scope ships, mutation tools can land in the MCP surface.cli/AGENTS.mdadds "Command surface design SOP" and "CRUD command flag canon" sections for future contributors. The design-SOP section includes a step reminding contributors to decide flag-vs-escape-hatch per field rather than trying to flag-mirror every SDK capability.cli/README.mdnow documents theweknora apiraw HTTP passthrough as the canonical escape hatch for deep KB config, per-requestchat/agent invokeoverrides, and operations without a CLI verb.
v0.4 — output contract hardening and mainstream alignment
Breaking changes
- Dropped the JSON envelope.
stdoutnow emits bare typed data ({...}or[...]); errors are written tostderrascode: msgwith an actionablehint:line. Pipelines using--json | jqno longer have to filter out an envelope wrapper. - Dropped
--dry-run. Destructive writes still require-y/--yes; non-TTY callers that omit-yexit with code 10 andinput.confirmation_requiredso an agent must surface the prompt to a human before retrying. - Dropped the per-command AI footer that rendered when AI-coding-agent
env detection fired. The same machine-readable guidance now lives in
the standard
--help(visible to all callers) and inmcp serve's tool descriptions.
Added
weknora mcp serve— curated read-only stdio MCP server exposing 9 tools (kb_list,kb_view,doc_list,doc_view,doc_download,search_chunks,chat,agent_list,agent_invoke). Destructive verbs are intentionally excluded.weknora agent list/agent view/agent invoke— manage and call WeKnora's server-side Custom Agent resources.weknora auth token— print the active credential tostdoutfor scripting (raw secret by default;--jsonemits{token, mode, context}).weknora doc upload --from-url— ingest a remote URL.--json=fields,...field projection and--jq <expr>filtering on every command that emits JSON.--limitand--all-pageson list / search commands for bounded output and explicit pagination control.- Per-resource filter flags:
kb list --pinned,doc list --status,session list --since.
Changed
- Go toolchain bumped from 1.24 to 1.26.
auth login --with-tokenvalidates the supplied key against/auth/mebefore persisting, and prints an advisory if the keyring is unavailable and credentials fall back to a 0600 file under$XDG_CONFIG_HOME/weknora/secrets/.- AGENTS.md rewritten as a developer guide (~170 lines, 6 H2 sections).
v0.3 — extended management surface and a session subtree
Added
context add/context list/context remove— first-class CRUD over connection targets (previously implicit viaauth login --name). Removing the current context requires explicit-y(exit-10 protocol) because subsequent commands have no default target.auth refresh— exchanges the stored refresh token for a new access + refresh pair (OAuth refresh-token grant). Transparent 401 → refresh → retry is also wired into the SDK transport with singleflight de-dup, so most callers never need to invoke this explicitly.kb edit— partial-update edit with only-sent-fields semantics (*stringoptions so unset fields stay unset in the PUT body).kb pin/kb unpin— idempotent pin/unpin toggle; no-op when already in the target state (emits_meta.warnings, no server call).kb empty— bulk-delete documents while preserving the KB record and its config. High-risk-write; exit-10 confirmation in non-TTY /--jsonpaths.doc view <id>— show one document's metadata (title, file name, type, size, parse status, embedding model, processed-at, error message). Counterpart tokb viewandsession view.doc download— stream a knowledge file to disk (-O FILE/-O -for stdout) with--clobbercontrolling overwrite. Rejects server-supplied path-like filenames; partial writes on error are cleaned up.doc upload --recursive --glob '*.md'— walk a directory and upload every match. Per-fileOK/FAILprogress lines on the human path; aggregateduploaded[]/failed[]envelope on--json. Exit code typed to the first failure's class on partial failure.search chunks/search kb/search docs/search sessions— verb-noun subtree (ghsearch code/repos/issues/…shape).search chunksis hybrid (vector + keyword) retrieval; the other three are client-side substring filters useful for discovering identifiers. All four take--limit N/-L N(1..1000) to cap returned rows.session list/session view/session delete— chat session management.api --input FILE/api --input -— body source for raw HTTP passthrough (file or stdin); mutually exclusive with--data.unlink— remove the cwd's.weknora/project.yamlso subsequent commands stop auto-resolving--kbfrom it. Walks up from cwd so a user in a subdirectory can unlink without cd-ing to the project root.- Completion smoke test guards against cobra bumps silently breaking bash / zsh / fish / powershell completion.
SDK additions (Go client at client/, strictly additive)
OpenKnowledgeFile(ctx, id) (filename, body io.ReadCloser, err)— new primitive returning the body as a stream plus the server-suggested Content-Disposition filename.DownloadKnowledgeFileis now a thin wrapper (signature unchanged, gained partial-file-on-error cleanup).WithTransport(http.RoundTripper) ClientOption— lets the CLI install the 401-retry transport.PathAuthLogin/PathAuthRefreshconstants — so HTTP middleware doesn't re-hardcode the literals.IsPinned boolfield onKnowledgeBase(server already returned it; SDK just hadn't modeled it).