Skip to content

feat(knowledge): URL・文章・画像から curated ナレッジの下書きを作って保存する - #1123

Open
owk-owk130 wants to merge 6 commits into
developfrom
feat/knowledge-curated-draft
Open

feat(knowledge): URL・文章・画像から curated ナレッジの下書きを作って保存する#1123
owk-owk130 wants to merge 6 commits into
developfrom
feat/knowledge-curated-draft

Conversation

@owk-owk130

Copy link
Copy Markdown
Contributor

Summary

  • ダッシュボードのナレッジタブに「ナレッジを追加」を置く。URL・文章・画像/PDF のどれかから LLM が下書きを作り、タイトルと本文を確認・修正してから curated/<slug>.md として保存する
  • サーバーに POST /admin/knowledge/curated-draft を追加する(R2 には書かない。保存は既存の PUT /admin/knowledge/files/{key}
  • ファイル一覧の curated/ 配下だけに編集ボタンを出し、既存の FileEditor で追記できるようにする

主な変更内容

server

  • lib/html-to-text.ts: 依存追加なしの HTML → テキスト化。charset は Content-Type と <meta charset> から判定して TextDecoder でデコード。title / og:title / og:description も拾う
  • lib/x-post.ts: X の個別投稿は公開 oEmbed(publish.x.com/oembed)で本文を取る
  • services/knowledge/curated-draft.ts: URL fetch(5MB 上限をストリームで即時判定、15 秒タイムアウト、ログインページへの転送は除外)、PDF/画像は既存 convertToMarkdown、貼り付けテキストを 1 つの資料束にして drafter agent に structuredOutput で渡す。frontmatter は feat(knowledge): curated 区分を新設し検証用ナレッジを追加 #1083 の curated 契約(source_type: curated / source_authority: 2 / verified_at / url)。url は入力 1 件目で、読めなくても情報源に載せる。読めなかった資料は理由付きで返し、全部読めないときだけ 422
  • mastra/agents/curated-drafter-agent.ts: 資料に無いことは書かない・自分の知識で補わない・資料が短ければ短いまま、の指示
  • LLM usage に curated-draft を追加し、コスト区分は knowledge-base
  • openapi-errors に 422 を追加

shared

  • constants/knowledge.ts: 変換できる MIME 種別と件数上限(URL 10・ファイル 5・合計 20MB)を server / web で共有
  • knowledge-repository.draftCurated(multipart)、toFormData の配列対応、CuratedDraft / CuratedDraftRequest

web

  • CuratedComposer: 「URL から作る」「文章から作る」「画像・PDF から作る」の排他タブ。URL はチップ入力(貼り付けで即追加、複数可)、画像はドロップ / 選択 / 貼り付け。生成後はタイトル欄と整形表示の本文(「編集」で直せる)、参照した資料のリンク、保存先は自動で「変更」から編集、既存キーなら上書き警告
  • FileList に curated/ 限定の編集ボタン、KnowledgePanel に組み込み

確認したこと

  • lint、server / shared / web / widget の test:cov 全通過
  • ローカルで実 LLM を使い、peraichi の URL → feat(knowledge): curated 区分を新設し検証用ナレッジを追加 #1083otoineppu-tokyo.md と同じ構成の下書き(約 9 秒)。Instagram プロフィール URL は og:description が返るので読めた。X 投稿 + 別 URL の複数入力、画像のみ、テキスト + URL も通過
  • 保存は R2 書き込みまでローカルで確認。Vectorize 同期は remote binding の認証が無く未確認(既存の PUT ルートで無変更)

未確認・注意

  • Shift_JIS デコードは Node でのみ検証。workerd で未対応なら utf-8 にフォールバック
  • 保存後の Vectorize 同期は dev で確認が必要
  • 管理画面から作った curated/*.md は git 管理外。knowledge:upload --clean 後は POST /admin/knowledge/sync で再同期する(CLAUDE.md に記載)
  • 同じ URL を別 slug で 2 回取り込むと 2 ファイルできる。一覧で気付いて片方を消す運用

Test plan

  • dev で URL を貼って下書きが出る
  • 保存後にチャットで該当店名を聞くと回答に反映される
  • 利用コストタブに curated-draft が knowledge-base 区分で載る
  • ファイル一覧で curated/ の行だけ編集できる

owk-owk130 and others added 4 commits September 3, 2026 14:04
POST /admin/knowledge/curated-draft を multipart で呼ぶ
draftCurated を knowledge repository に足し、toFormData を
配列フィールド対応にする。変換できる MIME 種別と下書きの
件数上限は server と web で共有する定数に置く。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AYsHuZj1hWRdK1hieBG5YU
POST /admin/knowledge/curated-draft を追加する。URL は fetch して
HTML をテキスト化(charset は Content-Type と meta から判定、
X の投稿は公開 oEmbed)、画像と PDF は既存の converter で読み、
貼り付けテキストと合わせて 1 つの資料束にする。読めなかった資料は
理由付きで返し、全部読めないときだけ 422 にする。

資料は structuredOutput の drafter agent に渡し、#1083 の curated
frontmatter(source_type / source_authority / verified_at / url)で
Markdown を組み立てて返す。R2 には書かず、保存は既存の
PUT /admin/knowledge/files/{key} に任せる。

LLM usage に curated-draft を追加し knowledge-base 区分で集計する。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AYsHuZj1hWRdK1hieBG5YU
「URL から作る」「文章から作る」「画像・PDF から作る」のタブで
資料を渡し、下書き API の結果をタイトルと本文の形で確認・修正して
保存する。URL はチップ入力で複数貼れる。frontmatter は画面に出さず、
保存先の slug は自動で決めて必要なときだけ変更する。

ファイル一覧では curated/ 配下だけに編集ボタンを出し、既存の
FileEditor で追記できるようにする。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AYsHuZj1hWRdK1hieBG5YU
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for server

Status Category Percentage Covered / Total
🟢 Lines 98.05% (🎯 97%) 3635 / 3707
🟢 Statements 97.49% (🎯 96%) 3812 / 3910
🟢 Functions 98.53% (🎯 97%) 673 / 683
🟢 Branches 89.12% (🎯 87%) 1516 / 1701
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
server/src/db/schema.ts 100% 100% 100% 100%
server/src/lib/date.ts 100% 100% 100% 100%
server/src/lib/html-to-text.ts 100% 92% 100% 100%
server/src/lib/image-converter.ts 100% 83.33% 100% 100%
server/src/lib/openapi-errors.ts 100% 100% 100% 100%
server/src/lib/x-post.ts 100% 100% 100% 100%
server/src/repository/llm-usage-repository.ts 100% 75% 100% 100%
server/src/routes/admin/knowledge/convert.ts 95.58% 86.48% 100% 95.31%
server/src/routes/admin/knowledge/schemas.ts 100% 100% 100% 100%
server/src/services/analytics/llm-usage.ts 81.57% 94.44% 75% 79.41%
server/src/services/knowledge/curated-draft.ts 95.59% 82.27% 100% 95.86%
Generated in workflow #2122 for commit ae1853f by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for web

Status Category Percentage Covered / Total
🟢 Lines 97.06% (🎯 96%) 1821 / 1876
🟢 Statements 95.8% (🎯 95%) 1941 / 2026
🟢 Functions 95.52% (🎯 95%) 769 / 805
🟢 Branches 89.43% (🎯 88%) 1244 / 1391
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
web/src/app/dashboard/components/knowledge/CuratedComposer.tsx 87.4% 82.85% 86.66% 91.66%
web/src/app/dashboard/components/knowledge/FileList.tsx 85.18% 76.47% 75% 83.33%
web/src/app/dashboard/components/knowledge/helpers.ts 100% 90.32% 100% 100%
web/src/app/dashboard/hooks/useKnowledge.ts 97.61% 75% 100% 100%
Generated in workflow #2122 for commit ae1853f by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for shared

Status Category Percentage Covered / Total
🟢 Lines 99.17% (🎯 98%) 240 / 242
🟢 Statements 81.07% (🎯 80%) 257 / 317
🟢 Functions 100% (🎯 98%) 80 / 80
🟢 Branches 63.74% (🎯 62%) 109 / 171
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
shared/src/api/types.ts 100% 100% 100% 100%
shared/src/api/repository/knowledge-repository.ts 80.7% 57.69% 100% 100%
Generated in workflow #2122 for commit ae1853f by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for widget

Status Category Percentage Covered / Total
🟢 Lines 99.62% (🎯 98%) 265 / 266
🟢 Statements 97.94% (🎯 96%) 286 / 292
🟢 Functions 98.11% (🎯 98%) 52 / 53
🟢 Branches 93.28% (🎯 92%) 139 / 149
File CoverageNo changed files found.
Generated in workflow #2122 for commit ae1853f by the Vitest Coverage Report Action

owk-owk130 and others added 2 commits September 4, 2026 11:03
git 管理の基本ナレッジ約 329 件に管理画面から追加した curated が
埋もれていたので、「追加したナレッジ」を既定タブにして分ける。
削除ボタンは curated/ 配下と、画像・PDF 変換で入った元ファイル付きの
行にだけ出し、knowledge:upload で戻ってしまう基本ナレッジからは外す。
一覧は 70dvh で収めてスクロールさせ、表のヘッダーは固定する。

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YZeugZ89XV3Vdh59ELCiXS
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