| 355 | |
| 356 | @dataclass |
| 357 | class MemoryAttachmentConfig(BaseConfig): |
| 358 | name: str |
| 359 | retrieve_stage: List[AgentExecFlowStage] | None = None |
| 360 | top_k: int = 3 |
| 361 | similarity_threshold: float = -1.0 |
| 362 | read: bool = True |
| 363 | write: bool = True |
| 364 | |
| 365 | @classmethod |
| 366 | def from_dict(cls, data: Mapping[str, Any], *, path: str) -> "MemoryAttachmentConfig": |
| 367 | mapping = require_mapping(data, path) |
| 368 | name = require_str(mapping, "name", path) |
| 369 | |
| 370 | stages_raw = mapping.get("retrieve_stage") |
| 371 | stages: List[AgentExecFlowStage] | None = None |
| 372 | if stages_raw is not None: |
| 373 | stage_list = ensure_list(stages_raw) |
| 374 | parsed: List[AgentExecFlowStage] = [] |
| 375 | for idx, item in enumerate(stage_list): |
| 376 | try: |
| 377 | parsed.append(AgentExecFlowStage(item)) |
| 378 | except ValueError as exc: |
| 379 | raise ConfigError( |
| 380 | f"retrieve_stage entries must be one of {[stage.value for stage in AgentExecFlowStage]}", |
| 381 | extend_path(path, f"retrieve_stage[{idx}]"), |
| 382 | ) from exc |
| 383 | stages = parsed |
| 384 | |
| 385 | top_k_value = mapping.get("top_k", 3) |
| 386 | if not isinstance(top_k_value, int) or top_k_value <= 0: |
| 387 | raise ConfigError("top_k must be a positive integer", extend_path(path, "top_k")) |
| 388 | |
| 389 | threshold_value = mapping.get("similarity_threshold", -1.0) |
| 390 | if not isinstance(threshold_value, (int, float)): |
| 391 | raise ConfigError("similarity_threshold must be numeric", extend_path(path, "similarity_threshold")) |
| 392 | |
| 393 | read_value = mapping.get("read", True) |
| 394 | if not isinstance(read_value, bool): |
| 395 | raise ConfigError("read must be boolean", extend_path(path, "read")) |
| 396 | |
| 397 | write_value = mapping.get("write", True) |
| 398 | if not isinstance(write_value, bool): |
| 399 | raise ConfigError("write must be boolean", extend_path(path, "write")) |
| 400 | |
| 401 | return cls( |
| 402 | name=name, |
| 403 | retrieve_stage=stages, |
| 404 | top_k=top_k_value, |
| 405 | similarity_threshold=float(threshold_value), |
| 406 | read=read_value, |
| 407 | write=write_value, |
| 408 | path=path, |
| 409 | ) |
| 410 | |
| 411 | FIELD_SPECS = { |
| 412 | "name": ConfigFieldSpec( |
| 413 | name="name", |
| 414 | display_name="Memory Name", |
nothing calls this directly
no test coverage detected