mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-08-30 16:53:21 +08:00
main
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6f8b825f5f |
feat(cli): agent-first WeKnora CLI
The `weknora` command-line client for the WeKnora RAG server. Full command surface: kb / doc / chunk / session / message / agent / model / search / chat / auth / profile / link / api / mcp / skills / config / doctor / schema / exit-codes. Agent-first wire contract: JSON envelope by default, typed error codes mapped to stable exit codes, error.retry_argv / retryable / partial-failure status, global --dry-run preview, the exit-10 confirmation protocol for writes, and control/ANSI/Bidi input hygiene. Stateless env-credential auth (WEKNORA_API_KEY / WEKNORA_TOKEN + WEKNORA_HOST) for headless/CI/agent use. A curated read-only MCP tool surface (`mcp serve`) and embedded Agent Skills (`skills install`). Extensive unit + contract-golden tests and CI. |
||
|
|
2ce348d020 |
feat(cli): --format json default + NDJSON event stream + context→profile cascade + help calibration + docs (BREAKING)
D1 — --format default flipped to json regardless of TTY: - v0.6: smart default (text on TTY, json on pipe). - v0.7: always json; TTY only affects indent (compact in pipe). Enum values unchanged (text | json | ndjson). - Typed FormatMode enum replaces untyped string consts. - --format / --jq promoted to persistent root flags so unknown- subcommand paths still reach the typed-envelope guard (per-command registration in v0.6 would have rejected --format on unknown commands as cobra-prose exit 2). - WEKNORA_FORMAT env var added; precedence --format > env > default. Invalid env values silently ignored. D2 — chat / session ask default to NDJSON event-stream: - New cli/internal/output/ndjson_stream.go: InitEvent struct + EmitInit / EmitSDKEvent / WriteNDJSONLine helpers. EmitInit doc encodes the must-be-first-line invariant agents key on. - chat / session ask: --format json AND --format ndjson both emit one JSON event per line (no envelope wrapping). CLI injects exactly one `init` event at stream head carrying session_id + optional kb_id / agent_id / profile. Subsequent events pass through verbatim from the SDK (passthrough discipline per spec §5.1). - --format text keeps the SSE-style live renderer. context → profile full cascade: - Command group: cli/cmd/context/ → cli/cmd/profile/ (git mv; package contextcmd → profilecmd). - Global flag --context → --profile. Factory.ContextOverride → ProfileOverride. WEKNORA_PROFILE env var honored (--profile flag > env > config.CurrentContext). When --profile or WEKNORA_PROFILE references a missing profile, the error is input.invalid_argument with hint "weknora profile list" — not the destructive local.config_corrupt path (which would have told users to delete their config file). - Binding file .weknora/project.yaml field context: → profile: (no backwards-compat alias; re-run weknora link). - profile use JSON fields current_context / previous_context → current_profile / previous_profile. - weknora link JSON field context → profile. - CodeLocalContextNotFound → CodeLocalProfileNotFound (typed code rename). - Envelope top-level profile field populated via globalProfile (set by root PersistentPreRunE from Factory.ActiveProfile). chat / session ask NDJSON init event carries the same profile. - Rationale: "context" collided with LLM context window / RAG context / Go context.Context; mainstream multi-credential CLIs (AWS / Stripe / OpenAI / Anthropic / lark) all use "profile". H2/C1' help calibration: - AgentHelp gains Warnings []string; single SetAgentHelp helper routes on WEKNORA_AGENT_HELP=1 (emits JSON blob including warnings) vs human help (appends "AI agents:" block from same source). Warnings surface as both a structured JSON field and visible help-text addendum without drift. - 9 destructive commands carry warnings: kb / doc / agent / session / chunk delete; profile remove; kb / agent edit; auth logout. - weknora doc wait dedups ids at entry; SIGINT mid-wait returns silently (root signal handler maps to exit 130) instead of being miscategorised as operation.timeout / operation.failed. A4 — docs: - cli/AGENTS.md gains four agent-facing sections: Wire contract for AI agents (stdout / stderr / NDJSON / _notice evolution / SDK contract boundary); Deliberate deviations + mainstream alignments; Pre-1.0 breaking policy; Exit-10 anti-patterns. ERROR_REFERENCE table extended. - cli/README.md adds Agent quick start under Wire contract. - cli/CHANGELOG.md v0.7 section: BREAKING entries with migration notes, Added (WEKNORA_FORMAT / WEKNORA_PROFILE / retry_command / retry_after_seconds / risk / _notice reserved infra / meta.count / meta.has_more / doc fetch / doc create / session ask / doc delete --all / NDJSON init), Changed (docs additions), Deprecated (none — pre-release one-shot breaking). Spec: docs/superpowers/specs/2026-05-20-weknora-cli-v0.7-design.md §3 / §4 / §5 / §6 / §11 |
||
|
|
ad150c7126 |
refactor(cli): envelope sweep — Emit shape, batch ops, MCP StructuredContent, api flag cleanup
Sweep every CLI output path through the v0.7 envelope contract.
FormatOptions.Emit signature changes to (w, data, meta *output.Meta)
so list commands surface meta.count / has_more in the wire envelope.
TTY indent decision plumbed via FormatOptions.TTY (set by
ResolveDefault). --format and --jq promoted to persistent root flags
so unknown-subcommand paths still reach the typed-envelope guard
(per-command registration would have rejected --format on unknown
commands as cobra-prose exit 2). WEKNORA_FORMAT env-var fallback
honored before TTY-resolved default. AddFormatFlag retained for the
per-command --jq field-hint Long-text addendum.
~55 production Emit call sites swept across cli/cmd/**: list paths
populate meta.count; mutation paths pass nil meta; envelope.profile
threaded via globalProfile. Existing JSON-shape tests migrated to
decode the envelope wrapper.
Multi-target batch operations get a unified shape via new helpers:
- output.BatchItem + output.WriteBatchEnvelope (§4.5 per-item ok
pattern; data:[{id, ok, result?|error?}], meta:{count, successes*,
failures*}; Successes/Failures *int so explicit zero survives
omitempty in all-fail case).
- cmdutil.RunBatch + cmdutil.EmitBatch + cmdutil.DeletedAtNow +
cmdutil.ClassifyContextErr collapse the three previously-duplicated
multi-delete pipelines (doc / chunk / session) into one call site
pattern. doc upload --recursive uses the same helpers with a per-
file resultFn. Summary error sets Silent:true so the stderr
envelope path doesn't duplicate the stdout batch detail (exit 1
preserved via Code → ExitCode).
ConfirmDestructive / ConfirmDestructiveBatch extended with action +
retryCmd parameters. Every destructive command (kb delete, kb edit,
doc delete, doc delete --all, agent delete, agent edit, session
delete, chunk delete, auth logout, api -X DELETE) now attaches
error.risk.{level:"destructive", action:"<noun.verb>"} +
error.retry_command on the exit-10 envelope. kb edit / agent edit
also gain the destructive guard wiring (CHANGELOG listed them as
gated but they were silently executing without -y).
MCP tool handlers' 31 error paths return CallToolResult with
IsError + Content text fallback + StructuredContent (envelope.error
shape via cmdutil.ErrorToDetail). Handler Out type changed from
typed *sdk.X to any so the go-sdk auto-marshal doesn't overwrite
StructuredContent with a zero-struct on error returns. Success path
manually populates CallToolResult.StructuredContent via successResult
helper.
weknora api cleanup:
- -d/--data flag removed; body via --input <file> or --input -
(stdin) only. Aligns with gh / curl convention.
- HTTP method whitelist removed; any non-empty method accepted.
- HTTP Retry-After header → cmdutil.Error.RetryAfterSeconds →
envelope.error.retry_after_seconds.
- runAPIPaginated raw-passthrough fallback now wraps response in
envelope so --paginate never emits bare JSON to stdout.
Test sweep: ~60 cmd/** tests migrated to decode envelope shape.
9 wire-contract goldens updated under cli/acceptance/testdata/wire/.
Spec: docs/superpowers/specs/2026-05-20-weknora-cli-v0.7-design.md §4 / §5
|
||
|
|
0e081aec5c |
feat(cli): --log-level + kb/agent status & check + cross-cutting refactor
Operability surface and the bulk of the jopts→fopts migration: * --log-level error|warn|info|debug + WEKNORA_LOG_LEVEL env, wired to the SDK via client.SetDebugLevel. Invalid --log-level returns FlagError (exit 2). * kb status <kb-id> / kb check <kb-id> verb split (1 HTTP vs 1+N for failed_count aggregation). * agent status <agent-id> / agent check <agent-id> verb split (probes kb_scope_all_reachable via 1+N HTTP). * kb create <name> positional (matches agent create). * Positional id help strings namespaced (<kb-id> / <agent-id>). * All auth / context / link / doctor / kb / agent CRUD commands migrated to the FormatOptions API. * root.go Execute(ctx) takes a context so signal-cancellation propagates via cmd.Context() into long-running commands. * Pagination termination uses len(accum) >= total (not page*pageSize) so server-capped page sizes do not truncate aggregations. |
||
|
|
cc8254f862 |
refactor(cli): drop --dry-run + introduce bare-JSON output path
Two intertwined mainstream-alignment moves bundled because they share
the migration target (every command's --json path):
1. Drop --dry-run entirely. Survey of comparable API-wrapper CLIs
(gh, aws, stripe, lark): none expose --dry-run. The mainstream that
does (kubectl/git/helm/ansible) operates on declarative manifests
or local state where the preview is materially different from the
executed action. WeKnora's CLI just echoed the same parameters
that would have gone on the wire — the preview added no real
signal over `--help` + reading the call site. Removes:
- root --dry-run persistent flag + cmdutil/dryrun.go
- DryRun fields + EmitDryRun calls in 12 write commands
- format.Envelope.DryRun field
- 8 corresponding *_test.go cases
- --dry-run mention from README.md and CHANGELOG.md
- "dry_run":false from 16 golden envelopes
2. Migrate every --json output to bare data:
- New format.WriteJSON / WriteJSONFiltered helpers
(cli/internal/format/bare.go) share filterArrayItems /
filterObjectKeys / writeJQ with the (still-live for now) envelope
filter helpers.
- Read commands (kb/doc/session list+view, search chunks/docs/
sessions/kb, auth list/status, agent list/view, context list,
doctor) emit bare arrays / objects on stdout.
- Write commands (kb create/edit/delete/pin/empty, doc upload/
upload_recursive/delete, session delete, auth login/logout/
refresh/token, link/unlink, context add/use/remove, agent
invoke, chat, api, version) emit bare result objects. Risk
classification dropped — the resource + exit code already
convey the action.
Per-command shape changes:
list / search → []T (was {ok, data:{items:[…]}})
view → T (was {ok, data:T, _meta:…})
create / edit → T
delete / pin / etc. → {id, …action result…}
doctor → {summary, checks}
api → {status, headers, body}
_meta dropped on the read path:
pagination (page/page_size/total/has_more) — agents iterate with
--all-pages or accept --limit (gh CLI parity);
kb_id / context echo — caller already knows what it asked for.
Acceptance contract goldens regenerated for the new bare shape.
Error envelope on stdout (PrintErrorEnvelope) stays live for now —
the envelope-infra deletion lands in the next commit.
|
||
|
|
bdc589e1c0 |
refactor(cli): --limit/--all-pages, Go 1.26, internal/agent → aiclient
Cross-cutting cleanup that lands alongside the new feature surface: - `--limit / -L` and `--all-pages` on every list command. Default --limit 30 (gh-parity); --all-pages drains every server page client-side, capped by --limit. Closes the audit finding that the old "1000 max per call" implicit cap was undiscoverable. - `auth token` emits a TTY-only stderr advisory when stdout is a terminal (the credential just got displayed in scrollback) plus an api-key-mode rotation hint. - Comment + doc discipline pass: drop external project name references from in-code comments (we reference them in design notes, not inline). - Bump `go` directive to 1.26.0 and CI matrix to 1.26.x to align with the main module's go.mod. - Rename `cli/internal/agent` → `cli/internal/aiclient` to disambiguate from the new `cli/cmd/agent` resource subtree. The package handles AI coding-agent env detection + per-command --help annotations; the new name reflects that more precisely. |
||
|
|
493fc41e98 |
feat(cli): agent subtree (list/view/invoke)
Manages WeKnora's first-class Custom Agent resources — server-side records (system prompt + model + allowed tools + KB scope) that the user authored in the web UI. Commands: - `weknora agent list` — tenant-visible agents (built-in + custom), sorted updated_at desc; `--limit`/`-L` caps the slice client-side. - `weknora agent view <id>` — full sdk.Agent including nested AgentConfig (mode / model / allowed_tools / KB scope). Human mode prints a compact KV layout + Config: block. - `weknora agent invoke <agent-id> "<text>"` — streams the agent's configured workflow against a query over SSE. Auto-creates a fresh session unless `--session` is passed. Streaming defaults to TTY + no-stream/no-json; agent-friendly buffered single-object output with `--json` (or `--no-stream`). Decoupled from the existing `chat` subtree: agents bring their own system prompt / tool surface / KB selection, so the chat / agent split matches the server-side resource boundary. |