mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-08-28 05:25:04 +00:00
Some checks failed
Tests ReMe / Unit Tests - py3.12 (push) Has been cancelled
Tests ReMe / Unit Tests - py3.13 (push) Has been cancelled
Windows Smoke / CLI smoke - py3.11 (push) Has been cancelled
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Tests ReMe / Unit Tests - py3.11 (push) Has been cancelled
* refactor: rebuild auto-fin and daily-paper cookbooks on structured-output agents Rework the auto-fin and daily-paper cookbooks to run on structured-output LLM agents instead of Claude Code agent wrappers, replace the SSH proxy with data-source mirrors, and rewrite the affected unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(auto_fin): unify JSON output serialization and writing - Extracted _write_output static method to serialize and write Pydantic models as compact JSON - Replaced inline JSON dump and write calls with _write_output usage across auto_fin steps - Added _report_path and _current_report for managing intra-day reports in AutoFinMergeStep - Updated auto_fin merge step to write output via new _write_output method - Enhanced news reading with caching in AutoFinHistoryStep - Refined returns calculation to handle events before close on non-trading days correctly feat(daily_paper): improve note path resolution and metadata handling - Introduced iter_note_metadata generator for safe Markdown frontmatter iteration - Added resolve_unique_note_path to avoid note filename conflicts on disk and in used titles - Updated analyze, collect, digest, and select steps to use centralized constants and helpers - Used utc_now_iso for consistent timestamping in metadata - Replaced direct frontmatter loads with iter_note_metadata in collect and analyze steps - Replaced hardcoded paper selection count with PAPER_COUNT constant in all relevant places - Added _MAX_SELECT_ATTEMPTS constant in select step for attempt management - Improved error messages for filename validation in daily paper title normalization feat(auto_fin): add multi-run cron schedules for intraday refinement - Defined three auto_fin cron jobs at 09:30, 11:30, and 18:00 Shanghai time for gradual report updates - Each intraday run adds evidence cumulatively instead of replacing prior output wholly - Updated daily_cookbook.yaml to register new cron schedules and remove legacy 12:00 cron refactor(auto_fin_data): clean ETF code handling and page limits - Replaced hardcoded DEFAULT_ETF_CODES with required non-empty config value "etf_codes" - Added constants for major news and fund page limits to control pagination - Improved ETF name extraction logic to handle missing fields consistently fix(auto_fin_merge): fix report retrieval and merging logic - Added support for getting current intra-day report in addition to previous day's report - Modified merge template to include prior and current report sections for better context - Adjusted report path handling to consistently use Path objects test(auto_fin): add coverage for returns calculation and report retrieval - Added test for returns when event occurs before close on non-trading day, checking next session entry - Added test for previous and current report retrieval feeding merge context with disk files - Extended test asserts for auto_fin cron schedule changes in config style(daily_paper): reorder and cleanup imports - Reorganized imports in _common.py for clarity and added missing collections.abc.Iterator import - Cleaned up commented and unused imports across daily_paper steps * feat: add configurable upstream mirror proxy * style: format auto-fin data step * fix: align cookbook mirrors and contracts --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
559 lines
15 KiB
YAML
559 lines
15 KiB
YAML
app_name: ReMe Daily Cookbook
|
|
workspace_dir: ${DAILY_PAPER_WORKSPACE_DIR:-reme_workspace}
|
|
timezone: Asia/Shanghai
|
|
language: zh
|
|
|
|
# This is a standalone application config. It intentionally does not inherit
|
|
# default.yaml and listens on a separate port so it can run beside ReMe.
|
|
service:
|
|
backend: http
|
|
host: ${DAILY_PAPER_HOST:-127.0.0.1}
|
|
port: ${DAILY_PAPER_PORT:-8001}
|
|
|
|
jobs:
|
|
index_update_loop:
|
|
backend: background
|
|
watch_dirs: [daily_dir, digest_dir]
|
|
watch_suffixes: [md, jsonl]
|
|
steps:
|
|
- backend: init_changes_step
|
|
monitor_type: file_store
|
|
monitor_name: default
|
|
dispatch_steps: [update_index_step]
|
|
- backend: watch_changes_step
|
|
dispatch_steps:
|
|
- backend: update_index_step
|
|
persist: false
|
|
|
|
auto_dream:
|
|
backend: base
|
|
description: "Auto-dream: consolidate recent daily notes into digest memory and interest topics."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
date:
|
|
type: string
|
|
description: "YYYY-MM-DD to scan; defaults to today in the configured timezone."
|
|
default: ""
|
|
hint:
|
|
type: string
|
|
description: "Optional guidance for extraction and integration."
|
|
default: ""
|
|
scan_days:
|
|
type: integer
|
|
description: "Number of recent daily directories to scan."
|
|
default: 2
|
|
max_units:
|
|
type: integer
|
|
description: "Maximum number of extracted memory units."
|
|
default: 5
|
|
topic_count:
|
|
type: integer
|
|
description: "Maximum number of interest topics to write."
|
|
default: 3
|
|
topic_diversity_days:
|
|
type: integer
|
|
description: "Previous interest-topic days used for de-duplication."
|
|
default: 7
|
|
steps:
|
|
- backend: dream_extract_step
|
|
file_catalog: dream
|
|
topic_session_id: interests
|
|
scan_days: 2
|
|
max_units: 5
|
|
- backend: dream_integrate_step
|
|
- backend: dream_topics_step
|
|
topic_count: 3
|
|
topic_diversity_days: 7
|
|
- backend: dream_finish_step
|
|
file_catalog: dream
|
|
|
|
auto_memory:
|
|
backend: base
|
|
description: "Auto-memory: record conversation facts into a daily note."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
messages:
|
|
type: array
|
|
description: "Conversation messages."
|
|
items:
|
|
type: object
|
|
session_id:
|
|
type: string
|
|
description: "Source conversation session identifier."
|
|
default: ""
|
|
memory_hint:
|
|
type: string
|
|
description: "Optional memory-writing guidance."
|
|
date:
|
|
type: string
|
|
description: "YYYY-MM-DD daily-note date; empty infers it from messages or current time."
|
|
default: ""
|
|
required: [messages]
|
|
steps:
|
|
- backend: auto_memory_step
|
|
|
|
reindex:
|
|
backend: base
|
|
description: "Wipe the derived search store and rebuild it from memory files."
|
|
watch_dirs: [daily_dir, digest_dir]
|
|
watch_suffixes: [md, jsonl]
|
|
parameters:
|
|
type: object
|
|
properties: {}
|
|
steps:
|
|
- backend: clear_store_step
|
|
- backend: init_changes_step
|
|
monitor_type: file_store
|
|
monitor_name: default
|
|
dispatch_steps: [update_index_step]
|
|
|
|
memory_search:
|
|
backend: base
|
|
description: "Long-term memory retrieval via hybrid workspace search (vector + BM25, RRF-fused)."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
query:
|
|
type: string
|
|
description: "Search query."
|
|
limit:
|
|
type: integer
|
|
description: "Maximum number of results."
|
|
default: 5
|
|
min_score:
|
|
type: number
|
|
description: "Minimum fused score."
|
|
default: 0.0
|
|
start_date:
|
|
type: string
|
|
description: "Optional inclusive start date (YYYY-MM-DD)."
|
|
end_date:
|
|
type: string
|
|
description: "Optional inclusive end date (YYYY-MM-DD)."
|
|
required: [query]
|
|
steps:
|
|
- backend: search_step
|
|
vector_weight: 0.7
|
|
candidate_multiplier: 5.0
|
|
expand_links: true
|
|
max_links_per_direction: 10
|
|
|
|
node_search:
|
|
backend: base
|
|
description: "Recall digest nodes for auto-dream de-duplication and linking."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
query:
|
|
type: string
|
|
description: "Candidate memory-node name and description."
|
|
limit:
|
|
type: integer
|
|
description: "Maximum number of digest nodes."
|
|
default: 20
|
|
required: [query]
|
|
steps:
|
|
- backend: node_search_step
|
|
vector_weight: 0.7
|
|
candidate_multiplier: 5.0
|
|
|
|
daily_list:
|
|
backend: base
|
|
description: "List notes under one day."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
date:
|
|
type: string
|
|
description: "YYYY-MM-DD; empty means today."
|
|
default: ""
|
|
steps:
|
|
- backend: daily_list_step
|
|
|
|
frontmatter_read:
|
|
backend: base
|
|
description: "Read a file's frontmatter."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: "Workspace-relative path."
|
|
required: [path]
|
|
steps:
|
|
- backend: frontmatter_read_step
|
|
|
|
frontmatter_update:
|
|
backend: base
|
|
description: "Merge key-values into a file's frontmatter."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: "Workspace-relative path."
|
|
metadata:
|
|
type: object
|
|
description: "Key-values to merge."
|
|
required: [path, metadata]
|
|
steps:
|
|
- backend: frontmatter_update_step
|
|
|
|
move:
|
|
backend: base
|
|
description: "Move or rename a workspace file and retarget inbound wikilinks."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
src_path:
|
|
type: string
|
|
description: "Workspace-relative source path."
|
|
dst_path:
|
|
type: string
|
|
description: "Workspace-relative destination path."
|
|
overwrite:
|
|
type: boolean
|
|
default: false
|
|
retarget:
|
|
type: boolean
|
|
default: true
|
|
required: [src_path, dst_path]
|
|
steps:
|
|
- backend: move_step
|
|
|
|
read:
|
|
backend: base
|
|
description: "Read a markdown file under the workspace."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: "Workspace-relative markdown path."
|
|
start_line:
|
|
type: integer
|
|
end_line:
|
|
type: integer
|
|
required: [path]
|
|
steps:
|
|
- backend: read_step
|
|
with_neighbors: false
|
|
max_neighbors_per_direction: 10
|
|
|
|
write:
|
|
backend: base
|
|
description: "Create or overwrite a markdown file with frontmatter."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: "Workspace-relative markdown path."
|
|
name:
|
|
type: string
|
|
description: "Frontmatter name."
|
|
description:
|
|
type: string
|
|
description: "Frontmatter description."
|
|
content:
|
|
type: string
|
|
description: "Markdown body."
|
|
metadata:
|
|
type: object
|
|
description: "Optional extra frontmatter fields."
|
|
required: [path, name, description, content]
|
|
steps:
|
|
- backend: write_step
|
|
|
|
daily_write:
|
|
backend: base
|
|
description: "Write a daily markdown note linked to its source conversation."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: "Filename stem and frontmatter name."
|
|
description:
|
|
type: string
|
|
description: "Frontmatter description."
|
|
session_id:
|
|
type: string
|
|
description: "Source conversation session identifier."
|
|
content:
|
|
type: string
|
|
description: "Markdown body."
|
|
date:
|
|
type: string
|
|
description: "YYYY-MM-DD; empty means today."
|
|
default: ""
|
|
metadata:
|
|
type: object
|
|
description: "Optional extra frontmatter fields."
|
|
required: [name, description, session_id, content]
|
|
steps:
|
|
- backend: daily_write_step
|
|
|
|
edit:
|
|
backend: base
|
|
description: "Find and replace text in a markdown file."
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: "Workspace-relative path."
|
|
old:
|
|
type: string
|
|
description: "Text to replace."
|
|
new:
|
|
type: string
|
|
description: "Replacement text."
|
|
default: ""
|
|
required: [path, old, new]
|
|
steps:
|
|
- backend: edit_step
|
|
|
|
auto_fin:
|
|
backend: base
|
|
description: "Analyze configured ETFs from current news and comparable historical events."
|
|
etf_codes: &auto_fin_etf_codes
|
|
- 518880.SH
|
|
# - 159516.SZ
|
|
# - 512800.SH
|
|
# - 512890.SH
|
|
# - 159992.SZ
|
|
- 159530.SZ
|
|
# - 159869.SZ
|
|
# - 512690.SH
|
|
# - 159755.SZ
|
|
# - 159611.SZ
|
|
# - 159652.SZ
|
|
- 512760.SH
|
|
# - 159732.SZ
|
|
news_lookback_days: 60
|
|
current_news_limit_per_etf: 10
|
|
historical_news_limit: 5
|
|
historical_search_limit: 10
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
date:
|
|
type: string
|
|
description: "Current date in YYYY-MM-DD; empty means today in Asia/Shanghai."
|
|
default: ""
|
|
now:
|
|
type: string
|
|
description: "Optional simulated current time in ISO 8601 format; empty means the real current time."
|
|
default: ""
|
|
historical_search_limit:
|
|
type: integer
|
|
description: "Maximum historical-news candidates retrieved for each current event."
|
|
default: 10
|
|
minimum: 1
|
|
steps: &auto_fin_steps
|
|
- backend: auto_fin_data_step
|
|
etf_codes: *auto_fin_etf_codes
|
|
news_lookback_days: 60
|
|
- backend: update_index_step
|
|
- backend: auto_fin_topic_step
|
|
current_news_limit_per_etf: 10
|
|
- backend: auto_fin_history_step
|
|
historical_news_limit: 5
|
|
historical_search_limit: 10
|
|
- backend: auto_fin_merge_step
|
|
- backend: dingtalk_markdown_send_step
|
|
input_mapping:
|
|
auto_fin_digest_path: markdown_path
|
|
app_key: ${DINGTALK_APP_KEY:-}
|
|
app_secret: ${DINGTALK_APP_SECRET:-}
|
|
robot_code: ${DINGTALK_ROBOT_CODE:-}
|
|
conversation_ids: ${DINGTALK_CONVERSATION_IDS:-}
|
|
title: ReMe Auto Fin
|
|
timeout: 15
|
|
|
|
# Three intraday runs (Asia/Shanghai). Non-trading days are skipped inside
|
|
# auto_fin_data_step, so a daily trigger is fine. Each rerun refines the same
|
|
# day's report on top of the earlier run rather than replacing it wholesale.
|
|
auto_fin_0930_cron:
|
|
backend: cron
|
|
cron: "30 9 * * *"
|
|
steps: *auto_fin_steps
|
|
|
|
auto_fin_1130_cron:
|
|
backend: cron
|
|
cron: "30 11 * * *"
|
|
steps: *auto_fin_steps
|
|
|
|
auto_fin_1800_cron:
|
|
backend: cron
|
|
cron: "0 18 * * *"
|
|
steps: *auto_fin_steps
|
|
|
|
daily_paper:
|
|
backend: base
|
|
description: "Build detailed readings and a five-minute brief from Hugging Face weekly/monthly papers."
|
|
candidate_limit: &candidate_limit 20
|
|
rrf_k: &rrf_k 60
|
|
weekly_weight: &weekly_weight 0.7
|
|
history_days: &history_days 30
|
|
hf_timeout: &hf_timeout 600
|
|
hf_max_retries: &hf_max_retries 3
|
|
pdf_timeout: &pdf_timeout 600
|
|
max_pdf_bytes: &max_pdf_bytes 52428800
|
|
max_pdf_pages: &max_pdf_pages 20
|
|
max_pdf_chars: &max_pdf_chars 300000
|
|
parameters:
|
|
type: object
|
|
properties:
|
|
date:
|
|
type: string
|
|
description: "Run date in YYYY-MM-DD; empty means today in Asia/Shanghai."
|
|
default: ""
|
|
force:
|
|
type: boolean
|
|
description: "Regenerate even when that day's final brief already exists."
|
|
default: false
|
|
topics:
|
|
type: string
|
|
description: "Optional topics to prioritize when selecting papers."
|
|
default: ""
|
|
weekly_weight:
|
|
type: number
|
|
description: "Weekly contribution in reciprocal-rank fusion."
|
|
default: 0.7
|
|
history_days:
|
|
type: integer
|
|
description: "Prior recommendation window excluded by arXiv ID."
|
|
default: 30
|
|
steps: &daily_paper_steps
|
|
- backend: daily_paper_collect_step
|
|
- backend: daily_paper_rank_step
|
|
- backend: daily_paper_select_step
|
|
- backend: daily_paper_analyze_step
|
|
- backend: daily_paper_digest_step
|
|
- backend: dingtalk_markdown_send_step
|
|
input_mapping:
|
|
daily_paper_digest_path: markdown_path
|
|
app_key: ${DINGTALK_APP_KEY:-}
|
|
app_secret: ${DINGTALK_APP_SECRET:-}
|
|
robot_code: ${DINGTALK_ROBOT_CODE:-}
|
|
conversation_ids: ${DINGTALK_CONVERSATION_IDS:-}
|
|
title: ReMe Daily Paper
|
|
timeout: 15
|
|
|
|
daily_paper_cron:
|
|
backend: cron
|
|
cron: "0 8 * * *"
|
|
candidate_limit: *candidate_limit
|
|
rrf_k: *rrf_k
|
|
weekly_weight: *weekly_weight
|
|
history_days: *history_days
|
|
hf_timeout: *hf_timeout
|
|
hf_max_retries: *hf_max_retries
|
|
pdf_timeout: *pdf_timeout
|
|
max_pdf_bytes: *max_pdf_bytes
|
|
max_pdf_pages: *max_pdf_pages
|
|
max_pdf_chars: *max_pdf_chars
|
|
steps: *daily_paper_steps
|
|
|
|
dingtalk_wait:
|
|
backend: background
|
|
supervisor: true
|
|
close_timeout: 10
|
|
steps:
|
|
- backend: dingtalk_wait_step
|
|
app_key: ${DINGTALK_APP_KEY:-}
|
|
app_secret: ${DINGTALK_APP_SECRET:-}
|
|
robot_code: ${DINGTALK_ROBOT_CODE:-}
|
|
worker_count: 4
|
|
builtin_tools: [bash]
|
|
job_tools:
|
|
- memory_search
|
|
- read
|
|
- write
|
|
- edit
|
|
- daily_list
|
|
- daily_write
|
|
- frontmatter_read
|
|
- frontmatter_update
|
|
|
|
components:
|
|
tokenizer:
|
|
default:
|
|
backend: regex
|
|
|
|
as_llm:
|
|
default:
|
|
backend: openai
|
|
model: ${LLM_MODEL_NAME:-qwen3.7-plus}
|
|
stream: true
|
|
context_size: 200000
|
|
max_retries: 3
|
|
credential:
|
|
api_key: ${LLM_API_KEY:-}
|
|
base_url: ${LLM_BASE_URL:-}
|
|
parameters:
|
|
max_tokens: 65536
|
|
thinking_enable: false
|
|
|
|
agent_wrapper:
|
|
default:
|
|
backend: agentscope
|
|
as_llm: default
|
|
builtin_tools: false
|
|
|
|
# as_embedding:
|
|
# default:
|
|
# backend: openai
|
|
# model: ${EMBEDDING_MODEL_NAME:-text-embedding-v4}
|
|
# dimensions: 1024
|
|
# max_retries: 0
|
|
# credential:
|
|
# api_key: ${EMBEDDING_API_KEY:-}
|
|
# base_url: ${EMBEDDING_BASE_URL:-https://dashscope.aliyuncs.com/compatible-mode/v1}
|
|
# parameters: {}
|
|
#
|
|
# embedding_store:
|
|
# default:
|
|
# backend: local
|
|
# as_embedding: default
|
|
# max_retries: 3
|
|
# quota_retry_delay: 60.0
|
|
|
|
file_graph:
|
|
default:
|
|
backend: local
|
|
|
|
file_catalog:
|
|
dream:
|
|
backend: local
|
|
|
|
file_chunker:
|
|
markdown:
|
|
backend: markdown
|
|
supported_extensions: [md]
|
|
embed_toc: true
|
|
max_ast_sections: 100
|
|
include_frontmatter_in_metadata: false
|
|
include_frontmatter_keys_in_metadata: []
|
|
jsonl:
|
|
backend: jsonl
|
|
supported_extensions: [jsonl]
|
|
max_lines_per_chunk: 1
|
|
|
|
keyword_index:
|
|
default:
|
|
backend: bm25
|
|
tokenizer: default
|
|
|
|
file_store:
|
|
default:
|
|
backend: local
|
|
store_name: local
|
|
# embedding_store: default
|
|
embedding_store: ""
|
|
keyword_index: default
|
|
file_graph: default
|