dsh-cortex-memory 0.2.0-rc.11 → 0.2.0-rc.13

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.
package/client.js CHANGED
@@ -105,6 +105,11 @@ window.__ModuleLoader__.load({
105
105
  extractTitle: '从本地提取到记忆',
106
106
  extractHint: 'OCR/ASR 结果会写成一条派生记忆,不改原 trace。',
107
107
  extractTarget: '目标记忆',
108
+ extractLayout: '版面',
109
+ layoutAuto: '自动',
110
+ layoutSingle: '单栏',
111
+ layoutTwoColumn: '双栏',
112
+ layoutHandwriting: '手写',
108
113
  extractRun: '提取并写入',
109
114
  extractSaved: '已写入派生记忆',
110
115
  extractSuggested: '建议:当前这条',
@@ -363,6 +368,11 @@ window.__ModuleLoader__.load({
363
368
  extractTitle: 'Extract into memory',
364
369
  extractHint: 'OCR/ASR output is stored as a derived trace; the original trace is unchanged.',
365
370
  extractTarget: 'Target trace',
371
+ extractLayout: 'Layout',
372
+ layoutAuto: 'Auto',
373
+ layoutSingle: 'Single column',
374
+ layoutTwoColumn: 'Two columns',
375
+ layoutHandwriting: 'Handwriting',
366
376
  extractRun: 'Extract and write',
367
377
  extractSaved: 'Derived trace written',
368
378
  extractSuggested: 'Suggested: current trace',
@@ -1080,6 +1090,7 @@ button.cortex-badge:disabled{cursor:not-allowed;opacity:.55}
1080
1090
  const [uri, setUri] = useState('');
1081
1091
  const [mode, setMode] = useState('ocr');
1082
1092
  const [language, setLanguage] = useState('');
1093
+ const [layout, setLayout] = useState('auto');
1083
1094
  const [targetId, setTargetId] = useState(trace.id);
1084
1095
  const [candidates, setCandidates] = useState([{ id: trace.id, title: trace.title || trace.snippet || trace.id }]);
1085
1096
  const [busy, setBusy] = useState(false);
@@ -1110,7 +1121,7 @@ button.cortex-badge:disabled{cursor:not-allowed;opacity:.55}
1110
1121
  try {
1111
1122
  const result = await api('/attachments/extract', {
1112
1123
  method: 'POST',
1113
- body: JSON.stringify({ uri: uri.trim(), mode, language: language.trim() || undefined, traceId: targetId }),
1124
+ body: JSON.stringify({ uri: uri.trim(), mode, language: language.trim() || undefined, layout, traceId: targetId }),
1114
1125
  });
1115
1126
  setNote(`${t('extractSaved')} ${result.extractedTraceId ?? ''}`.trim());
1116
1127
  setUri('');
@@ -1129,6 +1140,12 @@ button.cortex-badge:disabled{cursor:not-allowed;opacity:.55}
1129
1140
  h('option', { key: 'asr', value: 'asr' }, 'ASR'),
1130
1141
  ]),
1131
1142
  h('input', { className: 'cortex-input', value: language, placeholder: mode === 'ocr' ? 'zh-Hans' : 'zh', onChange: (event) => setLanguage(event.target.value) }),
1143
+ h('select', { className: 'cortex-input', value: layout, title: t('extractLayout'), onChange: (event) => setLayout(event.target.value) }, [
1144
+ h('option', { key: 'auto', value: 'auto' }, t('layoutAuto')),
1145
+ h('option', { key: 'single', value: 'single' }, t('layoutSingle')),
1146
+ h('option', { key: 'two-column', value: 'two-column' }, t('layoutTwoColumn')),
1147
+ h('option', { key: 'handwriting', value: 'handwriting' }, t('layoutHandwriting')),
1148
+ ]),
1132
1149
  ]),
1133
1150
  h('label', { className: 'cortex-line', style: { marginTop: 8 } }, [
1134
1151
  t('extractTarget'),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-cortex-memory",
3
- "version": "0.2.0-rc.11",
4
- "description": "A local-first layered memory engine for DeepSeek Harness: temporal facts, hybrid retrieval, DSR forgetting, reflection, growth and controlled evolution.",
3
+ "version": "0.2.0-rc.13",
4
+ "description": "A layered, temporal, self-developing memory engine for DeepSeek Harness: working, episodic, semantic, procedural and reflective memory with hybrid retrieval, DSR forgetting, reflection, consolidation, gated self-evolution and guardian.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
7
7
  "icon": "./icon.svg",
package/src/api/routes.js CHANGED
@@ -299,6 +299,9 @@ export function createApiHandler({ cortex, logger = null, getExtractor = null }
299
299
  }
300
300
  if (route === '/forget') {
301
301
  const input = validateForget(body);
302
+ if (!input.id || typeof input.id !== 'string' || !input.id.trim()) {
303
+ return sendJson(response, 400, { ok: false, error: 'traceId is required' });
304
+ }
302
305
  if (!cortex.scopeWritableById('trace', input.id, agentOf(request))) {
303
306
  return sendJson(response, 403, { ok: false, error: 'scope-read-only' });
304
307
  }
@@ -369,6 +372,7 @@ export function createApiHandler({ cortex, logger = null, getExtractor = null }
369
372
  uri: requireString(body.uri, 'uri', { max: 2000 }),
370
373
  mode: requireString(body.mode, 'mode', { max: 16 }),
371
374
  language: body.language ? requireString(body.language, 'language', { max: 32 }) : undefined,
375
+ layout: body.layout ? requireString(body.layout, 'layout', { max: 16 }) : undefined,
372
376
  });
373
377
  const ingested = cortex.ingestExtractedText({
374
378
  targetTraceId: requireString(body.traceId, 'traceId', { max: 200 }),
@@ -589,6 +589,7 @@ export function createToolDefinitions(service) {
589
589
  output: TEXT_OUTPUT,
590
590
  isConcurrencySafe: () => true,
591
591
  async execute(args = {}) {
592
+ if (!args.id || !String(args.id).trim()) return { text: `没有这条记忆:${args.id}` };
592
593
  const trace = service.get(args.id);
593
594
  if (!trace) return { text: `没有这条记忆:${args.id}` };
594
595
  return {
@@ -730,6 +731,7 @@ export function createToolDefinitions(service) {
730
731
  output: TEXT_OUTPUT,
731
732
  isConcurrencySafe: () => false,
732
733
  async execute(args = {}) {
734
+ if (!args.id || !String(args.id).trim()) throw new Error('traceId is required');
733
735
  if (!service.scopeWritableById('trace', args.id)) return { text: '未执行:该记忆属于只读共享 scope。' };
734
736
  const result = service.forget({ traceId: args.id, mode: args.mode });
735
737
  if (!result.removed) {