Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ REMEMBERSTACK_OPENROUTER_MAX_COMPLETION_TOKENS=32000
# effort literals. Example: pin flash models to none while keeping high for a
# reasoning model.
# REMEMBERSTACK_OPENROUTER_REASONING_EFFORT_MAP={"z-ai/glm-4.7-flash":"none","openai/gpt-5.6-luna":"high"}

# Restrict CHAT completions to named OpenRouter providers (allowlist of provider
# slugs, not quantization tags). `only` bounds the pool, so failover moves
# between these and can never leave them. Unset = ordinary marketplace routing.
# REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY=z-ai,novita,deepinfra,gmicloud
#
# How OpenRouter orders those providers: price | throughput | latency.
# Unset uses OpenRouter's default, which weights price heavily -- and the
# cheapest endpoint is usually the most contended, so every call AND retry
# lands on it and dead-letters together when it is overloaded. Note that
# allow_fallbacks does NOT rescue this: a provider-returned 429 is surfaced
# as "Provider returned error", not treated as the provider being unavailable.
# REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT=throughput
# Debug only: retain raw schema-invalid completions under the private app-state
# volume. Disabled by default because captured output may repeat source text.
# REMEMBERSTACK_OPENROUTER_INVALID_COMPLETION_CAPTURE_DIR=/var/lib/rememberstack/openrouter-invalid-completions
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/locomo/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"""The pinned RS-LoCoMo-Full-v20 benchmark adapter."""
"""The pinned RS-LoCoMo-Full-v21 benchmark adapter."""
2 changes: 1 addition & 1 deletion benchmarks/locomo/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def _parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="python -m benchmarks.locomo",
description=(
"RS-LoCoMo-Full-v20: prepare is local; ingest/answer/judge require "
"RS-LoCoMo-Full-v21: prepare is local; ingest/answer/judge require "
"explicit execution acknowledgements"
),
)
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/locomo/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ def load_manifest(tier: str) -> QuestionManifest:
)
if manifest.dataset_commit != DATASET_COMMIT:
raise DatasetValidationError(
"manifest dataset commit is not RS-LoCoMo-Full-v20"
"manifest dataset commit is not RS-LoCoMo-Full-v21"
)
if manifest.dataset_sha256 != DATASET_SHA256:
raise DatasetValidationError("manifest dataset hash is not RS-LoCoMo-Full-v20")
raise DatasetValidationError("manifest dataset hash is not RS-LoCoMo-Full-v21")
actual = item_ids_hash(item_ids=manifest.item_ids)
if actual != manifest.item_ids_sha256:
raise DatasetValidationError(
Expand Down
18 changes: 9 additions & 9 deletions benchmarks/locomo/model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Typed values for the full-system RS-LoCoMo-Full-v20 protocol."""
"""Typed values for the full-system RS-LoCoMo-Full-v21 protocol."""

from __future__ import annotations

Expand Down Expand Up @@ -28,11 +28,11 @@
Category = Literal[1, 2, 3, 4, 5]
RetainedCategory = Literal[1, 2, 3, 4]
Tier = Literal["smoke", "development", "publication"]
ProtocolKey = Literal["full-v20"]
ProtocolName = Literal["RS-LoCoMo-Full-v20"]
ProtocolKey = Literal["full-v21"]
ProtocolName = Literal["RS-LoCoMo-Full-v21"]
SourceTimezoneBasis = Literal["assumed_utc"]
AnswerAgentModel = Literal["openai/gpt-5.6-luna"]
JudgeModel = Literal["openai/gpt-5.6-luna"]
AnswerAgentModel = Literal["z-ai/glm-5.3-flash"]
JudgeModel = Literal["z-ai/glm-5.3-flash"]
FailureKind = Literal[
"readiness", "tool", "reader", "judge", "accounting", "invalid_response", "missing"
]
Expand Down Expand Up @@ -120,7 +120,7 @@ class QuestionManifest(FrozenModel):
class RunConfiguration(FrozenModel):
"""Immutable identity of one prepared benchmark run."""

protocol_name: ProtocolName = "RS-LoCoMo-Full-v20"
protocol_name: ProtocolName = "RS-LoCoMo-Full-v21"
adapter_version: NonEmpty
prepared_at: datetime
repository_revision: NonEmpty
Expand All @@ -139,10 +139,10 @@ class RunConfiguration(FrozenModel):
api_timeout_seconds: float = Field(default=60.0, gt=0)
knowledge_mode: Literal["not_composed"] = "not_composed"
document_binding_generation: Literal["document-t0-v1"] = "document-t0-v1"
answer_agent_model: AnswerAgentModel = "openai/gpt-5.6-luna"
answer_agent_model: AnswerAgentModel = "z-ai/glm-5.3-flash"
answer_agent_reasoning_effort: Literal["none"] = "none"
answer_word_cap: int | None = Field(default=None, ge=1)
judge_model: JudgeModel = "openai/gpt-5.6-luna"
judge_model: JudgeModel = "z-ai/glm-5.3-flash"
judge_reasoning_effort: Literal["none"] = "none"
answer_agent_temperature: float = Field(default=0.0, ge=0, le=2)
judge_temperature: float = Field(default=0.0, ge=0, le=2)
Expand Down Expand Up @@ -393,7 +393,7 @@ class SessionDiagnosticSummary(FrozenModel):
class RunSummary(FrozenModel):
"""Publication-ready local aggregate with no hidden denominator."""

protocol_name: ProtocolName = "RS-LoCoMo-Full-v20"
protocol_name: ProtocolName = "RS-LoCoMo-Full-v21"
protocol_fingerprint: NonEmpty
tier: Tier
questions: int = Field(ge=1)
Expand Down
46 changes: 25 additions & 21 deletions benchmarks/locomo/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
from rememberstack.model import Envelope
from rememberstack.model import ToolDescriptor

PROTOCOL_NAME: Final = "RS-LoCoMo-Full-v20"
DEFAULT_PROTOCOL_KEY: Final = "full-v20"
ADAPTER_VERSION: Final = "locomo-full-adapter-2026.09-complete-values-v20"
PROTOCOL_NAME: Final = "RS-LoCoMo-Full-v21"
DEFAULT_PROTOCOL_KEY: Final = "full-v21"
ADAPTER_VERSION: Final = (
"locomo-full-adapter-2026.09-complete-values-glm53-pinned-providers-v21"
)
MAX_TOOL_CALLS: Final = 8
MAX_AGENT_CALLS: Final = 9
ANSWER_READER_RETRY_BUDGET: Final = 2
Expand Down Expand Up @@ -87,30 +89,32 @@
EXPECTED_INGEST_MODEL_BINDINGS: Final[Mapping[str, str]] = MappingProxyType(
{
"chunk_embedding": "qwen/qwen3-embedding-8b",
"claim_extraction": "openai/gpt-5.6-luna",
"context_prefix": "openai/gpt-5.6-luna",
"claim_extraction": "z-ai/glm-5.3-flash",
"context_prefix": "z-ai/glm-5.3-flash",
"entity_observation_embedding": "qwen/qwen3-embedding-8b",
"fact_label": "openai/gpt-5.6-luna",
"observation_frontier": "openai/gpt-5.6-luna",
"observation_small": "openai/gpt-5.6-luna",
"fact_label": "z-ai/glm-5.3-flash",
"observation_frontier": "z-ai/glm-5.3-flash",
"observation_small": "z-ai/glm-5.3-flash",
"openrouter_chat_provider_only": "z-ai,novita,deepinfra,gmicloud",
"openrouter_chat_provider_sort": "throughput",
"openrouter_embedding_provider": "nebius",
"openrouter_embedding_provider_order": "unset",
"openrouter_max_completion_tokens": "32000",
"openrouter_reasoning_effort": "auto",
"openrouter_reasoning_effort_map": '{"openai/gpt-5.6-luna": "high"}',
"openrouter_reasoning_effort_map": '{"z-ai/glm-5.3-flash": "high"}',
"p1_embedding": "qwen/qwen3-embedding-8b",
"relation_normalization": "openai/gpt-5.6-luna",
"section_role": "openai/gpt-5.6-luna",
"section_summary": "openai/gpt-5.6-luna",
"skeleton_check": "openai/gpt-5.6-luna",
"structure_fallback": "openai/gpt-5.6-luna",
"supersession_frontier": "openai/gpt-5.6-luna",
"supersession_small": "openai/gpt-5.6-luna",
"relation_normalization": "z-ai/glm-5.3-flash",
"section_role": "z-ai/glm-5.3-flash",
"section_summary": "z-ai/glm-5.3-flash",
"skeleton_check": "z-ai/glm-5.3-flash",
"structure_fallback": "z-ai/glm-5.3-flash",
"supersession_frontier": "z-ai/glm-5.3-flash",
"supersession_small": "z-ai/glm-5.3-flash",
}
)
ANSWER_AGENT_MODEL: Final = "openai/gpt-5.6-luna"
ANSWER_AGENT_MODEL: Final = "z-ai/glm-5.3-flash"
ANSWER_AGENT_REASONING_EFFORT: Final = "none"
JUDGE_MODEL: Final = "openai/gpt-5.6-luna"
JUDGE_MODEL: Final = "z-ai/glm-5.3-flash"
JUDGE_REASONING_EFFORT: Final = "none"
TEMPERATURE: Final = 0.0

Expand Down Expand Up @@ -211,8 +215,8 @@ class LoCoMoProtocol:
answer_word_cap: int | None = None


_FULL_V20 = LoCoMoProtocol(
key="full-v20",
_FULL_V21 = LoCoMoProtocol(
key="full-v21",
name=PROTOCOL_NAME,
answer_agent_model=ANSWER_AGENT_MODEL,
judge_model=JUDGE_MODEL,
Expand All @@ -234,7 +238,7 @@ class LoCoMoProtocol:
)

PROTOCOL_REGISTRY: Final[Mapping[ProtocolKey, LoCoMoProtocol]] = MappingProxyType(
{_FULL_V20.key: _FULL_V20}
{_FULL_V21.key: _FULL_V21}
)


Expand Down
10 changes: 5 additions & 5 deletions benchmarks/locomo/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ def ingest_sample(
_require_current_ingest_bindings(model_bindings=build.model_bindings)
if build.document_binding_generation != EXPECTED_DOCUMENT_BINDING_GENERATION:
raise ExecutionGuardError(
"deployment document binding generation differs from RS-LoCoMo-Full-v20"
"deployment document binding generation differs from RS-LoCoMo-Full-v21"
)
_require_current_query_surface(context=context, client=client)
_require_exact_live_ingests(
Expand Down Expand Up @@ -570,7 +570,7 @@ def answer_sample(
):
raise ExecutionGuardError(
"the deployment did not report the exact completed"
" RS-LoCoMo-Full-v20 pipeline, live graph, and fresh P3 projection"
" RS-LoCoMo-Full-v21 pipeline, live graph, and fresh P3 projection"
)
_require_serving_revision(context=context, readiness=readiness)
prior_readiness = context.state.readiness.get(sample_id)
Expand Down Expand Up @@ -1177,7 +1177,7 @@ def _validate_run(
"""Recompute immutable run identity before any local or remote stage."""
selected_protocol = protocol_for_name(configuration.protocol_name)
if configuration.dataset_sha256 != DATASET_SHA256:
raise BenchmarkRunError("run dataset hash is not RS-LoCoMo-Full-v20")
raise BenchmarkRunError("run dataset hash is not RS-LoCoMo-Full-v21")
if item_ids_hash(item_ids=manifest.item_ids) != manifest.item_ids_sha256:
raise BenchmarkRunError("run manifest item hash changed")
if manifest_bytes_hash(manifest=manifest) != configuration.manifest_sha256:
Expand All @@ -1187,7 +1187,7 @@ def _validate_run(
if manifest.tier != configuration.tier:
raise BenchmarkRunError("run manifest tier changed")
if configuration.dataset_commit != DATASET_COMMIT:
raise BenchmarkRunError("run dataset commit is not RS-LoCoMo-Full-v20")
raise BenchmarkRunError("run dataset commit is not RS-LoCoMo-Full-v21")
if configuration.adapter_version != ADAPTER_VERSION:
raise BenchmarkRunError("run adapter version differs from current code")
if _models_hash(values=documents) != configuration.documents_sha256:
Expand Down Expand Up @@ -1445,7 +1445,7 @@ def _require_current_ingest_bindings(*, model_bindings: dict[str, str]) -> None:
if model_bindings.get(name) != expected.get(name)
)
raise ExecutionGuardError(
"deployment ingest model bindings differ from RS-LoCoMo-Full-v20: "
"deployment ingest model bindings differ from RS-LoCoMo-Full-v21: "
+ ", ".join(mismatches)
)

Expand Down
34 changes: 19 additions & 15 deletions benchmarks/locomo/sharding/run_shard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ run_dir=$2
dataset_path=$3
python_bin=${LOCOMO_PYTHON:-.venv/bin/python}
tier=${LOCOMO_TIER:-publication}
protocol=${LOCOMO_PROTOCOL:-full-v20}
protocol=${LOCOMO_PROTOCOL:-full-v21}
mount_root=${LOCOMO_MOUNT_ROOT:-$run_dir/.mounts}
max_documents=${LOCOMO_MAX_DOCUMENTS:-100}
max_questions=${LOCOMO_MAX_QUESTIONS:-1540}
Expand All @@ -50,28 +50,30 @@ export GOOGLE_APPLICATION_CREDENTIALS=${LOCOMO_GCP_CREDENTIALS_FILE:-/etc/rememb
export GOOGLE_API_CERTIFICATE_CONFIG=${LOCOMO_GCP_CERTIFICATE_CONFIG_FILE:-/etc/rememberstack/locomo-gcs/certificate-config.json}
export GOOGLE_API_USE_CLIENT_CERTIFICATE=true

# RS-LoCoMo-Full-v20's non-secret ingest identity. Override ambient self-host
# RS-LoCoMo-Full-v21's non-secret ingest identity. Override ambient self-host
# defaults so every shard runs the exact Luna/Qwen pipeline the protocol checks.
export REMEMBERSTACK_STRUCTURER_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_SKELETON_CHECK_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_ROLE_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_SUMMARY_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_STRUCTURER_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_SKELETON_CHECK_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_ROLE_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_SUMMARY_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_E1_EMBEDDING_MODEL=qwen/qwen3-embedding-8b
export REMEMBERSTACK_E1_PREFIX_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_E2_EXTRACT_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_E3_NORMALIZE_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_E1_PREFIX_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_E2_EXTRACT_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_E3_NORMALIZE_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_OBS_EMBEDDING_MODEL=qwen/qwen3-embedding-8b
export REMEMBERSTACK_OBS_SMALL_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_OBS_FRONTIER_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_ADJUDICATOR_SMALL_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_ADJUDICATOR_FRONTIER_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_OBS_SMALL_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_OBS_FRONTIER_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_ADJUDICATOR_SMALL_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_ADJUDICATOR_FRONTIER_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_P1_EMBEDDING_MODEL=qwen/qwen3-embedding-8b
export REMEMBERSTACK_P1_LABEL_MODEL=openai/gpt-5.6-luna
export REMEMBERSTACK_P1_LABEL_MODEL=z-ai/glm-5.3-flash
export REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER=nebius
unset REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER_ORDER
export REMEMBERSTACK_OPENROUTER_MAX_COMPLETION_TOKENS=32000
unset REMEMBERSTACK_OPENROUTER_REASONING_EFFORT
export REMEMBERSTACK_OPENROUTER_REASONING_EFFORT_MAP='{"openai/gpt-5.6-luna":"high"}'
export REMEMBERSTACK_OPENROUTER_REASONING_EFFORT_MAP='{"z-ai/glm-5.3-flash":"high"}'
export REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY=z-ai,novita,deepinfra,gmicloud
export REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT=throughput
export REMEMBERSTACK_OPENROUTER_INVALID_COMPLETION_CAPTURE_DIR=/var/lib/rememberstack/invalid-completions

[[ -x "$python_bin" ]] || die "Python is not executable: $python_bin"
Expand Down Expand Up @@ -139,6 +141,8 @@ attest_worker_environment() {
REMEMBERSTACK_ADJUDICATOR_FRONTIER_MODEL
REMEMBERSTACK_P1_EMBEDDING_MODEL
REMEMBERSTACK_P1_LABEL_MODEL
REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY
REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT
REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER
REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER_ORDER
REMEMBERSTACK_OPENROUTER_MAX_COMPLETION_TOKENS
Expand Down
4 changes: 4 additions & 0 deletions benchmarks/locomo/sharding/store_backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
"fact_label": "REMEMBERSTACK_P1_LABEL_MODEL",
"observation_frontier": "REMEMBERSTACK_OBS_FRONTIER_MODEL",
"observation_small": "REMEMBERSTACK_OBS_SMALL_MODEL",
"openrouter_chat_provider_only": "REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY",
"openrouter_chat_provider_sort": "REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT",
"openrouter_embedding_provider": "REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER",
"openrouter_embedding_provider_order": (
"REMEMBERSTACK_OPENROUTER_EMBEDDING_PROVIDER_ORDER"
Expand All @@ -69,6 +71,8 @@
"supersession_small": "REMEMBERSTACK_ADJUDICATOR_SMALL_MODEL",
}
UNSET_MODEL_BINDINGS = {
"openrouter_chat_provider_only": "unset",
"openrouter_chat_provider_sort": "default",
"openrouter_embedding_provider": "auto",
"openrouter_embedding_provider_order": "unset",
"openrouter_max_completion_tokens": "unset",
Expand Down
2 changes: 2 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ x-app: &app
REMEMBERSTACK_OPENROUTER_MAX_COMPLETION_TOKENS: ${REMEMBERSTACK_OPENROUTER_MAX_COMPLETION_TOKENS:-}
REMEMBERSTACK_OPENROUTER_REASONING_EFFORT: ${REMEMBERSTACK_OPENROUTER_REASONING_EFFORT:-}
REMEMBERSTACK_OPENROUTER_REASONING_EFFORT_MAP: ${REMEMBERSTACK_OPENROUTER_REASONING_EFFORT_MAP:-}
REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY: ${REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_ONLY:-}
REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT: ${REMEMBERSTACK_OPENROUTER_CHAT_PROVIDER_SORT:-}
REMEMBERSTACK_OPENROUTER_INVALID_COMPLETION_CAPTURE_DIR: ${REMEMBERSTACK_OPENROUTER_INVALID_COMPLETION_CAPTURE_DIR:-}
REMEMBERSTACK_SELFHOST_DEPLOYMENT_ID: ${REMEMBERSTACK_SELFHOST_DEPLOYMENT_ID}
REMEMBERSTACK_SELFHOST_DEPLOYMENT_SLUG: ${REMEMBERSTACK_SELFHOST_DEPLOYMENT_SLUG}
Expand Down
Loading