memleaf 0.2.56__tar.gz → 0.2.58__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {memleaf-0.2.56 → memleaf-0.2.58}/CHANGELOG.md +13 -0
- {memleaf-0.2.56/src/memleaf.egg-info → memleaf-0.2.58}/PKG-INFO +4 -3
- {memleaf-0.2.56 → memleaf-0.2.58}/README.en.md +3 -2
- {memleaf-0.2.56 → memleaf-0.2.58}/README.md +3 -2
- {memleaf-0.2.56 → memleaf-0.2.58}/pyproject.toml +1 -1
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/__init__.py +1 -1
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/plugin.yaml +1 -1
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/single_pass_memory_planner.py +9 -62
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/single_pass_plan.py +2 -2
- {memleaf-0.2.56 → memleaf-0.2.58/src/memleaf.egg-info}/PKG-INFO +4 -3
- {memleaf-0.2.56 → memleaf-0.2.58}/LICENSE +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/MANIFEST.in +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/capture-budget-design.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/config-migrations.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/core-refactor.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/evidence-retention.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/extraction-latency.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/gate-evidence-boundary.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/general-processing.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/hermes-mcp-runtime.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/processing-quality-acceptance.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/docs/v0.2.26-processing-status.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/examples/README.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/examples/basic_usage.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/examples/mcp_stdio.ndjson +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/install.ps1 +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/install.sh +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/setup.cfg +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/__main__.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/adapters/__init__.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/adapters/antigravity.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/adapters/base.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/adapters/codex.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/adapters/hermes.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/admission.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/batch_review.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/budget.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/capture.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/cli.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/compaction.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/config.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/create_coordinator.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/credentials.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/evidence_budget.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/evidence_policy.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/evidence_structure.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/evidence_syntax.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/extraction_budget.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/extraction_capability.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/extraction_work_state.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/frontmatter.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/README.md +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/__init__.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/_mcp_client.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/_provider.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/_shared.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_provider/evidence_budget.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/hermes_runtime.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/host_events.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/host_runtime.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/inbox.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/index.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/inspection.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/installer.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/__init__.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/base.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/claude_compatible.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/gemini.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/openai_compatible.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/router.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/llm/thinking.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/locking.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/mcp_server.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/memory_commit.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/memory_planner.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/memory_writer.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/model_capabilities.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/model_discovery.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/model_execution.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/models.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/native_index.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/native_registration.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/parallel_model.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/planning_context.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/process_common.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/process_jobs.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/process_journal.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/process_owner.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/processing.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/prompts.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/provenance.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/recording_policy.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/redaction.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/retention.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/retrieval.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/retrieval_gate.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/scope_maintenance.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/scope_state.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/service.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/source_policy.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/state_layout.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/subprocess_flags.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/summary_batch.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/target_reconciliation.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/turn_audit.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/turn_plan.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/update_coordinator.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/update_review.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/validation.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf/vault.py +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf.egg-info/SOURCES.txt +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf.egg-info/dependency_links.txt +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf.egg-info/entry_points.txt +0 -0
- {memleaf-0.2.56 → memleaf-0.2.58}/src/memleaf.egg-info/top_level.txt +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to memleaf are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.2.58 — 2026-09-15
|
|
6
|
+
|
|
7
|
+
- Make `due_date` mean only the stated deadline of the todo action. Core no longer fills it from a candidate's other date mentions, which could describe the subject or desired outcome rather than when the action is due. The B3 contract says to omit the field unless that action deadline is explicit; any supplied date remains subject to candidate-local deadline validation.
|
|
8
|
+
- Remove the Core-side inference and ambiguous-date counter emission. Date-to-action association is semantic: when the evidence does not establish an unambiguous deadline for the todo itself, omission is safer than converting a nearby date into a deadline.
|
|
9
|
+
|
|
10
|
+
Verification for this release used 18 local synthetic regression tests with no model call and no production Vault write. They cover the action-deadline instruction, omission of an unsupported `due_date`, candidate-local date grounding and deadline-cue boundaries. Python 3.11 compilation and `git diff --check` pass; real-model adherence and a newly installed Hermes replay remain post-release runtime acceptance.
|
|
11
|
+
|
|
12
|
+
## 0.2.57 — 2026-09-14
|
|
13
|
+
|
|
14
|
+
- Let the model decide project ownership, and stop Core deciding it by string. Core required a model-selected project name to occur literally in the candidate's evidence, which cannot work: two descriptions of one project need share no substring, so "记录账单的项目" can never match a registered `记账`, and a literal test rejects a correct answer. It also cost whole memories. The reproduced turn is "跟你分享一下,最近在弄个记账的小玩意儿,就扔家里那台 N100 上跑,没打算上云"; the model named the project `记账小玩意儿`, the user wrote `记账的小玩意儿`, the literal test failed, and the candidate was deferred -- so the N100 deployment and the no-cloud decision were lost with the name. Deferring did not recover it either: deferred candidates are replayed from the journal rather than re-attempted, so a preview of that session makes zero model calls and processes zero turns. The guard is removed; a project name is a label, not a fact, and the model judges the ownership.
|
|
15
|
+
- State the rule generally, with no worked instance. The contract now says ownership is judged by meaning and never by wording, that a scope already listed in `scope_registry` is reused when the evidence means it even if the wording differs, and that a name does not have to appear in the evidence. A deferral is reserved for the case where the evidence is about a project but which project it is cannot be determined; a fact that simply has no project is `global` and is never deferred. An earlier draft stated that clause backwards and would have deferred every standing preference and environment fact. An earlier draft also carried a worked example naming one real project; an instance only ever helps the project it names, so it was removed and the same stability was obtained from the directive itself.
|
|
16
|
+
- Verification used the real model. 115 tests pass with no model call. Replaying the reproduced turn now writes the memory in both variants (with and without the assistant's reply). Four sentences were run against a registry holding one project: the same wording, a paraphrase ("我那个记录账单的小项目,部署挪到 Mac mini 上了"), an indirect reference, and an unrelated new project -- the first three all landed on the existing scope and the fourth correctly minted its own, so paraphrase is recognised and distinct projects are not merged. Six sentences carrying no project (a rule, a preference, an environment fact, a bare product mention) still resolved to `global` rather than deferring.
|
|
17
|
+
|
|
5
18
|
## 0.2.56 — 2026-09-14
|
|
6
19
|
|
|
7
20
|
- Keep assistant reports source-safe at candidate granularity. Markdown headings, paragraphs and list items become exact immutable evidence units with section context; broad whole-report `whole_unit` claims are deferred, while short unstructured replies remain intact. An assistant-only offer, question or forward commitment cannot establish user intent, but a factual report can still be admitted when its evidence and future value are independently grounded.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memleaf
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.58
|
|
4
4
|
Summary: A local-first Markdown memory core for AI agents
|
|
5
5
|
Author: memleaf contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,8 +23,9 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
25
25
|
|
|
26
|
-
> **版本:0.2.
|
|
27
|
-
>
|
|
26
|
+
> **版本:0.2.58。**
|
|
27
|
+
> 待办 `due_date` 只表示待办动作本身明确声明的截止日;Core 不再从候选证据中的其他日期自动补填。属于待办主题或预期结果的日期不会被误作截止日,无法确认动作截止日时就省略。
|
|
28
|
+
> 自动提取按助手回复中的 Markdown 结构建立候选级来源,过宽的整段引用和未被用户接受的助手意图不会形成记忆。项目归属由模型按语义判断,不再要求项目名在证据里逐字出现:同一个项目换个说法也能落到已有 Scope 上,名字也不再决定这条记忆的生死。日期和截止日期使用统一的边界安全解析,todo 只在候选自己的证据给出唯一明确截止日时填充。Markdown 仍是唯一事实源。
|
|
28
29
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
29
30
|
|
|
30
31
|
## 项目定位
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
[中文](README.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **Version: 0.2.
|
|
8
|
-
>
|
|
7
|
+
> **Version: 0.2.58.**
|
|
8
|
+
> A todo's `due_date` now means only the explicit deadline of the todo action. Core no longer fills it from other dates in candidate evidence; dates describing the todo's subject or desired outcome are not deadlines, and an unconfirmed action deadline is omitted.
|
|
9
|
+
> Automatic extraction now creates candidate-local source units from Markdown structure in assistant replies; broad whole-report citations and assistant-only intent are not allowed to create memories. Project ownership is the model's semantic judgement and no longer requires the project name to appear literally in the evidence: one project referred to in different words lands on the existing Scope, and the name no longer decides whether the memory survives. Dates and deadlines use one boundary-safe parser, and a todo receives a due date only when its own evidence supplies one unambiguous deadline. Markdown remains the sole source of truth with no SQLite runtime dependency. Acceptance covers deterministic regression suites and synthetic inputs; it does not claim real-mail or customer-business acceptance.
|
|
9
10
|
> **The current release supports Hermes and Codex.** Antigravity is not detected, installed, or configured.
|
|
10
11
|
|
|
11
12
|
## Project scope
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
6
6
|
|
|
7
|
-
> **版本:0.2.
|
|
8
|
-
>
|
|
7
|
+
> **版本:0.2.58。**
|
|
8
|
+
> 待办 `due_date` 只表示待办动作本身明确声明的截止日;Core 不再从候选证据中的其他日期自动补填。属于待办主题或预期结果的日期不会被误作截止日,无法确认动作截止日时就省略。
|
|
9
|
+
> 自动提取按助手回复中的 Markdown 结构建立候选级来源,过宽的整段引用和未被用户接受的助手意图不会形成记忆。项目归属由模型按语义判断,不再要求项目名在证据里逐字出现:同一个项目换个说法也能落到已有 Scope 上,名字也不再决定这条记忆的生死。日期和截止日期使用统一的边界安全解析,todo 只在候选自己的证据给出唯一明确截止日时填充。Markdown 仍是唯一事实源。
|
|
9
10
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
10
11
|
|
|
11
12
|
## 项目定位
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Local-first Markdown memory core for AI agents."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.2.
|
|
3
|
+
__version__ = "0.2.58"
|
|
4
4
|
|
|
5
5
|
from .config import DEFAULT_CONFIG, default_config, load_config, save_config
|
|
6
6
|
from .frontmatter import FrontmatterError, dump_frontmatter, dump_yaml, load_yaml, parse_frontmatter
|
|
@@ -10,7 +10,6 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import json
|
|
12
12
|
from copy import deepcopy
|
|
13
|
-
from dataclasses import replace
|
|
14
13
|
from typing import Any, Iterable, Mapping, Optional
|
|
15
14
|
|
|
16
15
|
from .admission import (
|
|
@@ -22,7 +21,6 @@ from .extraction_capability import supports_single_pass_protocol
|
|
|
22
21
|
from .memory_planner import (
|
|
23
22
|
MemoryPlanner,
|
|
24
23
|
_explicit_project_scope_authorizations,
|
|
25
|
-
_model_project_scope_is_source_grounded,
|
|
26
24
|
)
|
|
27
25
|
from .process_common import (
|
|
28
26
|
ProcessingError,
|
|
@@ -80,23 +78,6 @@ def _claim_date_evidence(
|
|
|
80
78
|
return result
|
|
81
79
|
|
|
82
80
|
|
|
83
|
-
def _fill_unambiguous_todo_deadline(
|
|
84
|
-
memory_type: Any,
|
|
85
|
-
summary: Mapping[str, Any],
|
|
86
|
-
deadline_dates: Iterable[str],
|
|
87
|
-
) -> tuple[dict[str, Any], bool]:
|
|
88
|
-
"""Fill an omitted todo date only when candidate evidence proves one deadline."""
|
|
89
|
-
|
|
90
|
-
normalized = dict(summary)
|
|
91
|
-
dates = {value for value in deadline_dates if isinstance(value, str)}
|
|
92
|
-
if memory_type != "todo" or normalized.get("due_date") is not None:
|
|
93
|
-
return normalized, False
|
|
94
|
-
if len(dates) == 1:
|
|
95
|
-
normalized["due_date"] = next(iter(dates))
|
|
96
|
-
return normalized, False
|
|
97
|
-
return normalized, len(dates) > 1
|
|
98
|
-
|
|
99
|
-
|
|
100
81
|
def _global_scope_conflicts_with_candidate_evidence(
|
|
101
82
|
scopes: Iterable[Any],
|
|
102
83
|
candidate_evidence: Iterable[Mapping[str, Any]],
|
|
@@ -423,8 +404,6 @@ class SinglePassMemoryPlanner(MemoryPlanner):
|
|
|
423
404
|
no_memory_by_unit: dict[str, str] = {}
|
|
424
405
|
observed_scopes: list[str] = []
|
|
425
406
|
requests: list[dict[str, Any]] = []
|
|
426
|
-
ambiguous_todo_deadlines: set[str] = set()
|
|
427
|
-
|
|
428
407
|
if not planning_units:
|
|
429
408
|
self._finalize_evidence_audit(
|
|
430
409
|
turn=turn,
|
|
@@ -543,33 +522,15 @@ class SinglePassMemoryPlanner(MemoryPlanner):
|
|
|
543
522
|
"global scope conflicts with an explicit project label",
|
|
544
523
|
validation_detail="scope_not_grounded",
|
|
545
524
|
)
|
|
546
|
-
#
|
|
547
|
-
#
|
|
548
|
-
#
|
|
549
|
-
#
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
end=len(claim["quote"]),
|
|
556
|
-
)
|
|
557
|
-
for claim in claims
|
|
558
|
-
if isinstance(claim, Mapping)
|
|
559
|
-
and isinstance(claim.get("unit_id"), str)
|
|
560
|
-
and claim["unit_id"] in by_unit
|
|
561
|
-
and isinstance(claim.get("quote"), str)
|
|
562
|
-
)
|
|
563
|
-
if decision in {"CREATE", "UPDATE"} and not _model_project_scope_is_source_grounded(
|
|
564
|
-
candidate,
|
|
565
|
-
candidate_scope_units,
|
|
566
|
-
validation_scope_registry,
|
|
567
|
-
authorized_project_scopes,
|
|
568
|
-
):
|
|
569
|
-
raise ModelOutputError(
|
|
570
|
-
"project scope is not grounded by this candidate's evidence",
|
|
571
|
-
validation_detail="scope_not_grounded",
|
|
572
|
-
)
|
|
525
|
+
# Ownership is a semantic judgement and belongs to the model, not
|
|
526
|
+
# to Core. Core used to require the project name to occur in the
|
|
527
|
+
# candidate's evidence, which cannot work: "记录账单的项目" and
|
|
528
|
+
# "记账" are the same project and share no substring, so a literal
|
|
529
|
+
# test rejects a correct answer, and a name the model composed from
|
|
530
|
+
# the user's own words ("记账小玩意儿" for "记账的小玩意儿") was
|
|
531
|
+
# refused and cost the whole memory. A project name is a label, not
|
|
532
|
+
# a fact, so the model's choice is kept; the guard against inventing
|
|
533
|
+
# ownership stays where it can be judged, in the contract.
|
|
573
534
|
if (
|
|
574
535
|
decision == "UPDATE"
|
|
575
536
|
and target_memory is not None
|
|
@@ -618,11 +579,6 @@ class SinglePassMemoryPlanner(MemoryPlanner):
|
|
|
618
579
|
summary["update_memory_id"] = target_memory.memory_id
|
|
619
580
|
else:
|
|
620
581
|
summary.setdefault("tags", [])
|
|
621
|
-
summary, deadline_is_ambiguous = _fill_unambiguous_todo_deadline(
|
|
622
|
-
memory_type, summary, deadline_dates
|
|
623
|
-
)
|
|
624
|
-
if deadline_is_ambiguous:
|
|
625
|
-
ambiguous_todo_deadlines.add(candidate_id)
|
|
626
582
|
summary["type"] = memory_type
|
|
627
583
|
summary["scopes"] = scopes
|
|
628
584
|
if isinstance(scope_source, str) and scope_source:
|
|
@@ -693,15 +649,6 @@ class SinglePassMemoryPlanner(MemoryPlanner):
|
|
|
693
649
|
},
|
|
694
650
|
)
|
|
695
651
|
|
|
696
|
-
if ambiguous_todo_deadlines:
|
|
697
|
-
metric = getattr(self.model, "_record_metric_event", None)
|
|
698
|
-
if callable(metric):
|
|
699
|
-
for _ in ambiguous_todo_deadlines:
|
|
700
|
-
metric(
|
|
701
|
-
{"stage": "single_pass", "operation": "single_pass_primary"},
|
|
702
|
-
"b3_due_date_ambiguous_count",
|
|
703
|
-
)
|
|
704
|
-
|
|
705
652
|
raw_defer_details = result.get("_defer_details") if isinstance(result, Mapping) else None
|
|
706
653
|
defer_details = (
|
|
707
654
|
{key: value for key, value in raw_defer_details.items()
|
|
@@ -148,10 +148,10 @@ Keep independently retrievable facts useful for future answers, actions, commitm
|
|
|
148
148
|
|
|
149
149
|
SCOPES
|
|
150
150
|
Legal values: global | domain:<name> | portfolio:<name> | project:<name> | unscoped. scopes is a nonempty array; at most one project:<name> per memory; unscoped must be the only value, and Core then records insufficient_context.
|
|
151
|
-
Scope to
|
|
151
|
+
Scope a candidate to a project when its evidence shows the user is doing that project's work, or shows that project owning the decision, state or deadline. Judge ownership by meaning, never by wording: name it with a short simple name, or reuse the scope already listed in scope_registry when the evidence means it, even if the wording differs. A name does not have to appear in the evidence. A platform, product or vendor mention alone is not ownership. Use global for a fact that no single project owns, such as a standing preference, a tool-wide or machine-wide rule, or an environment fact. Defer only when the evidence is about a project but which project it is cannot be determined; never guess a project, and never defer a fact that simply has none.
|
|
152
152
|
|
|
153
153
|
DATES
|
|
154
|
-
An evidence unit may carry an ISO-8601 UTC timestamp. Use it ONLY to resolve a relative, partial or yearless date that the unit's own text expresses; never borrow another unit's timestamp and never guess a missing year. The timestamp is an anchor, not content: never write its own date into a memory, and add no date the evidence text does not state. A date literal in a memory must appear in that memory's cited evidence, either verbatim or as the same month and day.
|
|
154
|
+
An evidence unit may carry an ISO-8601 UTC timestamp. Use it ONLY to resolve a relative, partial or yearless date that the unit's own text expresses; never borrow another unit's timestamp and never guess a missing year. The timestamp is an anchor, not content: never write its own date into a memory, and add no date the evidence text does not state. A date literal in a memory must appear in that memory's cited evidence, either verbatim or as the same month and day. due_date is only the stated deadline of the todo action, never a date belonging to its subject or desired outcome. Format it YYYY-MM-DD; otherwise omit it. Any memory carrying a date that no admitted evidence grounds is rejected and costs the whole turn, so defer instead of approximating.
|
|
155
155
|
|
|
156
156
|
{B3_COMPACT_CONTRACT}"""
|
|
157
157
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memleaf
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.58
|
|
4
4
|
Summary: A local-first Markdown memory core for AI agents
|
|
5
5
|
Author: memleaf contributors
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,8 +23,9 @@ Dynamic: license-file
|
|
|
23
23
|
|
|
24
24
|
[English](README.en.md) · [PyPI](https://pypi.org/project/memleaf/) · [GitHub](https://github.com/miffyblueboo/memleaf)
|
|
25
25
|
|
|
26
|
-
> **版本:0.2.
|
|
27
|
-
>
|
|
26
|
+
> **版本:0.2.58。**
|
|
27
|
+
> 待办 `due_date` 只表示待办动作本身明确声明的截止日;Core 不再从候选证据中的其他日期自动补填。属于待办主题或预期结果的日期不会被误作截止日,无法确认动作截止日时就省略。
|
|
28
|
+
> 自动提取按助手回复中的 Markdown 结构建立候选级来源,过宽的整段引用和未被用户接受的助手意图不会形成记忆。项目归属由模型按语义判断,不再要求项目名在证据里逐字出现:同一个项目换个说法也能落到已有 Scope 上,名字也不再决定这条记忆的生死。日期和截止日期使用统一的边界安全解析,todo 只在候选自己的证据给出唯一明确截止日时填充。Markdown 仍是唯一事实源。
|
|
28
29
|
> **当前版本支持 Hermes 和 Codex。** Antigravity(反重力)不检测、不安装、不配置。
|
|
29
30
|
|
|
30
31
|
## 项目定位
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|