写入 Agent 永久记忆。 mem_type: feedback | experience | preference tags: 逗号分隔的相关性标签
(agent_id, mem_type, content, source_task='', tags='')
| 720 | |
| 721 | |
| 722 | def cmd_memory(agent_id, mem_type, content, source_task='', tags=''): |
| 723 | """写入 Agent 永久记忆。 |
| 724 | |
| 725 | mem_type: feedback | experience | preference |
| 726 | tags: 逗号分隔的相关性标签 |
| 727 | """ |
| 728 | MEMORY_DIR.mkdir(parents=True, exist_ok=True) |
| 729 | mem_file = MEMORY_DIR / f'{agent_id}.json' |
| 730 | |
| 731 | tag_list = [t.strip() for t in tags.split(',') if t.strip()] if tags else [] |
| 732 | entry = { |
| 733 | 'id': f'mem_{now_iso().replace(":", "").replace("-", "")[:15]}', |
| 734 | 'type': mem_type if mem_type in ('feedback', 'experience', 'preference') else 'experience', |
| 735 | 'content': content, |
| 736 | 'source_task': source_task, |
| 737 | 'created_at': now_iso(), |
| 738 | 'relevance_tags': tag_list, |
| 739 | 'pinned': False, |
| 740 | } |
| 741 | |
| 742 | def modifier(data): |
| 743 | if not data: |
| 744 | data = {'agent_id': agent_id, 'memories': [], 'stats': {'tasks_handled': 0}} |
| 745 | memories = data.get('memories', []) |
| 746 | memories.append(entry) |
| 747 | # FIFO 淘汰(pinned 除外) |
| 748 | if len(memories) > MAX_AGENT_MEMORIES: |
| 749 | unpinned = [m for m in memories if not m.get('pinned')] |
| 750 | pinned = [m for m in memories if m.get('pinned')] |
| 751 | # 淘汰最旧的 unpinned experience 类记忆 |
| 752 | unpinned.sort(key=lambda m: (m.get('type') == 'feedback', m.get('created_at', ''))) |
| 753 | memories = pinned + unpinned[-(MAX_AGENT_MEMORIES - len(pinned)):] |
| 754 | data['memories'] = memories |
| 755 | return data |
| 756 | |
| 757 | atomic_json_update(mem_file, modifier, {}) |
| 758 | log.info(f'🧠 {agent_id} 记忆写入: [{mem_type}] {content[:40]}...') |
| 759 | _append_audit(source_task or 'system', agent_id, 'memory', None, mem_type, content) |
| 760 | |
| 761 | |
| 762 | def cmd_task_memo(task_id, agent_id, decisions, warnings=''): |
no test coverage detected