---
name: sourcepool
description: Read materials (news articles, videos, social posts) from the sourcepool aggregated content library. Use when the user asks to fetch, search, browse, or filter items from sourcepool — by source, tag, language, keyword, or time window — or to pull article body text for downstream summarization, drafting, or analysis.
type: instruction
builtin: true
readonly: true
autoLoad: sourcepool
allowed-tools:
  - Bash(curl:*)
  - WebFetch
---

# sourcepool — 素材库读取

> Canonical URL: <https://pool.btcdev.me/skill.md>

sourcepool 是一个聚合多源内容（新闻、视频、社交）的素材库，对外暴露 REST JSON API。本 skill 指导 AI Agent 如何**只读地**从素材库取素材：列表、检索、按标签/语言/时间过滤、拉正文。

写入路径（`POST /ingest`、`DELETE /items/:id`）需要 `ADMIN_TOKEN`，不在本 skill 范围内 —— Agent 默认不要调用。

---

## 服务地址

Base URL：`https://pool.btcdev.me`

读接口**不需要鉴权**，直接 `curl` / `WebFetch` 即可。

---

## 数据模型速览

一个 **item** 表示一条素材，关键字段：

| 字段 | 说明 |
|---|---|
| `id` | 32 位 hex，`sha256(source_id + ":" + external_id).slice(0,32)`，稳定 |
| `source_id` / `source_name` / `source_kind` | 来源 key、显示名、类型（`news` / `video` / `social`） |
| `url` | 原文链接 |
| `title` / `summary` | 标题、摘要（摘要由 Haiku 生成） |
| `author` | 作者（可能为 null） |
| `language` | `en` / `zh` / `ja` / `ko` / `other` |
| `published_at` | 原始发布时间（可能为 null） |
| `fetched_at` | 入库时间 —— **所有列表都按它倒序**，且游标基于它 |
| `tags[]` | `[{ slug, name, kind }]`，`kind ∈ topic/person/org/geo/section/category/event/hashtag` |
| `tagging_status` | 只暴露 `done` 的；`pending`/`failed` 不会出现在读接口里 |

正文（`content_text`）默认**不返回**，需要在 `GET /items/:id` 上加 `?include=content`。

> ⚠️ FTS 范围：`?q=` 全文检索**只覆盖 title + summary**，不覆盖正文。需要按正文里的概念过滤时，走 `?tag=` 而不是 `?q=`。

---

## 端点

所有读端点都是 `GET`，返回 JSON。失败一般返回 `{ ok: false, error: "...", ... }`。

### `GET /healthz`

存活探测。返回 `{ ok: true }`。

### `GET /sources`

列出所有来源，附 `item_count`（仅统计 `tagging_status='done'` 的）。

```bash
curl -s "https://pool.btcdev.me/sources" | jq
```

返回：
```json
{ "data": [ { "id": "nyt", "name": "NYT", "kind": "news", "enabled": true, "item_count": 1234 } ] }
```

### `GET /items` — 列表与检索（主力接口）

按 `fetched_at` 倒序分页。所有 query 参数都可选，组合可叠加（AND 语义）。

| 参数 | 类型 | 说明 |
|---|---|---|
| `source` | string，可重复 | 限定来源 id，例如 `?source=nyt&source=bloomberg` |
| `language` | `en`/`zh`/`ja`/`ko`/`other`，可重复 | 内容语言；不合法会返回 400 |
| `q` | string | 关键词（**仅 title + summary** FTS，英文 `plainto_tsquery`） |
| `tag` | slug，可重复 | 标签 slug 过滤 |
| `tag_mode` | `any`（默认）/ `all` | 多 tag 时取并集 or 交集 |
| `kind` | tag kind | 限定 `tag` 参数命中的 kind（topic/person/org/...） |
| `within` | `<n>h` 或 `<n>d` | 相对时间窗，例如 `24h`、`3d`；上限 90 天 |
| `from` / `to` / `tz` | `YYYY-MM-DD` + IANA tz | 日历时间窗；`to` 是闭区间（自动加 1 天） |
| `since` / `until` | ISO-8601 或 epoch 秒 | 绝对时间窗 |
| `cursor` | opaque base64 | 用上一页返回的 `next_cursor` |
| `limit` | int，1–100 | 默认 20 |

时间过滤优先级：`within` > `from`/`to` > `since`/`until`。

返回：
```json
{
  "data": [ { /* item */ } ],
  "next_cursor": "eyJmIjoiMjAyNi0wNS0xOFQwMjowMDowMC4wMDBaIiwiaSI6ImFiYzEyMyJ9"
}
```

`next_cursor` 为 `null` 表示已到末页。

