<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ollama-web.git/src/ollama_web/tools/helper, branch v0.5.3</title>
<subtitle>A lightweight personal Ollama Web UI with web search, PDF attachments, and MCP tools.
</subtitle>
<id>https://git.takashi-2521.com/ollama-web.git/atom?h=v0.5.3</id>
<link rel='self' href='https://git.takashi-2521.com/ollama-web.git/atom?h=v0.5.3'/>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-web.git/'/>
<updated>2026-08-23T08:28:39+00:00</updated>
<entry>
<title>fix(tools): PDFページングを損失なしカーソル方式へ再設計</title>
<updated>2026-08-23T08:28:39+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-08-23T08:28:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-web.git/commit/?id=33f6b4dbb69e9366e312a8b44dbed9d22e7cba5b'/>
<id>urn:sha1:33f6b4dbb69e9366e312a8b44dbed9d22e7cba5b</id>
<content type='text'>
PDF本文をページ単位で抽出した後に文字数上限で切断しつつ、継続位置だけ次ページへ進めていたため、ページ末尾が復元不能になる問題を修正する。ツール側の本文上限とLLM側の結果上限の不整合、25ページの処理上限、添付経路での継続情報欠落も共通契約で解消する。

- 共通PageResultと、メタデータ込みの結果上限内で本文量を決めるフォーマッターを追加

- v2トークンにPDFのページ番号とページ内文字位置を保持し、v1トークンの読み取り互換性を維持

- pdf_to_text、scrape_url、search_and_fetchを返却済み本文だけカーソルが進む方式へ統一

- max_pdf_pagesを文書全体ではなく1呼び出しの処理上限として扱い、長い単一ページと26ページ目以降の継続取得に対応

- attachment:&lt;file_id&gt;をセッション限定で解決し、既存添付も保存済みプレビューではなく元PDFから再解析

- Web取得ファイルをセッションとURL単位で重複排除し、HTMLおよびテキスト経路の全文ページングも維持

- 正常なページング結果の後段切断を禁止し、結果上限・コンテキスト予算・ラウンド上限では未取得状態を明示

- 日英プロンプト、UIメッセージ、ツールスキーマ、変更履歴を実装へ同期

- 実PDF、30ページ超、長い単一ページ、旧トークン、セッション分離、コンテキスト境界の回帰テストを追加

検証:

- pytest: 130 passed

- ruff check src tests: passed

- mypy src: passed

- c2144.pdf: 19ページ、抽出本文46015文字（ページ区切り込み46051文字）を8回で重複・欠落なく完全再構成
</content>
</entry>
<entry>
<title>fix(tools): search_and_fetch のページングトークン破損バグを修正</title>
<updated>2026-08-02T07:18:29+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-08-02T07:18:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-web.git/commit/?id=af1da765acafec4d7468a79d462427f4245b44db'/>
<id>urn:sha1:af1da765acafec4d7468a79d462427f4245b44db</id>
<content type='text'>
## 背景

search_and_fetch の next_token / continue_from によるページング継続が
PDF 形式で間欠的に失敗するバグが報告された。発生エラー:
  1. payload is not valid JSON: Expecting ':' delimiter
  2. 'utf-8' codec can't decode byte 0xda in position 278

1ページ目の取得自体は成功し、next_token 返却まで正常だが、
next_token を continue_from に渡した2ページ目でエラーが発生。
txt/md/csv/json では安定動作し、PDF で間欠的・再現性なし。

## 根本原因

コード精査の結果、報告の「非UTF-8バイト混入」仮説に対し、より有力な
主因として「トークン巨大化による末尾欠損」を特定:

- _render_file_page() は matched 配列（title/href/body 全部入り）を
  トークンに埋め込んでいたが、レンダリングで使うのは title と href
  のみ。body（DuckDuckGo のスニペット、PDF 論文要約で数KB）は未使用
- 候補複数件でトークンが数KB〜十数KBに膨張
- LLM が continue_from にコピーする際、コンテキスト長や
  _trim_tool_result の切り詰めでトークン末尾が欠損
- base64 デコード結果が不正になり JSONDecodeError（JSON途中切断）
  と UnicodeDecodeError（マルチバイト境界切断）の両エラーが発生
- PDF で間欠的・再現性なしは、検索結果セットごとにスニペット長が
  変動しトークンサイズが破損閾値を前後するためと説明がつく

補助要因: make_token() の ensure_ascii=False が、末尾欠損時に
マルチバイト文字境界で切れる確率を上げていた。

## 修正内容（案A: ユーザー承認済み）

1. pagination.py の make_token() を ensure_ascii=True 化
   - トークンを純ASCII化し、末尾欠損でも UnicodeDecodeError を防止
   - 非ASCII文字は \uXXXX エスケープ（6バイト固定）で安定化

2. fetch.py に _slim_matched() ヘルパーを追加
   - matched から body を除外し title+href のみ埋め込み
   - 3箇所の make_token 呼び出し（fetch失敗時・ファイル内継続時・
     次ファイル移行時）を matched=_slim_matched(matched) に変更
   - トークンサイズを数KB〜十数KB → 数百バイトに削減

3. トークン形式バージョン v は 1維持（構造不変・後方互換）
   - 旧トークン（body入り・ensure_ascii=False）も parse_token で
     正常デコード可能
   - 再検索回避機能も維持

## テスト

tests/test_tools.py に新規テスト5件を追加:
- test_make_token_ensure_ascii_true
- test_search_and_fetch_token_excludes_body
- test_search_and_fetch_token_size_reduced
- test_search_and_fetch_continue_with_slim_token
- test_search_and_fetch_pagination_with_nonascii_title

## 検証結果

- pytest: 113 passed (新規5件含む、既存回帰なし)
- ruff check src/ tests/: All checks passed
- mypy src/: Success: no issues found in 30 source files

## ドキュメント

docs/tools-schema.md に実装ベースの差分を反映:
- make_token() の説明に ensure_ascii=True 化の旨を追記
- search_and_fetch 処理フローの注記に _slim_matched() による
  body 除外とトークンサイズ削減の旨を追記
- トークンペイロード構造の matched 例から body を削除
</content>
</entry>
<entry>
<title>scrape_url / pdf_to_text / search_and_fetch はページング（継続トークン方式）に対応</title>
<updated>2026-08-02T06:50:41+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-08-02T06:50:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-web.git/commit/?id=515f96a7779f117a7e37f854de2ded99160d0c76'/>
<id>urn:sha1:515f96a7779f117a7e37f854de2ded99160d0c76</id>
<content type='text'>
mypy 6エラー修正
</content>
</entry>
<entry>
<title>Harden web UI security</title>
<updated>2026-06-24T13:47:13+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-06-24T13:47:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-web.git/commit/?id=e4d421c782a181f421e2987f75b4610845e3ef55'/>
<id>urn:sha1:e4d421c782a181f421e2987f75b4610845e3ef55</id>
<content type='text'>
</content>
</entry>
</feed>
