feat: workspace-wide Knowledge with agent tools and WebUI#150
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a workspace-wide shared Knowledge base feature, adding backend support (domain models, Firestore/in-memory repositories, GraphQL schema, and a usecase with semantic search), agent tools, and a frontend UI for managing knowledge entries. Feedback on the changes highlights a critical Stored XSS vulnerability in the frontend where user-controlled titles are rendered unescaped via dangerouslySetInnerHTML. Additionally, several high-severity scalability issues were identified in the Firestore repository and usecase, such as loading the entire collection for in-memory filtering, sorting, and tag extraction. Other recommendations include removing a redundant Get check before document deletion, adding defensive nil checks to prevent pointer panics, using useEffect instead of onCompleted for React form state initialization, and normalizing tags to lowercase to avoid casing duplicates.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
# Conflicts: # frontend/src/i18n/en.ts # frontend/src/i18n/ja.ts # frontend/src/i18n/keys.ts # pkg/controller/graphql/generated.go # pkg/controller/http/graphql_test.go # pkg/usecase/agent/agent.go # pkg/usecase/agent/casebound/casebound.go # pkg/usecase/eval/env/env.go
Summary
Adds a workspace-wide shared Knowledge feature: organization-specific information that does not exist in the LLM's general knowledge (operating rules, internal proper nouns, past judgements, threat intel, …), captured so it can be reused on future case processing. Both humans (WebUI) and AI agents read and write it.
A Knowledge entry is intentionally minimal: title + a single Markdown
claimbody + one-or-more free-formtags(no custom fields, not tied to a case). Retrieval is by embedding-based semantic search (in-memory cosine, with substring fallback) and by tag AND filter.What's included
Backend (Go)
model.Knowledge(Claim stringMarkdown,Tags []string,Embedding []float64) withValidate(title + ≥1 tag required, claim ≤ 8000 runes) andNormalizeTags.KnowledgeRepositoryinterface + memory and Firestore implementations. Firestore uses the subcollectionworkspaces/{ws}/knowledges; tag filtering and ordering are done in memory, so no new Firestore index is required.KnowledgeUseCase: Create / Get / List / Search / Update / Delete / ListTags. Embedding generation is fail-open (works without an embed client; search falls back to substring). Reuses the existing embedding client (--embedding-*flags) — no new flags/env vars.knowledges,knowledge,knowledgeTags,searchKnowledge;createKnowledge/updateKnowledge/deleteKnowledge).knowledge__*(search/get/list_tags read; create/update write). Read is always available; write is withheld while processing a PRIVATE case so a private case's contents cannot leak into the workspace-shared base. Wired into casebound, threadcase/planexec (read), and Job execution.graphql.Knowledge/Case.Knowledgesremnants of a previously demolished feature.Frontend (React/TS)
TagInputcomponent (IME-guarded). All strings via i18n (en/ja), design-token CSS only.Docs
docs/concepts.md,docs/user_guide.md(Knowledge section + agent tool table),docs/eval.md(notes that in-process tools are not in the eval catalog).Repository test performance (timeout fix)
The
pkg/repositorysuite runs against real Firestore and was already near thego test10-minute default (~880s before this change). To keep it green:t.Parallel()to the top-level repository tests (TestFirestoreSlackUserRepositoryleft serial because it uses collection-wideDeleteAll/GetAll). This broughtpkg/repositoryfrom 892s → ~300s, under the 600s default.task testtarget (go test ./... -timeout 30m) for extra headroom; run aszenv task test.Testing
zenv go test ./...— all pass (real Firestore;pkg/repository~300s).-race.claim/tags/embedding.go vet,golangci-lint,gosecclean.