**常见用法：**

```bash
# 最新 20 条
curl -s "https://pool.btcdev.me/items"

# 最近 24 小时的英文素材
curl -s "https://pool.btcdev.me/items?within=24h&language=en&limit=50"

# 关键词 + 来源
curl -s "https://pool.btcdev.me/items?q=openai&source=nyt&source=bloomberg"

# 同时命中两个 tag（交集）
curl -s "https://pool.btcdev.me/items?tag=ai&tag=regulation&tag_mode=all"

# 指定日期范围（北京时间整天）
curl -s "https://pool.btcdev.me/items?from=2026-05-10&to=2026-05-17&tz=Asia/Shanghai"

# 翻下一页
curl -s "https://pool.btcdev.me/items?cursor=$NEXT_CURSOR&limit=50"
```

### `GET /items/:id` — 单条详情

```bash
curl -s "https://pool.btcdev.me/items/<id>"                  # 不含正文
curl -s "https://pool.btcdev.me/items/<id>?include=content"  # 含 content_text
```

返回 `{ data: { ...item, tags, content_text? } }`。`tagging_status != 'done'` 的会返回 `404 not_found`。

### `GET /tags` — 标签云

| 参数 | 说明 |
|---|---|
| `kind` | 限定 tag kind |
| `q` | slug 前缀匹配 |
| `top` | 返回条数，默认 50，上限 200 |

```bash
curl -s "https://pool.btcdev.me/tags?kind=org&top=30"
```

返回：`{ data: [ { slug, name, kind, count } ] }`，按 `count` 降序。只统计已完成 tagging 的 item。

### `GET /tags/:slug/items` — 按标签取素材

`GET /items?tag=<slug>` 的语法糖。支持 `language`、`cursor`、`limit`。

```bash
curl -s "https://pool.btcdev.me/tags/openai/items?limit=20"
```

### `GET /hot` — 24 小时热门

经过热度排序的英文素材，每小时刷新。

| 参数 | 说明 |
|---|---|
| `language` | 当前只支持 `en`（默认）。传其它返回 400。**只能传一个**。 |
| `limit` | 1–100，默认 20 |
| `cursor` | 翻页 |

```bash
curl -s "https://pool.btcdev.me/hot?limit=20"
```

返回 `{ data, next_cursor, language }`。

---

## 推荐工作流

### 1. 给定话题，抓最近一周相关素材并阅读正文

```bash
# 1) 看看有没有现成的标签
curl -s "https://pool.btcdev.me/tags?q=ai&top=10"

# 2) 用标签 + 时间窗拉列表
curl -s "https://pool.btcdev.me/items?tag=ai&within=7d&language=en&limit=20"

# 3) 对感兴趣的逐条取正文
for id in $IDS; do
  curl -s "https://pool.btcdev.me/items/$id?include=content"
done
```

### 2. 跟踪某来源近况

```bash
curl -s "https://pool.btcdev.me/items?source=bloomberg&within=24h&limit=100"
```

### 3. 关键词检索（注意只查 title+summary）

```bash
curl -s "https://pool.btcdev.me/items?q=quantum%20computing&limit=20"
```

若怀疑关键词只出现在正文里，改用 tag 过滤；如果还没有合适 tag，可以先抓宽一些（来源/语言/时间）再在客户端过滤正文。

### 4. 分页遍历

```bash
cursor=""
while :; do
  resp=$(curl -s "https://pool.btcdev.me/items?within=24h&limit=100${cursor:+&cursor=$cursor}")
  echo "$resp" | jq -c '.data[]'
  cursor=$(echo "$resp" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done
```

---

## 注意事项

- **只看到已完成 tagging 的素材**：pending / failed 的 item 不会出现在任何读接口里。这是有意的，免得 Agent 拿到空摘要、空标签的半成品。
- **列表按 `fetched_at` 倒序**，不是 `published_at`。如果用户问"最新"，按 fetched_at 解读；如果用户问"今天发布的"，可能要再过滤 `published_at`。
- **FTS 只查 title+summary**。需要正文级检索时，要么先 tag，要么客户端过滤。
- **缓存头**：列表响应带 `Cache-Control: public, max-age=60`，详情 `max-age=300`。Agent 一般不用关心，但要意识到 30–300s 内的回查可能拿到 CDN 缓存。
- **错误格式**：参数错误一般 400 + `{ ok: false, error, ... }`；不存在 404 + `{ error: "not_found" }`。
- **不要写**：`/ingest`、`DELETE /items/:id`、`/hot/refresh` 需要 `ADMIN_TOKEN`。除非用户明确给出 token 并要求写入，否则只读。
