@a9i5k4/dsh-auto-memory 3.1.5 → 3.1.6
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/docs/CONTINUITY-FLOW.md +6 -6
- package/docs/HANDBOOK.md +54 -53
- package/docs/M-CM-PLAN.md +1 -1
- package/docs/M-CM-STATE.md +1 -1
- package/docs/M-CM7-HANDOFF-LAYERED-RETRIEVAL.md +1 -1
- package/docs/M3B-CONTRACT.md +7 -7
- package/docs/M7-AUTONOMOUS-STATE.md +1 -1
- package/docs/M7-TASKSET-DISPATCH.md +1 -1
- package/docs/PROMPT-PACK-LAYERED-RECALL.md +3 -3
- package/docs/PROMPT-SET-STRICT.md +3 -3
- package/docs/RELEASE-GO-NOGO.md +1 -1
- package/docs/STATUS-BOARD.md +1 -1
- package/docs/USER-GUIDE.en.md +21 -21
- package/docs/USER-GUIDE.zh-CN.md +21 -21
- package/docs/WHITEPAPER.md +1 -1
- package/docs/prompts/FIX-AGENT-P12-FULL-REGRESSION.md +1 -1
- package/docs/prompts/LIVE-VERIFY-ZCODE.md +2 -2
- package/docs/prompts/P2-semantic-recall.md +2 -2
- package/docs/prompts/P7-write-fix.md +1 -1
- package/docs/prompts/ZCODE-DROPIN.md +1 -1
- package/lib/acceptance.js +6 -6
- package/lib/activation-host.js +15 -14
- package/lib/activation-inbox-state.js +4 -4
- package/lib/activation-inbox.js +44 -44
- package/lib/board-mode.js +3 -3
- package/lib/client.js +193 -34
- package/lib/config-io.js +12 -12
- package/lib/context-bridge.js +22 -22
- package/lib/context-host.js +24 -23
- package/lib/datadir.js +95 -0
- package/lib/degrade.js +21 -21
- package/lib/dsh-home.js +8 -8
- package/lib/engine-identity.js +12 -12
- package/lib/engine-switch.js +3 -3
- package/lib/episodic-store.js +13 -13
- package/lib/evidence-agg.js +4 -4
- package/lib/evidence-store.js +12 -12
- package/lib/fact-store.js +47 -47
- package/lib/handoff-anchor.js +4 -4
- package/lib/hub-io.js +356 -3
- package/lib/index-sync.js +5 -5
- package/lib/index.js +381 -236
- package/lib/intent-clean-safe.js +3 -3
- package/lib/intent-clean.js +1 -1
- package/lib/l0-extract.js +15 -15
- package/lib/l0-index-sync.js +8 -8
- package/lib/l0-index.js +11 -11
- package/lib/ledger-criteria.js +8 -8
- package/lib/m4-corpus.js +1 -1
- package/lib/m7-index-sync-host.js +2 -2
- package/lib/m7-wire.js +24 -24
- package/lib/memory-anchor.js +1 -1
- package/lib/memory-envelope.js +15 -15
- package/lib/memory-hub.js +95 -50
- package/lib/memory-importance.js +7 -7
- package/lib/memory-mutation.js +5 -5
- package/lib/note-status-apply.js +2 -2
- package/lib/note-status.js +7 -7
- package/lib/policies/activation_policy_v2.json +2 -2
- package/lib/policies/recall_intent_lr_v1.json +1 -1
- package/lib/procedure-observation.js +2 -2
- package/lib/procedure-store.js +117 -28
- package/lib/python-setup.js +6 -5
- package/lib/python-sidecar-client.js +26 -26
- package/lib/recall-fusion.js +12 -12
- package/lib/recall-stats.js +36 -1
- package/lib/rerank-host.js +11 -11
- package/lib/rules-edit.js +9 -9
- package/lib/rules-layer.js +26 -26
- package/lib/semantic-decide.js +7 -7
- package/lib/semantic-js.js +13 -13
- package/lib/shadow-host.js +7 -6
- package/lib/shadow-retrieval.js +40 -40
- package/lib/skill-export-host.js +7 -7
- package/lib/skill-export.js +6 -6
- package/lib/state-commit.js +10 -10
- package/lib/storage-manage.js +6 -6
- package/lib/tier-layer-inject.js +28 -28
- package/lib/tier0-catalog.js +4 -4
- package/lib/wb-contract.js +45 -45
- package/lib/wb-sidecar.js +11 -11
- package/package.json +3 -4
- package/python/m7_activation_features_v2.py +7 -7
- package/python/m7_embedding_v1.py +12 -12
- package/python/policies/activation_policy_v2.json +2 -2
- package/python/policies/decision-record-activation-v2-delta-exp-override-20260824.json +1 -1
- package/python/policies/decision-record-reasoning-kind-admission-20260826.json +2 -2
- package/python/policies/decision-record-stale-gate-per-candidate-20260825.json +2 -2
- package/python/policies/recall_intent_lr_v1.json +1 -1
- package/python/verify_policy_artifact.py +3 -3
- package/python/worker_semantic_v1.py +18 -18
- package/python/worker_v1.py +18 -18
|
@@ -6,7 +6,7 @@ Extends the tested M7-0/M7-1 fake worker (python/worker_v1.py) WITHOUT
|
|
|
6
6
|
touching its protocol semantics: same JSONL framing, same validators, same
|
|
7
7
|
index_sync rejection matrix, same atomic derived-corpus persistence. Adds:
|
|
8
8
|
|
|
9
|
-
- after a successful index_sync commit: chunk (
|
|
9
|
+
- after a successful index_sync commit: chunk (m7_chunk_pre_v1) + embed
|
|
10
10
|
(frozen provider) every record and persist versioned vectors with an
|
|
11
11
|
identity block under <dsh-home>/memory/semantic/ (atomic replace)
|
|
12
12
|
- on startup: reuse persisted vectors only when the identity block
|
|
@@ -19,7 +19,7 @@ index_sync rejection matrix, same atomic derived-corpus persistence. Adds:
|
|
|
19
19
|
|
|
20
20
|
Embedding backend is selected by an optional JSON config file passed via
|
|
21
21
|
the DSH_M7_EMBEDDING_CONFIG environment variable (no CLI change, no JS
|
|
22
|
-
change): {"provider":"bge-m3-v1"|"hash-v1", "modelDir":...,
|
|
22
|
+
change): {"provider":"bge-m3-pre-v1"|"hash-pre-v1", "modelDir":...,
|
|
23
23
|
"modelRevision":..., "dimension":1024, "torchThreads":16}.
|
|
24
24
|
Without the env var the worker degrades to fake-worker behavior (protocol
|
|
25
25
|
alive, embedding not ready) - never crashes, never changes ack semantics.
|
|
@@ -51,24 +51,24 @@ SHADOW_TOP_K = 8
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def canonical_workspace_key(key):
|
|
54
|
-
"""Byte-twin of lib/evidence-store.js canonicalWorkspaceKey:
|
|
54
|
+
"""Byte-twin of lib/evidence-store-pre.js canonicalWorkspaceKey:
|
|
55
55
|
path.resolve + backslash->slash + lowercase."""
|
|
56
56
|
return os.path.abspath(str(key == None and '' or key)).replace('\\', '/').lower()
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
def wsref_of(workspace_key):
|
|
60
|
-
"""Byte-twin of evidence-store.js workspaceRefOf. JS owns identity;
|
|
60
|
+
"""Byte-twin of evidence-store-pre.js workspaceRefOf. JS owns identity;
|
|
61
61
|
this is a deterministic reproduction of its published pure function so
|
|
62
62
|
the worker can apply the workspace/scope/miv triple filter required by
|
|
63
63
|
the M7-7.5 hardening audit (P1: isolation must be explicit, never an
|
|
64
64
|
artifact of differing miv values)."""
|
|
65
65
|
canon = canonical_workspace_key(workspace_key)
|
|
66
66
|
return 'wsr_' + hashlib.sha256(
|
|
67
|
-
('evidence-wsref-v1\u0000' + canon).encode('utf-8')).hexdigest()[:32]
|
|
67
|
+
('evidence-wsref-pre-v1\u0000' + canon).encode('utf-8')).hexdigest()[:32]
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def _tokenize(text, stopwords=frozenset()):
|
|
71
|
-
"""
|
|
71
|
+
"""lexical_pre_v2 parity tokenizer: NFKC + CJK 2-gram + ascii tokens."""
|
|
72
72
|
t = unicodedata.normalize('NFKC', str(text)).lower()
|
|
73
73
|
out = []
|
|
74
74
|
for run in __import__('re').findall(r'[\u4e00-\u9fff]+|[a-z0-9_./-]+', t):
|
|
@@ -111,7 +111,7 @@ class LexicalBM25:
|
|
|
111
111
|
return s
|
|
112
112
|
|
|
113
113
|
# ---- M7-6 activation policy (default: shadow calibration only) ----
|
|
114
|
-
ACTIVATION_POLICY_VERSION = '
|
|
114
|
+
ACTIVATION_POLICY_VERSION = 'm7_semantic_threshold_pre_v1'
|
|
115
115
|
DEFAULT_ACTIVATION_POLICY = {
|
|
116
116
|
'mode': 'shadow', # 'shadow' = calibrate/log only; 'active' = emit frames
|
|
117
117
|
'tOn': 0.62, 'tOff': 0.52, # dual threshold, T_on > T_off (hysteresis)
|
|
@@ -166,7 +166,7 @@ class SemanticWorker(base.Worker):
|
|
|
166
166
|
# 'shadow'(默认)=只记 shadow 行零发射;'canary-explicit'=仅 explicit 车道
|
|
167
167
|
# 的 emit 决策发 activation_request 帧;'active' 预留。非法值回退 shadow
|
|
168
168
|
# (fail closed)。此开关属 JS/用户运营面,不进策略工件——阈值权威仍在
|
|
169
|
-
#
|
|
169
|
+
# activation_policy_pre_v2.json(append-only),发射节流依赖 M6 收件箱的
|
|
170
170
|
# 硬校验+cooldown+TTL+latest-wins,worker 侧不重复限速。
|
|
171
171
|
_em = str(self.embedding_config.get('activationEmitMode') or 'shadow')
|
|
172
172
|
self.activation_emit_mode = _em if _em in (
|
|
@@ -184,9 +184,9 @@ class SemanticWorker(base.Worker):
|
|
|
184
184
|
'policies')
|
|
185
185
|
try:
|
|
186
186
|
self._fv2 = featv2.load_and_verify_policy(
|
|
187
|
-
os.path.join(pol_dir, '
|
|
187
|
+
os.path.join(pol_dir, 'recall_intent_lr_pre_v1.json'),
|
|
188
188
|
os.path.join(pol_dir,
|
|
189
|
-
'
|
|
189
|
+
'activation_policy_pre_v2.json'))
|
|
190
190
|
except Exception as exc: # fail closed, retrieval unaffected
|
|
191
191
|
self._fv2_invalid = str(exc)[:200]
|
|
192
192
|
base.diag('featuresV2-policy-invalid: ' + self._fv2_invalid)
|
|
@@ -361,7 +361,7 @@ class SemanticWorker(base.Worker):
|
|
|
361
361
|
payload = {
|
|
362
362
|
'schemaVersion': 1,
|
|
363
363
|
'namespace': base.NAMESPACE,
|
|
364
|
-
'policyVersion': '
|
|
364
|
+
'policyVersion': 'semantic_vectors_pre_v1',
|
|
365
365
|
'identity': identity,
|
|
366
366
|
'workspaceRef': ws_ref,
|
|
367
367
|
'scope': scope,
|
|
@@ -627,7 +627,7 @@ class SemanticWorker(base.Worker):
|
|
|
627
627
|
if len(excerpt.encode('utf-8')) > 480:
|
|
628
628
|
excerpt = excerpt[:150]
|
|
629
629
|
cands.append({
|
|
630
|
-
'candidateId': '
|
|
630
|
+
'candidateId': 'cand_pre_' + base.first32(
|
|
631
631
|
base.sha_str('m7-semantic-cand\u0000' + obs + '\u0000' +
|
|
632
632
|
c['memoryId'] + '\u0000' + str(i))),
|
|
633
633
|
'memoryId': c['memoryId'], 'anchorId': c['anchorId'],
|
|
@@ -639,8 +639,8 @@ class SemanticWorker(base.Worker):
|
|
|
639
639
|
})
|
|
640
640
|
if not cands:
|
|
641
641
|
return None
|
|
642
|
-
activation_id = '
|
|
643
|
-
base.sha_str('m7-semantic-activation-v1\u0000' + obs))
|
|
642
|
+
activation_id = 'act_pre_' + base.first32(
|
|
643
|
+
base.sha_str('m7-semantic-activation-pre-v1\u0000' + obs))
|
|
644
644
|
created = req.get('sentAt', 0)
|
|
645
645
|
ttl = int(pol['ttlSteps'])
|
|
646
646
|
return {
|
|
@@ -736,7 +736,7 @@ class SemanticWorker(base.Worker):
|
|
|
736
736
|
|
|
737
737
|
# ---------- M7-7 judgement shadow (audit only, never writes) ----------
|
|
738
738
|
|
|
739
|
-
JUDGEMENT_POLICY = '
|
|
739
|
+
JUDGEMENT_POLICY = 'judgement_shadow_pre_v1'
|
|
740
740
|
|
|
741
741
|
_J_MARKERS = ('CORRECTION', 'UPDATED', 'REVISED', 'FREEZE',
|
|
742
742
|
'HARD RULE', 'DECISION reversing', '纠正', '更新:',
|
|
@@ -911,7 +911,7 @@ class SemanticWorker(base.Worker):
|
|
|
911
911
|
self._append_shadow({
|
|
912
912
|
'schemaVersion': 1,
|
|
913
913
|
'namespace': base.NAMESPACE,
|
|
914
|
-
'policyVersion': '
|
|
914
|
+
'policyVersion': 'semantic_shadow_pre_v1',
|
|
915
915
|
'observationId': str(p.get('observationId', '')),
|
|
916
916
|
'workerEpoch': str(req.get('workerEpoch', '')),
|
|
917
917
|
'memoryIndexVersion': miv,
|
|
@@ -1063,7 +1063,7 @@ class SemanticWorker(base.Worker):
|
|
|
1063
1063
|
|
|
1064
1064
|
def _intent_config_hash(self):
|
|
1065
1065
|
ip_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
|
1066
|
-
'policies', '
|
|
1066
|
+
'policies', 'recall_intent_lr_pre_v1.json')
|
|
1067
1067
|
try:
|
|
1068
1068
|
with open(ip_path, encoding='utf-8') as f:
|
|
1069
1069
|
ip = json.load(f)
|
|
@@ -1367,7 +1367,7 @@ def main():
|
|
|
1367
1367
|
args, _unknown = ap.parse_known_args()
|
|
1368
1368
|
if args.selftest:
|
|
1369
1369
|
base.run_selftest()
|
|
1370
|
-
w = SemanticWorker('ep', '', {'provider': 'hash-v1',
|
|
1370
|
+
w = SemanticWorker('ep', '', {'provider': 'hash-pre-v1',
|
|
1371
1371
|
'dimension': 64})
|
|
1372
1372
|
view = w.embedding_view()
|
|
1373
1373
|
assert view['enabled'] is True and view['ready'] is False
|
package/python/worker_v1.py
CHANGED
|
@@ -24,9 +24,9 @@ import sys
|
|
|
24
24
|
import tempfile
|
|
25
25
|
import time
|
|
26
26
|
|
|
27
|
-
PROTOCOL = '
|
|
28
|
-
NAMESPACE = 'dsh-auto-memory'
|
|
29
|
-
INDEX_POLICY = '
|
|
27
|
+
PROTOCOL = 'm7_wire_pre_v1'
|
|
28
|
+
NAMESPACE = 'dsh-auto-memory-pre'
|
|
29
|
+
INDEX_POLICY = 'index_sync_pre_v1'
|
|
30
30
|
MAX_LINE_BYTES = 256 * 1024
|
|
31
31
|
MAX_RECORDS_PER_PAGE = 64
|
|
32
32
|
# ★2026-09-17 修「索引永久不就绪 → 语义唤回全程降级」:JS 侧契约是「新 miv latest-wins;
|
|
@@ -47,9 +47,9 @@ PY_TYPES = frozenset(['health_result', 'context_ack', 'index_ack', 'activation_r
|
|
|
47
47
|
|
|
48
48
|
RE_MEMORY_ID = re.compile(r'^mem_[0-9a-f]{32}$')
|
|
49
49
|
RE_HEX64 = re.compile(r'^[0-9a-f]{64}$')
|
|
50
|
-
RE_IDX = re.compile(r'^
|
|
50
|
+
RE_IDX = re.compile(r'^idx_pre_[0-9a-f]{32}$')
|
|
51
51
|
RE_WSR = re.compile(r'^wsr_[0-9a-f]{32}$')
|
|
52
|
-
RE_OBS = re.compile(r'^
|
|
52
|
+
RE_OBS = re.compile(r'^obs_pre_')
|
|
53
53
|
RE_SOURCE_REF = re.compile(r'^(user|workspace|workspace-log):[A-Za-z0-9._\u4e00-\u9fff-]+$')
|
|
54
54
|
|
|
55
55
|
_stderr_used = {'n': 0}
|
|
@@ -84,7 +84,7 @@ def dumps(v):
|
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
def canonical(v):
|
|
87
|
-
"""Byte-identical twin of lib/m7-wire.js canonicalJson()."""
|
|
87
|
+
"""Byte-identical twin of lib/m7-wire-pre.js canonicalJson()."""
|
|
88
88
|
if v is None:
|
|
89
89
|
return 'null'
|
|
90
90
|
if isinstance(v, bool):
|
|
@@ -105,7 +105,7 @@ class ProtocolError(Exception):
|
|
|
105
105
|
self.detail = detail
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
# ---------- payload validators (mirror of lib/m7-wire.js) ----------
|
|
108
|
+
# ---------- payload validators (mirror of lib/m7-wire-pre.js) ----------
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
def validate_semantic_record(rec):
|
|
@@ -126,7 +126,7 @@ def validate_semantic_record(rec):
|
|
|
126
126
|
need(RE_HEX64.match(str(rec.get('recordDigest', ''))), 'recordDigest')
|
|
127
127
|
need(rec.get('heading') is None or isinstance(rec.get('heading'), str), 'heading')
|
|
128
128
|
need(isinstance(rec.get('text'), str), 'text')
|
|
129
|
-
need(isinstance(rec.get('chunkId'), str) and str(rec.get('chunkId')).startswith('
|
|
129
|
+
need(isinstance(rec.get('chunkId'), str) and str(rec.get('chunkId')).startswith('chk_pre_'), 'chunkId')
|
|
130
130
|
ordinal = rec.get('chunkOrdinal')
|
|
131
131
|
count = rec.get('chunkCount')
|
|
132
132
|
need(isinstance(ordinal, int) and not isinstance(ordinal, bool) and ordinal >= 0, 'chunkOrdinal')
|
|
@@ -219,7 +219,7 @@ class Worker:
|
|
|
219
219
|
|
|
220
220
|
def maybe_activation(self, req, p):
|
|
221
221
|
"""Deterministic fake ActivationRequestPre copied from JS-owned provenance.
|
|
222
|
-
Emits only when the frame carries valid identity +
|
|
222
|
+
Emits only when the frame carries valid identity + idx_pre_ index version;
|
|
223
223
|
otherwise stays silent (fail closed). Field-compatible with M6 validator."""
|
|
224
224
|
miv = str((p.get('index') or {}).get('memoryIndexVersion', ''))
|
|
225
225
|
if not RE_IDX.match(miv):
|
|
@@ -257,9 +257,9 @@ class Worker:
|
|
|
257
257
|
continue
|
|
258
258
|
if not RE_HEX64.match(fdig) or not RE_HEX64.match(rdig):
|
|
259
259
|
continue
|
|
260
|
-
activation_id = '
|
|
260
|
+
activation_id = 'act_pre_' + first32(sha_str('m7-fake-activation-pre-v1\u0000' + obs))
|
|
261
261
|
cand = {
|
|
262
|
-
'candidateId': '
|
|
262
|
+
'candidateId': 'cand_pre_' + first32(sha_str(activation_id + '\u0000' + mid + '\u0000' + str(i))),
|
|
263
263
|
'memoryId': mid,
|
|
264
264
|
'anchorId': aid,
|
|
265
265
|
'scope': rscope,
|
|
@@ -273,7 +273,7 @@ class Worker:
|
|
|
273
273
|
candidates.append(cand)
|
|
274
274
|
if not candidates:
|
|
275
275
|
return None
|
|
276
|
-
activation_id = '
|
|
276
|
+
activation_id = 'act_pre_' + first32(sha_str('m7-fake-activation-pre-v1\u0000' + obs))
|
|
277
277
|
created = req.get('sentAt', 0)
|
|
278
278
|
ttl_steps = 2
|
|
279
279
|
activation = {
|
|
@@ -290,7 +290,7 @@ class Worker:
|
|
|
290
290
|
'contextVersion': cv,
|
|
291
291
|
'memoryIndexVersion': miv,
|
|
292
292
|
'threshold': {
|
|
293
|
-
'policyVersion': '
|
|
293
|
+
'policyVersion': 'm7_fake_threshold_pre_v1',
|
|
294
294
|
'score': 0.92,
|
|
295
295
|
'threshold': 0.8,
|
|
296
296
|
'reason': 'deterministic fake activation (python worker)',
|
|
@@ -326,7 +326,7 @@ class Worker:
|
|
|
326
326
|
require(isinstance(p, dict), 'invalid-payload', 'not-object')
|
|
327
327
|
require(p.get('schemaVersion') == 1, 'invalid-payload', 'schemaVersion')
|
|
328
328
|
sync_id = str(p.get('syncId', ''))
|
|
329
|
-
require(sync_id.startswith('
|
|
329
|
+
require(sync_id.startswith('syn_pre_'), 'invalid-payload', 'syncId')
|
|
330
330
|
ws_ref = str(p.get('workspaceRef', ''))
|
|
331
331
|
require(RE_WSR.match(ws_ref), 'invalid-payload', 'workspaceRef')
|
|
332
332
|
scope = p.get('scope')
|
|
@@ -469,7 +469,7 @@ class Worker:
|
|
|
469
469
|
for i in range(st['pageCount']):
|
|
470
470
|
flat.extend(st['pages'][i])
|
|
471
471
|
expected_final = sha_hex(canonical({
|
|
472
|
-
'kind': '
|
|
472
|
+
'kind': 'index_sync_final_pre_v1',
|
|
473
473
|
'syncId': st['syncId'],
|
|
474
474
|
'memoryIndexVersion': st['memoryIndexVersion'],
|
|
475
475
|
'workspaceRef': st['workspaceRef'],
|
|
@@ -511,7 +511,7 @@ class Worker:
|
|
|
511
511
|
'records': e['records'],
|
|
512
512
|
})
|
|
513
513
|
payload = {'schemaVersion': 1, 'namespace': NAMESPACE,
|
|
514
|
-
'policyVersion': '
|
|
514
|
+
'policyVersion': 'semantic_derived_pre_v1', 'entries': entries}
|
|
515
515
|
data = (dumps(payload) + '\n').encode('utf-8')
|
|
516
516
|
try:
|
|
517
517
|
os.makedirs(dir_path, exist_ok=True)
|
|
@@ -584,10 +584,10 @@ def run_selftest():
|
|
|
584
584
|
assert frames[0]['frameId'] == 'res_' + first32(sha_str('r1:health_result'))
|
|
585
585
|
checks += 1
|
|
586
586
|
push = {'requestId': 'r2', 'workerEpoch': 'ep', 'sentAt': 20, 'frameId': 'f2', 'type': 'context_push',
|
|
587
|
-
'payload': {'kind': 'context_push', 'observationId': '
|
|
587
|
+
'payload': {'kind': 'context_push', 'observationId': 'obs_pre_' + '0' * 32,
|
|
588
588
|
'session': {'sessionId': 's', 'agentId': 'a', 'workspaceKey': 'w', 'scope': 'Workspace'},
|
|
589
589
|
'cursor': {'eventSeq': 1, 'contextVersion': 3},
|
|
590
|
-
'index': {'memoryIndexVersion': '
|
|
590
|
+
'index': {'memoryIndexVersion': 'idx_pre_' + 'ab' * 16}, 'memoryRefs': []}}
|
|
591
591
|
f2 = w.handle_frame(push)
|
|
592
592
|
assert len(f2) == 1 and f2[0]['payload']['accepted'] is True
|
|
593
593
|
again = w.handle_frame(push)
|