ReMe/tests/unit
Ziyang Guo b0991db725
fix(frontmatter-read): put the frontmatter in the answer, not just a key count (#564)
* fix(frontmatter-read): put the frontmatter in the answer, not just a key count

`frontmatter_read` answered `Read frontmatter from <path> (N key(s))` and left
the frontmatter itself in `metadata["frontmatter"]`. MCP returns only
`response.answer`, so the LLM that asked for a file's frontmatter learned how
many keys exist and nothing else — the same shape of gap #379 describes for
`list`, where the caller cannot act on the result.

Render each key on its own line in the answer. Values are flattened to one
line each so a multi-line description cannot break the line-per-key layout:
lists join with commas and nested mappings render as compact JSON. An empty
frontmatter says `(no keys)` rather than trailing off after the colon.

The answer also names the probed path instead of the raw input, so a
suffix-less request reports the `.md` file that was actually read and the
caller can follow up with `read` without consulting metadata. Structured
`metadata["frontmatter"]` is unchanged, so programmatic consumers see no
difference.

Towards #379.

* docs(config): match the frontmatter_read description to the new answer

The job description still advertised "Read a file's frontmatter as a dict",
but the answer is now rendered `key: value` lines — the dict only survives in
metadata. An LLM choosing between `frontmatter_read` and a whole-file `read`
would expect a dict it can index into and get prose instead.

This is the wording-alignment point raised on #397, applied here before
review rather than after.

* fix(frontmatter-read): never fail a valid YAML read on rendering

Review on #564 found two rendering regressions plus boundary losses:

- json.dumps(..., sort_keys=True) raised on datetime.date values (YAML
  timestamps) and on mixed-type mapping keys, turning a parseable
  frontmatter into a failed job with empty metadata - the base revision
  read those files fine.
- Comma-joining lists lost item boundaries (["a, b", "c"] read back as
  one ambiguous string), [] was indistinguishable from an empty string,
  and the whitespace collapse also mangled spaces inside serialized
  values.

_render_value is now a single tolerant renderer: bare strings keep their
text but have line breaks escaped; everything else goes through
json.dumps(ensure_ascii=False, default=str) (no key sort) so collections
stay structured and YAML-only types serialize; anything JSON still
cannot represent falls back to repr. Keys are rendered through the same
path so a multiline key cannot break the one-key-per-line layout either.
The structured metadata contract is untouched.

Also aligns the benchmark.yaml job description with the textual answer
(default.yaml already says 'one key: value per line') and the module
docstring now distinguishes the textual answer from the structured
payload in metadata.

Regression coverage: nested dates, mixed mapping keys, empty lists,
comma-containing items, significant whitespace, and a literal block
scalar with a real newline.

* fix(frontmatter-read): use json.dumps for all scalars to preserve string and mapping distinctions

Follow-up to the @jinliyl review on #564 (10-15 round 2):

- _render_value now sends every scalar through json.dumps rather than
  the str-only branch. The str-only branch collapsed a literal '\n'
  two-character sequence and an actual newline into the same rendered
  form ('\n') and lost the distinction between the string 'null'
  and YAML null. The JSON form preserves both.
- Mixed mapping key types (int 1 vs string '1') now round-trip with
  their JSON-form distinction in the answer, matching the metadata.
  Callers that re-parse the answer body as JSON still discard one
  value (this is a YAML-side limitation, not a renderer one); pinned
  by a regression test.
- Updated the three existing answer assertions to carry the new
  quoted scalar form, and added two regression tests:
  test_read_answer_distinguishes_newline_from_literal_backslash_n and
  test_read_answer_mixed_mapping_key_types_render_via_json.

Note: the str-only branch's '\n' escape was the only reason the
description: |- literal-block test in test_read_answer_tolerates_rich_yaml_types
rendered as 'line one\\nline two'. With the change, the same
description renders as '"line one\nline two"' (real newline, JSON-
escaped), which is exactly the fix the review asked for.

* fix(frontmatter-read): split key/value rendering so keys are not JSON-quoted

The round-2 change sent every scalar (including string keys) through
json.dumps, which added quotes around string keys. The rendered answer
came out as '- "name": "Cobalt"' instead of '- name: "Cobalt"' on
the round-2 head; the 5 new and updated tests in test_frontmatter_steps
all failed for that reason on Unit Tests - py3.11 through py3.14.

Split the renderer:
- _render_key: pass-through str(key) so the answer reads as '- key:'.
- _render_value: still json.dumps (with default=str and ensure_ascii=False)
  for the structural pinning the round-2 review asked for (literal
  '\n' vs actual newline, the string 'null' vs YAML null, mixed mapping
  key types). Caller formats the line as '- {key}: {value}'.

Updated the three existing answer assertions to match the key-unchanged,
value-quoted shape (e.g. '- name: "Cobalt"'). The two new tests added
in the round-2 commit (newline, mixed keys) were already pinned on the
right shape; the round-1 key-quote was the only bug.

* fix(frontmatter-read): JSON-encode keys too so every answer entry stays on one line

A multiline YAML key broke the one-key-per-line layout because keys were
interpolated raw. Route keys through the same json.dumps renderer as
values, update the expected answers to the quoted-key form, correct the
renderer docstring and mixed-key test comments (JSON collapses int 1 and
string "1" keys alike — the metadata keeps the distinction), and pin the
rich-type answer to the quoted "created": "2026-10-12" rendering.

* test(frontmatter-read): cover multiline keys, reseed YAML blocks as literal strings

Add the multiline-key regression the review asked for, restate the
mixed-mapping-key case as a documented presentation limitation (JSON
stringifies both keys, so a re-parser keeps only the last value), and
write the YAML seeds as triple-quoted literals so black stops joining
the implicit concatenations and pylint's implicit-str-concat goes quiet.

* refactor(frontmatter-read): simplify answer rendering

---------

Co-authored-by: jinli.yl <jinli.yl@alibaba-inc.com>
2026-10-28 16:19:15 +08:00
..
__init__.py init: reme version 0.4.0 (#284) 2026-06-22 15:41:19 +08:00
auto_resource_test_plugin.py feat(auto_resource): interpret image resources into daily notes (#500) 2026-09-07 12:00:38 +08:00
auto_resource_test_support.py feat(auto-resource): unify text and image auto-resource using agentwrapper (#555) 2026-09-23 10:20:35 +08:00
file_store_test_support.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_agent_state_io.py fix(agent): preserve Unicode separators in saved state (#594) 2026-10-05 11:25:37 +08:00
test_app_config_step.py feat: add workspace web APIs and star growth report (#416) 2026-08-05 18:03:37 +08:00
test_application_config.py feat: add entry-point plugin system and extract Auto Fin (#459) 2026-08-19 17:23:23 +08:00
test_as_embedding_lazy.py fix(embedding): isolate caches by vector space (#442) 2026-08-10 22:42:16 +08:00
test_as_llm_lazy.py feat(docker): add container deployment and multi-platform release workflow (#582) 2026-10-03 23:54:58 +08:00
test_async_utils.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_atomic_file_write.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_auto_dream.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_auto_image_steps.py feat(auto-resource): unify text and image auto-resource using agentwrapper (#555) 2026-09-23 10:20:35 +08:00
test_auto_memory_cc.py feat(evolve): tag auto-dream outputs (#538) 2026-09-11 14:08:29 +08:00
test_auto_memory_direct_images.py feat(auto-memory): save session images with source links (#574) 2026-10-09 17:42:13 +08:00
test_auto_memory_idempotency.py fix(dsh): recover memory backlogs and protect endpoint credentials (#653) 2026-10-21 18:58:29 +08:00
test_auto_memory_session_messages.py fix(auto-memory): serialize session transcript writes per session (#633) 2026-10-19 16:13:42 +08:00
test_auto_resource_agent_inputs.py feat(auto-resource): unify text and image auto-resource using agentwrapper (#555) 2026-09-23 10:20:35 +08:00
test_auto_resource_batch_lookup.py feat(auto-resource): unify text and image auto-resource using agentwrapper (#555) 2026-09-23 10:20:35 +08:00
test_auto_resource_review_regressions.py feat(auto-resource): unify text and image auto-resource using agentwrapper (#555) 2026-09-23 10:20:35 +08:00
test_auto_tag.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_background_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_base_agent_wrapper.py feat: refine local-first research and memory workflows (#444) 2026-08-11 23:32:34 +08:00
test_base_component.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_benchmark_docker.py feat(docker): Add Docker benchmark sandbox and pooled runner (#608) 2026-10-19 16:26:38 +08:00
test_benchmark_docker_queries.py feat(docker): Add Docker benchmark sandbox and pooled runner (#608) 2026-10-19 16:26:38 +08:00
test_benchmark_docker_upload.py feat(docker): Add Docker benchmark sandbox and pooled runner (#608) 2026-10-19 16:26:38 +08:00
test_benchmark_docker_workspace.py feat(docker): Add Docker benchmark sandbox and pooled runner (#608) 2026-10-19 16:26:38 +08:00
test_bm25_live_length.py fix(bm25): preserve the index when batch tokenization fails (#637) 2026-10-19 17:56:52 +08:00
test_cc_agent_wrapper.py feat(evaluation): track job calls and agent token usage in benchmarks (#406) 2026-08-04 11:42:18 +08:00
test_codex_agent_wrapper.py fix(codex): retain tool constraints until threads unload (#630) 2026-10-16 16:46:02 +08:00
test_codex_plugin_mcp.py feat(integrations): add automatic memory plugins for Claude Code and Codex (#575) 2026-10-12 20:12:47 +08:00
test_codex_plugin_runtime.py feat(integrations): add automatic memory plugins for Claude Code and Codex (#575) 2026-10-12 20:12:47 +08:00
test_coding_agent_plugins.py feat(integrations): add automatic memory plugins for Claude Code and Codex (#575) 2026-10-12 20:12:47 +08:00
test_common_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_compact_context.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_compaction_experiment.py refactor: generalize decision models and add recoverable context compaction (#626) 2026-10-19 17:56:30 +08:00
test_compaction_study.py refactor: generalize decision models and add recoverable context compaction (#626) 2026-10-19 17:56:30 +08:00
test_component_registry.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_compressor_step.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_config_parser.py fix(search): accept CLI queries that look like numbers (#612) 2026-10-16 10:36:05 +08:00
test_cookbook_config.py refactor(auto-fin): one note per topic, merged by a separate digest step (#558) 2026-09-20 14:52:56 +08:00
test_crud_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_daily_list_range.py feat(daily): add date-range queries and pagination (#685) 2026-10-27 15:38:56 +08:00
test_daily_note_links.py feat(auto_resource): reuse parsed resource ownership per batch (#529) 2026-09-14 16:55:42 +08:00
test_daily_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_decision_config.py refactor: generalize decision models and add recoverable context compaction (#626) 2026-10-19 17:56:30 +08:00
test_decision_demo.py refactor: generalize decision models and add recoverable context compaction (#626) 2026-10-19 17:56:30 +08:00
test_decision_model.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_default_file_chunker.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_docker_runtime.py feat(docker): add container deployment and multi-platform release workflow (#582) 2026-10-03 23:54:58 +08:00
test_dream_checkpoint_versions.py fix(auto-dream): preserve retries after invalid integration receipts (#654) 2026-10-22 11:22:32 +08:00
test_embedded_consumer_compat.py feat(docker): add container deployment and multi-platform release workflow (#582) 2026-10-03 23:54:58 +08:00
test_evaluation_interface.py feat(evaluation): track job calls and agent token usage in benchmarks (#406) 2026-08-04 11:42:18 +08:00
test_evolve_utils.py feat: auto-tag plugin-generated reports (#534) 2026-09-11 11:52:52 +08:00
test_faiss_index_maintenance.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_file_catalog.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_file_graph.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_file_sandbox_backend.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_file_store_consistency.py fix(embedding): recover over-limit items with a bounded input-shortening retry (#655) 2026-10-23 11:50:16 +08:00
test_frontmatter_steps.py fix(frontmatter-read): put the frontmatter in the answer, not just a key count (#564) 2026-10-28 16:19:15 +08:00
test_graph_snapshot_step.py feat: add frontend-ready wikilink graph APIs (#414) 2026-08-05 16:45:50 +08:00
test_hermes_agent_integration.py fix(hermes): preserve profile context and reset invalid provider state (#554) 2026-09-16 16:01:15 +08:00
test_http_client.py feat(service): support explicit wildcard network binds (#547) 2026-09-15 14:26:33 +08:00
test_http_web_workspace.py feat(jobs): add a unified enabled switch for all job types (#580) 2026-09-30 18:30:36 +08:00
test_injected_job_kwargs.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_job.py feat(jobs): add a unified enabled switch for all job types (#580) 2026-09-30 18:30:36 +08:00
test_json_file_chunker.py fix(chunker): restore malformed JSON text fallback (#557) 2026-10-14 14:43:27 +08:00
test_jsonl_file_chunker.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_keyword_index.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_line_anchor.py feat: simplify wikilink semantics and support line anchors (#412) 2026-08-05 11:47:50 +08:00
test_link_expansion.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_local_backend.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_local_embedding_store.py fix(embedding): recover over-limit items with a bounded input-shortening retry (#655) 2026-10-23 11:50:16 +08:00
test_logging_config.py feat: add Auto Fin cookbook and managed outbound proxy support (#392) 2026-07-25 18:09:39 +08:00
test_logo_utils.py feat(service): support explicit wildcard network binds (#547) 2026-09-15 14:26:33 +08:00
test_markdown_file_chunker.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_mcp_client.py feat(service): support explicit wildcard network binds (#547) 2026-09-15 14:26:33 +08:00
test_memlens_benchmark.py feat: add ReMe Image evaluation on MemLens (#640) 2026-10-26 15:07:16 +08:00
test_memlens_judge.py feat: add ReMe Image evaluation on MemLens (#640) 2026-10-26 15:07:16 +08:00
test_memlens_runner_failures.py feat: add ReMe Image evaluation on MemLens (#640) 2026-10-26 15:07:16 +08:00
test_mobilemem_audit.py feat: add ReMe Image evaluation on MobileMem-Omni (#641) 2026-10-26 15:20:23 +08:00
test_mobilemem_benchmark.py feat: add ReMe Image evaluation on MobileMem-Omni (#641) 2026-10-26 15:20:23 +08:00
test_mobilemem_judge.py feat: add ReMe Image evaluation on MobileMem-Omni (#641) 2026-10-26 15:20:23 +08:00
test_outbound_proxy.py feat: add Auto Fin cookbook and managed outbound proxy support (#392) 2026-07-25 18:09:39 +08:00
test_package_versions.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_packaging.py init: reme version 0.4.0 (#284) 2026-06-22 15:41:19 +08:00
test_path_bubble_backend.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_path_permission.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_plugin.py Separate benchmark judge plugins (#535) 2026-09-10 20:16:46 +08:00
test_plugin_cli.py fix(release): harden embedding store and plugins for ReMe 0.4.1.9 (#503) 2026-08-28 11:35:04 +08:00
test_prepared_search_filter.py perf(search): prepare search filters once per query (#591) 2026-10-14 18:14:21 +08:00
test_proactive_refresh.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_process_output_limits.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_prompt_handler.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_qwen_token_tools.py feat(token counter): add Qwen token counting utility with fallback (#616) 2026-10-16 11:58:35 +08:00
test_read_image_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_read_newlines.py fix(file-io): align newline reads and multiline edits (#643) 2026-10-26 14:40:46 +08:00
test_read_with_neighbors.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_reindex.py fix(reindex): return a readable summary so Studio stops showing a placeholder (#565) 2026-10-14 11:25:48 +08:00
test_reme_cli.py fix(python-execute): rename the timeout parameter to survive CLI client kwargs (#587) 2026-10-09 16:49:05 +08:00
test_runtime_context.py refactor: simplify core, Studio, and unit test scaffolding (#658) 2026-10-22 19:35:21 +08:00
test_sandbox_startup_cancellation.py feat(sandbox): Add Home AutoBash plugin and path-scoped execution sandboxes (#603) 2026-10-27 18:08:26 +08:00
test_search_empty_response.py fix(search): explain empty results in metadata (#647) 2026-10-23 15:53:44 +08:00
test_search_score_threshold.py fix(search): clarify score thresholds and warn above hybrid bound (#642) 2026-10-19 17:54:56 +08:00
test_search_step.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_service.py feat(jobs): add a unified enabled switch for all job types (#580) 2026-09-30 18:30:36 +08:00
test_service_utils.py feat(docker): add container deployment and multi-platform release workflow (#582) 2026-10-03 23:54:58 +08:00
test_session_image_assets.py feat(auto-memory): save session images with source links (#574) 2026-10-09 17:42:13 +08:00
test_shell_step.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_source_format_merge.py refactor: derive dialog paths from session_dir (#421) 2026-08-06 17:07:14 +08:00
test_status_step.py fix: skip dependency bindings in status memory walk (#510) 2026-08-31 16:24:41 +08:00
test_sync_qwenpaw_agentscope.py ci: sync AgentScope pin with QwenPaw (#569) 2026-10-12 17:16:01 +08:00
test_tag_index.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_threaded_watch.py fix(memory): preserve file consistency and decision client lifecycle (#672) 2026-10-26 13:08:02 +08:00
test_token_usage.py feat(evaluation): track job calls and agent token usage in benchmarks (#406) 2026-08-04 11:42:18 +08:00
test_tokenizer.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_utils.py feat(evaluation): track job calls and agent token usage in benchmarks (#406) 2026-08-04 11:42:18 +08:00
test_wikilink_utils.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_workspace_web_steps.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_write_metadata_lock.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00
test_zvec_file_store.py refactor: simplify async tests and shared response rendering (#662) 2026-10-23 13:10:45 +08:00